oh-my-muse/design-docs/临时-02-market-install下游物化方案.md
lili 26ff1af374 docs(market): market install 下游物化方案设计文档(评审版、待 review 拍板)
market install 后下游物化方向(用户选)方案设计:深调研 2 agent+spot-check 坐实两物化断点——install 只写 muse_market_installation 与 ai/knowledge 解耦、KB bind kbId=parseLong(sourceId)不建本地 muse_knowledge_base 行致检索 no_dataset 第四门省略、agent slot 放宽但 runtime requireVisibleAgent 拒裸引用。出 C(完整物化)/B(惰性)/B(installed_ref 最小留痕)/暂缓 四方案对比。

推荐 B(installed_ref 最小留痕、KB 优先共享发布者 dataset、物化落点放目标域绑定路径非 install——handoff 非物化桥、安装解耦正确不应改)。地基不对称坐实:KB(V5 kb_type/source_market_asset_id)+agent(V27 source_market_asset_id、注释物化后续主线本列先就位)列已备、但 agent market_installed 类型有文档(后端-04)无实现→两域工程量不同。决策点待拍板:物化深度(倾向 B)、时机(绑定同步非惰性)、dataset 共享 vs 复制(唯一硬风险、共享前必验多租户 RAGFlow 隔离)、agent market_installed 落地量(否则 KB 先行)、召回回滚。两图文+大纲注册。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-26 06:47:45 -07:00

34 KiB
Raw Blame History

临时-02 · Market Install 下游物化方案(评审版)

  • 版本v1评审版待人类 review 后拍板,不改任何代码)
  • 更新日期2026-06-26
  • 目标读者:架构 / 后端 / 产品 / PR reviewer
  • 阅读时间2030 分钟
  • 文档性质:临时件(评审/决策依据,落定后归并入正式分册或删除,不作长期 SSOT。本稿只做问题诊断、方案对比与决策收束不改代码、不定义新概念术语以 架构-02 为准,表结构归 后端-04,跨 BC 协作与 handoff 边界归 架构-01 / 架构-02 §7授权快照承载归 ADR-020。
  • 配套人读图:临时-02-market-install下游物化方案.html

一句话结论:用户从市场安装一个智能体或知识库后,点不出可用效果——知识库检索永远静默落到“无数据集”而命不中,智能体在生成任务里被运行期直接拒绝。根因不是安装坏了,而是安装按设计与 AI/知识两域完全解耦、只记账不物化,而本该承接物化的“绑定/槽位替换”这一步当前也只写了引用绑定、没有在安装者租户里造出真正可用的实体。本文把四个物化深度(完整物化 C / 最小留痕 B' / 纯引用按需物化 B / 暂缓)摆开权衡,推荐以 B'installed_ref 最小留痕,知识库优先共享发布者数据集)作为打通“可真用”的最小正确步,完整物化 C 作为远期演进,并明确把物化落点放在目标域的绑定路径而非安装本身。


1. 问题与现状

1.1 用户视角的症状

一个普通用户在市场里看中一个智能体资产或知识库资产,走完“获取授权 → 安装到账户”,界面会如实告诉他“已安装”。接着他按产品引导进入作品工作台,把这个知识库绑定到作品的知识来源、或把这个智能体替换进作品的某个开放槽位,绑定动作也会成功返回。一切看起来都对。

然后他开始写作、触发 AI 生成,问题就暴露了:

  • 装的是知识库:生成出来的内容完全没有用到这个知识库里的资料。检索环节没有报错,也没有任何“这个来源不可用”的提示,知识库就像不存在一样被静悄悄跳过了。用户会以为是自己资料没选对,反复检查也找不到原因。
  • 装的是智能体AI 任务直接失败,提示“智能体不存在”或“无权使用该智能体”,尽管这个智能体在市场上明明白白标着“已安装、已绑定槽位”。

也就是说,对市场安装来的智能体/知识库,“已安装、已绑定”到“真正生效”之间存在一道断崖。产品文档(产品-02D / 产品-02E / 流程-02B)描述的理想链路是“可发现 → 已授权 → 已安装到账户 → 已绑定作品 → 已用于生成/检索”,现状卡死在最后一跳。

需要先澄清一个容易误判的点:这不是市场发布侧的问题。发布者把自己的智能体/知识库上架成市场资产admin 审核通过、markListed)这条链路是通的、已活体验证过。本文要解决的是反方向——安装者把市场资产变成自己租户里能真正跑起来的实体即“install 侧下游物化”。

