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>
34 KiB
临时-02 · Market Install 下游物化方案(评审版)
- 版本:v1(评审版,待人类 review 后拍板,不改任何代码)
- 更新日期:2026-06-26
- 目标读者:架构 / 后端 / 产品 / PR reviewer
- 阅读时间:20–30 分钟
- 文档性质:临时件(评审/决策依据,落定后归并入正式分册或删除,不作长期 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.retrieveForWork,muse-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.createKnowledgeBinding,muse-module-knowledge/.../application/muse/MuseKnowledgeBindingService.java:129)只 insert 了两行——一行绑定事实、一行来源状态投影——而且它写入的 kbId 是直接把外部来源 id(sourceId)当字符串解析成数字塞进去的,并不是任何已物化的本地知识库主键。没有本地知识库实体,自然就没有它名下的数据集映射,第四门必然返回 null。
后果是“静默命不中”:检索把这个来源记为 no_dataset 并入“被省略来源”,但整个检索仍按 fail-closed 设计返回(空或部分结果),不抛错、不阻断主生成链。用户因此看不到任何报错,只是结果里没有这个知识库的内容。这种“假装成功的失败”比直接报错更难排查。
P1 阶段曾有一条 knowledge handoff 的 e2e 测试是绿的,那是 fixture 巧合——测试用的资产恰好映射到一个种子数据里已存在数据集的 kb_id,绕过了这个断点,不代表真实安装链路通。
断点②:智能体在运行期被“二次校验”拒绝
智能体这边的机理不同,关键在于绑定期和运行期用了两套宽严不同的校验。
绑定(槽位替换)期(MuseAgentSlotServiceImpl,muse-module-ai/.../application/muse/MuseAgentSlotServiceImpl.java):对市场来源的绑定,预检和绑定都调 requireVisibleSourceAgent,但带了一个 marketHandoff=true 的放宽参数,只放宽了“智能体属主可见性”这一项(即接纳类型为 market、非本人所有的智能体),其合法性改由市场一次性 handoff token 背书。需要强调的是:“智能体存在且 active、且有 active 版本”这一条,绑定期并没有放宽。
运行期(MuseAiTaskServiceImpl.resolveAgentForTask → requireVisibleAgent,muse-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=false(MarketInstallServiceImpl.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_id、license_snapshot_id三列,只是绑定/安装路径从不写它。智能体侧则有文档无实现:后端-04写了muse_agent区分system/user/market_installed,但现网muse_agent的建表与代码只用system/user,market_installed从未落地。这条不对称直接影响 C/B' 在两域的工程量。
2.1 方案 C:完整物化
WHAT:安装(或首次绑定)时,把市场资产复制成安装者租户内一份独立、自洽的实体。知识库 → 在安装者租户新建一行 muse_knowledge_base(kb_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_base(kb_type=installed_ref、source_market_asset_id 指回市场资产、license_snapshot_id 记授权来源),并为它建一行指向发布者已有 RAGFlow 数据集的 muse_knowledge_ragflow_binding(数据集级、status=active),使第四门能拿到数据集;智能体 → 建一行 muse_agent(market_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_binding(kb→数据集映射) |
仅本地上传文档时创建 | 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/user(market_installed 仅见于 后端-04 文档,未落地) |
需新增 market_installed 落地(schema 值 + 创建/解析分支),消除文档与实现的漂移 |
muse_agent 来源溯源列 |
无 | 需补一列指回市场资产(参照知识库 source_market_asset_id 命名),承载安装智能体溯源 |
muse_agent_version |
有 | 物化时写一行 active 版本(B' 引用发布者 config,C 复制 config) |
3.3 安装→实体映射 与 授权快照承载
- install→agent/kb 映射:B'/C 的物化实体已通过
source_market_asset_id(kb)/ 新增溯源列(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当前仍是 BIGINT(V6),V30/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 与 handoff(P2/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. 决策点(待人类拍板)
下面是需要人来拍的关键岔路,每条给出选项与倾向,但最终深度/时机/共享策略由人决策。
- 物化深度(最关键):完整复制 C / 最小留痕 B' / 暂缓。倾向 B' 优先(最小正确步、不碰数据集复制重活、地基大半已备),C 作为远期演进(当“安装者需要独立改造副本/发布者频繁改版冲击安装者”成为真实痛点时再上)。
- 物化时机:安装同步 / 绑定同步 / 异步 worker / 惰性首用。倾向 绑定同步(落点在目标域绑定路径,与 token 消费原子),不选惰性首用(把复杂度推进高频热路径,幂等/竞态最难)。
- 数据集:共享 vs 复制。这是 B' 与 C 的分水岭,也是 B' 唯一的硬风险点。选共享(B')必须先回答:多租户共享同一 RAGFlow 数据集时,检索的租户/授权隔离是否真隔得住?这点需要一次针对性验证才能拍。
- 智能体
market_installed落地:是否接受“先补 schema + 运行期校验放行”这部分工程量。若暂不接受,可考虑知识库先行 B'、智能体暂缓的分阶段(知识库地基更全、风险更小)。 - 授权快照承载:物化实体的授权溯源沿用 ADR-020 字符串 envelope(VARCHAR);是否一并处理
muse_market_installation两列 BIGINT 的残留(建议不纳入本方案,作为独立契约议题)。 - 来源溯源与回滚:物化实体经
source_market_asset_id溯源;来源被召回/下架/撤权时,已物化实体的处置策略——是停用(阻断新使用、不删)还是保留只读?倾向复用muse_source_propagation_target的既有传播目标机制做“阻断新使用、不自动删”,与架构-02“来源事件不删除正式知识/正文”一致。 - 幂等:重复安装/重复绑定时物化不得重复造实体。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-boundariesArchUnit(物化只能经目标 owner 自己的 facade 写自己的实体,不能让 market 直写 knowledge/ai 的.dal)。
8. 关联阅读
- 双轨模型 / Source / Authorization / 市场资产模型 / handoff 边界:
架构-02-核心数据结构与双轨模型.md(§4 来源与授权、§5 智能体运行权限、§6 市场资产、§7 handoff、§11.2 绑定安装授权) - BC 边界与跨域协作规则:
架构-01-系统全貌与边界上下文.md - 关键决策:
架构-03-关键决策与原则(ADR).md(ADR-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(安装与跳转)