跳到主要内容

外部知识源

English | 简体中文

外部知识源让 Wegent 在一次任务运行中同时检索内置知识库和受信任的外部内容系统。它面向运行时检索,不负责实现某个具体 provider,也不把 provider 专属界面、文案或路由放进 core。

这个能力和外部知识库 MCP 的方向不同:外部知识库 MCP 是让外部系统访问 Wegent 的知识库;外部知识源是让 Wegent 在任务执行时读取外部系统中用户选择的知识记录。

设计目标

  • 让 Backend 和 Chat Shell 可以通过统一协议检索外部知识。
  • 让前端可以选择外部知识源、展示来源引用,并按 provider 打开来源。
  • 保持 core provider-neutral,下游系统自行注册 provider 实现、opener 和来源视图。
  • 外部 provider 失败时按来源降级,不影响内置知识库检索。

Provider 协议和注册表

RetrievalSourceProvider 是 Backend 的外部检索源协议。一个 provider 负责:

  • 声明自己的 provider id 和能力。
  • 校验并解析任务中的外部知识引用。
  • internal_retrieve 返回可合并的外部记录。
  • 可选地提供文档列表能力,供前端或 agent 浏览可选内容。

registry 是 core 和 provider 之间的边界。Core 只依赖 registry 查找 provider,不 import 下游实现。下游部署在启动时注册 provider;如果某个 provider 不存在或不可用,core 应把该来源标记为失败或忽略,而不是让整个检索请求失败。

Task 级运行时绑定

externalKnowledgeRefs 是 Task 级 runtime binding。它描述当前任务运行时选择了哪些外部知识源,和 Ghost、Bot 或 Team 的默认配置不同。

关键约束:

  • 不把外部知识源作为 Ghost 默认知识配置写入。
  • 不把 provider 私有鉴权材料写入 Task spec。
  • 不把外部原始 URL 持久化到 source payload;如需定位来源,使用稳定、可校验、可由 provider 解释的 source_uri
  • Task detail、WebSocket payload 和 Chat Shell metadata 只透传 provider-neutral 字段。

引用字段

externalKnowledgeRefs[] 使用 provider-neutral 字段,不保存 provider 私有对象:

字段说明
providerprovider id。
mode绑定模式,通常为 explicitall_accessible 表示 provider 可解释的全部可访问范围。
idprovider 内稳定的知识源 ID。mode=explicit 时必填。
name用户可读的知识源名称,例如知识库名。
scopeprovider 可解释的范围,例如 personalgrouporganization
target_type可选目标类型:knowledge_basefolderdocument。缺省按整库处理。
node_id / document_id / parent_idprovider-neutral 的目录或文档定位字段。
target_name当选择的是文件夹或文档时的目标展示名。文档级引用应保留 name 为知识源名,并用 target_name 保存文档名,避免后续来源列表把文档名误当成知识源名。

管理入口和 API

外部知识源会像内置知识库一样形成 Task 级绑定,影响后续消息。用户取消输入框中的本轮选择不会解除 Task 级绑定;移除绑定只影响后续执行请求,不会修改历史消息上的 context 展示。

前端应复用原任务/群聊管理入口中的“知识库”页签,把内置知识库和外部知识源放在同一个列表中展示,而不是在输入框上下文选择器中单独维护一套“已绑定外部知识”管理入口。外部条目使用短 provider badge 区分,例如 AP

Backend 提供以下 Task 级外部绑定管理接口:

方法路径说明
GET/api/tasks/{task_id}/external-knowledge-refs返回当前 Task 已绑定的外部知识引用。
POST/api/tasks/{task_id}/external-knowledge-refs/remove按规范化 target key 移除一个外部知识引用。

移除接口请求体为:

{
"ref": {
"provider": "ap",
"mode": "explicit",
"id": "kb-1",
"target_type": "document",
"node_id": "document:node-1",
"document_id": "node-1"
}
}

管理 UI 必须把外部绑定加载失败视为非阻断错误:内置知识库列表和解绑能力仍应可用,外部失败只显示局部提示。

检索合并流程

internal_retrieve 负责把内置知识库记录和外部 provider 返回的记录合并给 Chat Shell。推荐流程:

  1. 读取 Task spec 中的 externalKnowledgeRefs
  2. 先执行内置知识库检索,保留原有权限和索引行为。
  3. 按 provider 分组调用 registry 中的 RetrievalSourceProvider
  4. 将外部记录转换成统一的上下文片段和引用字段。
  5. 合并结果并返回检索摘要。

外部 provider 的错误必须按来源隔离。某个来源超时、鉴权失败或返回空结果时,只应影响该来源的 status;内置知识库命中和其他 provider 结果仍应返回。

来源溯源字段

外部记录进入消息、工具事件或引用列表时,应使用 provider-neutral provenance 字段:

字段说明
source_type来源类型或 provider namespace,用于区分内置和外部来源。
source_idprovider 内部稳定 ID。
source_uriprovider 可解释的稳定 URI,不应是外部原始下载 URL。
source_name用户可读的来源名称。

引用渲染应能在缺少 opener 或 provider 不可用时降级为纯文本来源,不应丢失消息主体。

Opener 和来源视图接缝

前端 core 只提供两个 registry:

  • external source opener registry:把引用交给 provider opener 打开。
  • knowledge source view registry:在统一知识入口中挂载 provider-neutral 的来源视图。

Core 不包含下游 provider 的 opener 代码、路由、图标文案或业务 API。下游前端包可以在自己的初始化代码中注册 opener 和来源视图;没有注册时,core 使用 fallback 展示来源名称和基本 metadata。

可选文档列表能力

knowledge_list_documents 是可选 provider capability,用于列出某个外部来源下可选择的文档或记录。它不是某个 provider 的专属工具。

实现要求:

  • provider 自行负责权限过滤和分页。
  • core 只消费 provider-neutral 的列表结果。
  • Backend external listing endpoint 的分页语义是 pagination_scope: "per_provider";Chat Shell 聚合内置知识库和外部来源后返回 pagination_scope: "per_source"。调用方不应把这些字段解释成全局合并后的分页窗口。
  • capability 不存在时,前端应隐藏或禁用对应的浏览入口,而不是让任务执行失败。

安全和纯净度规则

  • Core 必须保持 provider-neutral。
  • Core 不应出现 provider-specific copy、route、import 或注册代码。
  • 外部原始 URL 不应持久化到 source payload。
  • Provider failure 必须按来源降级,不能破坏内置知识库检索。
  • 传给模型的内容应是经过权限校验和格式化后的片段,而不是 provider 原始响应。
  • 日志和检索摘要可以记录 provider id、source id、状态和计数,但不能记录敏感鉴权数据。

测试建议

  • 使用 fake provider 覆盖 registry、成功检索、空结果和失败降级。
  • Core tests 不使用 provider-specific fixtures。
  • 覆盖内置知识库和外部来源同时命中的合并顺序。
  • 覆盖 source_typesource_idsource_urisource_name 的透传和消息展示。
  • 覆盖 opener 未注册时的 fallback。
  • 覆盖 knowledge_list_documents capability 不存在时的 UI 和工具降级行为。