Claude 429 反复 rate limit 死循环:怎么停、怎么修

Claude 一直循环报 429 rate_limit_exceeded——读 retry-after、限制并发、分清 429 和 529、守住你那档的 RPM/ITPM/OTPM。

你在跑一个用 Claude API 的脚本——批量翻译 200 篇文章,或者用 agent 自动处理客服工单——结果跑到一半就开始反复报 429 rate_limit_exceeded。你那套出错就重试的逻辑只会一直猛敲,把坑越挖越深。又或者你在 Claude Code 里让 agent 跑大任务,它自己撞墙也停不下来,越撞越糟。

最快的修法:现在先把循环停掉,等限流窗口过去,重启时retry-after header,别用固定的 sleep(),并且按你那一档限制并发(截至 2026 年 6 月,Tier 1 只有 50 RPM)。如果你根本没在用 API——你是在 Claude.ai 网页版或 Claude Code 的 Pro/Max 套餐里——那撞的是订阅用量上限,不是 API rate limit,唯一的办法是等 reset(见下文第 6 类原因和套餐上限的修复路径)。

先确认你修的是对的问题。两个 HTTP 状态码长得像,但处理方式完全不同:

状态码error.type含义该怎么做
429rate_limit_error你的账号超了某个限制(RPM、ITPM 或 OTPM)遵守 retry-after,自己限速
529overloaded_errorAnthropic 的 API 全站过载带抖动退避;可考虑切到别的模型/服务商

本文讲的是 429。如果你看到的是 529 overloaded_error,那是服务端流量问题,不是你代码的问题——去看 Anthropic 状态页,带退避重试就行,放宽并发上限没用。

Claude 的限流到底怎么算(截至 2026 年 6 月)

Messages API 对每一类模型分别限三个维度,而不是一个笼统的 “TPM”:

  • RPM——每分钟请求数
  • ITPM——每分钟输入 token 数(多数模型只算未命中缓存的输入)
  • OTPM——每分钟输出 token 数

任意一个超了都会返回 429。每个新组织默认起步的 Tier 1 卡得很紧。当前标准上限:

Tier 1 模型(2026 年 6 月)RPMITPMOTPM
Claude Sonnet 4.x5030,0008,000
Claude Haiku 4.55050,00010,000
Claude Opus 4.x50500,00080,000

有两个点最容易让人栽跟头:

  1. Sonnet 的 Tier 1 ITPM 只有 30,000。 单个 30K token 的请求就能吃掉整整一分钟的输入额度。Opus 的 ITPM 高得多(500K),因为它走的是另一套更宽松的计量。
  2. 命中缓存的输入不算 ITPM(多数模型)。cache_read_input_tokens 不计入;只有 input_tokens(最后一个 cache breakpoint 之后的部分)加上 cache_creation_input_tokens 才算。缓存命中率到 80% 时,同样的 ITPM 上限能放进大约 5 倍的总输入量。

你可以从每一次调用(不只是 429)的响应 header 读到自己的实时数字,也可以在 Console 的 Limits 页面看。

常见原因

按命中率从高到低排。

1. 死循环重试,不看 retry-after

每个 429 响应都带一个 retry-after header(单位秒)。如果你拿到 429 就立刻 retry,每次都被拒,在 acceleration 限流下窗口还可能继续拉长。这个 header 是权威值:超 RPM 时它对齐 anthropic-ratelimit-requests-reset,超 token 限制时对齐 anthropic-ratelimit-tokens-reset(都是 RFC 3339 时间戳)。

如何判断:你的重试是固定 sleep(1),而不是读 retry-after——这就是 bug。

2. 并发扇出太大,瞬时打爆 RPM

Promise.all 同时发 50 个请求,差不多在一秒内就把 50 个全打出去了。哪怕你每分钟的平均没超,瞬时这一下也会触发——因为 API 用 token bucket 算法限 RPM,50 RPM 在突发下接近 “每 ~1.2 秒只允许 1 个请求”。

如何判断:你在用 Promise.all / 线程池,且没有并发上限。

