Files
deepseek-harness/.agents/notes/implemented/architecture/2026-07-23-unified-session-query-service.zh.md
T
2026-07-23 20:18:05 +08:00

3.4 KiB

Agent Note: 统一会话查询服务

Status: implemented

English | 中文

问题

精确读取、语义过滤、关系追踪与全文搜索都作用于同一个实时源优先的会话语料库。将全文搜索暴露在第二个上下文键下,会让消费方与应用组合把同一项查询功能视为两个服务,尽管只有 SQLite 实现是后端特有的部分。

接口包已经拥有共享的记录、过滤、追踪、搜索请求、游标与错误契约。提供方注册表或协调器会引入运行时选择语义,而目前没有任何消费方支持这种语义。

决策

SessionQueryService 是注册为 ctx.sessionQuery 的唯一抽象服务。它通过后端无关的 SessionCorpus 具体实现列表查询、标题与事件读取、表层读取、过滤和关系追踪。仅有 searchSessions() 与 searchEvents() 两个方法为抽象方法。

SessionQuerySqlite 扩展该服务,并且是唯一的具体后端。因此,一个挂载实例便可通过 ctx.sessionQuery 暴露全部操作;其继承的精确操作使用共享的语料库实现,而由 SQLite 管理的生命周期负责观察数据源、对齐派生 FTS 索引、对匹配项排序并管理游标代际。接口包不提供独立的具体插件、搜索提供方注册表或第二个上下文键。

后端配置除了自身的索引路径、日志模式、分页限制与文本片段长度上限外,还包含继承的 readWindowMax 设置。需要会话查询的第一方应用挂载 SQLite 后端,并将其可丢弃索引放在已配置的持久化根目录旁。

这一服务拓扑取代了精确查询决策和 SQLite 搜索决策中关于分离上下文键的部分;其中关于语料库、查询、分词器、对齐与安全性的决策仍然有效。

已考虑的替代方案

  • 保留相互独立的 ctx.sessionQuery 与 ctx.sessionSearch:不予采纳,因为二者都针对同一逻辑语料库提供操作,迫使消费方识别两个键,还可能让应用误挂载一组不完整的查询接口。
  • 保留具体的基础服务,再由 SQLite 插件注册或修改两个搜索方法:不予采纳,因为方法是否可用将取决于插件顺序与资源释放时机,而且该服务需要为唯一的实现定义一套提供方注册协议。
  • 将所有查询实现移入 SQLite 包:不予采纳,因为精确读取、过滤与追踪不需要索引,并且都属于应与提供方无关契约放在一起的共享行为。

后果

消费方只需注入一个服务,无需再次查找其他功能,便可组合精确操作与全文操作。生产环境的组合必须选择一个具体后端,即使当前某个消费方只调用继承的精确方法;如果后端行为不在测试范围内,测试可以使用最小子类。

统一后的对象有意保留两种内部观察策略:精确操作在每次调用时读取权威的实时源或持久化源,全文操作则使可丢弃索引与数据源对齐。共用上下文键不会让派生索引成为权威来源,也不会使精确读取的可用性依赖 FTS 查询。

单元测试在同一个键上同时固定继承实现与抽象方法的契约,SQLite 测试在具体后端上覆盖两类操作,真实 Loader 路径则验证单个导出的插件能够注册组合后的服务。