dsh-better-session-query:会话历史的块级并行索引

前言

在 DeepSeek Harness(DSH)里做智能体开发,会话一多,「上次在某段思考里写过什么」「某个工作区里 agent 在某一小时说了哪些话」这类问题,往往只能逐条翻事件日志。官方 @deepseek-ai/dsh-session-query-sqlite 把索引单元定在事件上:一条事件抽一段文本、一行文档,命中结果通常是「哪个会话的第几号事件」,粒度对不上消息内部的 text、reasoning、tool-call 等块。

下面介绍社区插件 dsh-better-session-query(维护者 leolee9086,SkillHub 分类:记忆)。它在不替换官方 sessionQuery、不改 DSH 源码的前提下,给会话历史再挂一套块级并行索引,让块成为索引行,从而回答块级检索与元数据过滤问题。

这是什么

一句话:DSH 插件,对会话历史建立块级 FTS5 索引,与官方事件级 session-query 并行存在。

  • 仓库:leolee9086/dsh-better-session-query
  • 当前版本(package.json):0.1.1,许可证 MIT
  • 依赖:分块逻辑来自 @leolee9086/dsh-session-blocks@0.1.0;存储使用 Node 自带的 node:sqlite(FTS5)
  • 硬边界(README 原文):
  • 不替换 provider,只消费运行时注入的 sessionQuery 读会话
  • 不 import 任何 @deepseek-ai/* 包
  • 可与官方 session-query 同时启用

v0.1.1 另导出 dsh-better-session-query/blocks 下的纯函数(extractRawBlocks、walkContentBlocks、parseToolArguments),可不加载索引服务单独使用。记忆同步、向量与混合召回仍在开发中,未包含在本版发行。

核心功能

与官方索引的差异

官方索引以事件为行;本插件把粒度下沉到块:一条消息里的 text / reasoning / tool-call / tool-result 等各自成块。块身份为 blockId = <sessionId>#<seq>#<path>,path 表示块在事件内的位置(如顶层 "0",tool-result 内层 "3.0")。

能回答的问题(摘要)

问题 方式
哪些块含某个词 FTS5 + bm25;中文经拆字变换支持 ≥1 字子串召回
思考块里 2000~5000 字的块 元数据:blockTypes:["reasoning"] + lengthMin / lengthMax
某段时间的 agent 消息 granularity:"messages"、eventTypes:["assistant/message"]、timeFrom / timeTo
某工作区有哪些会话/内容 session_blocks_workspaces;检索带 workspace(= 会话头 cwd)
标题含某词的会话 session_blocks_workspaces(groupBy="session", titleContains="…")
块正文 session_blocks_read(blockId) 或 sessionId + seq (+ path)

长度按 Unicode 码点计;时间用事件自带的 Unix epoch 毫秒(SessionEvent.time)。

块与倒排策略

默认进入全文倒排:text、tool-call、todo。reasoning、tool-result 外壳、image/file 等默认不进倒排,但元数据查询与 read 仍可用(与官方「思考块不入索引」语义一致)。思考内容若要被 search 命中,需打开 include.reasoning 并重建索引。

后台索引

索引在后台渐进更新(默认 reconcileOnSearch: "background",且每 30s 一轮定时);检索不等待索引完成。首次冷启动需对每个尚未索引的会话完整读日志建块,会话量大时会持续一段时间。可通过 session_blocks_list 指定会话 id,或 session_blocks_status {reindex:true} 手动推进。

索引库默认路径:<DSH_HOME>/session-blocks.db。倒排与过滤分表存储(block_fts、block_meta、block_text 等),与 session 持久化 JSONL 无关。

模型工具与服务

Agent 侧主要工具(README「模型工具」节):

session_blocks_search(query="并发模型", sessionId?, workspace?, excludeWorkspaces?, blockTypes?, surface?, limit?, offset?)
session_blocks_query(granularity="blocks"|"messages", workspace?, excludeWorkspaces?, blockTypes?, eventTypes?, surface?, lengthMin?, lengthMax?, timeFrom?, timeTo?, orderBy?, descending?, limit?, offset?, withText?)
session_blocks_list(sessionId, seq?, limit?, offset?)
session_blocks_workspaces(groupBy="workspace"|"session", workspace?, titleContains?, limit?, offset?)
session_blocks_read(blockId) | session_blocks_read(sessionId, seq, path?)
session_blocks_sql(sql, limit?)
session_blocks_status(sessionId?, reindex?, force?)

运行时还提供 ctx.sessionBlockQuery(刻意不复用 sessionQuery 名),含 searchBlocks、queryBlocks、queryMessages、reconcile、compact 等方法。

可选 Web 侧栏「会话块索引」监控(dsh.client.platform: "web");数据面仅本机 loopback。不需要界面时可设 monitor.enabled: false。

安装与启用

环境要求:Node.js 22.19.0 或更高(node:sqlite;Node 22.x 可能打印 ExperimentalWarning)。

README 说明:包位于 SAC_search 仓库的 dsh-better-session-query/ 子目录。开发时可把该目录放进 $DSH_HOME/plugins/,或在 profile 里 link:

dsh-better-session-query/  # 会话块级并行索引

在该 profile 的 cordis.patch.yml 里挂载(已有 insert 列表时只追加这一项):

- insert:
    - id: dsh-better-session-query
      name: dsh-better-session-query
      config:
        # path 留空 = <DSH_HOME>/session-blocks.db;要关后台索引更新就设 backgroundReconcileMs: 0
        {}

包内已带 cordis.patch.yml,也可以直接作为 bundle 挂载:

- name: dsh-better-session-query

重载插件或重启 DSH 后生效。不需要修改官方 session-query-sqlite 配置;官方索引关闭时本插件仍可用。

常用配置项(节选,完整表见 README「配置」节):

键 默认 说明
path <DSH_HOME>/session-blocks.db 索引库路径
backgroundReconcileMs 30000 后台定时索引间隔;0 关闭定时
maxSessionsPerReconcile 25 单轮最多处理的会话数
includeWorkspaces / excludeWorkspaces [] 索引层白/黑名单(排除的工作区连日志都不读)
reconcileOnSearch "background" 检索时是否触发索引更新

典型用法

下列示例来自 README,可在 Agent 工具调用中复现。

按类型与长度筛思考块:

session_blocks_query(blockTypes=["reasoning"], lengthMin=2000, lengthMax=5000, orderBy="length")

按时间窗查 assistant 消息:

session_blocks_query(granularity="messages", eventTypes=["assistant/message"], timeFrom="2026-09-13 10:00", timeTo="2026-09-13 12:00")

工作区与会话清单、限定工作区全文检索:

session_blocks_workspaces()

session_blocks_workspaces(groupBy="session", workspace="D:\\work")
session_blocks_search(query="并发模型", workspace="D:\\work")

读取某事件的块:

session_blocks_read(sessionId="session-xxxx", seq=42)

需要自定义统计时,可用 session_blocks_sql 对公开表结构执行单条只读 SELECT/WITH(写操作与多语句会被拒绝;连接层启用 query_only)。

适用场景与注意

适合谁: 长期在 DSH 里跑多会话、多工作区的开发者;需要按块搜正文、按 reasoning 长度或时间窗筛 agent 输出、按 cwd 隔离检索范围,或希望与官方事件索引并存而不改 Harness 源码。

务必知晓:

  • 插件在 当前 DSH 进程权限下运行,会读取会话日志并在本地 SQLite 中建索引。安装前请阅读 GitHub 源码 与 MIT 许可证,自行评估是否纳入 profile。
  • 只有已被索引的会话可查;首次全量完成前未扫到的会话会缺失,可用 session_blocks_list 指定 id 先拉入。
  • 中文 FTS 为子串语义,单字查询面较宽,建议用小 limit;升级涉及 STORE_SCHEMA_VERSION 变更时会自动重建派生表,索引体积可能增大(README 给出中英混排约 +14%、纯中文约 +71% 的量级说明)。
  • SkillHub(目录页)是社区插件目录,与 DeepSeek / 幻方无官方从属关系;DSH 生态本身是「一切皆插件」的扩展模型。

结尾

dsh-better-session-query 在官方 session-query 之外提供块级 FTS5 索引:块可搜、可滤、可读,后台渐进建库,并与事件级索引并行。若你的痛点是「事件太粗、思考块与工具块拆不开」,可以按 README 把包装进 profile,先用 session_blocks_status 看覆盖率,再按工作区与块类型组合查询。

羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

Xiaoye