3. 长 context 把 ITPM 用爆

Tier 1 Sonnet 的 ITPM 是 30,000。5 个并发、每个 30K 输入 token = 一分钟 150K,超 5 倍。输出还另有一个 8,000 OTPM 的上限。

如何判断:算一下 单请求输入 token × 每分钟请求数,对照 Anthropic 限流文档里你那一档的 ITPM。如果你反复带一大段 context(系统提示、长文档),看看用 prompt caching 能不能把你压到线下。

4. Agent 不知道停手

Claude Code 或自定义 agent 看到 tool 返回 429,把它当成”暂时不可用”继续 retry——没有明确的失败处理就会无限拖下去。

如何判断:agent 日志里短时间内 429 出现超过 5 次。

5. 多个 client 共用一个 API key

后端、cron、CI 都用同一个 key。每个都觉得自己那份够用,加起来就超了组织级上限(限流按组织算,设了 workspace 限制的话也按 workspace 算)。

如何判断:Console 的 Usage 页面显示一个 key 被多个来源 IP 打,或者你在 Usage 图表里看到的总 RPM 高于任何单个 service 的预期。

6. Claude Code / Claude.ai 套餐上限(不是 API 限流)

如果你是在 Claude.ai 网页版或 Claude Code 的 Pro($20)或 Max($100 / $200) 套餐里,那你根本没碰到 API rate limit——你撞的是订阅用量上限。截至 2026 年 6 月有两层:一个5 小时滚动会话窗口(计数从你的第一条消息开始,而不是整点),外加一个每周滚动上限。高强度模型(Opus 4.7)消耗每周额度比 Sonnet 4.6 快得多。撞到每周上限,就算 5 小时窗口还有余量也会被锁。

如何判断:UI 上出现类似 “You’ve reached your usage limit, resets in X hours.”,或者在 Claude Code 里跑 /usage / /status 看到 weekly limit 到了 100%。

最短修复路径(API)

Step 1:先停循环,退避

ps aux | grep my-script
kill -9 <PID>

或者在 Claude Code 里 Ctrl+C 中断 agent。别马上重启。token bucket 是持续回补的,停一会儿就能恢复一些余量;等 retry-after(或 anthropic-ratelimit-*-reset 时间戳)过去再排查。

Step 2:遵守 retry-after,指数退避作为兜底

import time
import anthropic
from anthropic import RateLimitError

client = anthropic.Anthropic()

def call_with_backoff(prompt, max_retries=5):
    for attempt in range(max_retries):
        try:
            return client.messages.create(
                model="claude-sonnet-4-6",
                max_tokens=1024,
                messages=[{"role": "user", "content": prompt}],
            )
        except RateLimitError as e:
            # 优先信 header,没有时退回指数退避
            wait = int(e.response.headers.get("retry-after", 2 ** attempt))
            print(f"Rate limited, sleeping {wait}s")
            time.sleep(wait)
    raise Exception("Max retries exceeded")

关键:retry-after,别写死 sleep。退回 2 ** attempt 时加上 ±20% 抖动,避免多个 worker 整齐划一地同时重试(“惊群效应”)。

注意 SDK 本身就会自动重试 4295xx(默认 max_retries=2,约 1-2 秒指数退避)。但历史上 SDK 并自动重试 529 overloaded_error,所以如果你碰到 529,要自己加处理或做 failover。

Step 3:限制并发

import asyncio
sem = asyncio.Semaphore(3)  # 同时最多 3 个

async def safe_call(prompt):
    async with sem:
        return await call_with_backoff(prompt)

经验法则:在飞的并发数保持在 RPM / 60 左右及以下,就不会在一秒内冲破额度。Tier 1(50 RPM)意味着只能开几个 worker,不是五十个。

Step 4:把多个小请求合并成一个

把 10 个小翻译合并成 1 个 prompt,让它一次返回 10 个结果:

翻译下面 10 段英文为中文。
按顺序返回一个含 10 个字符串的 JSON 数组:
[
  "text 1",
  "text 2",
  ...
]