1.2 设计意图:安装解耦是对的,物化本就该在目标域发生

先肯定现状的合理部分,避免把正确的解耦当成 bug 去“修”。

架构-02流程-02B 的设计,市场的边界非常清楚:授权不等于安装,安装不等于绑定,绑定不等于写入作品事实。市场只负责发现、授权、安装记账和发起一次性跳转handoff不是任何作品事实、智能体绑定、知识来源绑定的最终写入空间。安装这一步只写“账户可用资产”,刻意不去碰 AI、知识、内容三域的事实——这是数据主权和 owner 边界的体现,是对的,不应该改

那么物化(把市场资产变成可用实体)本该在哪里发生?答案也在设计里:目标域的绑定/槽位替换路径。用户从市场跳转进入知识库工作台/智能体工作台后,由目标域 owner 自己做预检、消费一次性 handoff token、在自己的事务里写下 owner 事实。换句话说,“物化”这个动作的正确落点是目标域的 createKnowledgeBinding / bindAgentSlot,而不是市场的 installMarketplaceAsset

现状的真正缺陷因此可以精确表述为:目标域的绑定路径只写了“引用绑定”,没有顺手把可用实体物化出来。 安装的解耦没错,错在物化这一步在目标域被遗漏了。

1.3 两个物化断点的机理

断点①:知识库检索的“数据集门”永远拿不到数据集

知识库检索对每个绑定的来源顺序过四道门(MuseKnowledgeRetrievalApiImpl.retrieveForWorkmuse-module-knowledge/.../api/MuseKnowledgeRetrievalApiImpl.java:96-137):用途门(绑定用途须含检索)、授权快照门(须有授权快照)、来源状态门(须有来源状态投影且状态未被阻断)、以及数据集门。前三门,市场安装来的知识库都能过:绑定时写了检索用途、写了授权快照、写了来源状态投影(状态 active。卡死在第四门。

第四门做的事是(MuseKnowledgeRetrievalApiImpl.java:122-127

dataset = selectActiveDatasetByKbId(kbId)
if (dataset == null || dataset.ragflowDatasetId 为空) {
    记为 OmittedSource(kbId, "no_dataset", ...)   // 静默省略,不报错
    continue
}

它要求本地存在一行把这个知识库映射到一个 RAGFlow 数据集的记录(muse_knowledge_ragflow_binding 表里 kb_id=? AND status='active' AND document_id IS NULL 的“数据集级”行)。而这行只在“本地上传文档、首次为该知识库创建 RAGFlow 数据集”时才会落库MuseKnowledgeDocumentService.persistDatasetBinding)。

市场安装路径从不上传文档、从不创建数据集,所以这行根本不存在。更深一层的原因是:绑定时根本没有为这个安装来的知识库创建本地知识库实体。绑定服务(MuseKnowledgeBindingService.createKnowledgeBindingmuse-module-knowledge/.../application/muse/MuseKnowledgeBindingService.java:129)只 insert 了两行——一行绑定事实、一行来源状态投影——而且它写入的 kbId 是直接把外部来源 idsourceId)当字符串解析成数字塞进去的,并不是任何已物化的本地知识库主键。没有本地知识库实体,自然就没有它名下的数据集映射,第四门必然返回 null。

后果是“静默命不中”:检索把这个来源记为 no_dataset 并入“被省略来源”,但整个检索仍按 fail-closed 设计返回(空或部分结果),不抛错、不阻断主生成链。用户因此看不到任何报错,只是结果里没有这个知识库的内容。这种“假装成功的失败”比直接报错更难排查。

P1 阶段曾有一条 knowledge handoff 的 e2e 测试是绿的,那是 fixture 巧合——测试用的资产恰好映射到一个种子数据里已存在数据集的 kb_id绕过了这个断点不代表真实安装链路通。

断点②:智能体在运行期被“二次校验”拒绝

智能体这边的机理不同,关键在于绑定期和运行期用了两套宽严不同的校验

