← 返回列表
未验证
状态:草稿。 在一天之内、在一台机器上、驱动本地 Qwen3.8-27B 编写并验证,针对 DeepSeek…
尚未跑自动兼容性验证,可查看页面内的依赖与入口分析。 · 最近上游提交 2026/8/22 · 已提供中文文档
草稿 — DeepSeek Harness 防护机制,使智能体跳出工具调用循环,并升级到更强的模型以执行一个具体的下一步操作。基于窗口的检测,带有进度纪元,因此能够捕获被原生单槽重复防护重置掉的循环。
综合分
27.2
GitHub 分
27.2
用户评分
—
★ Stars
0
周下载量
—
安装插件(需先安装 dsh CLI 引擎:npm install -g @deepseek-ai/dsh)
dsh plugin --profile web add sam-midlight/dsh-loop-rescue该插件未发布到 npm,走 GitHub 源安装(pnpm 若拦截 prepare 脚本,按其提示在 pnpm-workspace.yaml 的 allowBuilds 中放行后重跑)
数据截至 2026/9/18(元数据每日更新 · 实装验证按队列轮转,单条结论的验证时间见上方)
用户评分
还没有人投票,来当第一个
订阅周报,不错过优质插件更新
每周一封 · 高评分插件 + 新用户活动
README
dsh-loop-rescue
状态:草稿。 在一天之内、在一台机器上、驱动本地 Qwen3.8-27B 编写并验证,针对 DeepSeek Harness 0.1.0-rc.7。检测逻辑有测试覆盖,并通过回放真实对话记录进行了验证,但尚未在其他任何地方运行过。请将默认值视为起点,而非定论。欢迎反馈和反例。
将陷入工具调用循环的智能体解救出来,并从更强的模型那里为它争取一条具体的出路。
为什么
内置的防护机制 @deepseek-ai/dsh-repeat-tool-reminder 维护的是一条单槽链:
const count = chain !== void 0 && chain.key === key ? chain.count + 1 : 1
任何不同的被跟踪调用都会将其重置为 1。在 2026-08-22,一个运行 Qwen3.8-27B 的 dsh 会话陷入了这样的循环:
grep X, grep X, grep X, grep X, grep X, read Y, (repeat)
93 次完全相同的 grep 和 21 次完全相同的 read —— 占该会话 192 次工具调用中的 111 次,耗时 7 分钟 —— 全都只是为了重新学到一个它早已掌握的一行答案。周期为 6 的 read 每次都重置了链,因此内置防护机制永远重复触发其阈值 3 和阈值 5 的提醒,从未升级到更高层级。智能体在第 170 次调用时自行逃脱。mcp__claude__ask 全程可用,却被调用了零次。
将该对话记录通过此插件回放:第 62 次调用首次拒绝,第 65 次调用升级 —— 提前了六分五十三秒,在 3 次浪费的重复之后,而不是 93 次。
有何不同
1. 窗口,而非链。 在最近 window 次被跟踪调用内,某个签名出现的次数。任何周期的循环都能被捕获。
2. 进展纪元。 只有在确实没有任何变化时,重复才计数。一次成功的变更性调用(edit/write/……)或一条真实的用户消息会推进纪元,并使此前所有观察作废。这正是阻止围绕一对编辑进行的合法 cargo clippy × 4 触发它的原因 —— 已针对真实对话记录中有产出的尾部进行验证:在包含 9 次 cargo 调用的 22 次调用中,0 次误拒绝。
3. 拒绝。 tools/pre-execute 返回 deny,因此该调用永远不会运行,而指引会落入工具结果中 —— 也就是模型已经在看的地方。提醒在 27B 上已被证明无效;拒绝则有效。
4. 升级。 超过 rescueAt 后,它会以任务、循环调用以及智能体已有的输出为参数,外部调用 ask-claude(Claude/opus),并返回一条具体的下一步行动。
5. 忽略表面性参数。 在实时测试中发现:被要求运行同一条命令六次时,模型给每次调用的 description 都编了号 —— "…(run 1)"、"…(run 2)"、…… 六条字节完全相同的命令,六个不同的签名,检测器失明。ignoredArgs 在生成指纹之前剥离非语义的顶层字段。内置防护机制仍然存在这个漏洞。
askCommand 契约
升级会外部调用一个普通的可执行文件。该契约有意设计为
很小,所以它不绑定任何特定供应商:
- 以 askCommand "" 方式调用——单个 argv,无 stdin;
- 成功时把建议打印到 stdout 并以 0 退出;
- 任何非零退出(或空 stdout)都被视为“不可用”,插件会回退到其免费的本地拒绝。
examples/ask-claude.sh 是一个可用的参考实现,使用 Claude Code CLI,并禁用了所有文件/网络/任务工具,因此响应者仅根据问题的文本作答,无法读取调用机器的代码。把 askCommand 指向任何满足该约定的东西——另一个 CLI、一个围绕 API 的 curl 包装器、一个本地模型。
它收到的问题包含任务、循环调用、该调用的输出,以及最近调用的列表。它不包含循环工具已经打印内容之外的任何文件内容——但它仍然是你代码的文本离开本机,所以请把它指向你放心的位置。
成本控制
升级是这里唯一花钱的事情。
- 建议每个签名只购买一次,并在该 epoch 内缓存;之后对同一调用的每次尝试都免费复用。
- maxRescues(默认 3)限制每个会话;cooldownMs(默认 45 秒)拉开它们之间的间隔。
- 一次失败的询问会退还预算,并回退到免费的本地拒绝。
- mcp__claude__ask 默认被排除,因此升级工具永远不会被那个负责升级的东西阻塞。
配置
- id: loop-rescue
name: dsh-loop-rescue
config:
window: 12 # detection window, in tracked calls
nudgeAt: 3 # repeats -> free local denial
rescueAt: 5 # repeats -> denial carrying Claude's guidance
stallAt: 40 # redundant calls in one epoch -> rescue regardless of signature (0 disables)
maxRescues: 3 # Claude escalations per agent per session
cooldownMs: 45000
include: [] # tool-name patterns to watch ('' wildcard); empty = all
exclude: [todo_write, ask_user, 'mcp__claude__']
excludeCommands: [] # regexes over a bash command; the escape hatch for deliberate polling
ignoredArgs: [description, explanation, reasoning, thought, comment] # stripped before fingerprinting
mutatingTools: [edit, write, multi_edit, str_replace_editor, apply_patch, create_file, notebook_edit]
askCommand: ~/.local/bin/ask-claude
askModel: opus
askTimeoutMs: 90000
logFile: ~/.llmbox/loop-rescue.jsonl # one JSON line per trip; '' disables
每个值都会在加载时进行验证,遇到无意义的值会抛出错误,而不是静默回退到默认值。
有意为之的轮询
一个故意重复的 bash 调用——等待容器、健康检查——看起来和循环一模一样。有两样东西可以拯救它:excludeCommands,以及这样一个事实:拒绝只会阻止那一个签名,所以 sleep 10 && docker ps 在 docker ps 被拒绝后仍然可以通过。
当重复本身就是目的时
如果一个任务确实需要重复执行同一条命令——轮询容器、健康检查、刻意的基准测试——这个防护机制会与之对抗,而升级后 Claude 会告诉 agent 继续执行。请使用 excludeCommands。另请注意,一次拒绝只会阻止那一个签名,因此在 docker ps 被拒绝后,sleep 10 && docker ps 仍然可以通过。
安装
dsh plugin --profile add /path/to/dsh-loop-rescue
然后将其添加到该配置文件的 cordis.patch.yml 中:
- insert:
- id: loop-rescue
name: dsh-loop-rescue
config: {}
未发布到 npm——在草稿阶段,package.json 被标记为 private。
测试
node --test 'test/*.test.mjs'
14 个测试。测试框架默认将 askCommand 指向一个不可达的路径:除非显式请求一个桩,否则任何测试都无法触达真实的 ask-claude 并消耗 Opus token。
可观测性
触发会追加到 ~/.llmbox/loop-rescue.jsonl(kind:deny、rescue、escalation-failed)。升级也会记录到 ~/.llmbox/ask-claude.jsonl,因此它们会出现在已经跟踪该文件的任何地方。扫码进群