用 dsh-session-health 给 DeepSeek Harness 会话文件做只读健康检查

前言

DeepSeek Harness(dsh)是 DeepSeek 开源的智能体运行时,官方仓库把它概括成一句话:Everything is a plugin。模型、工具、技能、会话、沙箱、存储、循环和界面,都按插件挂载。官方还强调另一件事:模型看见的内容会写进只追加的会话日志——系统提示、推理、工具调用与结果、子智能体调度,以及每一次上下文注入。

这套日志默认不是普通文本。官方持久化子系统 dsh-session-persistence-jsonl 把每条会话存成带校验的 zstd 多帧串联:一个文件里首尾相接许多个 zstd frame,而不是单帧压缩包。进程被强杀、写入中断、或者用单帧解码 API 去读多帧文件时,常见结果不是报错,而是只看见 header,误判成「会话全空」。

dsh-session-health 把这件事做成模型可调用的工具:扫描 $DSH_HOME/sessions 下的会话文件,做帧级诊断,输出健康报告和清理建议。它只读,不改、不删。下面按社区目录页、GitHub 仓库 README / package.json / 源码,以及 DeepSeek Harness 官方仓库交叉核对后整理。

这是什么

dsh-session-health 是一款 会话与消息 类 DSH 插件,由社区组织 omdsh-dev 维护,仓库在 omdsh-dev/dsh-session-health,许可证 MIT。包名是 @deepseek-ai/dsh-session-health,安装后注册工具 session_health,profile 层 id 为 tool-session-health。社区目录收录于 2026-08-09,仓库最近一次推送在 2026-08-14;本文核对当日 GitHub API 显示 8 星。

需要先分清两层来源。DeepSeek Harness 本身由 DeepSeek AI 开发,官方仓库是 deepseek-ai/deepseek-harness,目前仍是 developer preview,文档写明会有破坏性变更。本文引用的插件目录 deepseek-harness-plugin.com 是独立社区站点,About 页写明与 DeepSeek / High-Flyer(幻方)无从属、背书或赞助关系,也不托管插件代码。omdsh-dev 组织简介同样写明:非官方社区插件收录组织,与 DeepSeek 无隶属或授权关系。

它解决的问题很具体:会话文件在磁盘上是不是完整的 zstd 多帧日志,有没有 torn write、结构损坏、空文件、明文 .jsonl 残留,以及 stray 临时文件。它不负责修复,也不改会话内容。

核心功能

帧级扫描,而不是整包解压