绑定(槽位替换)期(MuseAgentSlotServiceImplmuse-module-ai/.../application/muse/MuseAgentSlotServiceImpl.java):对市场来源的绑定,预检和绑定都调 requireVisibleSourceAgent,但带了一个 marketHandoff=true 的放宽参数,只放宽了“智能体属主可见性”这一项(即接纳类型为 market、非本人所有的智能体其合法性改由市场一次性 handoff token 背书。需要强调的是:“智能体存在且 active、且有 active 版本”这一条,绑定期并没有放宽

运行期(MuseAiTaskServiceImpl.resolveAgentForTaskrequireVisibleAgentmuse-module-ai/.../application/muse/MuseAiTaskServiceImpl.java:306,321):创建 AI 任务时,用绑定里存的智能体 id 重新解析一次真实智能体。这条路径不带任何 marketHandoff 放宽,一律按“系统智能体、或本人所有的用户智能体,且必须有 active 版本”来校验,否则抛 AI_AGENT_NOT_EXISTS / AI_AGENT_SCOPE_FORBIDDEN

把两者合起来:市场安装从不在安装者租户里物化任何智能体实体(muse_agent / muse_agent_version),槽位绑定写进去的只是一个裸引用(一个指向 market 出身的 agentId。到了运行期这个裸引用被重新解析既找不到对应的本地智能体行即便找到也过不了“本人所有 + active 版本”的校验,于是被拒。这就是“槽位放宽接纳、运行期拒绝”的断层。

一个智能体要在运行期真正可用,最小充分条件是三条:①安装者租户里有 muse_agent 行且 status=active②可见系统智能体或本人所有的用户智能体③有一行 status=active 的 muse_agent_version。三者缺一即被运行期拒。

1.4 现状代码诚实标注(无伪装,缺口是已知的)

值得肯定的是,现状代码没有用假数据掩盖缺口,到处是诚实的占位标注:安装服务把绑定摘要显式写成 targetFactsWritten=falseMarketInstallServiceImpl.java:95-96,199);知识库侧标注“当前没有 Market 安装表 / 现阶段没有独立 installed 表”market 模块 .agent 明确把“install 后下游物化(资产变可用 agent/kb”列为仍缺的 TODO。这意味着本方案不是去推翻一个错误实现,而是去补一个被有意识地推迟了的物化步骤。


2. 物化方案对比C / B' / B / 暂缓)

四个方案的本质区别是物化深度把市场资产变成安装者可用实体时造多“真”的实体、复制还是共享底层数据集。下面每个方案给出做什么WHAT、怎么做的要点HOW以及在用户价值、工程成本、跨租户、数据集复制还是共享、授权追溯、幂等六个维度上的权衡。

重要前提(影响成本判断):后端-04 与现网 schema 已为物化预留了一半地基。知识库根表 muse_knowledge_base 在 V5 就带了 kb_type(取值含 installed_ref)、source_market_asset_idlicense_snapshot_id 三列,只是绑定/安装路径从不写它。智能体侧则有文档无实现后端-04 写了 muse_agent 区分 system/user/market_installed,但现网 muse_agent 的建表与代码只用 system/usermarket_installed 从未落地。这条不对称直接影响 C/B' 在两域的工程量。

2.1 方案 C完整物化

WHAT:安装(或首次绑定)时,把市场资产复制成安装者租户内一份独立、自洽的实体。知识库 → 在安装者租户新建一行 muse_knowledge_basekb_type=user 或独立类型),并复制一份 RAGFlow 数据集(把发布者数据集的文档/切块克隆到安装者名下的新数据集);智能体 → 在安装者租户新建 muse_agent + active muse_agent_version,复制发布者的 prompt/模型绑定/参数配置。

HOW 要点:安装链路新增对 knowledge/ai 的 facade 调用(或事件),触发“按市场资产快照建实体”;知识库需调 RAGFlow 创建新数据集并发起文档复制 + 重新解析/切块/索引(这是异步重活);智能体需把发布版本 config 落成本地 active 版本;两者都要在物化实体上写 source_market_asset_id 之类的来源溯源列。

权衡

  • 用户价值:最高。安装者拿到完全自洽、可独立演进的副本,发布者后续下架/改版不影响已安装副本的可用性(除非授权失效)。
  • 工程成本:最高。数据集复制涉及跨 RAGFlow 的文档搬运 + 全量重解析重索引,是异步长任务,要处理失败/重试/部分成功;智能体侧还要先把 market_installed 类型从“文档概念”落成真实 schema + 代码分支。
  • 跨租户:副本天然隔离,无共享带来的可见性纠葛。
  • 数据集:复制。存储和索引成本随安装数线性放大N 个安装者 = N 份数据集)。
  • 授权追溯:副本与来源的关系靠 source_market_asset_id + 授权快照维系;但副本一旦独立,来源召回时要不要连带停用副本,是个需要明确的策略问题。
  • 幂等:复制是重操作,重复安装的幂等更难做(要避免重复克隆数据集),需在物化任务层做幂等键。

