前言¶
在 DeepSeek Harness(DSH)里跑 agent 循环时,有时会出现这样一种收尾:界面上只有一个思考气泡,标记为「已完成」,正文和工具调用都没有。DSH 看到「没有工具调用、也没有文本」,会按正常完成处理,无法区分「模型认为不需要回答」和「模型卡死说不出话」。维护者 nlflora 的插件 dsh-empty-turn-guard 专门监听回合结束前的钩子,用纯结构判断认出这类轮次,并在同一轮里 steer 一条提示,让循环再走一步。下面介绍它的定位、安装与配置。
这是什么¶
@nlflora/dsh-empty-turn-guard(GitHub:nlflora/dsh-empty-turn-guard)是 DSH 社区插件,当前版本 0.1.0,MIT 许可证。它监听 agent/turn-stopping,在模型整轮只产出 reasoning、既没有正文也没有调用任何工具时介入,避免 agent 把空回合当作正常完成。
插件不调用裁判模型,只靠若干布尔条件做结构判断,因此不会为判定额外消耗 token。
它治的是什么问题¶
作者在 216 个会话、13758 条 assistant 消息里统计到 49 例「只有思考、没有输出」。按结束原因大致分为:max-tokens(思考占满输出额度)、aborted(用户中断)、completed(正常结束但零输出)。本插件主要针对最后一类,以及因思考过长撞到输出上限、尚未写到正文的情况。
典型「思考退化」包括模型侧重复循环,例如英文里反复出现 “Let me go / the tool call / the script”,或中文里连续重复的「做。」——DSH 仍可能以 completed 收尾。
需要与同类插件区分:dsh-loop-continue 处理的是模型写了「现在要重新应用修改」却忘记调工具的场景,且要求本回合此前至少调用过一次工具、结束在只有文本的 step。空回合场景往往一个字都没有,首次 step 就可能卡死,两条门槛都不满足,因此单独做成 dsh-empty-turn-guard。另外,dsh-loop-continue 需要裁判模型做主观判断;本插件用三个布尔值即可,不产生额外模型调用。
核心功能与判定规则¶
要触发补救,必须同时满足:
- 本轮没有非空
text块; - 本轮没有
tool-call块; - 本轮至少有一条 assistant 消息;
- 思考文字长度 ≥ 配置项
minReasoningChars(默认 40)。
任一不满足则放行,回合正常结束。只调工具、不说话的 step 带有 tool-call,不会被误伤。
补救时在同一轮内 steer 提示;maxContinuations 限制每轮最多补救次数,防止无限循环。可选重复检测(detectRepetition)主要影响日志里的原因标注;是否撞到输出 token 上限可参考 assumedMaxOutputTokens(默认 4096),并选用不同的内置 steer 文案(常规 vs 要求压缩思考)。
插件明确不做的事:不改模型行为,不能保证下一次不犯同样错误;不处理用户主动 aborted 的轮次;不增加裁判模型调用。
安装与启用¶
在指定 profile 下安装(命令来自项目 README):
dsh plugin --profile <profile> add @nlflora/dsh-empty-turn-guard
本地开发可链接目录:
dsh plugin --profile <profile> add link:/path/to/dsh-empty-turn-guard
运行环境要求(见 package.json):Node.js >= 22,DSH >= 0.2.1-rc.1;peer 依赖 @deepseek-ai/cordis ^4.0.1,@deepseek-ai/dsh-llm 为可选。
在 profile 的 cordis.patch.yml 里按插件 id empty-turn-guard 覆盖配置,例如:
- id: empty-turn-guard
config:
enabled: true
maxContinuations: 2 # 每轮最多补救几次
minReasoningChars: 40 # 思考少于这个字数就不管
detectRepetition: true # 是否检测重复退化
repetitionMinRepeats: 6 # 同一短语连续重复多少次算退化
assumedMaxOutputTokens: 4096
debug: false
| 字段 | 默认 | 说明 |
|---|---|---|
enabled |
true |
总开关 |
maxContinuations |
2 |
每轮最多补救次数 |
minReasoningChars |
40 |
思考太短视为「选择不回答」,不干预 |
detectRepetition |
true |
是否做重复检测(日志原因标注) |
repetitionMinRepeats |
6 |
退化重复次数阈值 |
assumedMaxOutputTokens |
4096 |
判断是否撞到输出上限 |
steerText |
内置 | 常规补救提示,可整段替换 |
steerTextCapped |
内置 | 撞到输出上限时的提示 |
debug |
false |
打印每次判定 |
典型用法与适用场景¶
典型用法是:在经常遇到 reasoning 模型或长思考链的 agent profile 上启用插件,保持默认配置先试;若仍频繁撞到 4096 输出上限,可调整 assumedMaxOutputTokens 或自定义 steerTextCapped;若误触发过多,可提高 minReasoningChars 或降低 maxContinuations。
适合:自建 DSH agent、希望减少「界面显示已完成却没有任何可读输出」的开发者。不适合指望插件根治模型重复退化——它只能事后 steer 一步。
注意:DSH 插件在当前 dsh 进程权限下运行;安装前请自行查看 GitHub 源码与 MIT 许可证。社区目录站点与 DeepSeek / 幻方无官方从属关系,可按目录页浏览同类插件,但不必当作官方应用商店。
结尾¶
dsh-empty-turn-guard 用结构化的 turn-stopping 判定,在零文本、零工具调用的空回合上多给 agent 一次机会,且不加裁判模型开销。目录页:https://www.skillhub.cn/plugins/nlflora/dsh-empty-turn-guard ;源码与完整说明:https://github.com/nlflora/dsh-empty-turn-guard 。