状态:已实施(2026-09-03;真机验收待执行) 依据:v0.19 检索与发现层设计(已批准,[ ] 已归档) · ADR-029(已接受) · REQ-258 · REQ-262(部分)
在既有事实源(notes/fragments)旁新增派生索引(kb_chunks + FTS5 影子表 kb_fts + kb_meta):保存/删除/升笔记经生命周期钩子保持索引一致,reindex_all 一键兜底,kb_search 以 FTS5 全库检索(LIKE 旧链零改动保留);无 embedding 也完整可用(v0.19.3 前 FTS-only 精度,引擎状态如实展示)。
| 层 | 内容 |
|---|---|
| 纯函数 | kb_chunk(heading-aware 节级切块:≤3 空格缩进/1==命中== 全站高亮协议同构——17 用例) |
| 数据层 | kb_chunks(多态源双可空 FK + CHECK)/ kb_fts(tokenize='trigram')/ kb_meta 三表 DDL(db_migrations 幂等,既有表零改动)· kb_index(影子表同事务双写收敛模块、不依赖触发器;删除先清影子表 FK 级联仅兜底;kb_meta 失败计数/最近错误软记录不阻断主链路) |
| 生命周期 | 笔记:create/update_note(正文变化才重建——纯标题零写)/versioned_save(保存收口事务内)/delete(先清后删,knowledge_links 同款位置);碎片:create 一次性入块/delete/promote_fragment_to_note(事务内清碎片块 + 建笔记块) |
| 重建/统计 | kb_reindex_all(后台线程 + 逐源进度回调;单源失败软记录继续;启动清失败计数落格式版本——碎片全量重建先清后写修复幂等)+ kb_index_stats(块数/源数/脏源(含孤儿检测)/版本不符/失败计数/last_error) |
| 命令层 | kb_search(输入校验 ≤500 字符;命中含 note_id/fragment_id/标题/组名/节标题/snippet/score_kind)· kb_index_stats · kb_reindex_all(Channel 进度事件 Progress/Done/Failed——与聊天流事件同构) |
- 中文 BM25 切词口径(spec 遗留 spike 项):索引 tokenizer 用 trigram(非草案默认 unicode61 remove_diacritics)——unicode61 将连续中文句整段视为单 token,整句/子串查询全部落空;trigram 免分词器且 bundled SQLite ≥3.34 已含(FTS5 使能核查同时完成:libsqlite3-sys 0.30.1 bundled 恒编
-DSQLITE_ENABLE_FTS5,含运行时测试覆盖)。代价:<3 字符 token 无法入 MATCH → 查询规划把 2 字词(如"配色")转 kb_chunks LIKE 子串扫描(个人库毫秒级,纯派生表不动 notes 旧链)。 - 保存钩子时序(spec 草案:"保存后 spawn_blocking 静默重索引"):改为保存事务内同步重建——Db 连接本由 Mutex 串行,异步线程只把毫秒级开销移出事务却引入"同笔记两次快速保存 → 旧内容后写覆盖新内容"的索引乱序竞态;同步事务内重建零竞态且不阻塞 UI 的量级不变。失败仍软记录(error_count/last_error 角标可见),保存不反悔。
- chunk 源 = 净化后正文(notes.content/fragments.text 全部,归档碎片文本仍在库属素材);标题不在 chunk 源内(ADR-029 决策 2 字面)——标题检索继续由既有 LIKE 链承担。
- kb 纯函数/数据层 54 用例全绿(
-- kb_过滤实测):切块矩阵(标题/围栏/缩进/空文/800 硬切/字符区间连续性);FTS 查询规划(停用字切段/滑窗展开/双引擎 AND);RRF(空集/双列/并列稳定/截断);snippet(大小写不敏感/多词/省略号);生命周期(建改删/versioned_save/promote/删除清块);reindex_all(幂等/孤儿自愈/FK-off 极端写入口兜底/进度到顶);kb_search(trigram 子串命中/2 字 LIKE/组名溯源/空查询诚实空) - 验证:cargo test / clippy 全绿(本批域);全量套件 3 例预存失败(budget_allocator pack_fragments 截断断言 + note_filter golden 2 例——与本次变更域无关,dev HEAD 基线同现,登记观察);既有 LIKE 搜索命令零改动
- 编辑/删除笔记后"即时一致";设置→学习库 统计与重建按钮可全量修复(角标如实)
- 无 embedding 模型时以 FTS 精度工作(引擎状态显示"词法引擎就绪 · 语义未接入")
- 回归:既有搜索/笔记/碎片流程零回归
- 设计/ADR:v0.19 设计规格 §五/§六 · ADR-029 · REQ-258/REQ-262(FTS 使能核查 + 中文校准部分落地)
- 后续:v0.19.1 读路径 A(学习库问答——kb_search/索引即其本地命中链)· v0.19.2 读路径 B · v0.19.3 语义增强(embedding——RRF 已备)
- 真机验收(重建/角标/精度/回归)
- kb_fts trigram 在超长单查询(滑窗 OR 膨胀)的性能观察——个人库量级预期毫秒,若超限再收紧滑窗范围(当前 ≤6 字窗仅对 >6 字段展开)