DeepSeek Harness 中使用商汤deepseek v4 flash 的 429 限流排查与解决
记一次 DeepSeek V4 Flash 在 DeepSeek Harness 中的 429 限流排查与解决
背景
最近在使用 DeepSeek Harness (DSH) 搭建 AI Agent 工作流,模型用的是商汤 SenseNova 平台提供的 deepseek-v4-flash。使用过程中频繁遇到请求超时/失败,一开始以为是网络问题,结果仔细一看错误信息,发现另有玄机。
现象
Agent 在执行任务时,经常卡住很长时间,然后报错。从 DSH 的日志中可以看到类似这样的记录:
重试延迟:8515ms
失败原因:429: {"message":"inference tpm exhausted","type":"invalid_request_error","code":"429001"}
关键信息:
- HTTP 429 — 不是超时,是限流(Rate Limit)
- 错误码
429001— 这是 SenseNova 网关的限流标识 - 错误消息
inference tpm exhausted— TPM(Tokens Per Minute,每分钟 Token 配额)用尽了 - 重试延迟 8515ms(约 8.5 秒)— SenseNova 网关要求等待这么久之后才能重试
根本原因分析
1. 什么是 TPM?
TPM = Tokens Per Minute,即每分钟能处理的 Token 数量上限。这是 API 网关对每个用户/每个 API Key 设置的硬性配额限制。当你在短时间内发送的请求累积 Token 数超过这个配额时,网关就会返回 429 Too Many Requests。
2. 为什么 deepseek-v4-flash 特别容易撞墙?
查看 DSH 的配置:
deepseek-v4-flash:
apiKeyEnv: DEEPSEEK_V4_FLASH_API_KEY
api: openai-completions
baseURL: https://token.sensenova.cn/v1
models:
- id: deepseek-v4-flash
name: deepseek-v4-flash
contextWindow: 1048576 # 100万 token 上下文!
"Flash" 系列模型的设计定位是高吞吐、低延迟、低成本,因此网关对这类模型的 TPM 配额通常设置得更低。再加上它宣称的 contextWindow 高达 1,048,576 tokens(100万),每次请求的输入可能非常大。
3. Agent 的工作模式加剧了问题
DSH 的 Agent 在单个 turn 内的工作流程大致是:
用户提问
→ Agent 调用工具(如 pwsh、read、grep 等)
→ 工具返回结果
→ Agent 再次请求模型处理结果
→ 又调用另一个工具
→ 工具返回结果
→ Agent 再次请求模型...
每次模型请求,输入 Token = 系统提示词 + 全部历史对话 + 当前工具结果,上下文越来越长。在密集的工具调用场景下,几分钟内就能把 TPM 配额打满。
4. 重试延迟 8515ms 的由来
DSH 内置了 dsh-llm-retry 模块来处理模型请求失败。它的行为是:
- 收到 429 错误后,检查 provider 是否返回了
Retry-After延迟 - 如果 provider 返回的延迟值不超过配置的
maxDelayMs(默认 10000ms),则直接使用 provider 返回的延迟 - SenseNova 返回了 8515ms,小于 10000ms,所以 DSH 直接等待 8.5 秒后重试
默认的重试策略是:
maxRetries: 5 次initialDelayMs: 500msmaxDelayMs: 10000ms(10秒)jitterRatio: 0.1
如果网关返回的 Retry-After 超过 10 秒,normal 模式就会直接放弃重试。
解决方案
1. 自定义 retryPolicy
在 ~/.dsh/settings.yaml 中给 deepseek-v4-flash provider 添加自定义重试策略:
llm-pi-ai:
providers:
deepseek-v4-flash:
apiKeyEnv: DEEPSEEK_V4_FLASH_API_KEY
api: openai-completions
baseURL: https://token.sensenova.cn/v1
models:
- id: deepseek-v4-flash
name: deepseek-v4-flash
contextWindow: 1048576
# ... 其他模型
retryPolicy:
mode: normal
maxRetries: 8 # 默认 5 → 提高到 8
backoff:
initialDelayMs: 1000 # 默认 500ms → 提高到 1s
maxDelayMs: 60000 # 默认 10s → 提高到 60s
jitterRatio: 0.2 # 默认 0.1 → 增加抖动
关键改动:
maxRetries: 8— 从默认 5 次提高到 8 次,给更多机会maxDelayMs: 60000— 从默认 10 秒提高到 60 秒,即使网关要求等 30 秒也能接受initialDelayMs: 1000— 首次退避从 500ms 提高到 1s,减少不必要的快速重试
2. 注意事项:retryPolicy 是 provider 级,不是 model 级
dsh-llm-pi-ai 的代码中,retryPolicy 是 provider 路由级 的设置,同一个 provider 下的所有模型共享同一份重试策略。如果你需要不同模型用不同策略,需要把它们拆成独立的 provider 路由。
配置会在下一次请求时立即生效,无需重启 DSH 服务。
原理:DSH 重试机制的工作流程
模型请求失败
→ 触发 agent/request-error 事件
→ dsh-llm-retry 拦截
→ 检查 retryPolicy 是否存在
→ 检查失败 code 是否在 retryableCodes 中(RATE_LIMIT 在列表内)
→ 检查是否超过 maxRetries
→ 计算退避延迟
→ 如果 provider 返回了 Retry-After 且 ≤ maxDelayMs → 使用 provider 的延迟
→ 否则使用指数退避:initialDelayMs × 2^retry
→ 追加 llm/retry 事件(含 retryId、延迟、失败原因)
→ 等待延迟时间
→ 追加 llm/retry-started 事件
→ 返回 { kind: "retry" }
→ 循环重新发送请求
经验总结
- HTTP 429 不等于网络超时 — 看到 429 先看错误消息,
tpm exhausted说明是配额问题 - Flash 模型 TPM 配额通常更低 — 选择模型时要考虑它的限流特性,尤其是 Agent 密集调用的场景
- DSH 的 retryPolicy 配置是解决限流的正确方式 — 不要试图修改代码,配置就能搞定
- 配置实时生效 —
settings.yaml的llm-pi-ai分节在每次请求时重新读取,改完就能用 - 如果限流仍然严重,考虑换模型 — 同一个 provider 下
sensenova-6.7-flash-lite的 context window 更小(262K),单次请求消耗更少 Token,可能更不容易触发限流
记录于 2026 年,使用 DeepSeek Harness 作为 AI Agent 框架的日常踩坑。
浙公网安备 33010602011771号