Claude API 报错 429 怎么办?4 种方案实测,最后一种改一行代码就搞定

张开发
2026/4/20 6:40:16 15 分钟阅读

分享文章

Claude API 报错 429 怎么办?4 种方案实测,最后一种改一行代码就搞定
上周赶一个 AI 客服的 DemoClaude Opus 4.6 效果确实不错结果跑到一半控制台疯狂刷429 Too Many Requests整个服务直接瘫了。我盯着报错信息坐了半小时心态差点崩——Demo 明天就要给老板看限流了我能怎么办直接回答Claude API 报错 429是你的请求触发了 Anthropic 的速率限制。解决方向有四个客户端指数退避重试、申请提升官方配额、本地请求队列削峰、换聚合 API 平台绕开单一供应商的限流天花板。四种我都试了下面把完整踩坑过程和代码贴出来。先说结论方案实现难度见效速度适合场景我的评价指数退避重试⭐ 低即时偶发 429流量不大治标不治本申请提升配额⭐ 低1-3 天长期稳定的高流量项目得等急不来本地请求队列⭐⭐⭐ 高即时自建服务想精细控制重但稳聚合 API 平台⭐ 低即时想省事、多模型切换我最终的选择为什么会报 429很多人看到 429 就慌其实 Anthropic 的限流策略是公开的。2026 年的速率限制分三个维度RPMRequests Per Minute每分钟请求数TPMTokens Per Minute每分钟 Token 吞吐量TPDTokens Per Day每天 Token 总量不同 Tier 的限制差异很大。免费试用 Tier 1 的 RPM 才 50Tier 4 可以到 4000。大部分人踩坑都是因为还在 Tier 1根本扛不住并发。429 响应头里会带retry-after字段告诉你多少秒后可以重试——这个信息很多人直接忽略了。RPM 未超RPM 超限读取等待时间忽略直接重试你的请求Anthropic 网关正常响应 200返回 429retry-after 字段等待后重试继续 429 ❌方案一指数退避重试基础必须有不管你最终用哪种方案指数退避都应该作为兜底逻辑写进代码。importtimeimportanthropic clientanthropic.Anthropic(api_keyyour-api-key)defcall_claude_with_retry(prompt:str,max_retries:int5):带指数退避的 Claude API 调用forattemptinrange(max_retries):try:responseclient.messages.create(modelclaude-sonnet-4-20250514,max_tokens1024,messages[{role:user,content:prompt}])returnresponse.content[0].textexceptanthropic.RateLimitErrorase:ifattemptmax_retries-1:raise# 最后一次直接抛出# 优先读 retry-after没有就用指数退避retry_aftergetattr(e,response,None)ifretry_afterandhasattr(retry_after,headers):wait_timeint(retry_after.headers.get(retry-after,2**attempt))else:wait_time2**attempt# 1, 2, 4, 8, 16 秒# 加随机抖动避免多个客户端同时重试惊群效应importrandom wait_timerandom.uniform(0,1)print(f[429] 第{attempt1}次重试等待{wait_time:.1f}s...)time.sleep(wait_time)returnNone# 测试resultcall_claude_with_retry(用一句话解释什么是 Rate Limiting)print(result)偶发的 429 基本能扛住。但如果你是持续高并发——比如我那个客服 DemoQPS 稳定在 20——退避重试只会让延迟越来越高用户体验直线下降。踩坑一开始没加随机抖动5 个并发线程同时退避、同时重试造成更大的瞬时峰值429 反而更频繁。加了random.uniform(0, 1)之后才好。方案二申请提升官方配额没什么技术含量但很多人不知道可以申请。操作路径Anthropic Console → Settings → Limits → Request Increase需要填使用场景描述、预期月消费金额、预期 RPM/TPM 需求。提交后等了 2 天才批下来从 Tier 1 升到 Tier 2RPM 从 50 提到 1000基本够用。但有两个问题第一等不起我 Demo 明天就要第二 Tier 升级跟消费金额挂钩新账号充得少别指望一步到位。方案三本地请求队列削峰在应用层做一个令牌桶或滑动窗口来控制发送速率让请求排队而不是一股脑怼上去。importasyncioimporttimefromcollectionsimportdequefromopenaiimportAsyncOpenAIclassRateLimitedClient:滑动窗口限流器 Claude API 客户端def__init__(self,api_key:str,base_url:str,rpm:int45):self.clientAsyncOpenAI(api_keyapi_key,base_urlbase_url)self.rpmrpm self.windowdeque()# 记录每次请求的时间戳self.lockasyncio.Lock()asyncdef_wait_for_slot(self):等待可用的请求槽位asyncwithself.lock:nowtime.monotonic()# 清理 60 秒之前的记录whileself.windowandself.window[0]now-60:self.window.popleft()iflen(self.window)self.rpm:# 等待最早的请求过期sleep_time60-(now-self.window[0])0.1print(f[限流] 队列已满等待{sleep_time:.1f}s)awaitasyncio.sleep(sleep_time)self.window.append(time.monotonic())asyncdefchat(self,prompt:str,model:strclaude-sonnet-4-20250514):awaitself._wait_for_slot()responseawaitself.client.chat.completions.create(modelmodel,messages[{role:user,content:prompt}],max_tokens512)returnresponse.choices[0].message.content# 使用示例asyncdefmain():clientRateLimitedClient(api_keyyour-key,base_urlhttps://api.anthropic.com/v1,rpm45# 留 10% 余量官方限制 50 就设 45)# 模拟 100 个并发请求tasks[client.chat(f请回答{i}{i} ?)foriinrange(100)]resultsawaitasyncio.gather(*tasks)print(f完成{len(results)}个请求)asyncio.run(main())429 完全消失了。代价是排队后延迟飙升——100 个请求在 RPM45 的限制下最后一个要等 2 分多钟才能发出去。实时对话场景下这个体验不能接受。踩坑一开始用的threading.Lock在 asyncio 环境下死锁了。异步代码必须用asyncio.Lock。写到凌晨 3 点脑子不转犯了这种低级错误。方案四换聚合 API 平台最终方案折腾了前面三种我发现核心矛盾在于单一供应商的速率限制是硬天花板客户端怎么优化都是在天花板下面腾挪。后来同事推荐我试了 ofox.ai一个 AI 模型聚合平台一个 API Key 可以调用 Claude Opus 4.6、GPT-5、Gemini 3、DeepSeek V3 等 50 模型后端做了多供应商冗余Azure、Bedrock、VertexAI 等请求分散到多个供应商的配额池里单点限流的问题自然缓解了。改动量极小换个base_url就行fromopenaiimportOpenAI# 之前直连 Anthropic# client OpenAI(api_keyyour-anthropic-key, base_urlhttps://api.anthropic.com/v1)# 现在走聚合接口clientOpenAI(api_keyyour-ofox-key,base_urlhttps://api.ofox.ai/v1# 兼容 OpenAI 协议)responseclient.chat.completions.create(modelclaude-sonnet-4-20250514,messages[{role:system,content:你是一个客服助手},{role:user,content:我的订单什么时候发货}],max_tokens1024,streamTrue)forchunkinresponse:ifchunk.choices[0].delta.content:print(chunk.choices[0].delta.content,end,flushTrue)跑了一下午压测QPS 20 的情况下没再出现一次 429。延迟大概 300ms比直连 Anthropic 官方还快一点可能跟路由优化有关。支持支付宝按量计费不用提前囤大额度。方案一的指数退避我还是留在代码里了——不管用什么平台兜底重试不能省。几个坑顺手记一下坑 1429 和 529 傻傻分不清Anthropic 除了标准的 429你请求太多还有个 529Anthropic 自己过载了。529 不是你的问题。处理策略不同429 退避重试529 建议直接降级到备用模型。坑 2Streaming 模式下 429 的表现不一样普通请求 429 直接返回错误码streaming 模式有时候连接已经建立了中途才断开SDK 抛的异常类型不一样。我一开始只 catch 了RateLimitError漏掉了APIConnectionError。坑 3并发测试时本地端口耗尽压测开了 200 个并发连接本地端口不够用了macOS 默认临时端口范围比较小。这个跟 429 无关但报错信息容易跟网络超时混淆排查时浪费了不少时间。小结Claude API 429 就是限流按优先级先加指数退避重试——5 分钟搞定基本功评估是否需要提升配额——适合长期项目但要等高并发场景上请求队列——重但稳适合自建基础设施嫌麻烦就用聚合平台——改一行 base_url把限流问题甩给平台方我现在的做法是方案四 方案一聚合平台解决主要问题指数退避兜底极端情况。跑了两周429 再也没出现过。有问题评论区聊。

更多文章