592 lines
24 KiB
Markdown
592 lines
24 KiB
Markdown
# 知识库检索与分块增强 PRD
|
||
|
||
## 文档信息
|
||
|
||
| 项目 | 内容 |
|
||
| --- | --- |
|
||
| 状态 | 实施中 |
|
||
| 版本 | 0.1 |
|
||
| 日期 | 2026-08-11 |
|
||
| 适用产品 | GoodBuddy 桌面端 |
|
||
| 实施范围 | 第一阶段:可用、可见、可诊断;第二阶段:可调、可优化、可维护 |
|
||
|
||
## 1. 背景
|
||
|
||
GoodBuddy 已具备本地多知识库、文件与目录同步、网页导入、SQLite FTS5、
|
||
OpenAI 兼容向量模型、RRF 混合检索、知识图谱、任务状态和来源引用。现有实现
|
||
优先建立了本地数据主权、安全边界和跨 Runtime 工具授权,但用户仍难以稳定
|
||
获得“导入资料后即可准确问答”的体验。
|
||
|
||
当前主要问题不是缺少知识图谱,而是基础 RAG 链路缺少完整闭环:
|
||
|
||
1. 在对话中启用知识库只会开放搜索工具,是否检索仍由模型自行决定。
|
||
2. 默认向量检索关闭,中文全文检索对自然语言问法和同义表达的召回不足。
|
||
3. 向量请求失败会降级为全文检索,但知识库页面仍可能显示索引完成。
|
||
4. 大于 5,000 个向量分块的知识库会跳过向量召回。
|
||
5. 用户不能独立测试召回、查看各通道得分或确认实际送入模型的上下文。
|
||
6. 分块参数固定,缺少结构化、父子分块、分块预览和人工修正。
|
||
7. 引用只能阅读片段,不能查看完整上下文或打开原始来源。
|
||
|
||
本项目先完成稳定性和可观测性,再增加高级分块、重排与维护能力。知识图谱
|
||
继续作为可选召回通道,但不替代全文和向量检索的基础质量。
|
||
|
||
## 2. 已确认的产品决策
|
||
|
||
1. 保持本地优先,不引入必须联网的托管知识库服务。
|
||
2. 保持 Electron Main、Preload、Renderer 的安全边界,Renderer 不直接读取
|
||
数据库、原文件或向量。
|
||
3. 保留“模型按需检索”,并新增“每次先检索”模式。后者必须由 Main 进程
|
||
预检索,不能只依赖提示词要求模型调用工具。
|
||
4. 知识库新建后不默认启用全部已有知识库;对话中的范围继续由用户显式选择。
|
||
5. 向量服务不可用时保留全文检索,但必须返回明确降级状态。
|
||
6. 中文召回使用应用内可控的 CJK n-gram 索引,不新增远程服务依赖。
|
||
7. 混合检索保留 RRF 候选融合,并增加本地确定性重排、可选的
|
||
Cohere/Jina 兼容学习型重排、最低相关度和上下文预算。学习型重排失败时
|
||
安全降级,不影响全文、向量和图谱召回。
|
||
8. 向量搜索取消 5,000 分块静默失效,使用有界内存的分页扫描。在没有稳定
|
||
跨平台向量扩展前,接受本地 CPU 线性扫描,并持续显示性能诊断。
|
||
9. 向量索引兼容性同时校验 Provider、Model、维度和 Provider Fingerprint。
|
||
同名模型切换端点后,旧向量不能继续参与召回。
|
||
10. 失败或取消的重建不能停用上一版已就绪索引。新索引只有完整校验成功后才
|
||
原子替换当前服务版本。
|
||
11. 分块设置属于知识库,修改后不会伪装为立即生效。用户需要显式重建索引。
|
||
12. 分块允许预览、编辑、启用、停用和删除。来源再次同步可能覆盖人工修改,
|
||
UI 必须在修改前持续说明该行为。
|
||
13. 第一阶段和第二阶段均不新增付费或外部模型调用。现有 Embeddings 调用仍由
|
||
用户配置决定。
|
||
14. Ask 的运行时边界保持只读。知识库内容始终被标记为不可信证据,
|
||
不能成为系统指令。
|
||
|
||
## 3. 目标
|
||
|
||
### 3.1 用户目标
|
||
|
||
- 明确知道本次回答是否检索、检索了哪些知识库,以及是否发生降级。
|
||
- 在知识库页面输入真实问题,查看命中分块、通道、得分和最终上下文。
|
||
- 为不同文档选择适合的分块模式,并在导入前理解影响。
|
||
- 查看和修正错误分块,不需要删除并重新导入整个来源。
|
||
- 从回答引用查看完整上下文,并打开对应本地文件或网页。
|
||
- 在向量、解析或图谱失败时获得可恢复的状态和明确操作。
|
||
|
||
### 3.2 产品目标
|
||
|
||
- 默认中文问法在没有向量模型时仍具有可用的关键词召回。
|
||
- 向量服务故障、大知识库和模型变更不再产生静默空结果。
|
||
- 建立可复现的检索调试入口,支持固定问题进行回归测试。
|
||
- 将解析、全文、向量和图谱状态拆分,避免“索引完成”误导。
|
||
- 为后续元数据过滤、远程 Rerank Provider 和自动评测保留稳定契约。
|
||
|
||
### 3.3 质量目标
|
||
|
||
- 中文同义改写测试集的 Recall@5 相比现有全文检索基线提升至少 30%。
|
||
- 检索测试结果必须在本机重复执行时保持稳定排序。
|
||
- 任意向量失败都必须在检索诊断或任务状态中可见。
|
||
- 10,000 个分块的知识库不得因固定上限返回空向量结果。
|
||
- 每条展示引用都能找到仍存在且属于已授权知识库的分块和文档。
|
||
- 检索输出和上下文拼装均遵守字符、结果数和 IPC 大小上限。
|
||
|
||
## 4. 非目标
|
||
|
||
本项目不包含:
|
||
|
||
- 团队共享知识库、SSO、SCIM 或跨设备同步。
|
||
- 企业级 ACL、文档级角色继承和远程权限同步。
|
||
- 云端网站爬虫、Notion、飞书、语雀等第三方连接器。
|
||
- MinerU、PaddleOCR-VL 或其他远程文档解析服务。
|
||
- 专用向量数据库、外部 Elasticsearch 或打包平台原生向量扩展。
|
||
- 托管重排服务账户、计费或供应商绑定;仅提供通用兼容接口配置。
|
||
- 自动问题生成、FAQ 生成和训练数据标注平台。
|
||
- 完整 RAG 离线评测平台。第二阶段只提供手动检索测试与可导出的诊断信息。
|
||
- 在应用内高保真渲染所有原始 Office 和 PDF 文档。
|
||
|
||
## 5. 竞品基线与 GoodBuddy 定位
|
||
|
||
截至 2026-08-11,Dify、FastGPT 和 RAGFlow 的公开文档均把检索测试、可配置
|
||
分块和可调检索参数作为知识库基础能力:
|
||
|
||
| 能力 | Dify | FastGPT | RAGFlow | GoodBuddy 本期 |
|
||
| --- | --- | --- | --- | --- |
|
||
| 检索测试 | 支持 | 支持 | 支持 | 第一阶段支持 |
|
||
| Top K / 阈值 | 支持 | 支持 | 支持 | 第一阶段支持 |
|
||
| 全文 + 向量 | 支持 | 支持 | 支持 | 已有,第一阶段增强中文 |
|
||
| Rerank | 模型 Rerank | 模型 Rerank | 模型 Rerank | 本地确定性与可选兼容模型重排 |
|
||
| 父子分块 | 支持 | 可通过索引与大分块组合 | 支持多种切分策略 | 第二阶段支持 |
|
||
| 分块维护 | 支持内容维护 | 支持数据维护 | 支持块级检查 | 第二阶段支持 |
|
||
| 深度文档理解 | 中等 | 中等 | 强 | 继续复用本地解析与 OCR |
|
||
| 本地目录监听 | 非核心 | 非核心 | 非核心 | GoodBuddy 差异化能力 |
|
||
| 本地可编辑图谱 | 非核心 | 非核心 | 部分版本支持 GraphRAG | GoodBuddy 差异化能力 |
|
||
|
||
本期不复制竞品的云端工作流平台,而是将其成熟 RAG 交互映射为桌面、本地、
|
||
受控的数据链路。
|
||
|
||
参考公开文档:
|
||
|
||
- Dify Knowledge:
|
||
<https://docs.dify.ai/en/use-dify/knowledge/readme>
|
||
- Dify 检索测试:
|
||
<https://docs.dify.ai/en/use-dify/knowledge/test-retrieval>
|
||
- Dify 分块设置:
|
||
<https://docs.dify.ai/en/use-dify/knowledge/create-knowledge/chunking-and-cleaning>
|
||
- FastGPT 知识库搜索方案和参数:
|
||
<https://doc.fastgpt.io/docs/introduction/guide/knowledge_base/dataset_engine>
|
||
- RAGFlow Dataset 配置:
|
||
<https://ragflow.io/docs/configure_knowledge_base>
|
||
- RAGFlow 检索测试:
|
||
<https://ragflow.io/docs/run_retrieval_test>
|
||
|
||
## 6. 信息架构
|
||
|
||
知识工作区继续使用主从布局和现有四个页签:
|
||
|
||
```text
|
||
知识库
|
||
├─ 文档与来源
|
||
│ ├─ 来源管理
|
||
│ ├─ 检索测试入口
|
||
│ ├─ 文档状态
|
||
│ └─ 分块查看与维护
|
||
├─ 知识图谱
|
||
├─ 任务中心
|
||
└─ 设置
|
||
├─ 检索设置
|
||
├─ 分块设置
|
||
└─ 图谱设置
|
||
```
|
||
|
||
“检索测试”是当前知识库的高频诊断操作,通过知识库标题区次操作打开独立
|
||
工作台,不新增第五个一级页签。
|
||
|
||
对话输入区的知识范围弹层包含:
|
||
|
||
1. 已启用知识库多选。
|
||
2. 检索方式:模型按需检索、每次先检索。
|
||
3. 当前范围为空、索引降级或向量未配置时的短说明。
|
||
|
||
## 7. 第一阶段:可用、可见、可诊断
|
||
|
||
### 7.1 检索方式
|
||
|
||
新增请求级 `knowledgeRetrievalMode`:
|
||
|
||
| 值 | 用户文案 | 行为 |
|
||
| --- | --- | --- |
|
||
| `auto` | 模型按需检索 | 保留当前 `knowledge_search` 工具,由模型决定是否调用 |
|
||
| `always` | 每次先检索 | Main 在启动 Runtime 前使用原始用户问题检索一次,再把有界证据作为不可信上下文提供给 Runtime |
|
||
|
||
规则:
|
||
|
||
- 没有启用知识库时不显示为“已检索”。
|
||
- `always` 预检索后仍保留 `knowledge_search`,模型可以改写查询再次检索。
|
||
- 预检索零结果不阻止回答,但必须显示“已检索,未找到相关内容”。
|
||
- 预检索失败不得自动扩大范围或访问未选知识库。
|
||
- 图片生成能力不执行知识预检索。
|
||
- Ask 和 Execute 使用相同的只读检索范围。
|
||
|
||
### 7.2 中文全文检索
|
||
|
||
在现有 `unicode61` FTS 之外增加本地 CJK n-gram 检索文本:
|
||
|
||
- 连续汉字生成二元词组,保留必要的单字符短查询回退。
|
||
- 拉丁字母和数字使用 NFKC、大小写归一化和现有 FTS。
|
||
- 多个查询词使用召回优先的 OR 候选,再通过覆盖率和短语命中重排。
|
||
- 不把整句中文问题转换成“所有汉字必须同时出现”的条件。
|
||
- 索引更新、分块编辑、停用和删除必须同步更新 CJK 索引。
|
||
- 数据库迁移必须为已有分块有界回填,不要求用户重新导入。
|
||
|
||
### 7.3 检索设置
|
||
|
||
每个知识库保存以下设置:
|
||
|
||
| 字段 | 范围 | 默认值 |
|
||
| --- | --- | --- |
|
||
| `topK` | 1 至 20 | 6 |
|
||
| `minimumVectorSimilarity` | 0 至 1 | 0(不过滤低相似度结果) |
|
||
| `ftsWeight` | 0 至 2 | 1 |
|
||
| `vectorWeight` | 0 至 2 | 1 |
|
||
| `graphWeight` | 0 至 2 | 0.8 |
|
||
| `candidateMultiplier` | 2 至 10 | 4 |
|
||
| `contextMaxCharacters` | 2,000 至 48,000 | 16,000 |
|
||
| `adjacentChunkCount` | 0 至 2 | 0 |
|
||
| `localRerankEnabled` | 布尔值 | false |
|
||
|
||
至少一个召回通道权重大于 0。图谱未启用时,图谱权重只读显示为不可用。
|
||
向量模型未启用或索引不兼容时,向量权重保留但当前请求降级。
|
||
|
||
### 7.4 检索测试工作台
|
||
|
||
用户输入最多 4,000 字符的问题,工作台显示:
|
||
|
||
- 当前知识库和生效设置。
|
||
- 总耗时、各通道耗时和候选数。
|
||
- 请求通道、实际使用通道和降级原因。
|
||
- 最终结果序号、文档、定位、片段和最终相关度。
|
||
- FTS、CJK、向量、图谱的独立排名与向量相似度。
|
||
- 本地重排前后排名。
|
||
- 相邻分块或父块合并后的实际上下文。
|
||
- “查看分块”“打开来源”操作。
|
||
|
||
检索测试不创建聊天消息、不写入会话历史、不调用 LLM,也不改变知识库内容。
|
||
|
||
### 7.5 可扩展向量搜索
|
||
|
||
移除“超过 5,000 个候选则返回空结果”的逻辑:
|
||
|
||
1. 按稳定游标分页读取同一知识库、Provider、Model 和维度的向量。
|
||
2. 每批计算余弦相似度。
|
||
3. 内存中只保留候选上限所需的最佳结果。
|
||
4. 支持取消和应用关闭。
|
||
5. 维度、校验和或索引状态不匹配的向量不参与结果。
|
||
6. 诊断返回扫描数量和向量耗时。
|
||
7. Provider Fingerprint 不匹配时标记索引不兼容,不回退到同名旧模型向量。
|
||
|
||
线性扫描是本期跨平台保底实现。后续接入稳定向量扩展时不得改变上层契约。
|
||
|
||
### 7.6 状态与降级
|
||
|
||
文档状态拆分为:
|
||
|
||
| 状态 | 含义 |
|
||
| --- | --- |
|
||
| 解析 | 等待、运行、完成、失败 |
|
||
| 全文索引 | 等待、完成、失败 |
|
||
| 向量索引 | 未启用、等待、运行、完成、失败、不兼容 |
|
||
| 图谱 | 未启用、按需、等待、运行、完成、失败 |
|
||
|
||
知识库汇总不得仅以“文档 metadata 不是 failed”计算完成。UI 至少显示:
|
||
|
||
- 可用于全文检索的文档数。
|
||
- 已完成向量化的文档数。
|
||
- 失败文档数。
|
||
- 当前向量模型与索引是否兼容。
|
||
|
||
降级事件包括:
|
||
|
||
- 未配置向量模型。
|
||
- 查询向量生成失败。
|
||
- 当前模型没有匹配索引。
|
||
- 部分文档向量失败。
|
||
- 图谱关闭或没有证据。
|
||
- 结果被相关度或上下文预算过滤。
|
||
|
||
### 7.7 引用查看
|
||
|
||
每条引用增加稳定 `chunkId`、最终相关度和检索通道。用户展开引用后可以:
|
||
|
||
1. 查看命中分块。
|
||
2. 查看相邻分块或父块形成的完整上下文。
|
||
3. 查看知识库、文档、来源和定位。
|
||
4. 对本地文件调用 Main 校验后的 `shell.openPath`。
|
||
5. 对 HTTP(S) 来源调用 Main 校验后的外部打开。
|
||
|
||
Renderer 不能提交任意路径或 URL。Main 必须根据 `libraryId`、`documentId` 和
|
||
`chunkId` 重新读取已保存来源并验证归属。
|
||
|
||
界面把该列表描述为“本次检索证据”或“已查阅来源”,不把仅被召回的片段
|
||
自动宣称为回答中某个句子的精确出处。后续只有经过稳定 Citation ID 校验的
|
||
句级标注才能使用更强的“该句引用”语义。
|
||
|
||
## 8. 第二阶段:可调、可优化、可维护
|
||
|
||
### 8.1 分块模式
|
||
|
||
每个知识库选择一种模式:
|
||
|
||
| 模式 | 行为 | 适用内容 |
|
||
| --- | --- | --- |
|
||
| 固定分块 | 按目标长度、重叠和自然边界切分 | 普通文本、日志、代码 |
|
||
| 结构分块 | 优先保持解析 section、Markdown 标题和段落结构 | 手册、制度、长文档 |
|
||
| 父子分块 | 小块用于召回,大块用于模型上下文 | 长篇说明、合同、研究资料 |
|
||
|
||
设置:
|
||
|
||
| 字段 | 范围 | 默认值 |
|
||
| --- | --- | --- |
|
||
| `mode` | `fixed` / `structure` / `parent-child` | `structure` |
|
||
| `targetCharacters` | 400 至 8,000 | 1,600 |
|
||
| `overlapCharacters` | 0 至目标长度的 40% | 160 |
|
||
| `parentCharacters` | 1,600 至 16,000 | 4,800 |
|
||
| `childCharacters` | 300 至 4,000 | 900 |
|
||
|
||
父子分块要求:
|
||
|
||
- 父块只作为上下文,不进入 FTS、CJK 或向量候选。
|
||
- 子块用于召回,并保存父块关联。
|
||
- 引用默认突出子块,同时允许查看父块全文。
|
||
- 父块和子块总输出仍受上下文预算限制。
|
||
|
||
### 8.2 本地与学习型重排
|
||
|
||
第二阶段提供不调用外部模型的可选本地重排。评分特征包括:
|
||
|
||
- 原始 RRF 排名。
|
||
- 中文和拉丁词覆盖率。
|
||
- 完整短语命中。
|
||
- 文档标题、分块标题和路径命中。
|
||
- 向量相似度。
|
||
- 同文档重复结果惩罚。
|
||
|
||
重排结果必须:
|
||
|
||
- 归一化为 0 至 1 的 `relevance`。
|
||
- 对相同输入和索引保持确定性。
|
||
- 保留重排前排名和各特征得分用于诊断。
|
||
- 在关闭时完全保留原有 RRF 排序。
|
||
|
||
学习型模式使用 Main 进程中的 Cohere/Jina 兼容客户端,凭据只进入加密设置和
|
||
Main 进程。请求限制为 100 个候选、每个候选 8,000 字符,并具有 15 秒默认
|
||
超时、取消传播和有界响应。失败时可回退本地重排或 RRF,并只返回脱敏诊断。
|
||
|
||
### 8.3 相邻分块合并与上下文预算
|
||
|
||
- 对最终候选按文档和 ordinal 合并相邻分块。
|
||
- 不把同一分块重复放入上下文。
|
||
- 保留每个命中分块的引用定位。
|
||
- 按相关度从高到低消耗 `contextMaxCharacters`。
|
||
- 单个超长父块按安全边界截断并标记 `truncated`。
|
||
- 不允许低排名结果挤掉已经选中的高排名证据。
|
||
|
||
### 8.4 分块管理
|
||
|
||
文档行提供“查看分块”,打开分块管理对话框:
|
||
|
||
- 显示 ordinal、角色、标题、定位、字符数、启用状态和内容预览。
|
||
- 支持分页和文档内搜索。
|
||
- 支持编辑内容。
|
||
- 支持启用或停用。
|
||
- 支持删除,并说明来源同步可能重新创建分块。
|
||
- 编辑后更新 FTS 和 CJK 索引,并使旧向量失效。
|
||
- 已配置向量模型时,编辑操作完成后为该文档重建向量。
|
||
- 删除最后一个可检索分块时,文档显示“无可检索内容”,不能显示完全就绪。
|
||
|
||
高影响删除使用具体确认文案。普通启停使用共享 Switch,并声明
|
||
`role="switch"`。
|
||
|
||
### 8.5 单文档与全库重建
|
||
|
||
- 单文档重建重新读取来源、解析、分块、全文索引、向量和图谱。
|
||
- 全库重建按来源顺序执行,并显示文档级进度。
|
||
- 修改分块模式或关键参数后,知识库显示“设置已更新,等待重建”。
|
||
- 重建采用文档级原子替换,失败时保留上一版可用分块和向量。
|
||
- 用户可以取消全库重建;已经成功替换的文档保持可用。
|
||
- 文件不存在、网页失败或 OCR 不可用时保留可重试错误。
|
||
- 单来源允许的 2,000 个文件必须全部参与增量同步、删除检测和校验和跳过,
|
||
不受普通页面 500 项列表上限影响。
|
||
|
||
## 9. 数据模型与兼容性
|
||
|
||
### 9.1 KnowledgeBase
|
||
|
||
知识库增加版本化设置:
|
||
|
||
```ts
|
||
type KnowledgeRetrievalSettings = {
|
||
version: 1
|
||
topK: number
|
||
minimumVectorSimilarity: number
|
||
ftsWeight: number
|
||
vectorWeight: number
|
||
graphWeight: number
|
||
candidateMultiplier: number
|
||
contextMaxCharacters: number
|
||
adjacentChunkCount: number
|
||
localRerankEnabled: boolean
|
||
}
|
||
|
||
type KnowledgeChunkingSettings = {
|
||
version: 1
|
||
mode: 'fixed' | 'structure' | 'parent-child'
|
||
targetCharacters: number
|
||
overlapCharacters: number
|
||
parentCharacters: number
|
||
childCharacters: number
|
||
}
|
||
```
|
||
|
||
SQLite 使用 JSON 列保存设置,读写均经过共享 Zod Schema。迁移后的旧知识库使用
|
||
与当前行为接近的兼容默认值,不自动重建已有分块。
|
||
|
||
### 9.2 Chunk
|
||
|
||
分块增加以下语义:
|
||
|
||
```ts
|
||
type KnowledgeChunkRole = 'standalone' | 'parent' | 'child'
|
||
|
||
type KnowledgeChunkState = {
|
||
enabled: boolean
|
||
role: KnowledgeChunkRole
|
||
parentChunkId?: string
|
||
manuallyEdited: boolean
|
||
updatedAt?: string
|
||
}
|
||
```
|
||
|
||
实现可以使用显式列或受校验 metadata,但查询必须为旧数据提供默认值:
|
||
|
||
- 缺少 `enabled` 时视为 `true`。
|
||
- 缺少 `role` 时视为 `standalone`。
|
||
- 父块不参与召回索引。
|
||
|
||
### 9.3 检索响应
|
||
|
||
```ts
|
||
type KnowledgeRetrievalResponse = {
|
||
query: string
|
||
durationMs: number
|
||
settings: KnowledgeRetrievalSettings
|
||
diagnostics: {
|
||
requestedChannels: KnowledgeRetrievalChannel[]
|
||
usedChannels: KnowledgeRetrievalChannel[]
|
||
degradedChannels: Array<{
|
||
channel: KnowledgeRetrievalChannel
|
||
reason: string
|
||
}>
|
||
candidateCounts: Partial<Record<KnowledgeRetrievalChannel, number>>
|
||
}
|
||
results: KnowledgeRetrievalResult[]
|
||
context: {
|
||
characterCount: number
|
||
truncated: boolean
|
||
groups: KnowledgeContextGroup[]
|
||
}
|
||
}
|
||
```
|
||
|
||
错误、诊断和引用不得包含 API Key、Authorization Header、完整私人文档或未经
|
||
限制的 Provider 响应。
|
||
|
||
## 10. IPC 与安全边界
|
||
|
||
新增或扩展的 IPC:
|
||
|
||
- `knowledge:retrieve`
|
||
- `knowledge:settings:update`
|
||
- `knowledge:document:rebuild`
|
||
- `knowledge:library:rebuild`
|
||
- `knowledge:chunks:list`
|
||
- `knowledge:chunk:update`
|
||
- `knowledge:chunk:delete`
|
||
- `knowledge:reference:context`
|
||
- `knowledge:reference:open`
|
||
|
||
要求:
|
||
|
||
- 所有输入由共享 Zod Schema 校验。
|
||
- 所有处理器校验可信 Renderer sender。
|
||
- ID 必须重新检查知识库、来源、文档和分块归属。
|
||
- 列表使用有界分页,单次最多返回 200 个分块。
|
||
- 内容编辑限制单块最大字符数。
|
||
- 外部打开只接受数据库已保存的本地普通文件或 HTTP(S) URL。
|
||
- 不向 Preload 暴露原始数据库、Electron `shell` 或文件系统 API。
|
||
- 更新与重建遵守取消、超时、应用关闭和有界错误规则。
|
||
|
||
## 11. 交互与无障碍
|
||
|
||
- 复用 `PageTabs`、`SegmentedControl`、共享 Switch 和应用通知。
|
||
- 检索方式是互斥选项,使用 `SegmentedControl` 或语义化单选组。
|
||
- 分块启停是持久二元状态,使用 `role="switch"`。
|
||
- 检索结果列表使用可访问名称,得分不得只用颜色表达。
|
||
- 检索工作台打开后焦点进入问题输入框,关闭后返回触发按钮。
|
||
- 分块编辑和删除对话框遵守焦点陷阱、Escape 和焦点恢复。
|
||
- 异步成功使用应用通知;字段错误、检索进度和可就地恢复错误保留在工作台。
|
||
- 窄窗口下检索结果改为单列,配置摘要保持可读,不隐藏降级状态。
|
||
|
||
## 12. 失败与恢复
|
||
|
||
| 场景 | 行为 |
|
||
| --- | --- |
|
||
| 向量查询失败 | 继续全文和图谱检索,显示降级原因 |
|
||
| 部分文档无向量 | 使用可用文档,显示完成数和失败数 |
|
||
| CJK 索引迁移失败 | 回滚迁移,不损坏旧 FTS |
|
||
| 重排失败 | 回退 RRF 排序并显示诊断 |
|
||
| 分块编辑后向量失败 | 保留编辑和全文索引,标记向量失败 |
|
||
| 单文档重建失败 | 保留上一版可用索引 |
|
||
| 同名模型端点变化 | 旧 Fingerprint 索引标记不兼容,等待重建 |
|
||
| 新向量重建失败 | 保留上一版就绪向量继续服务,单独记录失败尝试 |
|
||
| 原文件已移动 | 显示来源不可用,提供重试或移除 |
|
||
| 引用对象已删除 | 显示引用已失效,不打开任意替代路径 |
|
||
| 上下文超预算 | 按排名截断并明确标记 |
|
||
| 请求取消或应用关闭 | 停止新批次,释放句柄,不留下半替换索引 |
|
||
|
||
## 13. 埋点与评测
|
||
|
||
GoodBuddy 不上传私人检索查询或文档内容。本地诊断至少记录有界统计:
|
||
|
||
- 检索模式。
|
||
- 启用知识库数量。
|
||
- 各通道候选数和耗时。
|
||
- 是否发生降级。
|
||
- 最终结果数和上下文字符数。
|
||
- 重建文档数、成功数、失败数和取消状态。
|
||
|
||
手动验收使用仓库内不含私人内容的固定样例集,覆盖:
|
||
|
||
- 中文自然语言改写和同义词。
|
||
- 中英文混合产品名。
|
||
- 精确编号、路径和代码标识。
|
||
- 多文档冲突信息。
|
||
- 无答案问题。
|
||
- 10,000 个以上分块。
|
||
- 向量服务断开和模型维度变化。
|
||
|
||
## 14. 实施顺序
|
||
|
||
### 14.1 第一阶段
|
||
|
||
1. 共享设置、请求和检索响应契约。
|
||
2. SQLite 迁移和 CJK 索引。
|
||
3. 可扩展向量扫描、检索诊断和状态模型。
|
||
4. 检索设置与工作台。
|
||
5. 对话“每次先检索”。
|
||
6. 引用上下文和打开来源。
|
||
7. 第一阶段单元、IPC 和 Renderer 测试。
|
||
|
||
### 14.2 第二阶段
|
||
|
||
1. 结构分块和父子分块。
|
||
2. 本地重排与相关度。
|
||
3. 相邻块合并和上下文预算。
|
||
4. 分块预览、编辑、启停和删除。
|
||
5. 单文档与全库重建。
|
||
6. 第二阶段回归、性能和生产构建验证。
|
||
|
||
## 15. 验收标准
|
||
|
||
### 15.1 第一阶段
|
||
|
||
- 用户可在对话中选择“模型按需检索”或“每次先检索”。
|
||
- “每次先检索”在 Runtime 启动前产生检索诊断和引用,即使模型未调用工具。
|
||
- 未配置向量模型时,中文改写问题仍能通过 CJK 索引召回相关分块。
|
||
- 向量查询失败时回答可继续,界面明确显示已降级。
|
||
- 10,000 个分块的向量测试能够返回正确 Top K,不出现固定上限空结果。
|
||
- 同名模型切换端点后,不会读取 Fingerprint 不匹配的旧向量。
|
||
- 重建失败时,上一版已就绪向量仍能继续召回。
|
||
- 包含 2,000 个文件的目录同步能够处理第 501 至 2,000 个文档的修改与删除。
|
||
- 检索测试展示通道、候选数、排名、相关度、上下文和降级原因。
|
||
- 引用可以查看完整上下文并打开 Main 校验后的来源。
|
||
- 查询长度在共享契约、IPC、MCP 和数据库层保持一致。
|
||
|
||
### 15.2 第二阶段
|
||
|
||
- 用户可选择固定、结构或父子分块并显式重建。
|
||
- 父块不参与召回,子块命中后可提供父块上下文。
|
||
- 本地重排可以开启或关闭,并显示重排前后排名。
|
||
- 上下文严格遵守字符预算,重复和相邻片段按规则合并。
|
||
- 用户可预览、编辑、启停和删除分块。
|
||
- 分块修改后 FTS、CJK 和向量状态保持一致。
|
||
- 单文档重建失败不会破坏上一版可用索引。
|
||
- 所有新增操作可用键盘完成,并在浅色、深色和窄窗口下可用。
|
||
|
||
### 15.3 工程验证
|
||
|
||
所有源代码变更完成后必须通过:
|
||
|
||
```text
|
||
npm test
|
||
npm run typecheck
|
||
npm run lint
|
||
npm run build
|
||
```
|
||
|
||
外部或付费模型调用不属于自动验证,只有获得明确授权后才运行。
|