输出 token 仍占 OTPM,但你的 RPM 大约除以 10——而 RPM 通常正是 Tier 1 上卡你的那个维度。

Step 5:用缓存、换轻模型、或用 Batch API

  • Prompt caching:如果每个请求都共享一大段系统提示或文档,加一个 cache breakpoint。多数模型上缓存读取不算 ITPM,计费也只按输入价的约 10%。
  • 换轻模型:不需要 Opus 的活儿 → Sonnet 4.6 或 Haiku 4.5(Haiku 的 Tier 1 ITPM/OTPM 更高)。
  • Message Batches API:异步、最多 24 小时完成、有独立的队列限额(不和实时流量抢),而且便宜 50%。批量、不在乎延迟的任务首选它。

Step 6:升 tier 或拆 key

随着累计充值跨过阈值,tier 会自动往上走:Tier 1 在 $5、Tier 2 在 $40、Tier 3 在 $200、Tier 4 在 $400(均为累计值,截至 2026 年 6 月)。每升一档,RPM/ITPM/OTPM 都翻倍式提升。production 场景就去 Limits 页面充值升档,或联系 sales 申请定制上限。短期方案:给每个 service 用独立 API key(或独立 workspace 并设 workspace 限制),让一个任务饿不死其他任务。

最短修复路径(Claude.ai / Claude Code 套餐上限)

这不是 API 限流,退避代码帮不上忙。你的选项:

  1. 等 reset。 在 Claude Code 里跑 /usage(或 /status),或在 Claude.ai 打开 Settings > Usage,看每个限制的确切 reset 时间。5 小时窗口在你第一条消息之后 5 小时重置;每周上限按滚动 7 天重置。
  2. 换便宜模型。 在 Claude Code 里从 Opus 降到 Sonnet 4.6,每周额度能撑好几倍。
  3. 升套餐(Pro → Max 5x → Max 20x),如果你经常撞上限。
  4. 把重活搬到 API、走按量付费,这样用的是上面那套 RPM/ITPM/OTPM 限制,而不是订阅上限。

怎么确认修好了

  • 重跑任务,在满并发下连续观察一整分钟,日志里 429 为零。
  • 每次调用后记录 anthropic-ratelimit-requests-remaininganthropic-ratelimit-input-tokens-remaining;只要两者都大于 0,就说明还有余量。
  • 跟踪一天的 429 比例。带退避后低于约 1% 算健康;一直更高就该升 tier 或降请求量。

FAQ

429529 是一回事吗? 不是。429 rate_limit_error你的账号撞了限制——遵守 retry-after529 overloaded_errorAnthropic 的服务器全站过载,跟你的用量无关。两者都是”稍后重试”,但 529 还应该去看 status.anthropic.com 并考虑 failover。

我每分钟平均明明远低于上限,为什么还被限流? 突发。API 用 token bucket,按短窗口判定,所以一秒内发 50 个请求,就算分钟平均没超也会触发 50 RPM 限制。把并发压到大约 RPM / 60

输出 token 也算限额吗? 算——有一个单独的 OTPM(每分钟输出 token)限制,和输入分开。Tier 1 Sonnet 是 8,000 OTPM。设大的 max_tokens 本身不耗 OTPM(只有实际生成的 token 才算),所以放心调高 max_tokens

Prompt caching 对限流有帮助吗? 有。多数模型上 cache_read_input_tokens 不算 ITPM,所以把一大段共享的系统提示或文档缓存起来,能在不升 tier 的情况下大幅抬高你的有效输入吞吐。

我是在 Claude Code 里,不是 API,为什么被限流? 你撞的是订阅上限(5 小时滚动窗口和/或每周上限),不是 API 限流。跑 /usage 看 reset 时间,换到 Sonnet 4.6 拉长额度,或升套餐。改代码没用。

重试更快能更早解锁吗? 正相反。在 retry-after 到期前就重试只会换来更多 429,在 acceleration 限流下还可能延长封锁。等 header 过去再继续。

相关阅读

标签: #Claude #排查 #排查