前言¶
在使用共享 LLM 网关(如校园网代理、自建网关、提供商池)时,网关经常返回 429 状态码,并在响应体中附带明确的 retry_after_seconds 提示,例如:“所有上游提供商正在冷却中,请在 28 秒后重试”。
DeepSeek Harness 的内置 llm-retry 机制虽然支持 failure.providerRetryAfterMs,但该字段通常由适配器解析 HTTP 头填充。当提示仅存在于响应体文本中(如 llm-pi-ai 适配器不解析头),llm-retry 会回退到本地退避策略(500ms → 1s,共 2 次),导致请求在冷却窗口内失败,而实际上等待 28 秒即可成功。这个插件旨在填补这一空白。
插件介绍¶
dsh-cooldown-retry 是一个 DeepSeek Harness 插件,提供耐心的自动重试机制。它从上游 429 容量冷却消息中读取重试延迟,而不是在两次快速尝试后放弃。
- 所有者: dboycht
- 分类: 工作流
- 许可证: MIT
核心功能¶
- 耐心重试: 对 DeepSeek Harness 进行自动重试,而非在两次快速尝试后放弃。
- 读取上游延迟: 从上游 429 容量冷却消息中读取重试延迟(
retry_after_seconds等)。 - 吸收误标 400: 吸收网关饱和时误标为“不支持音频模态”的 400 错误。
- 预算管理: 按轮次和提供商管理重试预算。
- 中止感知等待: 支持在轮次被取消时立即结束等待。
安装与启用¶
推荐使用官方安装命令添加插件。
dsh plugin --profile web add github:dboycht/dsh-cooldown-retry
前置条件: 安装命令需要 git 在系统 PATH 中(用于 github: 指定符)。
安装后,需要重新加载配置以生效,无需重启进程。
验证安装是否成功:
dsh --profile web --dump-config | grep -A2 'cooldown-retry'
注意: 插件行必须出现在内置 llm-retry 行之后。agent/request-error 是一个瀑布流,后注册的监听器作为内层监听器,因此该插件能优先拦截失败。
配置与用法¶
默认配置如下:
* maxRetries: 5
* minDelayMs: 1000
* maxDelayMs: 300000
* acrossSteps: true
* mislabeledClientError: true
可通过自定义配置覆盖默认值。由于非 insert 补丁会替换整行配置,修改时需重申所有保留的键。
- id: cooldown-retry
config:
maxRetries: 10
maxDelayMs: 600000
主要配置项说明:
* maxRetries: 每轮次/每个提供商在将失败传递给下游之前的耐心重试次数。
* minDelayMs / maxDelayMs: 每次等待的窗口限制(1s - 300s)。
* acrossSteps: 默认为 true,表示在轮次的所有步骤中共享一个预算;设为 false 则恢复每步独立预算。
* mislabeledClientError: 默认为 true。当同一提供商在短时间内出现过容量冷却,且网关返回声称“不支持模态”的 400 错误时,插件会将其视为电路重放并等待,而非直接报错。
* mislabeledMaxRetries: 专门用于处理“误标 400”的独立重试预算,与 maxRetries 分离。
* mislabeledEvidenceMs: 容量冷却作为“证据”的有效时间窗口。
限制:
* maxRetries 和 mislabeledMaxRetries 上限为 100。
* 非插入(非 insert)的补丁会替换整行配置,因此必须重申所有希望保留的键。
观察性¶
每次等待和放弃都会通过 ctx.logger 记录,标签为 cooldown-retry。这有助于在日志中追踪具体的重试行为和延迟时间。
结语¶
该插件通过解析上游响应体中的冷却提示,解决了共享网关环境下常见但被内置重试策略忽略的 429 处理问题,并提供了针对网关误标错误的容错机制。对于依赖不稳定网关或需要高可用性的 DSH 工作流,这是一个实用的增强。