dsh-plugin-retry-backoff:为模型限流追加可自定义的指数退避重试

前言

在 DeepSeek Harness(DSH)里跑 Agent 时,模型请求一旦遇到 429 或网关限流,内置策略只会做有界重试:默认最多 5 次,退避从 0.5 秒涨到 10 秒。限流若持续几十秒到几分钟,五次用尽后轮次直接失败,只能手动重发。下面介绍社区插件 dsh-plugin-retry-backoff(维护者 zmy15,分类:模型推理),它在官方 @deepseek-ai/dsh-llm-retry 之前挂到同一条 agent/request-error waterfall 上,用你设定的轮次与退避曲线追加一层预算;预算用尽后仍交回 DSH 原生策略,而不是替换官方行为。

这是什么

dsh-plugin-retry-backoff 是 DSH 的 bundle 型插件:宿主半边在失败分片时决策等待与重试,前端半边在官方设置面板左侧增加「重试退避」一节。网页端与桌面端共用同一份设置真源(插件自有 JSON 文件,不依赖 DSH 0.2.x 已移除的 settings 注册接口)。当前仓库版本为 1.0.4,许可证 MIT。

  • 目录页:https://www.skillhub.cn/plugins/zmy15/dsh-plugin-retry-backoff
  • 源码:https://github.com/zmy15/dsh-plugin-retry-backoff

核心功能

与内置重试的组合关系

Agent loop 在模型请求以失败分片结束时,会跑 agent/request-error waterfall;返回 { kind: 'retry' } 时在同一打开的轮次内重跑失败步骤。本插件登记在官方 dsh-llm-retry 之前:

失败 → 本插件(用户自定义退避,自己的预算)
        ├─ 还有预算 → 等待 → 返回 retry
        └─ 预算耗尽 / 已禁用 / 失败码不在集合 → next() → 官方策略照常接管

禁用插件或把「延长轮次」设为 0,行为与未安装时一致。

设置面板与默认值

安装并在 profile 中启用后,设置里会出现「重试退避」,主要控件如下(默认值来自 README):

控件 默认 说明
启用本插件 开 关则完全回到 DSH 原生行为
延长轮次 8 本插件最多追加多少次重试;0 表示不介入;可调至 200
首次等待 2000 ms 第 1 轮退避时长
退避倍率 2 每轮等待 ×N;1 为固定间隔
单轮上限 60000 ms 单轮等待上限
抖动比例 0.2 ±20% 随机,减轻多会话同时重试
尊重 Retry-After 开 提供方给出的等待(不超上限时)优先于本地曲线
重试哪些失败码 四类默认 限流 / 服务端 / 超时 / 传输;默认不含 AUTH、QUOTA、INVALID_REQUEST、CONTEXT

面板可查看整条退避曲线的柱状图与累计最长等待时间。

设置存储与环境变量

设置保存在插件自有文件中:

$DSH_HOME/retry-backoff/settings.json     # 缺省 ~/.dsh/retry-backoff/settings.json

写入采用同目录 tmp 再 rename 的原子方式;并发保存会排队。可用环境变量 DSH_RETRY_BACKOFF_SETTINGS 指向其他路径(测试或便携场景)。

实现上的三条不变量

  1. 先持久、后等待:计划重试前会先追加非 surface 的会话事件 llm/retry-backoff,避免崩溃或取消后留下不可见的待处理重试。
  2. 可取消:退避等待监听 loop 的 signal 与插件生命周期,取消或卸载会中止等待。
  3. 预算持久:轮次计数从会话日志的 llmRetryBackoff 投影读出,重连恢复不会清零;step/start 与 turn/end 会重置预算。预算按 provider 分别计数,同一 provider 上多个模型共用一份预算。

安装与启用

本插件按 bundle 渠道装入 profile,资料未给出 dsh plugin add 一类的一行命令。做法是在所用 profile 的 package.json 里登记 bundle,并把包装进该 profile 的 node_modules:

// ~/.dsh/profiles/<name>/package.json
"dsh": { "profile": { "bundles": [ ..., "dsh-plugin-retry-backoff" ] } }

包本体路径:<profile>/node_modules/dsh-plugin-retry-backoff。

改完 profile 后必须重启 DSH:宿主半边在启动期挂载,热重载不会带入 bundle 行;前端半边刷新后会重新注入。

版本闸门

DSH 启动时会校验插件 peerDependencies 与本机运行时是否兼容,不兼容则整行跳过(日志中常见 skipping profile bundle "…",前端看不到面板)。本插件要求 engines.dsh 与相关 peer 为 >=0.1.5-rc.1 的开放下界,避免 caret 在 0.x 下把 0.2.x 排除在外。仓库内可用 node test/verify-client-contract.mjs 与 node test/verify-semver.mjs 做安装期对照(面向插件开发者,非终端用户必做步骤)。

典型用法

  1. 在 profile 中加入 bundle 并安装包到 node_modules,重启 DSH。
  2. 打开官方设置,左侧进入「重试退避」,按需调整延长轮次与退避参数;遇到持续 429 时可提高「延长轮次」、拉大「单轮上限」,并保留「尊重 Retry-After」。
  3. 需要手改或备份时,直接编辑 settings.json,下一次重试或打开面板即可读到新值。
  4. 若「保存 / 恢复默认」变灰,面板会提示原因;1.0.3 起通常只有宿主无法写入 $DSH_HOME/retry-backoff 时才会只读——可点「重新检测」,并查看宿主日志中的 retry-backoff: settings write failed。

端到端验证脚本中的示例曲线为连续失败后再成功时,等待按 100→200→400→800 ms 递增(测试配置,非面板默认值)。

适用场景与注意

适合:长时间跑 Agent、经常撞上 provider 限流或服务端瞬时错误,希望在同一轮次内自动拉长等待而不是五次失败后立刻交卷的用户。

务必知晓:

  • 插件以当前 DSH 进程权限运行;安装前应自行审阅源码与 MIT 许可证。
  • 只覆盖 agent 轮次边界 上的失败重试;直接调用 ctx.llm.stream() 的路径仍是一次性尝试,与官方 llm-retry 相同约束。
  • 每次重试都是真实请求,会重复计费输入 token;调大轮次与上限前请确认额度。
  • 插件不判断「值不值得等」;若手动把 AUTH 等码加入重试集合,会按你的配置一直重试。
  • 社区目录 SkillHub 与 DeepSeek / 幻方无官方从属关系;DSH 生态是「一切皆插件」,本介绍事实均来自上述 GitHub README 与 package.json。

结尾

dsh-plugin-retry-backoff 在官方有界重试之上追加可配置的指数退避预算,限流耗尽内置次数后仍有机会在同一轮内等到成功;设置独立于 DSH settings 服务,网页与桌面共用一份 JSON。进一步了解可访问 SkillHub 目录页 与 GitHub 仓库。

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

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

Xiaoye