2.2 方案 B'installed_ref 最小留痕(推荐)

WHAT:不复制资产,而是在安装者租户建一行轻量的“安装引用型”实体,让检索/运行期能解析到它,底层数据集/配置优先共享发布者的。知识库 → 建一行 muse_knowledge_basekb_type=installed_refsource_market_asset_id 指回市场资产、license_snapshot_id 记授权来源),并为它建一行指向发布者已有 RAGFlow 数据集muse_knowledge_ragflow_binding数据集级、status=active使第四门能拿到数据集智能体 → 建一行 muse_agentmarket_installed 型,溯源指回市场资产)+ 一行引用发布者版本 config 的 active muse_agent_version,使运行期 requireVisibleAgent 能解析通过。

HOW 要点:物化落点放在目标域绑定路径(知识库 createKnowledgeBinding:129、智能体 bindAgentSlot)——这两处本就在消费 handoff token、本就在写绑定事实的同一个事务里顺手补建 installed_ref 实体 + 数据集映射(知识库)/ active 版本(智能体)即可,原子性天然有保证。知识库的数据集门改为:解析 kbId 时若是 installed_ref则用其 source_market_asset_id 找到发布者知识库的数据集 id 来填 muse_knowledge_ragflow_binding。运行期智能体解析需要识别 market_installed 型并按授权快照放行(这要求把 requireVisibleAgent 的校验从“仅 system/属主 user”扩展到“+ 授权有效的 market_installed”

权衡

  • 用户价值:高,且是打通“可真用”的最小正确步。检索能命中、智能体能跑,用户拿到的就是发布者那份内容/能力。
  • 工程成本:中。知识库侧地基已备(installed_ref + source_market_asset_id 在 V5 就有),主要工作是绑定路径补建实体 + 第四门兼容 installed_ref不碰 RAGFlow 文档复制这件重活;智能体侧需要先把 market_installed 落成真实 schema + 运行期校验放行,工程量略大于知识库。
  • 跨租户:这是 B' 的主要风险点。多个安装者的 installed_ref 知识库共享发布者同一个 RAGFlow 数据集,检索时跨租户读同一份索引,必须确认 RAGFlow 侧/检索门的租户与授权隔离不被绕过;而且 muse_knowledge_ragflow_binding 有唯一约束 (tenant_id, kb_id) WHERE status='active' AND document_id IS NULL(一个 kb 一个 active 数据集),当前 kbId 取的是 sourceId 字面值,跨租户/跨用户复用同一 kbId 值时这个唯一键的行为必须在方案里明确(建议 installed_ref 用安装者租户内新分配的 kb 主键,而非沿用 sourceId
  • 数据集:共享。存储/索引成本不随安装数放大,是 B' 相对 C 的最大成本优势。
  • 授权追溯清晰。installed_ref 行的 source_market_asset_id + license_snapshot_id 把“我能用是因为装了哪个市场资产、凭哪份授权”钉死,符合 架构-02 “引用对象必须保存快照 id”的要求。
  • 幂等:轻量 insert配合“按 (作品, 来源) 或 (租户, 市场资产) 唯一 + 命令回放”即可幂等,远易于 C 的数据集克隆幂等。

2.3 方案 B纯引用 + 按需物化

WHAT:安装和绑定都只留引用(维持现状的引用绑定),把物化推迟到“第一次真正使用时”惰性触发——知识库第一次被检索命中前、智能体第一次被任务解析前,才即时建实体/数据集映射。

HOW 要点:在检索第四门返回 null 的分支、运行期智能体解析失败的分支里,不直接判负,而是先尝试“按引用惰性物化”再重试一次;物化产物落 installed_ref同 B' 的实体形态),只是触发时机从绑定推迟到首次使用。

权衡

  • 用户价值:终态与 B' 相同(能命中、能跑),但首次使用有延迟(首检索/首生成要等物化完成,知识库若涉及数据集准备甚至是秒级以上)。
  • 工程成本:反而比 B' 高。惰性物化要在“读路径/运行热路径”里插入写操作和外部调用,破坏了读写分离,要处理并发首用的竞态(两个请求同时触发物化)、热路径里的失败回退、以及“物化中”这个中间态的用户反馈。把复杂度从一次性的绑定路径挪到了高频的使用路径,得不偿失。
  • 跨租户 / 数据集 / 授权追溯:与 B' 同(产物一样是 installed_ref + 共享数据集)。
  • 幂等:最难。热路径并发首用的幂等/加锁是这个方案的主要痛点。

2.4 方案:暂缓(维持现状 + 文档化 + 留接口位)

WHAT:不做物化。维持安装只记账的现状,但把“市场资产暂不可直接用”这件事在产品和文档层显式化:安装/绑定成功后明确提示“该资产已安装,作品内生效能力即将开放”,避免用户撞上静默断点;同时在目标域绑定路径留好物化的接口位(注释 + TODO 锚点),为后续 B'/C 铺路。

HOW 要点:不动后端物化逻辑;改产品文案与状态展示,把当前的“假装可用”降级为“诚实地标注未开放”;在 createKnowledgeBinding / bindAgentSlot 留物化扩展点说明。

权衡

  • 用户价值:低(功能仍不可用),但消除了“静默骗用户”这一最坏体验——用户不再误以为生效了。
  • 工程成本:最低。基本是文档和文案工作。
  • 跨租户 / 数据集 / 授权追溯:不涉及(不物化)。
  • 幂等:不涉及。
  • 适用前提:市场安装在当前产品优先级里不是近期主路径no-config 主创作链路不依赖它,见 流程-02B 第15条可以接受先不可用、先不骗人。

3. 数据模型增量

本节只说相对现状要补什么,不重复 后端-04 已有定义。owner 边界以 后端-04 为准,本稿不新增概念。

3.1 知识库侧B'/C 共用,地基大半已备)

现状 增量
muse_knowledge_base.kb_type V5 已有,取值含 installed_ref B'/C 实际写入 installed_ref(现状从不写本表)
muse_knowledge_base.source_market_asset_id V5 已有列 物化时回填,承载“来源市场资产”溯源
muse_knowledge_base.license_snapshot_id V5 已有列 物化时回填授权来源快照
muse_knowledge_ragflow_bindingkb→数据集映射 仅本地上传文档时创建 B':为 installed_ref 建一行指向发布者数据集的数据集级映射C建指向新复制数据集的映射。注意唯一键 (tenant_id, kb_id) WHERE status='active' AND document_id IS NULL

3.2 智能体侧B'/C 共用,需先补真实 schema

现状 增量
muse_agent.agent_type 现网 DDL/代码仅 system/usermarket_installed 仅见于 后端-04 文档,未落地) 需新增 market_installed 落地schema 值 + 创建/解析分支),消除文档与实现的漂移
muse_agent 来源溯源列 需补一列指回市场资产(参照知识库 source_market_asset_id 命名),承载安装智能体溯源
muse_agent_version 物化时写一行 active 版本B' 引用发布者 configC 复制 config

