前言¶
在 DeepSeek Harness(dsh)上跑本地大模型时,量化或 RL 调过的推理模型有时会在流式输出里卡死:同一句话反复生成,或对着同一主题用不同措辞反复调用 web_search,却拿不到新信息。dsh 自带的 @deepseek-ai/dsh-repeat-tool-reminder 只是在上下文中注入提醒,模型可以忽略;本地模型(例如关闭 reasoning 的 Qwen / Ornith 35B MoE)在实践中仍会继续循环。
下面介绍社区插件 dsh-loop-detector(维护者 viego-qiin),它在运行时监听智能体流与工具调用,命中后硬中断当前生成,再引导重试;超过重试次数则取消整轮对话。插件归类为 admin-security,当前 GitHub 星标为 2。目录页:skillhub.cn/plugins/viego-qiin/dsh-loop-detector;源码与文档:github.com/viego-qiin/dsh-loop-detector。社区插件目录为独立站点,与 DeepSeek / 幻方无官方从属关系。
这是什么¶
dsh-loop-detector 是面向 dsh 0.2.x 的 Cordis 插件(v2.0.0,MIT 许可)。它做两类检测:正文/推理流上的文本级重复,以及指定工具(默认 web_search)上的「同任务换说法」意图级重复;命中后先 agent.cancel 中止当前生成,再 steer 引导,而不是只排队一条下一轮才生效的软提示。
若你在 dsh 0.2.x 上仍用 v1,插件可能从未触发:v1 监听的是已非实时会话事件的 assistant/chunk,中断用的是仅影响下一步的 steer(),且每次 steer 开新 turn 会把重试计数清掉。v2 改为监听 agent/assistant-stream,先 cancel 再引导,并在真实用户输入时重置计数(插件注入消息按 id 排除)。
核心功能¶
文本级重复检测¶
监听 agent/assistant-stream 的 text-delta,可选 reasoning-delta。缓冲区内分层检测:
- 周期扫描:尾部以固定周期(默认 8–256 字符)重复 ≥4 次。
- n-gram:最近 2048 字符内同一 64 字符块出现 ≥3 次。
- 大锚点:尾部 512 字符在更早位置再次出现并向后延伸(例如整段计划打印两遍)。
重复单元需至少 2 个不同字符且实质性字符(字母/数字/CJK)占比 ≥30%,避免把 markdown 分隔线、表格对齐符误判为循环。v2 对中文换词搜索循环使用「停词切分 + CJK 二元组 + Jaccard 相似度」,不再像 v1 那样按非字母数字切分把整句中文压成一个 token。
工具调用意图级重复¶
监听 tools/post-execute,从参数提取关键词,与最近 3 次调用的并集比较。新颖度低于阈值或 Jaccard 相似度高于阈值,且连续两次满足,则视为「同任务、换说法」。toolPatterns 支持通配符,可纳入 grep、shell 等工具;空数组可关闭该能力。
硬中断与重试¶
默认在打断后引导重试 1 次(maxRetries),用尽后取消整轮。可配置为首次命中即 cancel(action: 'cancel')。命中后有 cooldownMs,避免残留 chunk 再次触发。
安装与启用¶
前提:已有一个在跑的 dsh profile(dsh 0.2.x,Node ≥ 22.18,dsh 自带运行时满足即可)。
官方 README 给出两种方式,均未使用 dsh plugin add github:... 一类命令。
方式一:本地 link¶
在 profile 目录下把插件链为本地依赖(路径换成你本机克隆或解压后的目录):
cd $env:USERPROFILE\.dsh\profiles\desktop
pnpm add link:"D:\path\to\dsh-loop-detector"
插件的运行时依赖(@deepseek-ai/cordis、dsh-agent、dsh-llm、dsh-tools、schemastery)必须留在 peerDependencies,不要挪到 dependencies,否则 Node 会在插件自己的 node_modules 里解析,缺失会导致插件加载失败;dsh 的 profile 解析器才会把裸 specifier 指到 dsh 已安装的副本。
方式二:复制到 node_modules¶
Copy-Item -Recurse -Force "D:\path\to\dsh-loop-detector" `
"$env:USERPROFILE\.dsh\profiles\desktop\node_modules\dsh-loop-detector"
注册 bundle¶
仅 pnpm add link: 可能已能工作,但设置 → 插件 → 已安装列表来自 profile 的 bundles。在 package.json 中追加包名:
// $env:USERPROFILE\.dsh\profiles\desktop\package.json
"dsh": {
"profile": {
"bundles": [
"@deepseek-ai/dsh-base",
// …existing entries…
"dsh-loop-detector"
]
}
}
重启 dsh 后可在 GUI 中开关插件。覆盖默认配置可在 profile 的 cordis.patch.yml 末尾写 id 定向项(升级插件后仍保留):
- id: loop-detector
config:
minLen: 1024
checkReasoning: false
临时关闭可用 GUI,或:
- id: loop-detector
disabled: true
典型用法与日志¶
安装并启用后,可故意让模型进入重复输出或重复搜索,在日志中应看到类似:
[loop-detector] session xxx 正文本命中: periodic repeat: period=8 x4|片段 "abcdefgh"
[loop-detector] session xxx 检测到死循环(重试 1/1): periodic repeat: period=8 x4;已打断并引导重试
[loop-detector] session xxx 意图级重复: repeated web_search intent: novelty=0.29 similarity=0.71
常用配置项(完整表见仓库 README):
| 字段 | 默认 | 含义 |
|---|---|---|
minLen |
512 |
累计多少字符后开始检测 |
maxRetries |
1 |
打断并引导的次数,之后取消 turn |
action |
'steer' |
'steer' 打断+引导;'cancel' 首次命中即取消 |
toolPatterns |
['web_search'] |
监视的工具名(通配符);[] 关闭意图检测 |
checkReasoning |
true |
是否检测 reasoning 流 |
非法配置(未知 action、minLen < 1、比例不在 [0,1])会在挂载时报错,不会静默回退。
适用场景与注意¶
适合在 dsh 0.2.x 上跑本地或易陷入文本复读、工具空转的智能体场景;需要比官方 repeat-tool-reminder 更强制的止损时可以考虑启用。
插件与当前 dsh 进程同权限运行,安装前请阅读 源码 与 MIT 许可证,自行评估是否纳入 profile。调参项(周期范围、n-gram、锚点窗口等)多数有合理默认,仅在误报/漏报时再动 README 中的 Detector tuning 一节。
结尾¶
dsh-loop-detector 针对 dsh 0.2.x 会话事件与中断语义做了对齐,用文本三层检测加工具意图检测,在循环发生时 cancel 硬中断并有限次引导重试。更多信息见 SkillHub 目录页 与 GitHub 仓库(含 README.zh.md)。