前言¶
在 DSH(DeepSeek Harness)里跑智能体时,模型偶尔会陷入重复输出:同一段 reasoning 或正文里反复出现 Now.、OK.、Emit. 等短句轮换,或整段文字 verbatim 复制多遍。常见应对是手动停生成或事后改会话,但停下来的内容若仍带着完整循环写进 session log,下一轮上下文会再次读到这段重复,模型容易接着绕圈。
dsh-loop-rescue 是社区维护的 DSH 工作流类插件,在 llm/stream 阶段检测循环、从内部截断流,并把写入会话日志的消息裁掉循环段后再自动 followup 续写。与「只掐断流、日志里仍留循环」的做法不同:进入下一轮上下文的中断消息不含循环正文,从而降低「读到自己重复内容再重复」的概率。
这是什么¶
- 名称:dsh-loop-rescue(GitHub:
citydirector/dsh-loop-rescue) - 维护者:citydirector
- 许可:MIT
- 依赖:DSH 0.1.7 及以上;纯 JavaScript,无需构建步骤
- 定位:当模型出现短语池轮换或 verbatim 周期重复时,切断流、从 session log 侧 prune 循环段,并在回合结束后自动 resume
插件通过 Cordis patch 注册为 loop-rescue。README 明确说明:不要与 @mrweicodes/dsh-loop-guard 同时启用,否则循环会被切两次。
核心功能¶
运行模式¶
在 profile 的 cordis.patch.yml 中可配置 mode:
| 值 | 行为 |
|---|---|
rescue(默认) |
切断 + prune + 自动 resume |
cut |
切断 + prune,不自动续写 |
observe |
仅记录检测命中,不干预 |
建议先设 observe 观察一两天,确认日志里每条 loop-rescue: ... loop detected 都是真循环,再改为 rescue。
检测规则¶
插件对流式 reasoning 与 text 块跑同一套检测器(watch 可选 both、reasoning、text):
- 短语池
pool:最近 30 句里,≥75% 落在少数 recurring 短句上(顺序不限)时命中,从该批短语首次出现处往回 prune。 - 逐字周期
cycle:尾部为同一段文本 verbatim 重复,周期 16–4000 字符、≥3 次、总长 ≥600 字符时命中,保留第一份,从第二份起 prune。
为降低误报:中文句号始终分句;英文句号仅在后跟空白时分句;符号行、列表/表格/引用行不计入;text 里 ``` 代码块内部跳过;短语池需至少两种不同短语轮换;存在未闭合的 tool call 块时不切断,避免宿主执行残缺参数。
与 session log 的关系¶
助手消息的块内容以 block-end 为准,而非此前 delta。命中后关闭所有打开块,循环块替换为 prune 后的内容(可选留一行 〔N chars of repeated reasoning removed〕 类标记),流以 stop 结束。写入日志的消息只保留循环前的有效内容;完整原始流仍保存在事件的 stream 字段,轨迹视图可查看。回合真正结束(whenIdle())后通过 followup() 发送带纠正的 resume;连续 rescue 次数受 maxConsecutiveRescues 限制,一次正常调用会重置计数。
README 说明:事后替换整条 assistant/message 无法保留 sourceEventSeqs,因此必须在 block-end 时 prune,才能保持角色与 tool-call 配对一致。
附带工具¶
仓库提供离线脚本(Node 22.15+,扫描支持 zstd 压缩会话):
tools/scan-session.mjs:用与插件相同的检测器回放历史会话,查看会在何处切断。tools/clean-session.mjs:在 DSH 完全关闭 时清理已写入历史的循环(v4 会话);会先备份。已入库的循环不会被运行中的插件改写,需离线清理;推荐工具还包括 dsh-session-manager 的dsm loops。
安装与启用¶
图形界面¶
- 侧栏打开 Plugins → Add plugin。
- 填入仓库地址并启用:
https://github.com/citydirector/dsh-loop-rescue
默认配置即可工作;若要只观察不切断,将 mode 设为 observe(见下文配置)。
命令行¶
若曾安装同类的 loop-guard,先移除再添加本插件(README 原文):
dsh plugin --profile web remove @mrweicodes/dsh-loop-guard
dsh plugin --profile web add -w github:citydirector/dsh-loop-rescue#v0.1.0
命令行安装后需重启 dsh web;无需批准 pnpm build 脚本。
配置示例¶
在对应 profile 的 cordis.patch.yml 中写入:
- set:
- id: loop-rescue
config:
mode: rescue # rescue: cut + prune + resume | cut: cut + prune | observe: log only
watch: both # both | reasoning | text
marker: true # leave a "〔N chars of repeated reasoning removed〕" line where it pruned
maxConsecutiveRescues: 3 # cap on back-to-back rescues; one normal call resets it
stallCalls: 3 # nudge after this many reasoning-only calls with no output; 0 = off
stallMinReasoningChars: 1024
retryTemperature: 1.0 # temperature for the resume request; unset = unchanged
retryReasoningEffort: low # reasoning effort for the resume request; unset = unchanged
retryRequests: 1 # how many requests after a resume use the two settings above
language: auto # auto | zh | en
detector: # detection thresholds; rarely need changing
poolWindow: 30
poolMinCoverage: 0.75
cycleMinChars: 600
resume 后的前若干次请求可使用 retryTemperature、retryReasoningEffort;需底层 adapter 支持 temperature。stallCalls 用于 reasoning 很长却无正文输出时的轻推,设为 0 可关闭。
典型用法¶
先观察再救援¶
- 将
mode设为observe,正常使用 DSH 一至两天。 - 在日志中核对
loop-rescue的 loop detected 行是否均为真实重复。 - 改为
mode: rescue启用切断与自动续写。
离线扫描历史会话¶
仅看命中:
node tools/scan-session.mjs <session file or directory>
命中与未命中一并列出,或输出 JSON:
node tools/scan-session.mjs <session file or directory> --all
node tools/scan-session.mjs <session file> --json
清理已写入历史的循环¶
DSH 关闭后,在仓库目录执行(会列出含循环的会话并按编号选择,Enter 选最新):
node tools/clean-session.mjs
node tools/clean-session.mjs --dry-run
node tools/clean-session.mjs --undo
Windows 也可使用 tools\clean-session.cmd;找不到数据目录时传 --data <data directory>。备份目录为 <data directory>\sessions-loop-rescue-backup\;DSH 运行中会拒绝执行(--force 可跳过,不推荐)。
适用场景与注意¶
适合:长时间 agent 任务、推理链较长、曾遇到短语轮换或段落 verbatim 死循环的 DSH 用户;需要在流式阶段干预且希望 session log 里不留下循环正文以便续写。
局限(README 已列):
- 已流式展示到聊天区的循环,在消息提交后会换成 prune 版本,重绘行为取决于 DSH 前端版本。
- 跨多步的「每步一行 + 同一工具」类循环不在本插件范围,由内置
guard/repeat-tool-reminder处理。 - 仅阻止新产生的循环;历史里已有的循环需离线清理,否则模型仍可能模仿。
安全与权限:插件随当前 DSH 进程加载,具备与会话、模型调用相关的同等权限。安装前请在 GitHub 阅读源码与 MIT 许可证,确认与你的工作流及合规要求一致。社区插件目录 SkillHub 为独立站点,与 DeepSeek / 幻方无官方从属关系。
结尾¶
dsh-loop-rescue 把「检测—prune 日志—自动 resume」收进一条 llm/stream 瀑布流,并附带与会话同规则的离线扫描与清理脚本。若你已在 DSH 0.1.7+ 上跑 agent,可从默认配置或 observe 模式试起。
- 目录页:https://www.skillhub.cn/plugins/citydirector/dsh-loop-rescue
- 仓库:https://github.com/citydirector/dsh-loop-rescue