Agent 失败重试指南:用对指数退避与随机抖动

作者:袖梨 2026-09-15

模型调用一旦进入 Agent 的循环流程,偶发的限流、服务过载或网络超时就可能中断整项任务。重试机制看似只是重新发送请求,实际却要同时判断错误是否可恢复、等待多久以及何时停止。处理不当不仅无法恢复任务,还可能造成无效等待、重复计费和集中请求冲击。

上一篇扒了工具调用,那是 Agent 的「手」。但手一伸出去,就有可能会碰到失败——模型 API 限流、过载、欠费、网络断。

前言

Agent 每一轮的思考,都要真金白银地调一次 LLM API。而 LLM API 是比较常出现的「不稳定」:限流、过载、超时、欠费……要是有一个没处理好,Agent 要么当场崩溃,要么就卡在原地浪费 token。

好在这些厂商的官方文档,把「失败之后怎么办」讲得很清楚。这篇就把 OpenAI、Anthropic、AWS 三家的文档串起来,给你一套「重试」的正确姿势。

核心是以下三个问题:

  1. 该不该重试?——不是所有失败都配重试。
  2. 等多久再试?——先读响应头,读不到再退避。
  3. 重试几次就放弃?——厂商 SDK 的默认值是一份参考答案。

一、该不该重试:先分清你撞的是哪种「失败」

这是重试的第一性原理:重试只对「暂时性」的错误有意义。 如果你本来就错了,再试一万次还是错。

OpenAI 和 Anthropic 的文档,把失败清清楚楚分成了几类:

  • 429(限流):你自己的额度用超了——请求太快,RPM(每分钟请求数)或 TPM(每分钟 token 数)爆了。这种「过一会儿额度就恢复」,值得重试。
  • 529(过载)对方自己忙不过来了(Anthropic 把这种错误叫 overloaded_error),跟你的额度无关。这种也值得重试,但最好考虑换一家。
  • 5xx:服务器暂时抽风,值得重试。
  • 4xx(400 / 401 / 404…):你的请求本身有问题——鉴权失败、参数不合法。这类永不重试。

取舍点:最容易被忽略的一个坑,藏在「429」这个码本身里——它有两种完全不同的成因。OpenAI 文档明确区分了:

  • rate limit exceeded(速度问题):请求太快了,退避有用。
  • insufficient_quota(欠费问题):钱花完了,退避没用

Anthropic 文档也有同样的警告:如果 429 的提示是「This request would exceed your account's monthly spend limit」(超出月消费上限),那它不是暂时性错误——有人实测对这类 429 做退避重试,会白等 40~50 分钟。所以重试之前,一定要看错误体,把「限流」和「欠费」分开:前者退避,后者直接抛给用户或者切换供应商。

二、等多久:先读响应头,别瞎猜

确定了「该重试」,下一个问题是「什么时候再试」。这里官方文档给了个很反直觉的答案:先读响应头,而不是自己猜。

429 响应里,厂商会直接告诉你「什么时候可以再试」:

  • OpenAI 返回 Retry-After / retry-after-ms,以及 x-ratelimit-remaining-*(你各个维度的额度还剩多少)。
  • Anthropic 返回 retry-after: <秒>,以及 anthropic-ratelimit-requests-*anthropic-ratelimit-tokens-*(哪个维度爆了、什么时候重置)。

取舍点:为什么「读头」优于「盲猜」?因为你自己的退避公式,永远只是估计;而响应头是服务器亲口告诉你的准确时间。文档推荐的 header-first 策略是:拿到 retry-after,就等那个秒数(再加一点点随机抖动),然后重试。只有当头缺失、或者解析不出来时,才回退到下面说的指数退避。有精确答案时用精确答案,没有时才用经验公式——这本身就是一种取舍。

三、指数退避 + 抖动:兜底方案和它的「为什么」

响应头不是每次都有,所以兜底的通用算法是指数退避(exponential backoff):每次等待时间翻倍。Anthropic 的 SDK 就是这么做的——0.5s → 1s → 2s → 4s → 8s,封顶,并且叠加随机抖动。

这个算法是 AWS 在《Exponential Backoff and Jitter》里写清楚的老智慧,现在 OpenAI、Anthropic 的文档和 SDK 都在用。它有两点值得记:

1. 为什么是「指数」,不是「固定」? 因为失败的大概率原因是对方过载。指数退避给了服务器喘息的时间:请求间隔越拉越大,压力慢慢降下来。固定间隔等于每隔固定时间就有人来敲门,服务器永远缓不过来。

2. 为什么要加随机抖动(jitter)? 指数退避是确定性的——如果一百个 Agent 都按同一个公式退避,它们的重试时刻还是同时的,会把服务器又「打」一遍,这就是惊群效应(thundering herd)。加一点随机抖动(文档建议是等待时间的 0~10%,或 ±25%),把重试时刻打散成一片稀疏的点,压力就摊平了。三家文档都明确建议加 jitter,原因就在这。

四、重试几次就放弃:厂商 SDK 的默认值是一份「参考答案」

有退避还不够,得有上限,否则就变成无限循环了。这个上限到底设多少?不妨先看看大家怎么处理——看厂商 SDK 的默认值

  • OpenAI 官方 SDK 对 429 会自动重试,默认 maxRetries: 2,可调。
  • Anthropic 官方 SDK 对 429 和 ≥500 默认重试,max_retries 默认也是 2

取舍点:为什么两家都默契地把默认值定在 2,而不是 5 或 10?因为每次重试都真金白银地烧 token——Anthropic 文档特别提醒「Retries cost tokens」,重试一次,前面那次失败的 token 照样计费。所以默认要保守:2 次足够覆盖「服务器抽风几秒」这种常见故障,又不至于让任务在一条死路上烧钱。你自己的 Agent 也可以参考这个数字——低频关键任务可以上调到 3~5,但别无脑堆。

五、最容易踩的坑:把「欠费」当「限流」去退避

最后补一个文档里反复强调的坑,因为它太常见了。

重试逻辑一旦写死「遇到 429 就退避」,就会出事故——因为不是每个 429 都是限流。前面说的欠费、月消费上限,也返回 429,但退避对它们完全没用,反而会让 Agent 卡在原地等上几十分钟。

所以给的完整姿势是:重试之前先分类——

限流 / 过载(暂时性的)→ 读 retry-after 头、退避重试; 欠费 / 配额(不是暂时性的)→ 立刻失败,切换供应商或抛给用户。

一句话:退避治得了「快」,治不了「穷」。

结语

把三家官方文档串起来,重试其实是一套清晰的决策链:

先分类(限流 / 过载 vs 欠费 / 4xx)→ 读响应头(有 retry-after 就用它)→ 头没有就指数退避 + 抖动(防惊群)→ 2 次封顶(别烧钱)。

少了任何一环,要么白等、要么白烧钱、要么把服务器打挂。而这套链背后,藏着 Agent 工程的一个通用心法:失败是常态,所以「怎么失败得优雅」比「怎么成功」更见功力。


参考:

  • OpenAI - How can I solve 429 Too Many Requests errors
  • Anthropic SDK(官方仓库)- 重试行为说明
  • AWS - Exponential Backoff and Jitter

相关文章

精彩推荐