← 返回列表
未验证
拦截连续三次参数完全相同的工具调用
尚未跑自动兼容性验证,可查看页面内的依赖与入口分析。 · 最近上游提交 2026/9/1 · 已提供中文文档
DeepSeek Harness 插件:相同工具+参数断路器(LOOP_BRAKE)
综合分
28.4
GitHub 分
28.4
用户评分
—
★ Stars
0
周下载量
—
安装插件(需先安装 dsh CLI 引擎:npm install -g @deepseek-ai/dsh)
dsh plugin --profile web add jwilson411/dsh-loop-brake该插件未发布到 npm,走 GitHub 源安装(pnpm 若拦截 prepare 脚本,按其提示在 pnpm-workspace.yaml 的 allowBuilds 中放行后重跑)
数据截至 2026/9/16(元数据每日更新 · 实装验证按队列轮转,单条结论的验证时间见上方)
依赖的 DSH / Cordis 模块
@deepseek-ai/dsh-tools@deepseek-ai/cordis用户评分
还没有人投票,来当第一个
订阅周报,不错过优质插件更新
每周一封 · 高评分插件 + 新用户活动
README
dsh-loop-brake
一个 [DeepSeek Harness][dsh] 函数插件:针对相同工具调用的断路器。
智能体会卡住。它用 {"q":"weather"} 调用 search,读取结果,判定自己需要用 {"q":"weather"} 调用 search,然后就调用了。任何单次调用都没有问题,所以没有什么能阻止它,循环会一直运行,直到预算、回合上限或人类注意到为止。
这个插件在第三次时就会注意到。
LoopBrakeError: loop brake: tool "search" called 3 times in a row with identical
arguments (call 9f2c1a7b3e04…, limit 3); the call was denied before it ran.
Change the arguments, call a different tool, or stop.
工具主体不会运行。错误携带 code: 'LOOP_BRAKE'、计数、上限,以及调用哈希的十二个十六进制字符,因此拒绝在日志中清晰可读,而无需将参数本身复制到日志中。
它不是什么
这不是一个 LLM 相似度评判器。 它不是嵌入,不是模糊匹配,不是向模型提出的语义问题“这两个调用是否基本相同”,不是工作流引擎,也不是监视第一个循环的第二个智能体循环。这个包中没有任何模型调用,也没有需要调整的阈值。
仅精确哈希匹配。 当
sha256(toolName + "\n" + canonicalJson(args))
产生相同的摘要时,两个调用就是同一个调用,否则就是不同的调用。规范化会在每个嵌套层级对对象键进行排序,仅此而已——因此 {"a":1,"b":2} 和 {"b":2,"a":1} 是同一个调用,而 {"q":"weather"} 和 {"q":"weather "} 是两个。
这个边界值得明确说明,因为它决定了这个插件能捕获什么:
- 智能体逐字节重复一个调用——会被捕获,在第 N 次尝试时。
- 智能体在循环时,其参数中的时间戳、随机数、页游标或重试计数器发生变化——不会被捕获。每次调用的哈希都不同,而这个插件对它们是否含义相同没有意见。
- 智能体在两个调用之间永远交替——不会被捕获。计数器是连续重复的连击数,因此 A, B, A, B 永远不会达到任何东西的三次。
一个在“这些看起来相似”时就触发的刹车需要一个模型来决定相似的含义,这意味着在组合中的每个工具调用之前都要进行一次模型调用,并带有误报率和账单。精确匹配版本只需微秒级成本,不会产生幻觉,并且可以向任何在凌晨三点阅读拒绝信息的人解释清楚。它能捕获卡住的智能体最常见的单一形态,并且对其余情况保持诚实。
安装
dsh plugin --profile default add github:jwilson411/dsh-loop-brake
安装程序从包清单中读取 dsh.bundle.patch,并将此包追加到配置文件的有序 bundle 列表中。它的 cordis.patch.yml 包含一行插入行,id: loop-brake,没有配置——即默认值。
将 tools 包固定为 0.1.1-rc.2;这是此插件开发和测试所针对的候选发布版本。
配置
在组合补丁中该插件所在行的一个旋钮:
- id: loop-brake
config:
maxRepeats: 5
| 键 | 默认值 | 含义 |
| --- | --- | --- |
| maxRepeats | 3 | 一个会话在下一个相同调用被拒绝之前,可以连续进行的相同调用次数。计数包含被拒绝的那次调用,因此在 3 时,两次相同调用会执行,第三次会被拒绝。 |
必须是至少为 1 的整数。不可用的值会在插件应用时被拒绝,而不是在第一次调用时:一个与某个 profile 所要求的牙齿不同的刹车,即使会被发现,也只有在循环已经在消耗 token 时才会被发现。1 会立即拒绝每一次重复,包括任何连续调用中的第一次——这是一个调试设置,而不是部署设置。
环境回退变量 DSH_LOOP_BRAKE_MAX_REPEATS 仅在配置键缺失时才会被读取。补丁行是部署所声明的意图,因此它优先于环境变量。
按 id 定位的补丁会替换该行的整个 config,而不是合并到其中,因此覆盖必须重新声明它想要保留的每个字段。
计数
计数是按会话进行的,并且每个会话中插件只保留一个当前哈希和一个计数——是一条连续记录,而不是直方图。
- 调用 A、A → 连续记录为 2。
- 调用 B → A 的连续记录消失;B 为 1。
- 调用 A → 回到 1,而不是 3。
两个会话永远不会共享计数:两个 agent 合法地进行相同调用,并不是一个 agent 在循环。会话是调用方传入的显式 sessionId,否则是执行输入中调用 agent 的 id,否则是 default。
内存不会随会话长度增长——每个会话一个槽位,而不是为曾经进行过的每个不同调用保留一个条目。
错误
error.code // 'LOOP_BRAKE'
error.toolName // 'search'
error.count // 3 — which consecutive repeat this was, counting this call
error.maxRepeats // 3
error.hashPrefix // '9f2c1a7b3e04' — the first 12 hex characters, and no more
error.sessionId // the session whose streak tripped
error.plugin // 'dsh-loop-brake'
抛出的是 LoopBrakeError,而不是返回它。一个调用方可以通过忽略返回值来绕过的刹车不是刹车,而它存在所要阻止的失败,恰恰是没有人认真读取返回值的情况。
参数永远不会放进错误中。它们最有可能包含调用方传入的路径、查询或凭据,而错误消息最有可能被记录、展示或交回给模型。
它如何挂接
apply 会在两个位置修补注入的工具注册表,并返回 LoopBrake 实例,以便想要检查或重置它的宿主可以这样做。
- ctx.tools.register 会被修补,因此在此 fiber 生命周期内注册的每个定义都会带有一个经过刹车的 execute。这是强制路径,也是此插件假定存在的唯一路径。
- ctx.tools.execute 会在运行时暴露它时被修补,这能捕获 register 补丁无法捕获的情况:一个在此插件应用之前注册的工具。
一次经过两道接缝的宿主调用只计为一次,以其调用 id 为键。若一对包装器都各自计数,就会以配置上限的一半触发拦截。
两个补丁在 dispose 时都会被撤销,因此停止或重新加载插件后,注册表会完全恢复为原样——同时遗忘所有连续记录,这是正确的默认行为。一个在重新加载后仍保留记忆的刹车,会因为上一次运行的所作所为而拒绝一次全新运行的首次调用。
没有注册任何工具。 此插件不会向模型的工具面添加任何内容。模型能够调用的刹车,就是能被说服与之争辩的刹车,而且状态工具所能报告的内容,拒绝信息中早已说明。
直接使用该库
计数部分单独导出,供拥有自身调用点的宿主使用:
import { LoopBrake, decorateTool, wrapExecute } from 'dsh-loop-brake/loop-brake'
const brake = new LoopBrake({ maxRepeats: 3 })
// Wrap one execute…
const guarded = wrapExecute(execute, brake, { tool: 'search', sessionId: 's1' })
// …or copy a whole definition with its execute braked.
const braked = decorateTool(definition, brake)
decorateTool 返回一个副本;原始定义保持不变。同样导出的还有:callHash、canonicalJson、hashPrefix、sessionKey、normalizeMaxRepeats、resolveMaxRepeats、LoopBrakeError、InvalidMaxRepeatsError。
依赖
运行时无依赖。随附源码只导入 node:crypto,别无其他——它不打开套接字、不读取文件、不生成进程,所有这些都由测试套件断言而非承诺。@deepseek-ai/cordis 和 @deepseek-ai/dsh-tools 是 peer 依赖,由测试框架提供。
Node >=22.14.0。
测试
npm install
npm test
无需网络、无需凭据、无需模型权重。CI 在 Node 22.x 和 24.x 上运行同一套测试。
许可证
MIT。Copyright (c) 2026 jwilson411。
[dsh]: https://www.npmjs.com/package/@deepseek-ai/dsh-tools同作者(jwilson411)的其他插件
扫码进群