仓库 README 写明:DSH 会话文件是多个 zstd frame 的串联。官方文档与社区讨论(例如 Discussion #2165)也把 JSONL 会话描述成 concatenated Zstandard frames。dsh-session-health 因此先做 帧边界扫描:用 DataView 按 RFC 8878 读 magic、帧头、块头,统计完整帧数,标出尾部截断,不解码 block 数据。源码注释写明,这套扫描器与官方 scanZstdFrames 做过分帧差分;官方对非法结构 throw,本工具则返回结构化错误码,方便诊断。

默认扫描根目录是 $DSH_HOME/sessions。未设置 DSH_HOME 时,源码回落到 ~/.dsh。会话文件的常见路径是:

$DSH_HOME/sessions/<cwd 编码>/<session-id>/session.jsonl.zstd

源码 files.ts 还记录了 Windows cwd 的编码方式:\ 换成 -,盘符 C: 换成 C-,外层再用 -- 包起来。枚举只走两级目录,识别 session.jsonl.zstd、明文 .jsonl,以及 *.tmp / *.tmp.zstd

检测项

帧级扫描能标出的问题,目录页与 README 一致,源码 report.ts 再分成 errorssuspicious 两桶:

类别 判定
missing 会话 id 解析不到文件
empty 0 字节文件
not-zstd 前 4 字节不是 zstd magic 28 b5 2f fd(明文 .jsonl 或损坏)
torn EOF 打断帧尾部(写入中断)
reserved-header / reserved-block 帧头或块头保留位非法
bad-header deep 模式:首帧不是 session header
empty-session 只有 1 帧(header)且超过 1 分钟未更新
oversized-single-frame 单帧大于 1MB(源码阈值 1_000_000 字节)
interrupted deep 模式:有 turn/start 无对应 turn/end
stray-file *.tmp 或非标准命名残留

报告字段包括:rootscannederrorssuspicioustotals(字节、帧数、事件批次估算)、detaildeepsuggestionssuggestions 按 issue 模板给出清理或修复建议,不自动执行。事件批次估算等于「帧数 - 1」,README 明确写了这不是精确事件数。

只读与路径围栏

这是插件反复强调的边界,目录页、README 和源码注释一致:

  • 只读:不修改、不删除任何文件。测试 files.spec 的 SH-06 用例覆盖「扫描后文件字节数不变」。
  • 路径围栏:会话 id 只允许 [A-Za-z0-9._-]+,拒绝 ../、盘符、空白和控制字符;绝对路径与最终文件都做 fs.realpath containment;枚举用 lstat,符号链接直接跳过。
  • 输入范围固定:只看 sessions 目录,无网络、无执行面。
  • 零业务依赖:帧扫描器是独立实现,不引入 zstd 原生库。

deep: true 时才会动态 import 官方解码器 @deepseek-ai/dsh-session-persistence-jsonl/src/zstd.ts。解析失败会明确降级,报告里标 deep: "unavailable",不会静默当成扫描成功。deep 还有资源上限:压缩文件超过 16MB 跳过;解压字节超过 64MB 或事件数超过 20 万就停止消费后续帧。

注册的工具

插件导出 apply(ctx),向 ctx.tools 注册 session_health,超时 5000ms,输出 JSON 文本。参数如下:

参数 类型 必填 说明
action string scan / file / stats
path string file / stats 必需 会话根内的绝对路径,或会话 id
deep boolean 深度分析(解码事件统计),默认 false
detail boolean scan 默认 true,列出异常文件;false 只出汇总

scan 扫整个 sessions 目录;file 诊断单个会话;stats 只出 totals。scandetail 为 true 时,只把带 issue 的文件放进 detail,不是全量清单。

安装与启用

目录页给出的安装命令如下,在 DeepSeek Harness 终端运行:

dsh plugin add github:omdsh-dev/dsh-session-health

如需可复现安装,目录页要求固定 commit 哈希。本文核对时 main 最新提交是 72065059cec89c5577b19ee8aaa26ebc2c34fbbf(2026-08-14):

dsh plugin add github:omdsh-dev/dsh-session-health#72065059cec89c5577b19ee8aaa26ebc2c34fbbf

仓库 README 补充了 profile 写法。web 与 headless 是 不同 profile:装到 web 不会自动覆盖 headless;dsh run 默认走 headless。Windows 路径用正斜杠。

# 交互式(web)profile
dsh plugin --profile web add github:omdsh-dev/dsh-session-health

# 一次性任务(headless)profile
dsh plugin --profile headless add github:omdsh-dev/dsh-session-health

安装后可用下面命令确认 layer 里出现了 tool-session-health

dsh --profile web --dump-config | grep tool-session-health

README 还给出运行验证:

dsh run "使用 session_health 工具扫描会话目录健康状态"

仓库声明已迁移到 @deepseek-ai/dsh@0.1.0-rc.6 依赖线,peer 依赖是 @deepseek-ai/cordis@^4.0.1@deepseek-ai/dsh-tools@deepseek-ai/dsh-invariantspackage.jsonengines.node^22.19.0 || >=24.0.0。DeepSeek Harness 仍在 developer preview,装插件前应对齐自己的 dsh 版本。

典型用法

工具由模型在会话里调用。README 给出的可复现形态如下。

扫描整个会话目录:

session_health { action: "scan" }

返回类似:

{
  "root": "C:\\Users\\admin\\.dsh\\sessions",
  "scanned": 39,
  "errors": {},
  "suspicious": {},
  "suggestions": []
}

上面的 rootscanned: 39 来自仓库 README 示例,不是你本机的实际数字。本机结果以扫描到的 $DSH_HOME/sessions 为准。

只看汇总、不列异常文件:

session_health { action: "scan", detail: false }

诊断单个会话,并打开深度分析:

session_health { action: "file", path: "session-abc123", deep: true }

path 可以是会话 id,也可以是 sessions 根内的绝对路径。越界、符号链接、含 ../ 的 id 都会被拒绝。statsfile 类似,但报告里不带 detail

若只想让智能体跑一遍目录健康检查,可以直接用 README 的 dsh run 例句。注意:这条命令走 headless profile,需要事先把插件装进 headless,只装 web 不够。

适用场景与注意事项

适合这些情况:

  • 会话列表里出现空白、打不开、或怀疑上次强杀把日志写断
  • 想确认磁盘上的 session.jsonl.zstd 是否仍是合法多帧 zstd,而不是明文 .jsonl 或 0 字节文件
  • 需要一份 JSON 健康报告,再决定要不要手工清理 stray / 空会话
  • 给模型一个只读工具,让它回答「会话文件健康吗」,而不是自己写扫描脚本

使用前注意下面几条,均能在目录页或仓库里核对:

  1. 插件以当前 dsh 进程的权限运行,安装时可能执行代码。安装前应检查源代码仓库和许可证;需要可复现安装时固定 commit 哈希。这是目录页的原文警告。
  2. 只诊断、不修复。README 把后续修复指向 dsh-session-repair-skill;本文检索时该仓库地址无法打开,因此不要把它当成已经可安装的配套工具。报告里的 suggestions 也只是建议文本。
  3. deep 模式在 npm 0.1.0-rc.6 下可能不可用。README 写明:@deepseek-ai/dsh-session-persistence-jsonl 的 npm tarball 仍不含 src/,根入口也不导出 zstd API,deep 会降级为 decoder-unavailable。帧级扫描不受影响。
  4. 事件批次是估算值;单帧扫描超时为 5 秒。会话特别多或文件特别大时,先用 scan + detail: false 看汇总。
  5. 社区目录不是官方应用商店。装任何 DSH 插件前,以 GitHub 源码和许可证为准。

小结

DSH 把一次运行写成只追加的多帧 zstd 会话日志,这让「文件还在」不等于「文件健康」。dsh-session-health 做的是帧级、只读、零业务依赖的诊断:扫 $DSH_HOME/sessions,标出 torn、损坏、空会话和 stray 文件,把结果交给模型和你,而不是替你改磁盘。

目录页:https://deepseek-harness-plugin.com/zh-CN/plugins/dsh-session-health/

GitHub:https://github.com/omdsh-dev/dsh-session-health

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

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

小夜