dsh-tool-governor:在工具调用失控前截断重复与失败循环

前言

在 DeepSeek Harness(DSH)里跑智能体时,模型有时会反复调用同一工具、在同一参数上打转,或在连续失败后仍继续重试。每一次调用都会占用上下文与 token。若没有在 harness 层做约束,这类行为往往在任务结束前就耗掉预算,且难以从日志里一眼看出是「策略问题」还是「工具层死循环」。

下面介绍社区插件 dsh-tool-governor(维护者 George-Java):在工具真正执行前后挂接 DSH 的 guard 与 step 钩子,对重复调用、连续失败和可选的单轮上限做统一裁决,并在拒绝后保持单调性,避免下游再把已拦截的调用放行。

这是什么

dsh-tool-governor 是 DSH 生态中的工作流类插件,一句话定位:在 token 被烧尽之前,拦截失控的工具调用。

它解决的是三类常见浪费:

  • 相同工具名 + 相同参数组合被反复发起;
  • 某工具连续返回结构化错误后仍被继续调用;
  • 需要时,为单轮对话显式设置工具调用次数或模型步数上限(默认不启用,避免误伤长任务)。

插件在 profile 根上挂接 tools/pre-execute、tools/post-execute、ctx.tools.guard 与 agent/pre-step,只依赖全局 tools 服务;执行上下文中的 agent 来自 exec.agent / event.agent。

核心功能

资料中列出的能力如下,均可在安装后通过配置调节阈值。

重复调用熔断(Repeat-call breaker)

当同一 工具名 + 参数组合 在单轮内重复达到阈值时,拒绝下一次相同调用。默认 repeatThreshold 为 3,即第 4 次相同组合会被 deny。

失败循环截断(Failure-loop cutoff)

仅当工具返回的结构化结果满足 result.isError === true 时计为失败;输出文本里偶然出现 “error” 字样但不带结构化错误标志的成功调用不算失败。连续失败达到 consecutiveFailureThreshold(默认 3)后,暂停该工具。

可选的单轮预算(Per-turn caps)

  • maxToolCallsPerTurn:单轮最大工具调用次数;
  • maxStepsPerTurn:单轮最大模型步数。

两者默认均为 0,表示不限制;只有显式设为正数时才作为熔断线,适合需要硬上限的环境。

单调守卫(Monotonic guard)

一旦被本插件拒绝,下游层不能再把该调用重新放行(deny 为最终态)。

工具黑名单

denyTools 接受 glob 模式列表,例如始终拒绝 browser_* 一类工具。

轮次与账本

每条新的用户消息会重置对应 agent 的账本,重复计数与失败计数从新的一轮开始累计。

安装与启用

官方安装命令(profile 为 web,与 README 一致):

dsh plugin --profile web add dsh-tool-governor

安装后需重启 DSH。可用下面命令确认 bundle 已注册(README 示例为 Windows 的 findstr;在 Linux/macOS 上可用 grep dsh-tool-governor 等等效过滤):

dsh --profile web --dump-config | findstr dsh-tool-governor

固定版本或从 GitHub 源安装(README 原文):

dsh plugin --profile web add dsh-tool-governor@1.1.0
dsh plugin --profile web add github:George-Java/dsh-tool-governor

卸载:

dsh plugin --profile web remove dsh-tool-governor

兼容性

项 要求
DSH 0.2.x(README 注明在 0.2.1-rc.2 上测试)
平台 Windows / macOS / Linux
Node.js ^22.19.0 \|\| >=24.0.0

许可证:MIT(package.json 当前版本为 1.1.0)。

典型用法:在 profile 里改配置

所有配置项均为可选,省略时使用默认值。在 profile 的 cordis.patch.yml 中覆盖插件 config 即可,例如提高重复阈值、或按需打开单轮上限:

- id: dsh-tool-governor
  name: dsh-tool-governor
  config:
    repeatThreshold: 5
    # 仅在需要硬熔断时启用:
    # maxToolCallsPerTurn: 100
    # maxStepsPerTurn: 50

完整配置字段(摘自 README):

字段 默认值 说明
maxToolCallsPerTurn 0 单轮最大工具调用;0 表示关闭
maxStepsPerTurn 0 单轮最大模型步数;0 表示关闭
repeatThreshold 3 拒绝第 (N+1) 次相同工具+参数调用
consecutiveFailureThreshold 3 连续 N 次结构化失败后暂停工具
denyTools [] 始终拒绝的工具 glob 列表
denyMessage 内置 拒绝时注入给模型的说明

拦截发生时,可通过 denyMessage 自定义提示;未配置时使用插件内置文案。

适用场景与注意

适合谁

  • 在 DSH web profile 下跑多工具智能体,希望 harness 层统一治理调用节奏;
  • 调试阶段需要快速发现「同一调用反复出现」或「某工具连续报错仍被重试」;
  • 在受控环境里需要可选的单轮调用/步数上限,而不是默认截断长任务。

使用前请知悉

  • 插件与当前 dsh 进程同权限运行;安装前建议阅读 GitHub 仓库 源码与 MIT 许可证,确认行为符合你的安全与合规要求。
  • DSH 社区插件目录(如 SkillHub 上的条目)由社区维护,与 DeepSeek / 幻方无官方从属关系;安装来源以你实际使用的 registry 或 github: 地址为准。
  • 默认不开启 maxToolCallsPerTurn / maxStepsPerTurn,避免误伤正常的长链路任务;只有明确需要熔断时再设为正值。

结尾

dsh-tool-governor 把重复调用、失败循环和可选单轮上限收拢到同一套 pre/post guard 里,并在拒绝后保持单调,减少无效工具往返带来的 token 浪费。若你在 DSH 工作流里需要一层轻量的工具治理,可按上文命令安装,并在 cordis.patch.yml 里按场景调整阈值。

羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

小夜