前言¶
在 DeepSeek Harness(DSH)里跑智能体时,模型有时会卡在「同一段短文本」上反复解码:推理通道里不断重复「好。→(执行)→好。→Write.→…」,却迟迟不发出工具调用。官方自带的 @deepseek-ai/dsh-repeat-tool-reminder 只盯连续重复的工具调用(同一工具、同一参数,连续 3/5/8 次),对推理通道里的文本循环无能为力;自动 compaction 也未必能及时触发。结果是输出越滚越长、会话记录被污染,人工点停止往往成了唯一出路。
下面介绍社区插件 dsh-output-loop-guard(维护者 ADistanceThereIs):它监听实时 agent/assistant-stream 帧,从文本结构判断是否进入退化环,中止失控回合,并用纠正性通知唤醒智能体继续工作。
这是什么¶
dsh-output-loop-guard 是面向 DSH 的 bundle 插件,定位是「输出自重复看门狗」:在推理或可见文本里检测退化循环,中止该轮生成,并向 agent 注入纠正说明,无需人工按停止或手动输入「继续」。
- 要求 DSH
>= 0.2.0-rc.2,ESM 打包,运行时零依赖。 - 在 SkillHub 社区目录中归类为 admin-security。
- 源码与说明见 GitHub 仓库,当前发布版本 0.1.0(MIT)。
与 repeat-tool-reminder 的差异¶
| 能力 | repeat-tool-reminder | output-loop-guard |
|---|---|---|
| 观测对象 | 重复工具调用 | 流式文本本身 |
| 推理通道循环 | 不可见 | 可检测 |
| 长时间无 tool call 的刷屏 | 不触发 | 可中止并 steer |
README 中记载的动机会话里,模型在推理中重复约 112,109 字符、50,196 个流式分片、持续解码约 126 秒且零次工具调用——repeat-tool-reminder 无法介入;在该语料回放校准中,本插件对该类模式有检测记录(见下文「校准数据」)。
核心功能:如何检测与如何处置¶
滑动窗口与四条信号¶
默认在流式输出上维护 1,200 字符滑动窗口,每新增 64 字符检查一次。四条规则如下:
| 信号 | 规则概要 | 主要覆盖 |
|---|---|---|
repeated-block |
最短周期块(≥2 换行、≥2 个不同非空白字符)重复 ≥6 次 | 多行短周期循环 |
dominant-gram |
某一 n-gram 占窗口 ≥55%、出现 ≥24 次且跨 ≥2 行 | 尾部参差但重复已占主导 |
repeated-line |
单行连续重复:推理通道 ≥40、可见文本 ≥60(singleLineTextMinRepeats,设为 0 可关闭) |
单行空转或答案里行级刷屏 |
flat-tic |
无空白短 gram 占窗口 ≥25%、出现 ≥48 次,仅推理通道 | 无换行的口吃式重复(如「好。好。好。」) |
设计上有两点刻意收紧误报:只认最短周期的多行块(避免把普通列表判成循环);对通道区分对待——可见文本单行阈值更高,缩进块、====/---- 分隔线、空行运行等不触发。
触发后的动作¶
- 调用
agent.cancel({ kind: 'hook', reason: 'output-loop-guard: …' }),中止进行中的生成并记为中断,退化文本不再增长。 - 调用
agent.steer(<notice>);因生成已中止,steer会升级为新回合,驱动智能体按通知纠正(停止复述、发出下一步动作或结束)。 - 同一回合内超过
maxTripsPerTurn次触发后,不再自动继续,仅inject通知,避免坏模型无限自旋。
安装与启用¶
插件以 DSH bundle 形式安装:loader 读取 package.json 中的 dsh.bundle.patch,cordis.patch.yml 会插入 output-loop-guard 行。任选一种方式(将 <profile> 换成你的 profile 名;方式 A 需将 <commit> 换成具体 commit):
# A. 从 git 主机安装,钉在某一 commit(DSH 进程 PATH 上需有 git)
dsh plugin --profile <profile> add "github:ADistanceThereIs/dsh-output-loop-guard#<commit>"
# B. 从 Release 压缩包安装(无需 git)
# 先从 Releases 页下载 dsh-output-loop-guard-0.1.0.tgz,再执行:
dsh plugin --profile <profile> add ./dsh-output-loop-guard-0.1.0.tgz
# C. 直接从 Release 资源 URL 安装(需 Node 信任系统 CA)
dsh plugin --profile <profile> add \
https://github.com/ADistanceThereIs/dsh-output-loop-guard/releases/download/v0.1.0/dsh-output-loop-guard-0.1.0.tgz
三种方式都会把包追加到 dsh.profile.bundles 并合并 bundle 的 patch 层。修改 bundle 后需重启 DSH,对应行才会生效。
卸载:
dsh plugin --profile <profile> remove dsh-output-loop-guard
配置¶
在 profile 的 cordis.patch.yml 中覆盖该行(patch 会替换整段 config,保留项需全部写回):
- id: output-loop-guard
name: dsh-output-loop-guard
config:
dryRun: false # true = 仅检测并打日志,不 cancel
autoContinue: true # 用纠正通知唤醒 agent
maxTripsPerTurn: 2 # 每回合自动继续预算
windowChars: 1200
checkEveryChars: 64
minPeriodRepeats: 6
singleLineMinRepeats: 40
singleLineTextMinRepeats: 60 # 可见文本单行阈值,0 = 关闭
useDominantGram: true
dominantGramCoverage: 0.55
dominantGramMinCount: 24
useFlatTic: true
ticMinCount: 48
ticMinCoverage: 0.25
verbose: false
若想在正式中止前先观察本机会话里的命中情况,可先设 dryRun: true。
典型用法与验证思路¶
- 安装 bundle 并重启 DSH,确认
cordis.patch.yml中出现output-loop-guard行。 - 生产环境前用
dryRun: true跑若干真实任务,看日志里是否有合理检测。 - 关闭
dryRun后,当模型进入结构化的自重复循环时,会话里应出现turn/end的reason.kind为hook、reason.reason含output-loop-guard,以及来源为output-loop-guard的用户向通知。
README 给出的端到端示例日志片段(任务被设计成重复两行 300 次):
{"type":"turn/end","data":{"turn":1,"reason":{"kind":"aborted","reason":{"kind":"hook","reason":"output-loop-guard: repeated output (repeated-block)"}}}}
{"type":"assistant/message","interrupted":true}
{"type":"user/message","source":{"kind":"output-loop-guard","form":"notice"}}
意图是:止住失控输出,而不是放弃任务——示例中 agent 随后把同样内容写进文件,而非继续重复刷屏。
仓库内 npm test 运行 21 项自包含回归(不依赖语料文件),覆盖真实退化必须被中止、健康长文档不受影响、列表/代码块/表格等正常输出不误报、dryRun 不 cancel、禁用插件不挂载等行为。
校准数据与局限¶
作者在 README 中公布的语料回放(27 个真实会话 / 1,783 个 assistant 步)结果:24 次检测,0 次误报;动机会话的每一步循环均被命中;112,109 字符失控在约 2,944 字符(2.6%) 处被截断,其他循环多在 1,152–7,808 字符内触发。
使用时需注意:
- 可见文本要触发单行重复需 ≥60 行连续相同;合法 fixture、列表可能被保护,若不需要可设
singleLineTextMinRepeats: 0。 - 检测基于周期与密度等结构特征,语义上「近重复」可能漏过
repeated-block,但dominant-gram/flat-tic常能补上。 - 插件在 当前 DSH 进程权限下运行,安装前请自行审阅源码与 MIT 许可证;社区目录 SkillHub 插件页 与 GitHub 为独立信息源,与 DeepSeek / 幻方无官方从属关系。
结尾¶
DSH 生态强调「一切皆插件」;当工具调用重复提醒覆盖不到推理通道刷屏时,dsh-output-loop-guard 用流式文本上的四条结构信号自动 cancel 并 steer,把「人工点停止」换成可配置的看门狗。需要进一步了解分类与条目信息可打开 SkillHub 目录页,安装与配置细节以 GitHub README 为准。