3.3 安装→实体映射 与 授权快照承载

  • install→agent/kb 映射B'/C 的物化实体已通过 source_market_asset_idkb/ 新增溯源列agent指回市场资产再经市场资产关联到安装记录链路可追。是否需要一张显式的“安装→物化实体”映射表取决于是否要支持“一个安装在多作品复用同一物化实体”——建议初版不建靠 (作品, 来源) 维度的绑定唯一键表达。
  • ADR-020 字符串授权快照承载:智能体槽位绑定的授权快照列已在 V31 收口为 VARCHAR(128) 直透传(承载 rpe-local-<uuid> 形态 envelope知识库相关表在 V14 已先行字符串化。物化实体若要直接携带字符串 envelope沿用 VARCHAR(128) + 直透传,不要回退 BIGINT/parseLong。
  • ADR-020 在 market 的残留缺口(需评估)muse_market_installation.authorization_snapshot_id / source_snapshot_id 当前仍是 BIGINTV6V30/V31 未覆盖 market 表。现状自洽——install 存的是授权快照行的数值主键而非 envelope 字符串。但如果某个物化方案要让安装事实本身直接携带字符串 envelope这两列的 BIGINT 会成为障碍,需随方案评估是否 widen。这是一个独立的契约小议题不属于本物化方案的必改项,列此备查。

3.4 数据集关联 / 复制:共享 vs 复制是核心岔路

这是 C 与 B' 在数据层最本质的区别,单列强调:

  • B'(共享)installed_ref 知识库不拥有自己的数据集,其 muse_knowledge_ragflow_binding 指向发布者数据集 id。成本不随安装数放大,但引入跨租户读同一份 RAGFlow 索引的隔离问题——必须验证检索门的租户/授权隔离在“多租户共享数据集”下不被绕过。
  • C复制:每个安装者拥有独立数据集,需跨 RAGFlow 克隆文档 + 重解析重索引。隔离天然干净,但存储/索引成本 N 倍放大,且复制是异步长任务(失败/重试/幂等都更重)。

4. 跨模块链路

4.1 物化触发:直接 facade vs 事件驱动 source 传播

两种触发风格,对应 架构-03 里两条既有原则:

  • 直接 facade同步、目标域内联物化发生在目标域绑定路径自己的事务里B'/C 推荐这条)。优点是与“写绑定事实 + 消费 handoff token”天然原子现状 handoff token 的消费就是这么做的——consume 绝不切独立事务、沿用 owner 事务),失败即整体回滚,无最终一致性窗口。契合 架构-02 §7“目标 owner 必须自己创建并消费 target precheck、自己写 owner 事实”。
  • 事件驱动 source 传播(异步、各模块自治)安装发事件、knowledge/ai 监听后异步物化ADR-017 的 Source 传播模式)。优点是安装与物化解耦、可独立重试;缺点是引入最终一致性窗口(安装成功但物化未完成时用户看到的中间态需处理),且对“物化必须在用户确认/绑定时发生”的产品语义不如同步贴合。

