docs: design external knowledge providers

This commit is contained in:
mesalogo
2026-09-03 16:29:51 +08:00
parent 6586192222
commit 468cf0483f
6 changed files with 1808 additions and 2 deletions
+18 -2
View File
@@ -1,6 +1,7 @@
# 知识库
知识库负责资料导入、解析、分块、索引、检索、图谱和带来源的知识问答。
知识库负责资料导入、解析、分块、索引、检索、图谱和带来源的知识问答,也负责将
Dify、FastGPT 和 RAGFlow 中已有的知识库接入同一检索范围。
## 文档导航
@@ -10,5 +11,20 @@
| [User Stories](./user-stories.md) | 知识使用者、维护者和调试者场景 |
| [本地文本向量技术设计](./local-embedding-technical-design.md) | 本地与兼容向量连接、模型包、索引和进程边界 |
| [知识检索评估](./retrieval-evaluation.md) | 检索质量评估方法、数据集、指标和门槛 |
| [外部知识库接入 PRD](./external-knowledge-prd.md) | 外部实例、知识库绑定、检索范围和产品验收 |
| [外部知识库 User Stories](./external-knowledge-user-stories.md) | 实例配置、添加、使用和故障恢复场景 |
| [外部知识库逻辑设计](./external-knowledge-logic-design.md) | 状态、不变量、配置优先级和失败规则 |
| [外部知识库 UI 设计](./external-knowledge-ui-design.md) | 知识库页面、外部实例管理和创建向导交互 |
| [外部知识库技术设计](./external-knowledge-technical-design.md) | Provider Adapter、凭据、持久化、IPC 和检索标准化 |
当前尚未拆出统一功能逻辑、UI 设计和功能进度文档。
## 术语
- **外部实例**:一个由用户配置的 Dify、FastGPT 或 RAGFlow 服务地址及其认证信息。
- **外部知识库绑定**:GoodBuddy 中的知识库记录与外部实例内一个远端知识库 ID 的只读关联。
- **Provider 配置**:某一 Provider 检索接口独有的设置,例如 RAGFlow 图谱检索。
外部知识库只提供检索结果。GoodBuddy 不接入外部 App、Chat、Assistant、Workflow
或 Agent,也不在外部实例中创建、修改、上传或删除知识库内容。远端资料不会批量同步
或进入本地索引;实际用于回答的有界片段会随引用保存在本地会话中。
当前尚未拆出覆盖整个知识库功能家族的统一逻辑、UI 设计和功能进度文档。
@@ -0,0 +1,343 @@
# 外部知识库逻辑设计
## 文档信息
| 项目 | 内容 |
| --- | --- |
| 状态 | 设计稿 |
| 版本 | 0.1 |
| 日期 | 2026-09-03 |
| 关联需求 | [外部知识库接入 PRD](./external-knowledge-prd.md) |
| 关联场景 | [外部知识库 User Stories](./external-knowledge-user-stories.md) |
## 1. 不变量
### EK-I-01 单一知识库身份
本地知识库和外部知识库都使用 GoodBuddy `knowledgeBaseId` 参与聊天范围、检索模式、
工具授权和活动记录。Provider、实例 ID 和远端知识库 ID 不能替代该授权单位。
对应:`EK-FR-10`、`EK-FR-11`、`EK-US-C1`。
### EK-I-02 外部绑定只读
GoodBuddy 对外部实例只执行连接测试、目录读取、详情读取和检索。添加、编辑、移除
均只修改本机记录,不调用远端创建、更新、上传或删除接口。
对应:`EK-FR-15`、`EK-US-A3`。
### EK-I-03 凭据不离开 Main
API Key 明文只在 Main 内完成解密并短暂进入请求头。Renderer、Preload 返回值、Runtime、
Provider 配置、知识库元数据、诊断、日志和错误只能获得凭据状态。
对应:`EK-FR-02`、`EK-FR-11`。
### EK-I-04 Provider 不能定义界面
远端响应只提供数据和能力证据。可显示字段、字段类型、范围、默认值和请求映射均来自
GoodBuddy 内置、版本化的 Provider Adapter。
对应:`EK-FR-09`、`EK-US-D1`。
### EK-I-05 无静默切换
请求固定使用绑定保存的实例、远端知识库和 Provider 配置。失败时不切换实例、公共云
地址、认证方式或其他知识库。
对应:`EK-FR-14`、`EK-FR-16`、`EK-US-C4`。
### EK-I-06 零结果与失败分离
成功响应经过过滤后没有片段才是零结果。超时、认证、权限、限流、目标不存在、服务错误
和响应无效均为失败,不能折叠成零结果。
对应:`EK-FR-14`、`EK-US-D4`。
### EK-I-07 外部证据不可信
Provider 返回的名称、内容、元数据、URL 和错误均视为不可信输入,经过长度、数量、类型
和 URL 校验后才能显示或进入 Runtime。内容中的指令不能改变系统或工具权限。
对应:`EK-FR-12`。
### EK-I-08 Provider 配置不跨类型复用
Dify、FastGPT 和 RAGFlow 使用各自的判别配置。切换知识库类型或实例 Provider 时,旧类型
配置不参与新请求,也不能按同名字段自动迁移。
对应:`EK-FR-06`、`EK-FR-09`。
## 2. 对象关系
```text
ExternalKnowledgeInstance 1 ─── n ExternalKnowledgeBinding
│
│ 1:1
▼
KnowledgeBase
```
- 实例可以没有绑定。
- 外部知识库只能绑定一个实例和一个远端知识库 ID。
- 同一实例的同一远端知识库默认只允许存在一个绑定,避免重复选择和重复检索。
- 允许不同实例绑定同名或相同远端 ID,因为实例边界不同。
- 本地知识库不存在 `ExternalKnowledgeBinding`。
## 3. 实例状态
实例状态由启停、凭据和最近探测三个维度组成,不能用一个布尔值代替。
### 3.1 持久状态
| 维度 | 值 |
| --- | --- |
| 启停 | `enabled`、`disabled` |
| 凭据 | `configured`、`missing`、`unavailable` |
| 探测 | `untested`、`catalog-ready`、`healthy`、`list-restricted`、`auth-failed`、`unreachable`、`incompatible`、`failed` |
`unavailable` 表示系统安全存储当前无法解密或保存凭据,与用户尚未配置的 `missing` 分开。
### 3.2 派生可用性
| 条件 | 目录读取 | 已绑定知识库检索 | 页面状态 |
| --- | --- | --- | --- |
| disabled | 禁止 | 禁止 | 已停用 |
| missing / unavailable | 禁止 | 禁止 | 缺少凭据 / 凭据不可用 |
| auth-failed | 禁止 | 禁止 | 认证失效 |
| unreachable | 可重试 | 可重试 | 无法连接 |
| incompatible | 禁止 | 禁止 | 接口不兼容 |
| list-restricted | 禁止 | 允许按 ID 验证与检索 | 需手工指定知识库 |
| catalog-ready | 允许 | 创建绑定时验证 | 目录可用,检索待验证 |
| healthy | 允许 | 允许 | 正常 |
| untested | 允许测试 | 已有绑定可尝试检索 | 未测试 |
保存新实例要求至少完成服务可达和认证验证。目录受限可以保存;检索接口尚未通过时,
实例不能用于创建绑定。
## 4. 连接测试状态机
```text
idle
└─ test → connecting
├─ network failure → unreachable
└─ connected → authenticating
├─ 401 → auth-failed
├─ incompatible response → incompatible
└─ authenticated → listing
├─ 403 / unsupported → list-restricted
└─ success
├─ no target → catalog-ready
└─ target selected → probing-retrieval
├─ success / empty → healthy
└─ failure → failed
```
检索探测需要一个目标知识库。新增实例尚未选择目标时,目录成功即可把实例保存为“目录可用,
检索待绑定验证”;创建绑定时补做真实检索。手工模式必须先填写目标 ID,再执行检索探测。
检索请求正常完成但返回零条结果时,说明接口和目标可访问,可继续创建绑定;失败状态按错误
分类处理。
每次测试拥有 request ID 和取消信号。用户修改 Provider、地址、凭据或实例后,旧 request ID
的结果作废。
## 5. 目录读取规则
1. 只有选定、启用且凭据可用的实例可以读取目录。
2. Provider 列表接口按适配器定义分页,Main 最多向 Renderer 返回 500 个目录项。
3. FastGPT 列表中的文件夹和知识库必须按类型区分;文件夹不可作为绑定目标。
4. 列表搜索优先使用 Provider 支持的服务端过滤,不支持时只过滤已经有界加载的当前结果。
5. 下拉列表以远端 ID 为值,以远端名称为标签;重名时追加短 ID 或父级名称。
6. 已经绑定的目标显示“已添加”并禁止重复添加。
7. 远端列表项名称变化不自动修改 GoodBuddy 显示名称,只更新远端名称快照。
8. 刷新失败时可以保留上次成功目录供查看,但不得用旧目录完成新绑定,直到目标重新验证。
## 6. 创建向导状态
### 6.1 类型
```text
local | dify | fastgpt | ragflow
```
`local` 使用现有字段和验证。外部类型使用以下步骤状态:
```text
provider selected
→ instance selected
→ catalog loading / manual ID
→ remote target selected
→ configuration valid
→ retrieval verified
→ binding created
```
前置字段变化时,后续状态按下表失效:
| 变化 | 必须清除或重新验证 |
| --- | --- |
| 类型 | 实例、远端目标、全部 Provider 配置、测试结果 |
| 实例 | 远端目标、能力快照、Provider 配置、测试结果 |
| 远端目标 | 远端详情、能力适用性、测试结果 |
| 通用或 Provider 配置 | 测试结果 |
| 显示名称 | 不清除测试结果 |
## 7. 配置模型
### 7.1 通用配置
| 字段 | 范围 | 默认值 | 语义 |
| --- | --- | --- | --- |
| `resultLimit` | 1 至 20 | 6 | Provider 结果标准化后最多保留的片段数 |
| `requestTimeoutMs` | 1,000 至 60,000 | 15,000 | 单次远端请求总时限 |
| `maxSnippetCharacters` | 500 至 8,000 | 4,000 | 单片段进入 IPC 和 Runtime 前的字符上限 |
Provider 请求仍使用自己的候选数量或 Token 预算。`resultLimit` 只定义 GoodBuddy 最终保留
上限,不改写 Provider 字段的单位。
### 7.2 Dify 配置
| 字段 | 初始范围 | 说明 |
| --- | --- | --- |
| `useDatasetDefaults` | boolean,默认 true | 开启时不发送 `retrieval_model` 覆盖 |
| `searchMethod` | keyword / semantic / full-text / hybrid | 对应 Dataset Retrieve 检索方式 |
| `providerTopK` | 1 至适配器上限 | Dify 返回候选数量 |
| `scoreThresholdEnabled` | boolean | 是否向 Dify 发送分数阈值 |
| `scoreThreshold` | 0 至 1 | 开启阈值后生效 |
| `rerankingMode` | weighted-score / reranking-model | 覆盖检索配置时必填 |
| `rerankingProvider`、`rerankingModel` | 受支持的远端标识 | 选择模型重排时必填 |
| `keywordWeight`、`vectorWeight` | 0 至 1,总和为 1 | 加权混合模式时生效 |
| `embeddingProvider`、`embeddingModel` | 受支持的远端标识 | Dify 要求时从知识库详情选择或填写 |
`useDatasetDefaults` 开启时,其余覆盖字段隐藏且不发送。关闭后必须收集当前 Dify 接口
构造 `retrieval_model` 所需的完整字段,缺少 Provider 或模型标识时不能保存。
### 7.3 FastGPT 配置
| 字段 | 初始范围 | 说明 |
| --- | --- | --- |
| `searchMode` | embedding / fullTextRecall / mixedRecall | 搜索方式 |
| `tokenLimit` | 适配器限制,最高 20,000 | Provider 返回内容预算,不等同结果条数 |
| `similarity` | 0 至 1 | 最低相关度 |
| `usingRerank` | boolean | 使用 FastGPT 重排 |
初始版本不开放 FastGPT 查询优化字段,避免把查询发送给 FastGPT 配置的 LLM。检索和重排
仍可能产生远端 Embedding、Rerank 用量及 API 审计记录,测试与保存配置时必须说明。
### 7.4 RAGFlow 配置
| 字段 | 初始范围 | 说明 |
| --- | --- | --- |
| `similarityThreshold` | 0 至 1 | 最低综合相似度 |
| `vectorSimilarityWeight` | 0 至 1 | 向量分数权重 |
| `knnTopK` | 1 至适配器上限 | KNN 候选数量,不使用已弃用 `top_k` |
| `rerankCandidatesCount` | 0 或正整数 | 重排候选数量,实例支持时显示 |
| `rerankId` | 可选受限字符串 | 远端重排模型 ID |
| `useKg` | boolean,默认 false | 仅在已有图谱证据成立时允许开启 |
| `includeKnowledgeCompilation` | boolean,默认 false | 实例支持时显式发送,禁止依赖服务端默认 true |
| `metadataCondition` | 后续受控编辑器 | 初始版本不接受任意 JSON 文本 |
`parser_config.graphrag.use_graphrag` 描述构建状态,不是检索参数。只有列表、详情或受控
探测提供已有图谱的证据时,界面才允许开启 `useKg`。Knowledge Compilation 是另一项
检索能力,必须与旧 GraphRAG 分别显示和保存。
## 8. 配置优先级
生效请求由以下信息组成:
```text
GoodBuddy 固定安全上限
∩ 当前 Adapter 支持矩阵
∩ 当前绑定保存的通用配置和 Provider 配置
= 本次请求配置
```
- 固定安全上限不可被实例或用户扩大。
- 远端知识库自身默认值只用于创建表单的建议值,不在每次请求时覆盖本地已保存值。
- Provider 增加新字段不会自动启用。
- 当前实例版本离开 Adapter 支持矩阵,或 Adapter 新版本无法解析已保存配置时,绑定标记
配置失效;用户确认前不重写配置。
- 服务端忽略未知字段不能视为成功。Adapter 只发送已知且受支持的字段。
## 9. 绑定状态
| 状态 | 条件 | 可进入聊天范围 |
| --- | --- | --- |
| `ready` | 实例可用,目标最近验证成功,配置有效 | 是 |
| `untested` | 迁移或新增后尚未完成真实检索 | 否 |
| `instance-disabled` | 实例停用 | 否 |
| `credential-error` | 凭据缺失、不可用或认证失败 | 否 |
| `remote-missing` | 远端目标返回不存在 | 否 |
| `config-invalid` | 已保存配置不再受支持 | 否 |
| `temporarily-unavailable` | 超时、限流或服务错误 | 是,但本次显示失败并允许重试 |
短暂故障不立即永久禁用绑定;认证失败、目标不存在和配置失效会改变持久状态。
## 10. 多知识库检索
1. 读取请求冻结的 GoodBuddy 知识库 ID 集合。
2. 本地库进入本地检索,外部库按实例和绑定构造独立请求。
3. 同一请求最多选择现有契约允许的 20 个知识库,并遵循全局并发上限。
4. 每个库单独记录成功、零结果、失败、耗时和截断。
5. 成功结果按知识库保留来源,不比较不同 Provider 的原始分数。
6. 上下文拼装使用现有总字符预算,在各成功知识库间采用确定性配额。
7. 全部失败时返回检索失败;至少一个成功时返回证据和部分失败诊断。
初始版本不对跨 Provider 结果运行统一学习型重排。后续如增加,必须保留原始 Provider
分数和重排来源,且单独定义评估数据。
## 11. 错误分类
| 稳定错误码 | 用户状态 | 持久影响 |
| --- | --- | --- |
| `EXTERNAL_KB_NETWORK` | 无法连接实例 | 无 |
| `EXTERNAL_KB_TIMEOUT` | 检索超时 | 无 |
| `EXTERNAL_KB_AUTH` | 认证失效 | 实例标记认证失败 |
| `EXTERNAL_KB_FORBIDDEN` | 没有访问权限 | 目录或绑定按操作标记受限 |
| `EXTERNAL_KB_NOT_FOUND` | 远端知识库不存在 | 绑定标记目标不存在 |
| `EXTERNAL_KB_RATE_LIMITED` | 请求过于频繁 | 无,可显示建议等待 |
| `EXTERNAL_KB_INCOMPATIBLE` | 接口或配置不兼容 | 实例或绑定标记不兼容 |
| `EXTERNAL_KB_INVALID_RESPONSE` | 返回内容无法读取 | 无,记录脱敏诊断 |
| `EXTERNAL_KB_SERVER` | 外部服务处理失败 | 无 |
| `EXTERNAL_KB_CANCELLED` | 已取消 | 无 |
Provider 原始正文不能直接成为用户错误。Adapter 将其映射为稳定错误码和有界短消息。
## 12. 删除规则
| 操作 | 无绑定 | 有绑定 |
| --- | --- | --- |
| 停用实例 | 直接停用 | 允许;绑定变为不可用 |
| 清除凭据 | 直接清除 | 需要确认;绑定保留但不可用 |
| 删除实例 | 直接删除 | 阻止直接删除,要求同时移除本地绑定 |
| 移除绑定 | 删除本地绑定 | 不影响实例和远端知识库 |
删除确认不得使用“删除远端知识库”等文案。
## 13. 需求追踪
| 需求 | 主要逻辑 | User Story |
| --- | --- | --- |
| `EK-FR-01` 至 `EK-FR-03` | 实例状态、连接测试状态机 | `EK-US-A1`、`EK-US-A2` |
| `EK-FR-04`、`EK-FR-05` | 目录读取规则、手工目标验证 | `EK-US-B1`、`EK-US-B2` |
| `EK-FR-06`、`EK-FR-07`、`EK-FR-08`、`EK-FR-09` | 创建向导状态、配置模型和优先级 | `EK-US-B3`、`EK-US-B4`、`EK-US-D1`、`EK-US-D3` |
| `EK-FR-10` 至 `EK-FR-13` | 单一身份、多知识库检索和引用规则 | `EK-US-C1` 至 `EK-US-C3`、`EK-US-D2` |
| `EK-FR-14` | 绑定状态、错误分类和部分失败 | `EK-US-C4`、`EK-US-D4` |
| `EK-FR-15` | 对象关系和删除规则 | `EK-US-A3` |
| `EK-FR-16` | 无静默切换、请求冻结和传输风险确认 | `EK-US-C2` |
## 14. 逻辑完整性
已确定:
- 产品入口、对象关系、只读边界和凭据边界。
- 目录读取与手工 ID 的切换条件。
- 三种 Provider 的初始配置范围和 RAGFlow 图谱语义。
- 多知识库部分失败、删除和版本变化规则。
实施前仍需技术验证:
- 选定支持的 Dify、FastGPT、RAGFlow 最低版本,形成固定支持矩阵并保存真实响应 fixture。
- 验证各版本检索探测的 API 审计、用量和内容修改行为。
- 确定 Provider 返回 URL 的安全打开策略;未验证前只显示文本定位和远端 ID。
- 依据真实延迟确定默认并发上限和跨知识库上下文配额。
@@ -0,0 +1,254 @@
# 外部知识库接入 PRD
## 文档信息
| 项目 | 内容 |
| --- | --- |
| 状态 | 设计稿 |
| 版本 | 0.1 |
| 日期 | 2026-09-03 |
| 适用产品 | GoodBuddy 桌面端 |
| 关联逻辑 | [外部知识库逻辑设计](./external-knowledge-logic-design.md) |
| 关联界面 | [外部知识库 UI 设计](./external-knowledge-ui-design.md) |
| 技术设计 | [外部知识库技术设计](./external-knowledge-technical-design.md) |
## 1. 背景
不少企业已经在内网部署 Dify、FastGPT 或 RAGFlow,并在其中维护制度、产品、研发
和客服知识。继续要求用户把相同资料导入 GoodBuddy,会产生重复存储、版本分叉和
额外维护成本。
GoodBuddy 需要把这些已有知识库加入当前知识库列表和聊天检索范围。外部系统只
承担知识存储与检索,问题理解、上下文组织、模型回答、Agent 和工具执行仍由
GoodBuddy 负责。
## 2. 产品决策
1. 外部知识库属于现有“知识库”功能,不新增一级页面,也不放入全局设置中心。
2. 知识库页面标题区增加“管理外部实例”;现有“新建知识库”向导增加知识库类型。
3. 一个外部实例代表一个 Provider 服务地址和一组凭据,可绑定多个远端知识库。
4. 一个外部知识库绑定在 GoodBuddy 中仍是一个 `KnowledgeBase`,可以进入现有聊天
范围、每次先检索、模型按需检索和检索测试流程。
5. 外部知识库保持远端检索,不批量同步或本地索引远端文档、分块、向量和图谱,也不
显示“已同步”。实际进入回答的有界片段和引用随会话保存在本机,并遵循会话删除规则。
6. Dify、FastGPT 和 RAGFlow 只使用知识库列表、详情和检索接口。App、Chat、
Assistant、Workflow 和 Agent API 均不接入。
7. 用户点击“添加”只创建本地绑定,不在外部实例中创建知识库;移除绑定也不删除
远端知识库。
8. 通用配置只包含跨 Provider 语义一致的选项。检索算法、阈值、重排和图谱开关
由 Provider 配置承担。
9. Provider 专属字段由 GoodBuddy 内置适配器定义。外部服务器不能下发任意表单、
脚本或字段 Schema。
10. API Key 在用户输入表单和受限 IPC 中短暂存在,由 Main 进程加密保存并用于请求;
保存后不回传 Renderer,也不进入 Runtime、日志、普通元数据和检索引用。
## 3. 目标
### 3.1 用户目标
- 在知识库页面配置企业现有的 Dify、FastGPT 或 RAGFlow 实例。
- 新建知识库时选择 Provider、实例和远端知识库,不手工复制资料。
- 在同一知识库列表和聊天选择器中使用本地与外部知识库。
- 按 Provider 能力调整检索参数,例如 RAGFlow 图谱检索。
- 明确看到查询发送到哪个实例、检索是否成功以及引用来自哪里。
- 连接失效后能更新凭据、重试或更换远端知识库,不丢失其他知识库配置。
### 3.2 产品目标
- 保持现有知识库 ID 作为聊天和 Runtime 的统一授权单位。
- 让三种 Provider 的结果进入同一有界证据与引用契约。
- 保留每种 Provider 的有效检索能力,不用最低公共字段覆盖全部差异。
- 将实例认证与知识库绑定分离,使一个实例可以服务多个绑定。
- 对 Provider 版本差异、列表权限关闭和部分检索失败提供可诊断状态。
## 4. 非目标
本功能不包含:
- 调用 Dify App、FastGPT 应用、RAGFlow Chat 或任何外部 Agent。
- 使用外部系统生成最终回答或维护外部会话。
- 在外部实例中创建、编辑、删除知识库、文档或分块。
- 向外部实例上传文件、网页、剪贴板、完整会话或本地知识库内容。
- 批量同步或本地索引外部文档、分块、Embedding、图谱或模型配置。回答实际引用的
有界片段仍会随会话保存在本机。
- 跨实例复制、迁移或统一管理外部知识内容。
- 企业 SSO、组织级凭据下发、文档级 ACL 映射或 ShareServer 管理策略。
- 自定义脚本适配器和任意 HTTP 请求模板。兼容检索 API 需要独立设计。
- 把不同 Provider 的原始分数解释成可直接比较的统一质量分数。
## 5. 核心对象
| 对象 | 定义 | 用户可执行操作 |
| --- | --- | --- |
| 外部实例 | Provider、服务地址、凭据和已探测能力 | 添加、测试、编辑、停用、删除 |
| 外部知识库目录项 | 实例列表接口返回的远端知识库摘要 | 刷新、选择 |
| 外部知识库绑定 | GoodBuddy 知识库与远端知识库的只读关联 | 添加、改名、配置、测试、移除 |
| Provider 配置 | 适配器支持的检索参数 | 查看、修改、恢复默认 |
| 标准化检索结果 | Provider 结果转换后的片段、来源和诊断 | 查看、引用、提供给 Runtime |
## 6. 主要流程
### 6.1 管理外部实例
1. 用户在知识库页面点击“管理外部实例”。
2. 页面列出实例名称、Provider、服务地址、状态和已绑定知识库数量。
3. 用户添加实例,填写名称、Provider、服务地址和 API Key。
4. “测试连接”分别验证服务可达、认证、知识库列表和检索能力。
5. 用户保存后,API Key 被加密保存,列表只显示凭据已配置。
列表接口不可用但已知远端知识库 ID 可检索时,实例可以保存为“需手工指定知识库”。
服务不可达或认证失败时不得保存为可用实例;用户可以保留表单并修正。
### 6.2 添加外部知识库
1. 用户点击现有“新建知识库”。
2. 在“知识库类型”中选择“本地”、Dify、FastGPT 或 RAGFlow。
3. 选择外部类型后,左侧选择同 Provider 的外部实例。
4. GoodBuddy 自动读取远端知识库列表,并填入可搜索下拉框。
5. 列表权限不可用时,用户可以手工填写远端知识库 ID。
6. 用户选择一个远端知识库,填写 GoodBuddy 显示名称。
7. 右侧展示通用配置和当前 Provider 的专属配置。
8. 用户填写测试查询并执行一次有界检索;请求成功后创建本地绑定,零结果不算失败。
添加完成后沿用现有知识库规则,把新绑定加入当前聊天选择,但不会重新启用用户此前
取消的其他知识库。
### 6.3 使用外部知识库
外部绑定出现在现有知识库列表和聊天知识范围中,持续显示 Provider 与实例名称。
检索请求只发送本次查询文本和该绑定已保存的检索配置。返回片段经过 Main 校验、
截断和标准化后,才作为不可信证据提供给 Runtime。
一次请求选择多个知识库时,本地与外部检索可以并行。单个外部知识库失败不扩大
检索范围,也不切换其他实例;其他知识库成功时可继续回答,并显示部分失败。
### 6.4 编辑和移除
- 修改显示名称只影响 GoodBuddy 本地名称。
- 修改 Provider 配置只影响后续检索,不写回远端知识库。
- 更换远端知识库属于重新绑定,保存前必须重新测试。
- 删除外部实例前必须处理其所有绑定:取消,或明确移除这些本地绑定。
- 移除绑定只删除 GoodBuddy 中的绑定和检索配置,不调用远端删除接口。已经保存在历史
会话中的引用继续可读,但不再提供依赖当前实例的刷新操作。
## 7. 功能需求
### EK-FR-01 知识库页面入口
知识库页面必须同时提供“管理外部实例”和“新建知识库”。外部实例管理不得迁移到
全局设置中心或创建新的一级导航。
### EK-FR-02 实例配置
实例必须包含唯一 ID、显示名称、Provider、规范化服务地址、凭据状态、启停状态、
最近测试结果和适配器能力快照。用户可以使用 `keep`、`replace`、`clear` 语义更新凭据。
### EK-FR-03 分项连接测试
连接测试必须区分服务可达、认证、列表读取和测试检索。新增实例尚未选择知识库时,
测试检索显示“绑定知识库时验证”,不能伪装成已通过。测试错误应包含可处理原因,
不得返回凭据、Authorization、完整响应正文或内部堆栈。
### EK-FR-04 远端目录读取
选择实例后自动读取有界、可分页的远端知识库列表。列表支持加载、刷新、搜索、空结果、
权限不足和失败状态,且异步旧响应不得覆盖当前实例结果。
### EK-FR-05 手工指定远端 ID
列表接口不受支持或没有权限时,允许手工填写远端知识库 ID 和显示名称。保存前必须通过
该 ID 的详情或检索验证;不能只验证字符串非空。
### EK-FR-06 知识库类型
新建向导必须提供“本地”、Dify、FastGPT、RAGFlow 四种类型。本地类型保持现有创建、
存储模式、图谱和导入行为;外部类型不得显示本地分块、导入或索引设置。
### EK-FR-07 两栏配置
外部类型的创建向导在常规宽度使用左右两栏。左侧负责 Provider、实例、远端知识库和
显示名称;右侧负责通用配置与 Provider 专属配置。窄窗口按来源、通用配置、专属配置
顺序堆叠。
### EK-FR-08 通用配置
通用配置至少包含最终返回片段数、请求超时和单片段最大字符数。数值必须有固定范围,
由 Main 再次校验。Provider 的 Top K、Token 预算或 Page Size 不得冒充同一字段。
### EK-FR-09 Provider 专属配置
Provider 配置使用受版本控制的判别联合。界面只展示当前适配器和已确认实例版本支持的字段;
不支持的已保存字段必须明确显示为失效配置并阻止静默提交。
### EK-FR-10 统一知识库列表
外部绑定与本地知识库出现在同一列表,但必须显示 Provider、实例和“远端检索”状态。
外部绑定不得显示本地文档数、同步、分块、向量覆盖率或本地图谱状态。
### EK-FR-11 统一检索范围
现有聊天知识范围、多选上限、`auto` 和 `always` 模式继续以 GoodBuddy 知识库 ID 工作。
Runtime 只能获得标准化后的有界证据,不能获得实例地址、API Key 或 Provider 原始响应。
### EK-FR-12 引用来源
每条外部结果必须保留 Provider、实例 ID、远端知识库 ID、文档名称和片段。远端文档 ID、
远端片段 ID、页码、URL、分数及其他定位只在 Provider 实际返回时保存,不得补造。
### EK-FR-13 检索测试
现有检索测试入口支持外部绑定。页面显示生效配置、总耗时、Provider 耗时、返回数量、
截断状态和脱敏错误。外部测试不创建聊天、调用 GoodBuddy LLM 或修改远端内容。
### EK-FR-14 故障隔离
认证失败、超时、限流、目标删除、版本不兼容和响应无效必须分别报告。多知识库检索中,
单项失败不得改写为零结果,也不得阻止已成功证据进入回答。
### EK-FR-15 生命周期边界
删除实例、移除绑定、清除凭据和更换远端目标必须经过明确确认。任何操作都不得调用
Provider 的远端创建、更新、上传或删除接口。
### EK-FR-16 网络与数据说明
界面必须说明查询会发送到所选实例,并列出不会发送的内容。请求遵循用户配置的服务地址
和当前内网兼容模式,不自动切换地址、Provider 或公共云端点。HTTP 或放宽证书校验会
传输 API Key,测试和保存实例前必须显示风险并取得针对当前地址的明确确认。
## 8. Provider 初始范围
| Provider | 目录能力 | 检索能力 | 首批专属配置 |
| --- | --- | --- | --- |
| Dify | 知识库列表与详情 | Dataset Retrieve | 使用知识库默认配置,或完整覆盖检索方式、Top K、Score 阈值及 Rerank 模式 |
| FastGPT | 知识库层级列表与详情 | Dataset Search Test | 搜索模式、Token 上限、相似度、Rerank |
| RAGFlow | Dataset 列表与详情 | Retrieval | 相似度、向量权重、KNN Top K、Rerank、图谱检索、Knowledge Compilation |
“首批专属配置”表示适配器允许表达的字段,不保证每个实例版本都支持。具体显隐由能力
探测和[逻辑设计](./external-knowledge-logic-design.md)共同决定。
## 9. 产品验收
1. 用户可以在知识库页面完成三种 Provider 的实例添加、连接测试、编辑和删除。
2. 每种 Provider 至少通过一个真实自部署实例完成列表读取、绑定和检索。
3. 列表权限关闭时,可以通过手工 ID 添加并验证一个可检索知识库。
4. 本地与外部知识库可以同时进入一次聊天检索,引用来源可区分。
5. RAGFlow 支持时可以开启图谱检索;不支持时不发送该字段。
6. 外部知识库详情不出现本地导入、同步、分块和索引操作。
7. 删除绑定或实例不会改变远端知识库和文档。
8. 保存完成后的 Renderer 状态、Runtime、SQLite 普通元数据、日志和错误中均找不到明文
API Key。
9. 超时、401/403、404、429、5xx 和响应格式错误都有独立测试并显示准确状态。
10. 中断、切换实例或关闭向导后,过期列表与测试响应不会写入当前表单。
11. FastGPT 页面说明检索会记录远端 API 使用情况,并可能产生 Embedding 或 Rerank 用量。
12. HTTP 或放宽证书校验的实例未经明确确认不能保存或发送 API Key。
## 10. 外部资料
以下链接用于核对初始适配范围,实施时仍须用受支持版本的真实实例和响应 fixture 验证:
- [Dify Knowledge API](https://docs.dify.ai/en/guides/knowledge-base/knowledge-and-documents-maintenance/maintain-dataset-via-api)
- [Dify Retrieve Chunks](https://docs.dify.ai/en/api-reference/knowledge-bases/retrieve-chunks-from-a-knowledge-base-test-retrieval)
- [FastGPT 知识库接口](https://doc.fastgpt.io/zh-CN/openapi/dataset)
- [RAGFlow HTTP API](https://ragflow.io/docs/dev/http_api_reference)
- [RAGFlow Release Notes](https://ragflow.io/docs/dev/release_notes)
@@ -0,0 +1,580 @@
# 外部知识库技术设计
## 文档信息
| 项目 | 内容 |
| --- | --- |
| 状态 | 设计稿 |
| 版本 | 0.1 |
| 日期 | 2026-09-03 |
| 产品需求 | [外部知识库接入 PRD](./external-knowledge-prd.md) |
| 逻辑设计 | [外部知识库逻辑设计](./external-knowledge-logic-design.md) |
| UI 设计 | [外部知识库 UI 设计](./external-knowledge-ui-design.md) |
## 1. 设计约束
1. 外部知识库扩展现有知识库领域,不建立独立检索工具、聊天范围或 Runtime 权限模型。
2. 外部绑定使用远端检索,不落地远端文档、分块、向量和图谱。
3. 所有网络、凭据、Provider 响应校验和结果标准化都在 Main 完成。
4. Renderer 只能通过受限 IPC 管理实例、读取目录、保存绑定和发起测试。
5. Dify、FastGPT、RAGFlow 使用独立 Adapter 和判别配置,不通过任意 JSON 请求模板实现。
6. 首次实现只调用无内容修改语义的列表、详情和检索接口。
7. Provider API 变化通过真实 fixture、Adapter 版本和能力快照处理,不通过猜测字段兼容。
## 2. 现有代码边界
当前实现中的主要扩展点:
| 边界 | 现有位置 | 需要的变化 |
| --- | --- | --- |
| 共享知识契约 | `src/shared/knowledge-contracts.ts`、`src/shared/contracts.ts` | 增加实例、绑定、Provider 配置和外部引用判别联合 |
| IPC 名称 | `src/shared/ipc-channels.ts` | 增加实例和目录操作通道 |
| Preload | `src/preload/index.ts` | 暴露受限、类型化的外部知识库 API |
| Main IPC | `src/main/ipc.ts` | 校验输入、调用服务、投影脱敏结果 |
| 知识服务 | `src/main/knowledge/knowledge-service.ts` | 按知识库来源分派本地或外部检索 |
| 数据库 | `src/main/knowledge/knowledge-database.ts` | 增加实例、绑定和迁移 |
| 内部类型 | `src/main/knowledge/types.ts` | 增加 Provider、实例、绑定和标准化结果类型 |
| 知识页面 | `src/renderer/src/KnowledgeWorkspace.tsx` | 实例管理、创建向导类型和外部详情 |
| 检索测试 | `src/renderer/src/KnowledgeRetrievalWorkbench.tsx` | 支持本地与外部诊断判别联合 |
| 聊天预检索 | `src/main/ipc.ts` | 统一调用 Provider-aware 检索编排 |
| Agent 知识工具 | `src/main/agent/knowledge-mcp-gateway.ts` | 与预检索复用同一编排和引用标准化 |
外部 Provider 不是 `KnowledgeSourceType`。现有 `file | directory | url` 表示会进入本地
文档、分块和索引的资料来源;把远端绑定塞入该枚举会错误触发同步、分块和来源打开逻辑。
## 3. 模块设计
建议增加:
```text
src/main/knowledge/external/
├─ external-knowledge-service.ts
├─ external-knowledge-store.ts
├─ external-knowledge-errors.ts
├─ external-knowledge-http.ts
├─ external-knowledge-registry.ts
├─ external-knowledge-normalizer.ts
└─ providers/
├─ dify-adapter.ts
├─ fastgpt-adapter.ts
└─ ragflow-adapter.ts
```
职责:
- `ExternalKnowledgeService`:实例、目录、绑定、测试和检索编排。
- `ExternalKnowledgeStore`:实例和绑定持久化,凭据加解密。
- `ExternalKnowledgeHttp`:超时、取消、大小限制、地址和响应读取。
- `ExternalKnowledgeRegistry`:按 Provider 返回内置 Adapter,不接受运行时插件注册。
- `ExternalKnowledgeNormalizer`:统一结果边界、截断和引用。
- Adapter:构造固定端点与请求,解析 Provider 响应,声明静态配置和能力条件。
`KnowledgeService` 继续作为聊天、检索测试和 MCP 网关的统一入口。它根据
`KnowledgeBase.kind` 调用现有本地检索或 `ExternalKnowledgeService.retrieve`。
## 4. Provider Adapter
```ts
type ExternalKnowledgeProvider = 'dify' | 'fastgpt' | 'ragflow'
interface ExternalKnowledgeAdapter<PersistedConfig, CapabilitySnapshot> {
readonly provider: ExternalKnowledgeProvider
readonly configVersion: number
normalizeBaseUrl(input: string): URL
testConnection(context: AdapterContext): Promise<ConnectionTestResult>
listKnowledgeBases(
context: AdapterContext,
input: CatalogPageInput
): Promise<CatalogPage>
getKnowledgeBase(
context: AdapterContext,
remoteKnowledgeBaseId: string
): Promise<RemoteKnowledgeBaseSummary>
probeRetrieval(
context: AdapterContext,
input: ProviderRetrieveInput<PersistedConfig>
): Promise<ProviderRetrieveResult>
retrieve(
context: AdapterContext,
input: ProviderRetrieveInput<PersistedConfig>
): Promise<ProviderRetrieveResult>
parseCapabilities(input: unknown): CapabilitySnapshot
validateConfig(
input: unknown,
capabilities: CapabilitySnapshot
): PersistedConfig
}
```
`probeRetrieval` 可以复用 `retrieve`,但必须使用用户在创建向导中明确输入的测试查询。
不得生成会泄露组织信息的默认问题,不得调用 Provider 的 App 或模型问答接口,也不得
修改远端知识内容。Provider 自身记录 API 审计或计算检索用量不属于内容修改,必须由界面
提前说明。
Adapter 返回数据对象,不返回 React 组件、HTML 或远端 Schema。Renderer 中的配置定义
由共享的 Provider 判别联合和本地字段描述生成。
## 5. 共享契约
### 5.1 实例
```ts
type CredentialMutation =
| { action: 'keep' }
| { action: 'replace'; value: string }
| { action: 'clear' }
interface ExternalKnowledgeInstanceSummary {
id: string
name: string
provider: 'dify' | 'fastgpt' | 'ragflow'
baseUrl: string
enabled: boolean
credentialStatus: 'configured' | 'missing' | 'unavailable'
probeStatus:
| 'untested'
| 'catalog-ready'
| 'healthy'
| 'list-restricted'
| 'auth-failed'
| 'unreachable'
| 'incompatible'
| 'failed'
detectedVersion?: string
bindingCount: number
lastTestedAt?: string
lastErrorCode?: string
}
```
Renderer 输入使用 `CredentialMutation`,因此新密钥会在输入控件和该次 IPC 中短暂存在。
Main 返回值永远没有 `credential`、`apiKey`、`authorization` 或加密 envelope。
### 5.2 绑定
```ts
interface ExternalKnowledgeBinding {
knowledgeBaseId: string
instanceId: string
remoteKnowledgeBaseId: string
remoteName: string
remoteDescription?: string
commonConfig: ExternalKnowledgeCommonConfig
providerConfig: DifyConfig | FastGptConfig | RagflowConfig
providerConfigVersion: number
adapterVersion: number
lastVerifiedAt?: string
}
```
`providerConfig` 必须带 `provider` 判别字段,且与实例 Provider 一致。`remoteName` 是用于
显示和变化检测的快照,不是授权标识。
### 5.3 标准化结果
现有 `KnowledgeRetrievalResult` 假定结果映射到本地 `documentId/sourceId/chunkId`。需要改为
引用定位的判别联合,同时保持现有调用方可按统一字段读取片段:
```ts
type KnowledgeReferenceLocator =
| {
kind: 'local'
documentId: string
sourceId: string
chunkId: string
parentChunkId?: string
}
| {
kind: 'external'
provider: ExternalKnowledgeProvider
instanceId: string
remoteKnowledgeBaseId: string
remoteDocumentId?: string
remoteChunkId?: string
providerScore?: number
location?: string
sourceUrl?: string
metadata?: Record<string, string | number | boolean | null>
}
interface UnifiedKnowledgeRetrievalResult {
knowledgeBaseId: string
documentTitle: string
sourceDisplayName: string
snippet: string
relevance?: number
rank: number
locator: KnowledgeReferenceLocator
}
```
`remoteDocumentId` 和 `remoteChunkId` 只保存 Provider 实际返回的标识,缺失时不得从标题、
序号或内容哈希推导。`providerScore` 保留原始值,但不改名为统一 `relevance`。只有经过
单独定义和验证的归一化算法才能填写跨 Provider `relevance`。初始跨库拼装按结果配额和
稳定 Provider 顺序工作,不按原始分数混排。
所有共享 Schema 使用严格对象并限制:
- 查询不超过 4,000 字符;同时遵守 Provider 更小限制,例如 Dify 当前公开接口的
250 字符限制,超出时在发送前明确失败,不静默截断查询。
- 单次目录页不超过 100 项,总目录最多 500 项。
- 标准化结果最多 20 条,单片段最多 8,000 字符。
- 标题、ID、定位、URL 和元数据键值均设独立上限。
- Provider 原始响应总字节数设固定上限,超限立即取消读取。
## 6. 持久化
### 6.1 数据库变化
保留现有 `knowledge_bases` 表,增加:
```sql
ALTER TABLE knowledge_bases
ADD COLUMN kind TEXT NOT NULL DEFAULT 'local'
CHECK (kind IN ('local', 'external'));
```
增加实例表:
```sql
CREATE TABLE external_knowledge_instances (
id TEXT PRIMARY KEY,
name TEXT NOT NULL,
provider TEXT NOT NULL CHECK (provider IN ('dify', 'fastgpt', 'ragflow')),
base_url TEXT NOT NULL,
enabled INTEGER NOT NULL CHECK (enabled IN (0, 1)),
credential_envelope_json TEXT,
probe_status TEXT NOT NULL,
detected_version TEXT,
capabilities_json TEXT NOT NULL,
transport_security TEXT NOT NULL,
transport_risk_accepted_url TEXT,
transport_risk_accepted_at TEXT,
last_tested_at TEXT,
last_error_code TEXT,
created_at TEXT NOT NULL,
updated_at TEXT NOT NULL
);
```
增加绑定表:
```sql
CREATE TABLE external_knowledge_bindings (
knowledge_base_id TEXT PRIMARY KEY
REFERENCES knowledge_bases(id) ON DELETE CASCADE,
instance_id TEXT NOT NULL
REFERENCES external_knowledge_instances(id) ON DELETE RESTRICT,
remote_knowledge_base_id TEXT NOT NULL,
remote_name TEXT NOT NULL,
remote_description TEXT,
common_config_json TEXT NOT NULL,
provider_config_json TEXT NOT NULL,
provider_config_version INTEGER NOT NULL,
adapter_version INTEGER NOT NULL,
binding_status TEXT NOT NULL,
last_verified_at TEXT,
last_success_at TEXT,
last_error_code TEXT,
UNIQUE(instance_id, remote_knowledge_base_id)
);
```
已有知识库迁移为 `kind = 'local'`。外部知识库仍保留现有名称、描述和创建时间,但本地
`storageMode`、图谱、分块和本地检索设置不进入外部请求;后续可以在数据库重构时再移除
这些历史必填默认值,本功能不为此扩大迁移范围。
### 6.2 凭据
复用 `SettingsCredentialCipher` 和 Electron `safeStorage`:
- `replace`:Main 加密新值后在一个事务中替换 envelope。
- `keep`:不读取、不重写现有 envelope。
- `clear`:确认后删除 envelope,并把实例凭据状态设为缺失。
- 安全存储不可用时拒绝新增或替换,不降级为明文。
- 解密只发生在发起请求前;请求结束后不缓存明文。
实例导出、诊断和数据库普通 JSON 视图均排除 `credential_envelope_json`。
## 7. IPC 设计
建议增加独立通道:
```text
knowledge:external-instances:list
knowledge:external-instances:test
knowledge:external-instances:save
knowledge:external-instances:set-enabled
knowledge:external-instances:delete
knowledge:external-catalog:list
knowledge:external-catalog:get
knowledge:external-bindings:create
knowledge:external-bindings:update
knowledge:external-bindings:remove
knowledge:external-retrieval:test
```
所有 Handler 必须:
1. `assertTrustedSender`。
2. 用共享 Zod Schema 解析严格输入。
3. 根据实例 ID 在 Main 读取地址和凭据,不接受 Renderer 在检索请求中重复传入。
4. 使用稳定错误码返回脱敏错误。
5. 对网络操作支持 AbortSignal、总超时和响应大小限制。
目录和测试请求返回 `requestId`。Renderer 仍需校验当前类型、实例和目标与响应关联,避免
旧响应覆盖新表单。
## 8. HTTP 边界
### 8.1 服务地址
- 只接受 `http:` 和 `https:`。
- 拒绝用户名、密码、查询和片段。
- Adapter 负责规范化 Provider 所需 API 根路径,避免用户填写完整操作端点。
- 请求只能拼接 Adapter 内置相对路径,远端目录项或错误不能改变目标 URL。
- 重定向默认拒绝;若某 Provider 的受支持部署确需重定向,只允许同源且不得跨跳转发送
Authorization。
- 当前全局“内网兼容模式”决定是否允许 HTTP 和非标准 HTTPS 证书;操作开始后冻结该值。
- HTTP 或实际使用证书例外时,Main 返回 `transportSecurity` 风险状态。用户必须针对规范化
后的当前地址明确确认,才能保存实例或发送 API Key;地址变化立即使旧确认失效。
- 不进行公共云回退,不把自部署地址替换成 Provider 官方地址。
用户明确配置内网地址属于产品用途,因此不能采用禁止私网地址的通用 SSRF 规则。安全边界
依靠显式实例配置、Main-only 请求、固定端点、无任意方法和无远端 URL 跟随。
### 8.2 请求限制
- 默认超时 15 秒,用户可在 1 至 60 秒内调整。
- 目录、详情和检索分别设置响应字节上限。
- JSON 解析后仍执行深度、数组数量、字符串长度和未知字段策略。
- 默认不自动重试。用户重试或上层下一次检索会产生新请求。
- 取消、应用关闭和实例删除立即终止相关请求。
- 日志只记录 Provider、实例 ID、操作、状态码、稳定错误码、耗时和字节数。
## 9. Provider 映射
本节记录 2026-09-03 核对的初始公开接口。实施时应把每个受支持版本的真实响应保存为
去敏 fixture,并以 fixture 和真实实例测试作为发布依据。
### 9.1 Dify
| 操作 | 接口 |
| --- | --- |
| 列表 | `GET /v1/datasets` |
| 检索 | `POST /v1/datasets/{dataset_id}/retrieve` |
| 认证 | `Authorization: Bearer <knowledge-api-key>` |
Adapter 只接受 Knowledge Service API Key,不调用应用 `/info`、Chat 或 Workflow。默认不
发送 `retrieval_model`,沿用远端知识库配置。用户选择覆盖时,Adapter 必须一次收集并验证
当前接口要求的搜索方式、Top K、阈值、`reranking_mode`,以及相应的 Rerank Provider/模型
或关键词/向量权重与 Embedding Provider/模型;缺少任何必填标识时不构造请求。响应从
`records[].segment`、`score`、文档名称和元数据提取标准化引用。
Dify 当前文档限制查询不超过 250 字符。GoodBuddy 不静默截断;超出时检索测试和聊天
诊断返回 Provider 限制,并允许后续单独设计查询压缩策略。
### 9.2 FastGPT
| 操作 | 接口 |
| --- | --- |
| 列表 | `POST /api/core/dataset/list` |
| 详情 | `GET /api/core/dataset/detail?id=...` |
| 检索 | `POST /api/core/dataset/searchTest` |
| 认证 | `Authorization: Bearer <api-key>` |
列表响应同时包含文件夹和知识库,只有 `type = dataset` 可以绑定。检索映射 `datasetId`、
`text`、Token `limit`、`similarity`、`searchMode` 和 `usingReRank`。初始版本不发送查询优化
字段,避免调用 FastGPT 配置的 LLM。
响应从 `q`、`a`、`sourceName`、`sourceId`、`collectionId` 和 `score` 构造片段与引用。
FastGPT 4.15.0 起部署实例的 `/apidoc/devapi` 是接口事实来源,手工文档可能落后。支持矩阵
必须按真实版本测试;不能因为健康页可访问就假定列表和检索 Schema 相同。`searchTest`
可能记录 `SEARCH_TEST` 等远端审计并更新 API Key 用量;Embedding 和 Rerank 也可能产生
费用。GoodBuddy 将这些行为作为检索成本显示,不宣称该接口没有副作用。
### 9.3 RAGFlow
| 操作 | 接口 |
| --- | --- |
| 列表/详情 | `GET /api/v1/datasets` |
| 检索 | `POST /api/v1/retrieval` |
| 认证 | `Authorization: Bearer <api-key>` |
检索映射 `question`、`dataset_ids`、`page_size`、`similarity_threshold`、
`vector_similarity_weight`、`knn_top_k`、重排、`use_kg` 和
`include_knowledge_compilation`。不发送已弃用的 `top_k`。响应从 `data.chunks` 和
`data.doc_aggs` 提取片段、文档、位置和原始相似度。
图谱规则:
- `parser_config.graphrag` 或等价详情字段作为已有图谱的证据,不写回。
- `use_kg` 是检索时开关,只在已有图谱和受支持版本均确认后发送。
- Knowledge Compilation 与旧 GraphRAG 分别建模。
- `include_knowledge_compilation` 使用本地保存的显式布尔值,初始默认 false;即使服务端
默认 true,也不依赖字段省略获得隐式行为。
- Provider 没有返回图节点或路径证据时,GoodBuddy 不生成图谱引用。
## 10. 检索编排
```text
retrieveMany(knowledgeBaseIds, query, requestContext)
├─ load and authorize GoodBuddy knowledge bases
├─ partition local and external bindings
├─ local: existing retrieval path
├─ external: bounded concurrent adapter requests
├─ validate and normalize each response
├─ allocate deterministic context budget
└─ return evidence plus per-library diagnostics
```
预检索和 `knowledge_search` 工具必须调用同一个 `retrieveMany`。如果只修改聊天预检索而
未修改 `KnowledgeMcpGateway`,`auto` 和 `always` 会产生不同能力,这是阻断发布的问题。
### 10.1 上下文预算
- 每个知识库先保留不超过其 `resultLimit` 的结果。
- 先给每个成功知识库一个最小有界配额,再按稳定顺序分配剩余字符。
- 不用不同 Provider 原始分数决定跨库优先级。
- 片段截断在 Main 完成并在引用中标记。
- 相同实例的多个绑定仍按绑定分别请求,除非 Provider 明确支持且 Adapter 实现等价的多
Dataset 请求;合并不得改变每个绑定的配置和诊断。
### 10.2 失败结果
返回结构包含每个知识库的:
```ts
interface KnowledgeRetrievalOutcome {
knowledgeBaseId: string
status: 'success' | 'empty' | 'failed' | 'cancelled'
durationMs: number
resultCount: number
errorCode?: ExternalKnowledgeErrorCode
truncated: boolean
}
```
至少一个 `success` 或 `empty` 表示检索编排完成;全部 `failed/cancelled` 时上层显示整体失败。
## 11. 引用与来源打开
外部结果不能进入依赖本地数据库的 `referenceContext` 和 `openSource` 路径。
- 引用详情直接使用请求时保存的标准化片段和定位。
- Main 可以按远端片段 ID 提供一次只读重新读取,但初始版本不要求。
- Provider 返回 URL 只作为不可信元数据保存。没有独立 URL 规则和真实实例验证前,
Renderer 不显示打开链接操作。
- 活动和会话持久化保存标准化引用,其中包含实际用于回答的有界远端片段;这属于引用
留存,不是批量同步或本地索引。删除会话或对应活动时按现有生命周期删除该副本。
- 实例删除后,历史引用仍显示 Provider、知识库、文档名称和已保存片段,但标记连接已移除。
## 12. 支持矩阵与版本变化
每个 Adapter 维护明确的最低版本、已验证版本和 `adapterVersion`。连接测试优先读取可靠的
版本接口或响应头;无法识别版本时,只允许经真实请求验证过的基础列表和检索字段,高级字段
保持不可用。
Adapter 可以保存少量受控事实,例如“目录接口可用”“详情表明已构建图谱”,但不尝试从
远端拼出完整 capability manifest,也不计算 capability fingerprint。
- `adapterVersion` 相同且实例仍在支持矩阵内:解析已保存配置并执行。
- Adapter 升级:使用明确的配置迁移或把绑定标记为 `config-invalid`,不猜测字段迁移。
- 实例版本离开支持矩阵:停止发送高级字段,并要求重新测试和确认。
- 新能力出现:保持默认关闭,用户主动配置后才发送。
- RAGFlow `use_kg` 还要求当前远端知识库存在已构建图谱的证据。
## 13. 安全与隐私
- API Key 在用户输入和保存 IPC 中短暂存在,随后使用系统安全存储加密;保存后不返回
Renderer,也不进入 Runtime、日志和普通元数据。
- 请求不附带完整会话、附件、本地知识库证据、系统提示、模型配置或其他 Provider 结果。
- Provider 结果使用与本地知识证据相同的不可信上下文标记。
- Adapter 拒绝响应中的原型污染键、过深对象、超长数组和非有限数值。
- 远端错误正文只用于 Main 内映射,日志与 UI 使用稳定错误码和短消息。
- 外部知识库不能扩大当前对话显式选择的 GoodBuddy 知识库 ID。
- Ask 与 Execute 对知识检索均为只读,Execute 不获得额外 Provider 权限。
- Provider 配置中的模型 ID、背景文本和 Metadata 条件按独立长度限制验证,不能携带凭据。
- HTTP 或证书例外需要按当前规范化地址确认凭据传输风险,地址变化后重新确认。
## 14. 测试
### 14.1 契约测试
- 每个 Provider 的列表、详情、检索成功和错误 fixture。
- 未知字段、缺字段、错误类型、超长内容、非有限分数和超大响应。
- Dify 查询长度、FastGPT 文件夹过滤、RAGFlow 图谱和 Knowledge Compilation 字段。
- Provider 配置判别联合拒绝类型错配和未知字段。
### 14.2 安全测试
- 保存完成后的 Renderer 快照、IPC 返回值、日志、错误、活动和导出中不存在明文 API Key;
`replace` 输入只在当前表单和单次 IPC 请求中短暂存在。
- `keep/replace/clear` 凭据语义和安全存储不可用路径。
- 地址中的凭据、查询、片段、危险 scheme、跨源重定向和远端 URL 注入被拒绝。
- 取消、超时、响应大小上限和应用关闭释放请求。
### 14.3 集成测试
- 实例保存、目录读取、手工 ID、绑定创建、编辑和本地移除。
- 同一远端目标重复绑定被拒绝。
- 删除实例的引用保护和级联本地移除确认。
- 本地与外部 `retrieveMany` 部分成功、全部失败和确定性上下文预算。
- 聊天 `always` 与 Agent `knowledge_search` 使用同一 Provider-aware 编排。
- 历史引用在实例或绑定移除后仍可读。
### 14.4 UI 测试
- 类型切换、异步旧响应、目录搜索、刷新和手工模式。
- 两栏与窄窗口堆叠、键盘、焦点恢复和离开保护。
- Provider 字段显隐、失效配置、RAGFlow 图谱说明和恢复默认。
- 外部详情不出现导入、同步、分块和本地图谱操作。
- 错误、零结果、部分失败和 Provider 引用显示。
### 14.5 真实实例验收
每个 Provider 至少选择一个明确版本的自部署实例,记录:
- 版本、部署方式和认证范围。
- 列表与检索的请求/响应 fixture,移除凭据和业务正文。
- 默认与专属配置是否真实生效。
- 401、403、404、429、超时和取消行为。
- 查询、片段、引用和诊断的实际上限。
Mock 或公开文档通过不能代替真实实例验收。
## 15. 实施顺序
这里的顺序只用于控制代码依赖,不裁剪产品设计:
1. 建立共享判别契约、数据库迁移和凭据存储。
2. 实现 HTTP 边界、错误映射和 Adapter Registry。
3. 逐个实现三种 Provider,并用 fixture 完成契约测试。
4. 实现实例管理和目录 IPC。
5. 扩展创建向导、统一列表和外部详情。
6. 扩展检索测试、引用和 `retrieveMany`。
7. 接入聊天预检索与 `KnowledgeMcpGateway`。
8. 完成真实实例、安全、响应式和跨平台验收。
## 16. 发布条件
- 三种 Provider 的受支持版本和限制已在产品界面或发布说明中可查。
- 真实实例列表、绑定、检索和错误矩阵均通过。
- 没有写入远端知识内容的代码路径。
- API Key 泄漏测试、地址边界和响应大小测试通过。
- 本地知识库创建、同步、检索、图谱和引用回归测试通过。
- `auto`、`always`、检索测试和 MCP 知识工具得到一致的外部知识能力。
## 17. 需求追踪
| 需求 | 技术落点 | 验证 |
| --- | --- | --- |
| `EK-FR-01` 至 `EK-FR-03` | 实例契约、Store、实例 IPC、凭据和测试状态 | 实例集成测试、安全测试 |
| `EK-FR-04`、`EK-FR-05` | Adapter 目录与详情接口、目录 IPC | Provider fixture、手工 ID 集成测试 |
| `EK-FR-06` 至 `EK-FR-09` | Provider 判别联合、Adapter 配置版本、Renderer 本地字段定义 | 契约测试、UI 字段显隐测试 |
| `EK-FR-10`、`EK-FR-11` | `KnowledgeBase.kind`、绑定表、统一 `retrieveMany` | 本地与外部混合检索测试 |
| `EK-FR-12`、`EK-FR-13` | 引用定位判别联合、结果标准化、检索测试 IPC | 引用持久化与 UI 测试 |
| `EK-FR-14` | 稳定错误码、逐库 Outcome、取消和超时 | 错误 fixture、部分失败测试 |
| `EK-FR-15` | 外键限制、绑定本地删除、无远端写接口 | 删除生命周期测试 |
| `EK-FR-16` | Main-only HTTP、固定端点、传输风险确认 | 地址、证书和凭据泄漏测试 |
@@ -0,0 +1,401 @@
# 外部知识库 UI 设计
## 文档信息
| 项目 | 内容 |
| --- | --- |
| 状态 | 设计稿 |
| 版本 | 0.1 |
| 日期 | 2026-09-03 |
| 产品需求 | [外部知识库接入 PRD](./external-knowledge-prd.md) |
| 行为规则 | [外部知识库逻辑设计](./external-knowledge-logic-design.md) |
| 全局规范 | [GoodBuddy UI 设计系统](../../../UI-DESIGN.md) |
## 1. 信息架构
外部知识库不增加左侧主导航和知识库一级页签。现有知识库页面结构保持:
```text
知识库
├─ 页面标题区
│ ├─ 管理外部实例
│ └─ 新建知识库
├─ 知识库列表
└─ 当前知识库详情
```
“管理外部实例”管理可复用连接;“新建知识库”负责创建本地知识库或添加一个远端绑定。
## 2. 页面标题区
常规宽度:
```text
知识库 [管理外部实例] [新建知识库]
导入、检索并维护本地和企业现有知识
范围:全局
```
- “新建知识库”保持主按钮。
- “管理外部实例”是带服务器图标的次按钮。
- 沿用知识库页面的全局 `ScopeBadge`,创建和管理外部连接时持续可见。
- 按钮使用文字和图标,不增加只含缩写的厂商快捷入口。
- 窄窗口下两个按钮换到标题下方,保持同一行;空间不足时各占一半宽度。
对应:`EK-FR-01`。
## 3. 知识库列表
本地和外部知识库保留在同一主列表。条目采用现有列表密度,不增加卡片墙。
```text
研发规范
RAGFlow · 研发知识平台 · 远端可检索
产品资料
本地 · 12 个来源 · 全文与向量可用
```
### 3.1 外部条目字段
- GoodBuddy 显示名称。
- Provider 图标或文字徽标。
- 外部实例名称。
- “远端可检索”、认证失效、目标不存在等准确状态。
- 最近一次成功检索时间;从未检索时显示“尚未检索”。
外部条目不显示来源数量、同步进度、向量覆盖率、本地图谱或导入失败数。
### 3.2 列表筛选
现有搜索同时匹配 GoodBuddy 名称、远端名称、Provider 和实例名称。来源筛选使用菜单:
```text
全部来源
本地
Dify
FastGPT
RAGFlow
```
筛选不是新的页面页签。
## 4. 管理外部实例
点击“管理外部实例”打开大尺寸 Modal。Modal 使用标题、可滚动内容和固定操作区,遵循
全局焦点陷阱、Escape、背景隔离和焦点恢复规则。
```text
┌──────────────────────────────────────────────────────────────┐
│ 外部实例 [添加实例] [×] │
│ 管理 Dify、FastGPT 和 RAGFlow 的连接 │
├──────────────────────────────────────────────────────────────┤
│ 名称 Provider 服务地址 状态 操作 │
│ 研发知识平台 RAGFlow ragflow.example 正常 ⋯ │
│ 客服知识平台 FastGPT fastgpt.example 认证失效 ⋯ │
└──────────────────────────────────────────────────────────────┘
```
### 4.1 实例行
显示:
- 名称、Provider、脱敏后的主机名、状态。
- 已绑定知识库数量。
- 最近测试时间。
- 行尾菜单:测试连接、编辑、停用或启用、删除。
服务地址可以显示 scheme、host 和非默认端口,不显示路径中的敏感信息、查询或凭据。
### 4.2 空状态
```text
尚未配置外部实例
添加企业现有的 Dify、FastGPT 或 RAGFlow 服务。
[添加实例]
```
筛选无结果和加载失败使用不同 `EmptyState` 变体。
## 5. 添加和编辑实例
实例表单在管理 Modal 内切换为编辑面板,不叠加第二层 Modal。
```text
添加外部实例
实例名称 [研发知识平台 ]
Provider [RAGFlow ▾]
服务地址 [https://ragflow.example ]
认证方式 API Key
API Key [•••••••••••••••• ]
凭据状态 尚未保存
连接测试
服务连接 未测试
身份认证 未测试
知识库列表 未测试
检索接口 绑定知识库时验证
[取消] [测试连接] [保存实例]
```
### 5.1 字段行为
- Provider 使用原生 Select;编辑已被绑定的实例时不可切换 Provider。
- 服务地址只接受完整 HTTP(S) 地址。字段下方说明其受全局内网兼容模式影响。
- API Key 使用密码输入和显示/隐藏图标。明文会在当前表单和保存 IPC 中短暂存在;编辑时
留空表示保留,不使用占位假密钥。
- 已保存凭据旁提供“替换凭据”和“清除凭据”,清除属于需要确认的操作。
- 地址使用 HTTP,或连接测试依赖放宽证书校验时,在测试和保存操作旁持续显示传输风险。
用户必须针对当前地址确认后才能保存;地址变化会清除该确认。
- “测试连接”不保存草稿;测试期间按钮显示进度并提供取消。
- 保存成功进入应用通知,Modal 返回实例列表并聚焦对应行。
### 5.2 测试结果
分项状态使用图标、文字和说明,不只依靠颜色:
```text
服务连接 通过 183 ms
身份认证 通过
知识库列表 受限 当前凭据不能读取列表,可手工填写知识库 ID
检索接口 待验证 添加知识库时执行
```
长错误折叠显示,正文经过脱敏。失败后保留全部草稿和 API Key 输入。
FastGPT 实例额外显示:`检索会计入该实例的 API 使用记录,并可能产生 Embedding 或
Rerank 用量。`
## 6. 新建知识库向导
扩展现有页面内 `CreateLibraryWizard`,不改为新的全屏页面或 Modal。
### 6.1 类型选择
表单第一项使用单选卡片或共享 SegmentedControl:
```text
知识库类型
[本地] [Dify] [FastGPT] [RAGFlow]
```
只有选择本地时显示现有存储模式、图谱和本地说明。外部类型选中后显示两栏配置。
### 6.2 外部类型两栏布局
```text
┌──────────────────────────────┬──────────────────────────────┐
│ 知识库来源 │ 检索配置 │
│ │ │
│ Provider RAGFlow │ 通用配置 │
│ 外部实例 [研发平台 ▾] │ 返回片段数 [ 6 ] │
│ 远端知识库 [研发规范 ▾] │ 请求超时 [15 秒] │
│ [↻] │ 单片段上限 [4000] │
│ [手工填写知识库 ID] │ │
│ │ RAGFlow 配置 │
│ 显示名称 [研发规范 ]│ 相似度阈值 [0.20] │
│ 远端名称 研发规范 │ 向量相似度权重 [0.30] │
│ 远端 ID 7f31…c902 │ KNN Top K [1024] │
│ 测试查询 [部署网络要求 ]│ 图谱检索 [开关] │
│ │ Knowledge Compilation [开关]│
├──────────────────────────────┴──────────────────────────────┤
│ 将向研发知识平台发送测试查询。不会上传文件或完整会话。 │
│ [取消] [测试检索] [添加知识库] │
└─────────────────────────────────────────────────────────────┘
```
测试查询由用户填写,不自动生成,也不取用当前会话内容。“添加知识库”在真实检索请求
成功前禁用;成功返回零条结果仍可添加,但界面显示“检索成功,未找到匹配片段”。验证结果
在底部说明区展示,不用成功 Alert 撑高表单。
添加成功后沿用本地知识库行为,把新绑定加入当前聊天选择,不重新启用其他已取消知识库。
### 6.3 目录下拉框
- 选择实例后自动打开加载状态,不要求再点击“读取”。
- 使用可搜索 Select,选项显示名称、远端短 ID 和可用状态。
- 右侧刷新使用刷新图标按钮,Tooltip 为“刷新知识库列表”。
- 加载时保持控件稳定尺寸,显示“正在读取知识库…”。
- 目录为空显示“当前实例没有可访问的知识库”。
- 403 或不支持列表时显示原因和“手工填写知识库 ID”。
- 列表失败后显示“重试”,不自动切换到手工模式。
### 6.4 手工模式
```text
远端知识库 ID [ ]
显示名称 [ ]
[验证知识库]
```
验证成功后显示远端名称和 Provider 返回的摘要。返回自动列表不会丢弃已输入 ID,切换前
如有未保存输入须确认。
## 7. 配置面板
右侧配置固定分为“通用配置”和“{Provider} 配置”,不创建嵌套卡片。高级字段可以使用
一个折叠区,但核心检索方式、阈值和 RAGFlow 图谱检索保持直接可见。
控件选择:
- 开关:图谱检索、Score 阈值启用、Rerank、使用 Dify 知识库默认配置。
- Select 或 SegmentedControl:少量固定检索方式。
- 数字输入或 Stepper:结果数、Token、Top K、超时。
- Slider 加数字输入:0 至 1 的阈值和权重,二者保持同步。
- Metadata 条件:初始版本不提供自由 JSON 编辑器。
字段显隐由 GoodBuddy 内置 Provider 描述和 Main 返回的能力状态共同决定。服务端返回的
任意字符串不得变成 HTML、控件标签或帮助链接。
### 7.1 RAGFlow 图谱文案
开关名称:`图谱检索`
说明:`检索远端知识库已经生成的图谱内容,不会创建或更新图谱。`
只有远端详情或受控探测表明图谱已经构建时,该开关才可用。证据缺失时显示“未确认远端
图谱状态”并禁用。Knowledge Compilation 单独显示为 `包含 Knowledge Compilation`,默认
关闭,不把它和旧 GraphRAG 合成同一开关。
## 8. 外部知识库详情
选中外部绑定后,现有详情区按来源类型裁剪:
```text
研发规范 RAGFlow · 远端检索
研发知识平台 / 远端知识库 7f31…c902
[概览] [检索配置] [检索测试]
```
### 8.1 概览
显示 Provider、实例、远端名称、远端 ID、连接状态、最近成功检索和数据位置。操作包括:
- 刷新远端信息。
- 更换远端知识库。
- 编辑 GoodBuddy 显示名称。
- 从 GoodBuddy 移除。
不显示导入文件、添加目录、添加网页、同步、分块、重建索引和本地图谱入口。
### 8.2 检索配置
复用创建向导右侧配置面板。存在失效字段时,页头显示“配置需要确认”,字段附近说明
Provider 版本变化,保存按钮保持禁用直到用户处理。
### 8.3 检索测试
复用现有检索测试工作台的查询、结果和焦点行为,但外部结果采用 Provider 诊断:
```text
RAGFlow · 研发知识平台
总耗时 642 ms · 返回 6 条 · 保留 6 条
1 部署规范.pdf
第四章 网络要求…
Provider 分数 0.82 · 文档 ID 98ab…
```
外部测试不显示 FTS/CJK/本地向量扫描等本地通道,也不提供依赖本地分块的“查看上下文”。
## 9. 聊天知识范围
现有多选列表保留一个选择面,只在每行增加来源:
```text
[✓] 产品资料 本地
[✓] 研发规范 RAGFlow · 研发知识平台
[ ] 客服知识 FastGPT · 客服平台
```
- 不按 Provider 创建多套选择器。
- 不可用绑定保留显示但禁用勾选,并给出认证失效或目标不存在原因。
- 当前会话已选绑定变为不可用时,不静默移除 ID;发送前提示该知识库本次无法检索。
## 10. 执行状态和引用
活动状态:
```text
正在检索“研发规范”
RAGFlow · 研发知识平台 · 已发送当前检索词
```
部分失败:
```text
已检索 3 个知识库,2 个成功,1 个超时
[查看详情]
```
引用:
```text
部署规范.pdf / 网络要求
研发规范 · RAGFlow · 研发知识平台
```
引用详情显示远端文档名、ID、片段、Provider 分数和实际返回的定位。未完成 URL 安全设计前,
不显示“打开远端来源”。
## 11. 删除确认
移除绑定:
```text
从 GoodBuddy 移除“研发规范”?
这会删除本机绑定和检索配置,不会删除 RAGFlow 中的知识库或文档。
[取消] [移除]
```
删除有绑定的实例:
```text
“研发知识平台”仍被 3 个知识库使用
删除实例会同时从 GoodBuddy 移除这些绑定。远端数据不会改变。
[取消] [查看知识库] [删除实例和本地绑定]
```
破坏性主操作使用 `danger-solid`,默认焦点放在“取消”。
## 12. 可访问性与响应式
- 常规宽度两栏使用稳定 Grid;小于 `960px` 时改为单栏,顺序为来源、通用配置、Provider 配置。
- 小于 `720px` 时外部实例表格转为单列列表,行操作保留菜单按钮和完整可访问名称。
- Modal、创建向导、下拉框和折叠区支持完整键盘操作。
- 异步列表和测试状态使用 `aria-live="polite"`;错误使用与字段关联的 `role="alert"`。
- 图标按钮必须提供 Tooltip 和 `aria-label`。
- 状态不只靠颜色;加载、成功、受限和失败均包含文字。
- 长实例名、地址、远端名称和 ID 使用单行省略,完整值可通过 Tooltip 或详情查看。
- 切换类型、实例或退出时存在有效草稿,应按全局离开保护规则确认。
## 13. 文案表
| 场景 | 文案 |
| --- | --- |
| 页面操作 | 管理外部实例 |
| 创建类型 | 本地 / Dify / FastGPT / RAGFlow |
| 创建主操作 | 添加知识库 |
| 列表加载 | 正在读取知识库… |
| 列表受限 | 当前凭据不能读取知识库列表,可手工填写知识库 ID。 |
| 远端状态 | 远端可检索 |
| 移除操作 | 从 GoodBuddy 移除 |
| 图谱开关 | 图谱检索 |
| 测试说明 | 测试只发送当前查询,不会调用 GoodBuddy 模型或修改远端内容。 |
产品文案不使用“同步外部知识库”“导入 Dify 知识库”或“创建远端知识库”,因为这些动作
都不是本功能的实际行为。
## 14. 需求追踪
| UI 区域 | 需求 | 场景 |
| --- | --- | --- |
| 页面标题与统一列表 | `EK-FR-01`、`EK-FR-10` | `EK-US-C1` |
| 外部实例管理与表单 | `EK-FR-02`、`EK-FR-03`、`EK-FR-15`、`EK-FR-16` | `EK-US-A1` 至 `EK-US-A3` |
| 新建知识库向导 | `EK-FR-04` 至 `EK-FR-09` | `EK-US-B1` 至 `EK-US-B4` |
| 外部详情与检索测试 | `EK-FR-12`、`EK-FR-13` | `EK-US-C3`、`EK-US-D1` 至 `EK-US-D4` |
| 聊天范围、状态和引用 | `EK-FR-11`、`EK-FR-12`、`EK-FR-14` | `EK-US-C1` 至 `EK-US-C4` |
@@ -0,0 +1,212 @@
# 外部知识库 User Stories
## 文档信息
| 项目 | 内容 |
| --- | --- |
| 状态 | 设计稿 |
| 版本 | 0.1 |
| 日期 | 2026-09-03 |
| 关联 PRD | [外部知识库接入 PRD](./external-knowledge-prd.md) |
## 1. 角色
- **知识库使用者**:在聊天中选择已经添加的本地或外部知识库并查看引用。
- **实例维护者**:持有外部知识库 API Key,负责配置实例、选择远端知识库和处理失效连接。
- **RAG 调试者**:需要调整 Provider 参数并直接验证检索结果。
## 2. 实例管理
### EK-US-A1 添加外部实例
作为实例维护者,我希望在知识库页面保存一个外部实例,以便后续绑定其中的多个知识库。
验收:
- Given 用户打开“管理外部实例”并选择 Dify、FastGPT 或 RAGFlow
- When 用户填写名称、服务地址和 API Key,并执行连接测试
- Then 页面分别显示服务、认证、目录和检索检查结果
- And 保存后只显示“凭据已配置”,不回显 API Key
- And 新实例可被同 Provider 的新建知识库向导选择
- And 使用 HTTP 或放宽证书校验时,保存前明确提示 API Key 的传输风险
### EK-US-A2 修复失效凭据
作为实例维护者,我希望替换认证失效的 API Key,同时保留已有知识库绑定。
验收:
- Given 实例因认证失败处于“认证失效”状态
- When 用户选择“替换凭据”、测试并保存
- Then 所有绑定继续引用同一实例 ID
- And 旧密钥不再使用
- And 用户没有输入新密钥时可以取消且不清除旧密钥
### EK-US-A3 删除仍被使用的实例
作为实例维护者,我希望删除实例前看到受影响的知识库,以免留下无法解释的绑定。
验收:
- Given 实例仍被一个或多个外部知识库绑定引用
- When 用户点击“删除实例”
- Then 确认界面列出受影响数量和名称
- And 用户可以取消,或明确同时移除本地绑定
- And 确认后不向外部实例发送删除请求
## 3. 添加知识库
### EK-US-B1 从远端列表添加
作为实例维护者,我希望选择 Provider 和实例后自动看到远端知识库,以便避免手工复制 ID。
验收:
- Given 至少存在一个可用的对应 Provider 实例
- When 用户在“新建知识库”中选择外部类型和实例
- Then GoodBuddy 自动读取有界知识库列表
- And 下拉框支持按名称搜索与刷新
- And 目录只显示当前凭据可见的知识库,不推断隐藏对象
- And 切换实例后旧实例的异步响应不会覆盖新列表
### EK-US-B2 手工填写远端 ID
作为实例维护者,我希望列表接口受限时仍可通过远端 ID 添加已有知识库。
验收:
- Given 连接测试表明认证和检索可用,但目录读取无权限或不受支持
- When 用户进入手工模式并填写远端知识库 ID
- Then GoodBuddy 使用详情或测试检索验证该目标
- And 验证失败时保留输入并显示原因
- And 未经真实验证不能完成添加
### EK-US-B3 配置 RAGFlow 图谱检索
作为 RAG 调试者,我希望在添加 RAGFlow 知识库时设置图谱检索,以便使用远端已经构建的图谱内容。
验收:
- Given 适配器确认实例检索接口支持 `use_kg`
- When 用户选择一个具备相关能力的 RAGFlow 知识库
- Then 右侧显示“图谱检索”开关并说明它只影响检索
- And 开启后测试请求携带该选项
- And 只有远端知识库存在已构建图谱的证据时才允许开启
- And 页面不把该开关描述为构建或更新远端图谱
- And 能力不明确时该开关禁用并说明原因
### EK-US-B4 保持本地创建流程
作为本地知识库用户,我希望新增外部类型后仍能按原流程创建本地知识库。
验收:
- Given 用户在新建向导中选择“本地”
- When 用户填写名称、存储模式和图谱设置
- Then 表单字段、默认值和创建结果与现有行为一致
- And 外部实例、远端 ID 和 Provider 配置不出现
## 4. 检索和引用
### EK-US-C1 在聊天中选择外部知识库
作为知识库使用者,我希望外部知识库出现在现有知识范围选择器中,以便与本地知识库一起使用。
验收:
- Given 外部知识库绑定处于可检索状态
- When 用户打开聊天知识范围
- Then 它与本地知识库出现在同一选择器中
- And 条目持续显示 Provider 和实例名称
- And 选择结果仍保存 GoodBuddy 知识库 ID
- And 新添加的绑定进入当前聊天选择,但不重新启用其他已取消知识库
### EK-US-C2 只发送检索查询
作为知识库使用者,我希望清楚知道哪些数据会发送到企业知识库。
验收:
- Given 本次请求选择了外部知识库
- When GoodBuddy 执行检索
- Then 只发送本次检索查询、远端知识库 ID 和已保存检索参数
- And 不发送完整会话、本地附件、其他知识库内容、系统提示或模型凭据
- And 活动状态显示目标 Provider 和实例
### EK-US-C3 查看外部引用
作为知识库使用者,我希望回答中的引用标明外部来源,以便回到企业知识系统核验。
验收:
- Given Provider 返回文档名、片段 ID、内容和分数
- When GoodBuddy 展示引用
- Then 引用显示 Provider、实例、知识库和文档名称
- And 详情只显示 Provider 实际返回且通过校验的定位信息
- And 缺失页码、链接或分数时不生成替代值
### EK-US-C4 多知识库部分失败
作为知识库使用者,我希望一个外部实例暂时失败时仍能使用其他成功结果。
验收:
- Given 本次选择了本地知识库和两个外部知识库
- When 一个外部请求超时,其他请求成功
- Then 成功证据继续进入回答
- And 页面显示一个知识库检索失败及其原因
- And 超时不显示为“未找到相关内容”
- And GoodBuddy 不自动改用同 Provider 的其他实例
## 5. 配置与诊断
### EK-US-D1 调整 Provider 配置
作为 RAG 调试者,我希望只看到当前 Provider 支持的参数,以便理解设置会怎样影响远端检索。
验收:
- Given 用户编辑一个外部知识库绑定
- When 页面读取实例能力和已保存配置
- Then 通用配置与 Provider 专属配置分区显示
- And 每个字段显示范围、默认值和作用
- And 不受支持的字段不会被静默发送
- And 恢复默认只恢复当前绑定的 Provider 配置
### EK-US-D2 运行检索测试
作为 RAG 调试者,我希望在知识库页面直接测试外部检索,不经过聊天模型。
验收:
- Given 当前选中一个外部知识库
- When 用户输入查询并点击“测试检索”
- Then 页面显示 Provider 耗时、返回数量、片段、来源和截断状态
- And 测试不创建聊天消息、不调用 GoodBuddy LLM、不修改远端内容
- And 远端原始响应和凭据不进入界面或日志
- And FastGPT 测试明确提示远端可能记录 API 使用并产生检索或重排用量
### EK-US-D3 Provider 版本变化
作为实例维护者,我希望升级外部系统后看到配置是否仍受支持。
验收:
- Given 最近一次能力探测与已保存快照不同
- When 用户测试实例或打开绑定设置
- Then 页面指出新增、失效或行为变化的配置
- And 失效配置不会静默删除或继续发送
- And 用户确认有效配置后才更新绑定
### EK-US-D4 远端知识库被删除
作为实例维护者,我希望远端目标不存在时看到准确状态并重新绑定。
验收:
- Given Provider 返回目标不存在
- When 用户打开知识库或执行检索
- Then 绑定状态显示“远端知识库不存在”
- And 聊天选择器不把它显示为可用
- And 用户可以刷新目录并选择新的远端知识库
- And 保存新目标前必须重新测试