前言¶
在 DSH 智能体开发中,当模型持续输出 reasoning-delta 时,现有的 dsh-agent-loop 逻辑仅能在流结束后判定终止,而 dsh-llm-deepseek 的 idleWatchdog 只检测连接活性,不会因为任务进展停滞而中断。这会导致回合无限持续,只能由用户手动中止。dsh-thinking-guard 挂在 agent/assistant-stream 事件上,通过三重熔断机制防止 Agent 进入“只思考、零产出”的退化状态。
插件概览¶
- 名称:dsh-thinking-guard
- 维护者:ethanwong-hk
- 许可证:MIT
- 核心功能:监听
agent/assistant-stream事件,对纯思考空转回合实施三重熔断(超时、容量、重复)。
安装¶
通过 npm 安装:
dsh plugin add @ethanwong-hk/dsh-thinking-guard
安装后重启 DSH。验证是否生效:
grep -n "thinking-guard" ~/.dsh/cordis.patch.yml
核心功能¶
该插件仅使用 harness 的 agent/assistant-stream 事件和 agent.cancel/followup 接口,无其他依赖。
三重熔断机制¶
- thinkingOnlyMs(超时)
- 默认值:45000 ms
- 生效条件:仅在零 text、零 tool-call 时生效。
- 逻辑:锚定“最后一次进展”(text 或 tool-call 到达的时刻),而非 attempt 起点。
- maxThinkingChars(容量)
- 默认值:80000 字符
- 逻辑:单次尝试 reasoning 总量超限,不依赖是否有 text 产出。
- degenerate-loop(退化循环)
- 默认值:3 次重复
- 逻辑:检测尾部窗口的重复模式,包括精确重复单元、句子级模板重复、稀疏复读或 N-gram 高密度。
命中任一条件时,触发 agent.cancel({ kind:'thinking-guard', reason, detail }),并尝试通过 agent.followup() 注入说明。
配置¶
在 ~/.dsh/cordis.patch.yml 的 thinking-guard 条目下调整参数,重启 DSH 生效。
- insert:
- id: thinking-guard
name: "dsh-thinking-guard"
config:
enabled: true
thinkingOnlyMs: 45000
maxThinkingChars: 80000
repeatThreshold: 3
notify: true
verbose: false
环境变量可临时覆盖参数:
| 环境变量 | 作用 |
|---|---|
DSH_THINKING_GUARD_DISABLED=1 |
停用插件 |
DSH_THINKING_ONLY_MS |
纯思考停滞阈值 |
DSH_MAX_THINKING_CHARS |
思考容量阈值 |
DSH_THINKING_REPEAT_THRESHOLD |
重复次数阈值 |
DSH_THINKING_GUARD_VERBOSE=1 |
开启详细日志 |
已修复缺陷¶
插件修复了 formatNotice 函数中的 cfg 作用域引用错误 (ReferenceError)。
* 原因:模块级函数引用了 apply() 内的局部 cfg 变量。
* 影响:该异常直接中断了 trip() 函数,导致 agent.cancel 永不执行,熔断器完全失效。
* 修复:显式传递 cfg 参数,并将 agent.cancel 逻辑前置,确保熔断动作不依赖于通知环节的成功。
测试与验证¶
运行内置测试用例,覆盖 11 个场景,包括纯思考超时、退化复读、容量上限、正常回合放行等。
node ~/.dsh/plugins/dsh-thinking-guard/test/guard.test.mjs
依赖与环境¶
- 依赖:
@deepseek-ai/cordis(^4.0.1) - Node 版本:>= 18
- 权限:插件以当前 DSH 进程权限运行,安装前建议检查源码与许可证。