前言¶
把长任务交给 DeepSeek Harness(DSH)跑的时候,最难判断的往往不是「慢」,而是「还在不在动」。一次编译可能要十分钟,一次长文本生成也可能一直没有新的界面反馈;与此同时,LLM 请求挂起、工具调用空等、循环空转,看起来同样像卡住。如果看门狗只按墙钟时间杀任务,长操作会被误伤;如果完全不管,会话又会在真静默里耗下去。
dsh-stall-guard 要解决的就是这件事:跟踪每个会话的最后活动时间和在飞操作,只有「运行中、没有任何事件、也没有任何在飞调用」才判定为真卡死,然后用「排查 → 修复 → 换方向」的阶梯消息把 Agent 推回去。仓库 README 把这一点写得很死:全程不终止任何任务。
本文按插件目录页、GitHub 仓库 README、package.json 和 lib/index.js 交叉核对后整理:它是什么、怎么判定卡住、如何安装配置,以及查看状态时该看哪些文件。
这是什么¶
dsh-stall-guard 是一款面向 DeepSeek Harness 的任务看门狗插件,由 GitHub 用户 akira399 维护,仓库地址是 akira399/dsh-stall-guard。社区目录把它归在「会话与消息」分类,许可证为 MIT,主要语言是 JavaScript。写作时(2026-08-18)GitHub 显示 3 颗星,package.json 版本为 1.3.0,要求 Node.js >=20,零 npm 依赖。
它解决的不是「给 Agent 加一个停止按钮」,而是这三类现场:
- 会话显示 running,但长时间既没有 turn/step/tool/LLM 事件,也没有在飞操作
- 长构建、长生成这类「看起来很久、其实还在干活」的任务,不能被当成卡死
- 真静默发生后,需要可复现的引导,而不是直接掐掉当前任务
DeepSeek Harness 官方仓库的定位是「一切皆插件」:模型、工具、会话、循环等能力都由插件组合。dsh-stall-guard 走的是社区插件这条路,收录在独立站点 DeepSeek Harness 插件库;该目录与 DeepSeek / 幻方没有官方从属关系,安装前应把它当成第三方源码来审查。
需要提前说清一处文案差异:目录页的一句话简介仍写「只在真正静默时轻推或终止」。对照仓库 README、package.json 描述和 1.3.0 源码,当前实现没有 terminate 选项,也不会发出终止指令;状态字段里虽然还留着 terminated,注释写明只是兼容保留、不会再被置位。下文以仓库一手资料为准。
核心功能¶
监控 → 判断 → 继续 / 修复 / 换方向¶
插件挂上 agent/status 和 session/event,为每个会话维护「最后活动时间」和「在飞操作计数」。周期扫描的间隔由 checkIntervalMs 控制(默认 5 秒)。判定逻辑可以压成一张表:
| 任务情况 | 判定 | 行为 |
|---|---|---|
| 持续有事件(步骤 / 工具 / LLM 流在动) | 推进中 | 不干预;任何活动都会把阶梯重置回第 1 级 |
| 单个长操作在飞(如 10 分钟构建、长文本生成) | 推进中(busy > 0) |
不引导;超过 busyTimeoutMs 只记一条 LONG_RUNNING |
无事件 + 无在飞,静默超过 stallThresholdMs |
真卡死 | 阶梯式引导:诊断 → 修复 → 换方向循环 |
默认真静默阈值是 120000 ms(2 分钟)。在飞观察窗口默认 600000 ms(10 分钟);把 busyTimeoutMs 设为 0 可以关掉 LONG_RUNNING 记录,但不会因此开始引导——有操作在飞时,源码直接 return。
三级阶梯,只注入消息¶
policy 默认是 auto。真静默确认后,插件通过会话的合法通道注入一条 user/message,按冷却间隔(默认 30 秒)升级:
- 第 1 级 DIAGNOSED(排查):请 Agent 说明自己在等什么、是否有操作失败或挂起。
- 第 2 级 FIXING(修复):请它针对卡点重试、完成挂起调用或修好出错步骤,然后继续。
- 第 3 级及以后 REDIRECTING(换方向):请它放弃当前方法、改用替代方案,并保留已完成成果。第 3 级之后按同一冷却间隔循环,没有终止档。
默认文案写在 lib/index.js 里,每条都会再附一行看门狗自己的诊断,格式类似:
[看门狗诊断] 最后活动:tool/call;位置:第 2 轮第 5 步;已静默 125000ms。
如果只想记日志、不向 Agent 说话,把 policy 改成 report 即可。
在飞豁免与运行状态¶
「有操作在飞 = 推进中」靠事件对来计数:
tool/call、tool/code-dispatch、tool-workflow/run-start、request/header:busy + 1tool/result、tool-workflow/run-end、assistant/message:busy - 1(不会减到 0 以下)step/end、turn/end:把busy清零,避免计数漂移
运行中状态由 turn/start / turn/end 驱动,同时也监听 agent/status。README 特别写了:即使错过 agent/status,turn 一打开就会开始监视。覆盖的无进展场景包括 LLM 调用挂起、工具调用挂起、循环空转。
还有一条设计边界必须知道:如果 Agent 卡在一个永不返回的 await 上,注入的消息会排队到该步骤结束后才被处理。插件此时不会杀任务,只会按冷却继续下一级引导。
事件落盘和状态接口¶
每次检测或引导都会追加到 $DSH_HOME/stall-guard/events.jsonl(未设置 DSH_HOME 时等价于 ~/.dsh/stall-guard/events.jsonl)。事件类型只有:
STALL:真静默检测(默认每 60 秒最多记一次,避免刷屏)LONG_RUNNING:在飞过久,仅记录DIAGNOSED/FIXING/REDIRECTING:阶梯注入是否成功
README 强调:永远没有终止类事件。若本机开了 Web UI,还可以查实时状态:
GET http://127.0.0.1:3080/api/dsh-stall-guard/status
返回当前配置、各会话的 ladderStage、以及最近 50 条事件。GUI 通知在 README 里被标成后续增强,当前版本没有这一项。
安装与启用¶
目录页给出的安装命令如下,在 DeepSeek Harness 终端里运行即可:
dsh plugin add github:akira399/dsh-stall-guard
如需可复现安装,按目录页说明固定 commit。写作时 main 分支最新提交是 db5b2147ccd60c0a0f9305f12402fb84491e919d(对应 1.3.0):
dsh plugin add github:akira399/dsh-stall-guard#db5b2147ccd60c0a0f9305f12402fb84491e919d
仓库 README 另给了一条带 profile 的写法,适合用 npx 拉 CLI、并明确装进 web profile 的场景:
npx -p @deepseek-ai/dsh dsh plugin --profile web add github:akira399/dsh-stall-guard
安装后需要重启 DSH。cordis.patch.yml 会把插件插入当前 profile 的组合配置,默认启用(opt-out)。修改 settings.yaml 里 stall-guard 段之后热生效,不必再重启。
目录页的安全提示同样适用:插件以当前 dsh 进程的权限运行,安装时可能执行代码。安装前请检查源代码仓库和许可证。
典型用法¶
1. 使用默认阈值,只在真静默时引导¶
装好并重启后,默认配置已经是「开着、2 分钟真静默、auto 阶梯」。适合大多数「偶尔会挂、但不希望长任务被碰」的编码 Agent。你不需要先写配置;只要会话处于 running,插件就会从 turn 打开开始监视。
2. 把静默阈值改短,并确认是 auto 策略¶
如果本地任务通常几分钟内就会有工具回包,可以把阈值改到 60 秒,扫描间隔改到 3 秒。仓库 README 给的示例是:
stall-guard:
stallThresholdMs: 60000
checkIntervalMs: 3000
policy: auto
保存后配置热生效。想先观察、不注入消息时,把 policy 改成 report。
3. 看日志,确认引导而不是误杀¶
真静默发生后,打开事件文件,确认出现的是 STALL 和阶梯事件,而不是对长操作动手:
tail -n 20 ~/.dsh/stall-guard/events.jsonl
同时请求状态接口,核对 busy、idleMs 和 ladderStage:
curl -s http://127.0.0.1:3080/api/dsh-stall-guard/status
如果某次构建已经跑了很久,但 busy > 0,状态里不应出现阶梯升级,日志里最多只有 LONG_RUNNING。这就是 README 说的:「任务执行时间长」不等于「卡住」。
4. 自定义三级文案(可选)¶
diagnoseMessage、fixMessage、redirectMessage 都可以改。留空或不写时,源码会回退到内置中文默认句。每条仍会自动拼接 [看门狗诊断] 那一行,自定义文案不用自己拼现场信息。
仓库提供了自检命令,覆盖语法、默认配置、在飞豁免、阶梯循环不终止、活动重置阶梯、STALL 节流和状态路由等:
pnpm verify
适用场景与注意事项¶
适合:
- 经常把编译、测试、长生成交给 DSH,又担心会话在无事件时悄悄停住
- 需要一份可审计的卡顿记录(JSONL + 状态接口),而不是只看聊天窗口
- 希望干预手段仅限于「给 Agent 再写一句话」,不要由插件结束任务
需要注意:
- 插件以当前 dsh 进程权限运行,安装时可能执行代码。使用前阅读 akira399/dsh-stall-guard 源码和 MIT 许可证;生产环境建议固定 commit。
- 它不是硬中止。卡在永不返回的 await 时,消息会排队;此时仍要靠宿主界面的停止能力或人工介入。
- 在飞计数依赖特定事件类型。若某个工具或工作流不走 README 列出的那几对事件,
busy可能不准,表现为该豁免或不该豁免。 - Web 状态路由依赖
webServer服务;没有 Web UI 时,仍可看events.jsonl和插件日志。 - 社区目录不是官方应用商店。DSH 仍处于开发者预览,核心 API 会继续变,插件行为以当时安装的 commit 为准。
结尾¶
dsh-stall-guard 把「慢」和「死」拆开:有事件或有在飞操作就当作推进中;只有真静默才按排查、修复、换方向循环轻推,并且把每次判定写进日志。对长时间跑任务、又不想被看门狗误杀的 DSH 用户,这是一套边界写得很清楚的社区方案。
目录页:https://deepseek-harness-plugin.com/zh-CN/plugins/dsh-stall-guard/
GitHub:https://github.com/akira399/dsh-stall-guard