implemented(除 4 篇超长文档随后补)、proposed、rejected 全树配对; 同一流水线 + 二遍校验(paraphrase-back + 仓库上下文一致性)产出。 docs/rfc/implemented/AGENTS.md 与其 CLAUDE.md 符号链接列入排除 (agent 指令文件,与根 AGENTS.md 同策略)。
5.1 KiB
RFC:SQLite FTS5 会话搜索
English | 中文
Status: proposed
问题
精确读取服务 ctx.sessionQuery 有意不维护派生索引。大规模持久化的历史记录需要全文搜索,而不能在每次查询时扫描所有事件;同时,当前活跃会话需要一个比上次持久性检查点更新的覆盖层。搜索还需要具体的排序、摘要片段、过滤、分页、取消以及重建行为。
如果把这些关注点拆分到一个推测性的 provider 协调器和一个数据库实现中,会产生两个耦合的协调状态机。第一个真实实现应当将源观察、提取、SQLite 事务、generation 管理和查询作为一个完整生命周期来拥有。
提案
在精确读取包旁新增 @deepseek-ai/dsh-session-query-sqlite。该包将暴露一个搜索服务或以其实际消费方所需的最小 API 扩展现有服务族;第一阶段不预先承诺 provider 注册协议。它将依赖 ctx.sessions 和可选的 ctx.sessionPersistence,拥有一个独立的派生 SQLite 数据库,并复用规范的 foldSurface() 分类。
实现拥有一个串行化的协调/数据库事务状态机。一次事务观察权威的持久化元数据和活跃快照,提取语义文档,更新派生表,推进相关的游标 generation,并执行或启用相应的查询。没有第二个服务维护并行的指纹、脏标记、活跃 ID 集合或失效 generation。
持久化文档在重启后保留。活跃覆盖层是连接局部的,为同一会话遮蔽持久化行,在活跃所有者或数据库关闭时消失。派生数据库与规范持久化分离,因此索引重置、损坏、分词器变更和 schema 变动不会危及持久的对话日志。
随实现确定的搜索语义
实现必须从可执行的用例出发定义跨会话和会话内两种搜索范围。每个可搜索事件是一个文档,包含会话元数据、事件元数据、surface 分类、归一化语义文本和有界的纯文本摘要片段。会话级结果按其最强匹配事件分组;数值化的后端分数保持私有。
过滤器在排序之前编译为参数化 SQL。查询语法作为数据处理。排序包含稳定的平局字段。不透明游标绑定到归一化的请求形状和最小相关 generation;不相关的会话变更不应使会话内游标失效。取消操作必须停止调用方等待,并在运行时允许的范围内中断 SQLite 工作。
分词器选择仍是一个实现实验。FTS5 trigram 支持子串召回,但会拒绝短于三字符的有用词项并增大索引体积;提案在将其纳入契约之前,必须对比默认 Unicode 分词器做基准测试。
提取与协调
该包首先为消息、推理(reasoning)、工具调用/结果、被拦截的提示词、上下文、steering(中途引导)、待办事项和错误/状态详情提供第一方语义提取。结构性事件和流式分片不贡献文档。未知的声明合并事件/内容类型保持不可搜索,除非有真实的扩展消费方证明需要公开的提取器注册表。
协调可以使用稳定指纹来避免重写未变更的持久化会话,但指纹的计算和存储由数据库包拥有。当源观察或提取失败时,它绝不能报告某行为最新。provider-schema 不匹配只重置派生数据库;普通的源变更使用事务性 upsert/delete。已挂载但不可读的持久化使受影响的搜索失败,但不影响规范写入或已知的活跃精确读取。
曾考虑的替代方案
- 在规范持久化数据库中添加 FTS 表:否决。可重建的索引不应与权威日志共享 schema/重置/故障边界。
- 在第一阶段重新引入 provider 协调:否决。只有一个计划中的实现,没有证据表明存在稳定的多 provider seam。
- 立即持久化活跃覆盖层:否决。活跃事件在现有检查点提交之前不是规范的。
- 返回 BM25 分数:否决。提供方特有的数值尺度在语料变化时不稳定。
验收标准
- 重启测试覆盖未变更、新增、已变更和已删除的持久化会话,且不重建整个索引。
- 重新打开时保留持久化行并移除活跃行;活跃行先遮蔽、后显露其持久化基底。
- 测试覆盖两种搜索范围、元数据过滤、surface 默认值、摘要片段、转义、确定性平局、分页、范围内的陈旧游标、取消、动态持久化挂载/卸载,以及事务失败后的恢复。
- schema 不匹配只重置派生数据库。
- 一个无 key 的端到端测试将真实的持久化后端与真实的 SQLite 搜索包组合使用。
- 在移入
implemented/之前,本 RFC 须修订为实际实现的分词器和公开 API。
风险
单一所有者比提供方无关的 seam 更简单,但初期可复用性较低。这是有意为之:第二个真实后端能揭示应当抽取什么。SQLite 运行时差异可能影响 FTS 排序和摘要片段,因此测试只能固定契约控制的排序和呈现。独立数据库增加了配置和生命周期工作,但保全了规范存储的安全边界。