判断:物化的正确触发点是绑定/槽位替换(用户在目标域的显式确认动作),不是安装本身。因此直接 facade 同步物化更贴设计,事件驱动更适合用于“来源召回/下架时反向停用已物化实体”的传播(这正是 muse_source_propagation_target 已定义 ai_agent_slot_binding/market_install 等传播目标的用途)。

4.2 与 handoffP2/P3的边界handoff 不是物化桥,物化在消费域

这是最容易踩错的边界,必须钉死:handoff token 不负责物化。市场侧的 target owner facade 只生成一个跳转 URL明确不调 AI/Knowledge/Content、不写目标事实真正写目标事实以及未来的物化发生在消费域内部——目标域调 MarketHandoffTokenApi.consume() 在自己的事务里核销 token、同步写自己的事实。

因此正确的链路是 install记账→ 用户跳转 → 目标域绑定路径(消费 token + 写绑定 + 物化实体),而不是 “install 直接物化”也不是“handoff 自己物化”。物化是目标域绑定路径多做的一步token 消费只是这步事务里的一环。这与 流程-02B §13 “来源空间只能发起跳转,不能替目标 owner 写最终事实;目标 owner API 必须消费预检结果和用户确认后才写 owner 事实”完全一致。

4.3 链路全景(现状断点 + B' 物化后)

见 §6 mermaid 与配套 HTML。要点现状链路在“目标域绑定”这一格只写了引用、止步于此B' 在同一格内补上 installed_ref 实体 + 数据集映射/active 版本,使下游的“检索第四门 / 运行期智能体解析”从必然失败转为可通过。


5. 决策点(待人类拍板)

下面是需要人来拍的关键岔路,每条给出选项与倾向,但最终深度/时机/共享策略由人决策

  1. 物化深度(最关键):完整复制 C / 最小留痕 B' / 暂缓。倾向 B' 优先最小正确步、不碰数据集复制重活、地基大半已备C 作为远期演进(当“安装者需要独立改造副本/发布者频繁改版冲击安装者”成为真实痛点时再上)。
  2. 物化时机:安装同步 / 绑定同步 / 异步 worker / 惰性首用。倾向 绑定同步(落点在目标域绑定路径,与 token 消费原子),不选惰性首用(把复杂度推进高频热路径,幂等/竞态最难)。
  3. 数据集:共享 vs 复制。这是 B' 与 C 的分水岭,也是 B' 唯一的硬风险点。选共享B')必须先回答:多租户共享同一 RAGFlow 数据集时,检索的租户/授权隔离是否真隔得住?这点需要一次针对性验证才能拍。
  4. 智能体 market_installed 落地:是否接受“先补 schema + 运行期校验放行”这部分工程量。若暂不接受,可考虑知识库先行 B'、智能体暂缓的分阶段(知识库地基更全、风险更小)。
  5. 授权快照承载:物化实体的授权溯源沿用 ADR-020 字符串 envelopeVARCHAR是否一并处理 muse_market_installation 两列 BIGINT 的残留(建议不纳入本方案,作为独立契约议题)。
  6. 来源溯源与回滚:物化实体经 source_market_asset_id 溯源;来源被召回/下架/撤权时,已物化实体的处置策略——是停用(阻断新使用、不删)还是保留只读?倾向复用 muse_source_propagation_target 的既有传播目标机制做“阻断新使用、不自动删”,与 架构-02“来源事件不删除正式知识/正文”一致。
  7. 幂等:重复安装/重复绑定时物化不得重复造实体。B'/C 都需在物化处加幂等键B' 轻、C 重);惰性方案的热路径并发幂等最重(又一条不选惰性的理由)。

