前言¶
在 DeepSeek Harness(DSH)里跑长对话或经多通道代理转发时,两类失败经常被内置执行器直接判为终态:上游返回 HTTP 429 限流,以及携带 thinking 块的请求因签名与会话绑定不匹配而被网关以 400 拒绝。DSH 默认对 429 只做最多五次、500 ms 到 10 s 的退避,限流窗口可能尚未过去重试预算就已用完;对 thinking 块绑定错误则归类为 INVALID_REQUEST 且不重试,整轮对话随之结束。Open Multi-Provider(OMP)生态里对上述情况有更耐心的策略。dsh-labs 维护的 dsh-omp-retry 以插件形式把其中与 DSH 相关的两条策略搬进 Harness,无需 fork DSH 本体。
这是什么¶
dsh-omp-retry 是分类为「工作流」的 DSH 插件,由 dsh-labs 发布,在 SkillHub 插件目录 可查阅条目。它针对两类失败定制重试:HTTP 429 限流,以及正文包含 Invalid signature in thinking block 或 bound to a different conversation 等特征的 thinking 块绑定拒绝。实现上在 dsh-llm-retry 之前挂载 agent/request-error 监听器,仅接管这两种场景;其余错误仍走内置执行器,插件未加载时行为与默认一致。
社区目录 SkillHub 与 DeepSeek、幻方无官方从属关系;安装与运行均在当前 DSH 进程权限下进行,启用前建议浏览 GitHub 仓库 源码与 MIT 许可证。
核心功能¶
HTTP 429 限流¶
- 每个失败步骤最多 10 次限流重试(可配置)。
- 等待时间为
max(30 s, 上游 Retry-After)。 - 若必须等待超过 5 分钟,则终止重试链,不再 sleep。
- 重试预算与
dsh-llm-retry共用:按解析后的 providerretryPolicy对应一个持久化策略键。
相较 DSH 默认的五次、亚秒到 10 秒退避,这一策略更贴近 OMP 对 TPM/RPM 窗口的等待方式。
thinking 块绑定拒绝¶
多上游或轮换会话身份的代理在重放带签名的 thinking 块时,可能返回 400 且文案指向签名或会话不匹配;同一历史再次发送往往能落到接受该块的上游。DSH 若不重试,整轮即失败。
本插件对此类错误:
- 每个失败步骤最多 5 次重试(可配置),指数退避 500 ms 至 8 s,抖动比例 25%,形状与 provider 本地退避相近。
- 预算与 provider
retryPolicy独立,即使用户未改 provider 默认策略也会获得绑定重试。 - 匹配依据为响应正文中的特征字符串,而非失败码,以降低网关改码后的误判。
共用行为¶
- 每次计划中的重试会追加持久的
llm/retry、llm/retry-started事件,常规重试 UI 与会话历史仍可用。 - 取消、回合结束、插件卸载会中止当前等待。
SERVER、TIMEOUT、TRANSPORT、EMPTY_RESPONSE、CONTEXT_WINDOW_EXCEEDED、QUOTA、AUTH不由本插件重试。
安装与启用¶
按 README 官方命令安装(将 desktop 换成你实际使用的 profile 名称,例如 Web 或自定义 profile):
dsh plugin --profile desktop add github:dsh-labs/dsh-omp-retry
安装后重启 DSH。插件会通过 bundle 自行插入 omp-rate-limit-retry 配置行,无需手工注册监听器。
README 记载已在 DSH Desktop 0.2.1-rc.5 上验证;依赖 agent/request-error 瀑布流、llm-retry 会话投影(llmRetry)以及内置重试执行器使用的 llm/retry 事件形态。若未来 DSH 变更这些契约,插件可能需要更新;无法处理时会 fail closed,交给下游监听器。
配置¶
默认值(限流):maxRetries: 10,floorMs: 30000,maxDelayMs: 300000。
默认值(thinking 块):maxRetries: 5,initialDelayMs: 500,maxDelayMs: 8000,jitterRatio: 0.25。
在 profile 的 cordis.patch.yml 中覆盖 omp-rate-limit-retry 行即可:
- id: omp-rate-limit-retry
config:
maxRetries: 10
floorMs: 30000
maxDelayMs: 300000
thinkingBlock:
maxRetries: 5
initialDelayMs: 500
maxDelayMs: 8000
jitterRatio: 0.25
将对应段的 maxRetries 设为 0 可关闭该策略。配置值畸形会导致插件加载失败并指明 offending key,而不是静默关闭重试。
若希望非 429 的 provider 重试退避形状接近 OMP,可在 provider 策略中保持 RATE_LIMIT 于 retryableCodes(插件移除后仍可作为 429 兜底):
retryPolicy:
mode: normal
maxRetries: 10
retryableCodes:
- EMPTY_RESPONSE
- RATE_LIMIT
- SERVER
- TIMEOUT
- TRANSPORT
backoff:
initialDelayMs: 500
maxDelayMs: 8000
jitterRatio: 0.25
插件激活时由 bundle 优先处理 429;RATE_LIMIT 留在列表中主要用于未安装本插件时的回退。
典型用法¶
1、确认 DSH profile 名称,执行上述 dsh plugin ... add 命令。
2、重启 DSH,遇 429 或 thinking 绑定拒绝时观察会话中的 llm/retry 相关事件与 UI。
3、若限流仍过于激进或过于保守,在 cordis.patch.yml 调整 floorMs、maxDelayMs 或 maxRetries;多上游场景可适当提高 thinkingBlock.maxRetries。
4、需要与 OMP 其他非重试能力(模型/凭证回退链等)对齐时,README 明确说明本插件未实现那些链路,仅覆盖两种失败类型。
适用场景与注意¶
适合谁: 使用 DSH 且经 OMP 或多通道代理访问模型、经常遇到 429 或 thinking 块 400 的开发者;希望在不修改 DSH 核心的前提下获得更接近 OMP 的等待与绑定重试行为。
局限(摘自上游文档):
- 不是通用重试框架,也不等同于 Ghostty;只处理 429 与 thinking 块绑定拒绝。
- 重试不改写历史;若拒绝持续出现,可能是会话中模型或 tool schema 已切换导致身份变化,预算耗尽后回合仍会结束。持久修复在上游:例如发送
anthropic-beta: thinking-binding-controls-2026-08-01并设置thinking.block_binding.prefix_mismatch_behavior: "drop_block",或在客户端丢弃陈旧块。 - 未实现 OMP 的 model/credential fallback chains。
- 上游
Retry-After超过maxDelayMs时不会继续等待。
插件以当前 DSH 进程权限运行;安装前请自行审阅 源码 与 MIT 许可。package.json 显示当前发布版本为 0.2.2;开发构建要求 Node >=22.19.0。
结尾¶
dsh-omp-retry 用最小侵入的方式补上 DSH 内置执行器在 429 与 thinking 绑定上的终态缺口,并与 dsh-llm-retry、内置 executor 分工明确。目录与仓库: