上周五晚上十一点半,我盯着终端里刷出的第 47 个 429 Too Many Requests,突然觉得自己这半年跟 AI API 打交道的经历可以出本书了。
年初开始做一个多模型对话产品,OpenAI、Claude、DeepSeek、Gemini 全接了一遍。踩的坑比写的业务代码还多。
429 Too Many Requests
AI API 报错排行榜常年第一。不管你用哪家,早晚会碰到。
关键是先搞清楚 429 到底在限什么。错误响应里一般有个 type 字段,标注 tokens 或 requests。前者是你每分钟消耗的 token 数(TPM)超了,后者是请求次数(RPM)超了。治法完全不一样。
RPM 超限,说明你短时间内发了太多请求。我之前写了个脚本批量给文档生成摘要,循环里直接 await 调接口,几十个请求一秒全打过去,瞬间 429。
解法就是加间隔。但别用固定的 sleep(1),用指数退避:
第 1 次重试等 1 秒
第 2 次等 2 秒
第 3 次等 4 秒
再加点随机抖动(jitter),防止多个客户端同时重试撞车。
TPM 超限隐蔽一点。你可能每分钟才发 3 个请求,但每个请求带了一整篇论文做上下文,token 数直接拉满。把不必要的上下文扔掉,或者做摘要后再喂给模型。
顺便说一句,Claude API 的 prompt caching 很好用,命中缓存的 token 不算进 TPM 限额。如果你反复用相同的 system prompt,有效吞吐量能翻好几倍。
401 Unauthorized
"API Key 不对呗,换一个就行了。"我以前也这么想。
直到花了两个小时排查一个 401,最后发现是环境变量里的 key 前面多了一个不可见的 Unicode 空格。从配置文件复制粘贴的时候带进去的,肉眼根本看不出来。
401 排查我现在有一套固定流程:
- 看 key 格式对不对。OpenAI 的以
sk-开头,Claude 的以sk-ant-api03-开头,格式都不对说明填错了位置 - 去对应平台的 dashboard 看 key 状态,有没有过期或被撤销
- 把 key 打印出来看长度,排查不可见字符
- 确认环境变量加载顺序,
.env.local会覆盖.env,改的是不是实际生效的那个文件 - 最容易忽略的:代理/中转地址和 key 是不是配套。用了第三方中转的 base_url,key 也得是那个平台发的,不能混着来
第 5 条是真正的重灾区。很多人用了中转服务但 key 还是填的官方的,或者反过来,报错信息一模一样都是 401,但原因天差地别。
Timeout
在国内直连海外 AI API,超时是家常便饭。
我测过,直连 OpenAI API 的平均延迟在 3-5 秒,这还是运气好的时候。高峰期直接 30 秒起步,然后就 timeout 了。
几个实测有效的办法。
第一个是开 streaming 模式。不会减少总生成时间,但首字节响应(TTFT)能从好几秒压到 1 秒以内,用户体感完全不一样。而且 streaming 模式下连接不容易被中间网络设备掐断。
然后是调超时时间。默认 30 秒对 AI 接口太短了,一个复杂的 Claude Opus 请求光生成就可能要 20 秒。我一般设 120 秒。
最后,也是效果最明显的,用国内有节点的 API 服务。我自己的项目后来切到 ofox.ai 这种聚合平台之后,超时率从 15% 直接降到不到 1%,走的是优化过的线路,不用自己折腾网络那些事。
529 Overloaded
这个错误码是 Anthropic 独创的,意思是他们服务器过载了,跟你没关系。
烦就烦在这里,你没做错任何事,它就是不给你返回结果。北京时间晚上到半夜(对应美国白天)碰到的概率更高。
碰到 529 我一般先去 status.anthropic.com 看一眼有没有全局故障公告。如果没有,做指数退避重试,等 30 秒到 1 分钟通常就能恢复。
但说真的,靠谱的做法是关键业务路径设个 fallback 模型。Claude 挂了自动切 GPT 或 DeepSeek。任何单一模型都有挂的时候,生产环境不该把鸡蛋放一个篮子里。
500 Internal Server Error
500 就是告诉你"后端炸了",但不告诉你为什么。
我遇到过的触发场景:prompt 里有特殊字符(某些 emoji 组合)导致模型解析失败;请求体太大超过了上限;还有一次是给不支持 function calling 的模型传了 tools 参数。
排查思路就是排除法,先把请求精简到最小可复现版本,一项一项加回来,看加到哪项就炸。笨办法,但管用。
model not found
看着低级,但频率比你想象的高。
各家模型命名规则完全不统一。gpt-4o 和 gpt-5.4 长得就不像一个系列。claude-sonnet-4-6-20250514 带日期后缀的更容易打错。DeepSeek 叫 deepseek-chat,Gemini 叫 gemini-3.1-flash。
建议统一用常量管理模型名,别在代码里到处散落字符串。
一开始我什么都自己搞,管 key、做重试、搭代理、写 failover,后来发现这些东西加起来的工作量比业务逻辑还大。切到 API 聚合服务之后轻松了不少,429 有平台层面的限速管控,超时有优化线路,模型挂了有自动切换。早知道就不自己造轮子了。
有什么其他奇葩报错,评论区聊,说不定我也遇到过。