6. 文本+mermaid 图(给 AI / 工程)

6.1 现状两断点(用户视角到机理)

flowchart TD
    A["用户: 市场获取授权"] --> B["安装到账户<br/>installMarketplaceAsset"]
    B --> B1["只写 muse_market_installation<br/>+ license 投影<br/>targetFactsWritten=false"]
    B1 --> C["用户跳转 → 目标域绑定"]

    C --> K["知识库: createKnowledgeBinding<br/>(消费 handoff token)"]
    C --> G["智能体: bindAgentSlot<br/>(消费 handoff token, marketHandoff 放宽属主可见性)"]

    K --> K1["只写 binding + 来源投影<br/>kbId = parseLong(sourceId)<br/>❌ 不建 muse_knowledge_base"]
    G --> G1["只写 slot binding 裸引用<br/>❌ 不建 muse_agent / version"]

    K1 --> KR["检索四门: 用途✓ 授权✓ 来源状态✓<br/>第四门 selectActiveDatasetByKbId → null"]
    KR --> KX["🔴 断点①: no_dataset 静默省略<br/>用户: 检索悄无声息命不中, 无报错"]

    G1 --> GR["运行期 resolveAgentForTask → requireVisibleAgent<br/>(无 marketHandoff 放宽)"]
    GR --> GX["🔴 断点②: AI_AGENT_NOT_EXISTS / SCOPE_FORBIDDEN<br/>用户: AI 任务直接失败"]

    style KX fill:#fde2e2,stroke:#c0392b
    style GX fill:#fde2e2,stroke:#c0392b
    style B1 fill:#eef3fb,stroke:#3b6fb6

6.2 B' 物化后的链路(物化落在目标域绑定路径)

flowchart TD
    A["用户: 安装(记账, 不变)"] --> C["用户跳转 → 目标域绑定路径"]
    C --> K["知识库 createKnowledgeBinding<br/>同一事务内"]
    C --> G["智能体 bindAgentSlot<br/>同一事务内"]

    K --> K1["写 binding + 来源投影 (原有)"]
    K --> K2["✅ 新增: 建 muse_knowledge_base<br/>kb_type=installed_ref<br/>source_market_asset_id 溯源"]
    K2 --> K3["✅ 新增: 建 ragflow_binding<br/>指向发布者数据集(共享)"]
    K3 --> KR["检索第四门 → 拿到数据集 ✓"]
    KR --> KO["🟢 检索命中, 用户可见效果"]

    G --> G1["写 slot binding (原有)"]
    G --> G2["✅ 新增: 建 muse_agent (market_installed)<br/>+ active muse_agent_version"]
    G2 --> GR["运行期 requireVisibleAgent<br/>(扩展: 放行授权有效的 market_installed)"]
    GR --> GO["🟢 智能体解析通过, AI 任务可跑"]

    style K2 fill:#e2f7e8,stroke:#27ae60
    style K3 fill:#e2f7e8,stroke:#27ae60
    style G2 fill:#e2f7e8,stroke:#27ae60
    style KO fill:#e2f7e8,stroke:#27ae60
    style GO fill:#e2f7e8,stroke:#27ae60

6.3 四方案权衡一览

flowchart LR
    subgraph C["C 完整物化"]
      C1["复制实体 + 复制数据集<br/>价值最高 / 成本最高<br/>数据集 N 倍放大 / 隔离干净"]
    end
    subgraph BP["B' 最小留痕 (推荐)"]
      BP1["installed_ref + 共享数据集<br/>价值高 / 成本中<br/>跨租户隔离需验证 / 地基大半已备"]
    end
    subgraph B["B 纯引用 + 按需物化"]
      B1["首用惰性物化<br/>终态同 B' / 成本反高<br/>热路径竞态幂等最难"]
    end
    subgraph H["暂缓"]
      H1["维持现状 + 诚实标注未开放<br/>价值低 / 成本最低<br/>消除静默骗用户"]
    end
    BP1 -.演进.-> C1

