dsh-thinking-guard:纯思考空转熔断器

前言

在 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 接口,无其他依赖。

三重熔断机制

  1. thinkingOnlyMs(超时)
    • 默认值:45000 ms
    • 生效条件:仅在零 text、零 tool-call 时生效。
    • 逻辑:锚定“最后一次进展”(text 或 tool-call 到达的时刻),而非 attempt 起点。
  2. maxThinkingChars(容量)
    • 默认值:80000 字符
    • 逻辑:单次尝试 reasoning 总量超限,不依赖是否有 text 产出。
  3. 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 进程权限运行,安装前建议检查源码与许可证。
羽毛球分组比赛记分
小程序二维码

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

小夜