@nlflora/dsh-empty-turn-guard

aginpmMIT

Recovers a DeepSeek Harness turn that ended with reasoning only, with no text and no tool call, by steering the same turn one more step. Structure-only detection, so it costs no extra model call.

下载量 / Downloads
380

Install

dsh plugin --profile web add @nlflora/dsh-empty-turn-guard

Sandbox test

This plugin has not been tested yet. Submit a test →

README

dsh-empty-turn-guard

兜住一类空回合:模型整轮只产出思考(reasoning),既没有正文、也没有调用任何工具,而 agent 循环把它当作正常完成收尾——界面上只有一个思考气泡,标记「已完成」,一个字没输出。

插件监听 agent/turn-stopping,用纯结构判断认出这种轮次,然后往同一轮里 steer 一条提示,让循环再走一步。

它治的是什么

在 216 个会话、13758 条 assistant 消息里统计到的 49 例「只有思考、没有输出」,按结束原因分:

结束原因 · 数量 · 说明

max-tokens · 16 · 思考把输出额度(4096)吃光,还没轮到写正文

aborted · 14 · 用户中断

completed · 11 · 正常结束但零输出 ← 本插件的主要目标

其中「思考退化」有两种典型形态,都是模型侧的重复循环:

… **writing** ✅. Let me go. Hmm — **the tool call** ✅. Let me go. Hmm — the script ✅. Hmm — go.
… 做。 做。 做。 做。 做。 做。 做。 做。 做。 做。 做。 做。 做。 …

DSH 看到「没有工具调用、也没有文本」,判定模型已经给出最终答复(空),按 completed 收尾。它无法区分「模型认为不需要回答」和「模型卡死了说不出话」。

与 dsh-loop-continue 的区别

dsh-loop-continue 治的是相邻但不同的问题:模型写了「现在我重新应用修改」却忘了调用工具。它的两条硬门槛是:

1. 结束在只有文本的 step;

2. 本回合此前至少调用过一次工具。

本插件的场景两条都不满足(一个字都没有,首次 step 就卡死也可能),所以另起一个。

另一个差别:dsh-loop-continue 需要一个裁判模型判 true/false(因为「这句话是不是承诺了动作」是主观判断);本插件是三个布尔值就能定的结构判断,不产生额外的模型调用。

安装

dsh plugin --profile <profile> add @nlflora/dsh-empty-turn-guard

本地开发:

dsh plugin --profile <profile> add link:/path/to/dsh-empty-turn-guard

配置

在 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 · 打印每次判定

判定规则

要补救,必须同时满足:

1. 本轮没有非空 text 块;

2. 本轮没有 tool-call 块;

3. 本轮至少有一条 assistant 消息;

4. 思考文字 ≥ minReasoningChars。

不满足任何一条就放行,让回合正常结束。正常的「只调用工具不说话」的 step 有 tool-call,不会被误伤。

它不做什么

  • 不改模型行为。重复退化是模型侧的问题,插件只能事后补救一次,不能保证下一次不犯。
  • 不调裁判模型,所以也不增加 token 消耗。
  • 不处理 aborted:用户主动中断的轮次不该被自动续上。

License

MIT

Rendered from the README published on npm. Formatted only, not edited.

Versions

Published on npm::2,最后更新 2026-10-30

Links

GitHub · Homepage · npm

Same category