7. 验证计划 + 推荐

7.1 推荐

推荐采用方案 B'installed_ref 最小留痕),物化落点放在目标域绑定路径,知识库优先共享发布者数据集;并优先做知识库、智能体视 market_installed 落地工程量决定是否同期。 暂缓作为合理的过渡兜底——若近期不投入物化,至少应立刻把现状的“静默断点”降级为“诚实标注未开放”,止住骗用户的最坏体验。

推荐理由:

  • B' 是“让市场安装资产真正可用”的最小正确步:终态与 C 等价(检索命中、智能体可跑),但避开了 C 最重的数据集复制工程。
  • 地基已备:知识库 installed_ref + source_market_asset_id + license_snapshot_id 在 V5 就有B' 主要是“去写本就该写的本地实体 + 第四门兼容 installed_ref”而非新建表。
  • 落点正确:物化放在目标域绑定路径,与现有 handoff token 消费同事务,原子性天然成立,完全契合 架构-02 §7 / 流程-02B §13 的 owner 边界,不破坏“安装解耦”这个对的设计。
  • 不偏袒暂缓是合理候选——物化是跨模块工程若产品优先级不在此no-config 主链路不依赖市场安装先文档化“暂不可用”、不骗用户是诚实且低成本的选择。C 不推荐为首选仅因成本与时机,不否定其远期价值。

不推荐 C 作首选:数据集复制是异步长任务重活、market_installed 智能体还要从文档落到实现,时机和成本都不划算,留作远期演进。不推荐 B惰性把复杂度推进高频热路径幂等/竞态最难,终态又不比 B' 更好。

7.2 验证计划(方案落地后如何证明“真可用”,非本稿执行项)

  • 知识库 B' 端到端:安装市场知识库 → 作品绑定 → 触发 AI 生成 → 检索第四门拿到(发布者)数据集 → chunk 真命中、生成内容含该来源 grounding。对照现状必然 no_dataset 省略)。
  • 智能体 B' 端到端:安装市场智能体 → 槽位替换 → 创建 AI 任务 → 运行期 requireVisibleAgent 解析通过 → 真 LLM 出候选。对照现状(必然 AI_AGENT_NOT_EXISTS/SCOPE_FORBIDDEN)。
  • 跨租户隔离B' 共享数据集的硬验证):两个不同租户安装同一发布者知识库,确认 A 租户检索不会越权读到 B 租户作品上下文、授权隔离不被共享数据集绕过。这是拍 B' 前必须先做的一次针对性验证。
  • 幂等:重复安装 + 重复绑定,确认物化实体不重复创建(命令回放 + 唯一键)。
  • 回滚/来源传播:发布者召回/下架/撤权后,已物化 installed_ref 实体被阻断新使用(经 muse_source_propagation_target),但不自动删除,符合 架构-02 来源事件语义。
  • 机械门禁:物化涉及跨 BC 写入,须确认不违反 bc-boundaries ArchUnit物化只能经目标 owner 自己的 facade 写自己的实体,不能让 market 直写 knowledge/ai 的 .dal)。

8. 关联阅读

  • 双轨模型 / Source / Authorization / 市场资产模型 / handoff 边界:架构-02-核心数据结构与双轨模型.md§4 来源与授权、§5 智能体运行权限、§6 市场资产、§7 handoff、§11.2 绑定安装授权)
  • BC 边界与跨域协作规则:架构-01-系统全貌与边界上下文.md
  • 关键决策:架构-03-关键决策与原则(ADR).mdADR-016 Governance 拆散、ADR-017 Source 传播事件驱动、ADR-020 授权快照字符串承载)
  • 表结构 SSOT后端-04-统一数据库Schema-v1.md§5 Knowledge、§6 Source/Authorization、§7 AI/Agent、§8 Market
  • 用户系统链路:流程-02B-普通用户系统处理流程(系统视角).md§12 市场资产链路、§13 跨空间 handoff
  • 产品规格:产品-02D-智能体工作台功能规格.md(已安装智能体)、产品-02E-知识库工作台功能规格.md(已安装知识库、作品绑定)、产品-02F-市场功能规格.md(安装与跳转)