Claude API 的报错大致分三类:凭证与请求格式、限流与容量、上下文长度。处理顺序应该是先看 HTTP 状态码和错误类型,再看请求 ID,最后才改提示词。顺序反了,很容易把配置问题当成模型问题。
本文按 401、429、529 overloaded、上下文超限四类拆开,给出原因、排查步骤和可复用的退避代码。模型与价格以站内模型价格为准。
说明:Anthropic、Claude 是其权利人的商标。错误类型和接口行为可能随版本调整,本文以 2026 年 10 月的常见情况为例,最终以官方文档为准。
一、先看状态码,不要先改提示词
| 状态码 | 错误类型 | 常见含义 | 是否重试 |
|---|---|---|---|
| 400 | invalid_request_error | 参数、格式或上下文长度有问题 | 改请求后重试 |
| 401 | authentication_error | Key 缺失、错误或失效 | 不重试,先修凭证 |
| 403 | permission_error | Key 无模型或项目权限 | 不重试,查权限 |
| 404 | not_found_error | 路径或模型名错误 | 不重试,查文档 |
| 413 | request_too_large | 请求体过大 | 拆分后重试 |
| 429 | rate_limit_error | 频率、并发或 Token 超限 | 退避后重试 |
| 500 | api_error | 服务端内部错误 | 退避后重试 |
| 529 | overloaded_error | 服务端过载 | 退避后重试 |
响应头里的 request-id 要保留。找服务方排查时,一个请求 ID 比十张截图有用。日志里至少记录时间、状态码、错误类型、模型名和请求 ID,不要记录完整 Key 和敏感内容。
二、401:先查请求头,再查 Key
401 表示身份没有通过验证,和余额、模型能力无关。按下面顺序排查:
- 是否用
x-api-key,而不是Authorization: Bearer。Claude Messages API 的鉴权头不是 Bearer。 - 是否带
anthropic-version: 2023-06-01。版本头缺失有时会表现成 400,但先补齐更省事。 - Key 前后是否有空格、换行或多余引号。从聊天窗口复制最常见这个问题。
- 环境变量是否真的加载。可以只看前缀,不要把完整 Key 打印到日志。
- Key 是否被吊销、是否属于当前组织或项目。
- Base URL 是否指向正确环境,路径是否为
/v1/messages。
export ANTHROPIC_API_KEY="sk-你的密钥"
curl "https://ai.zhongshangqihang.com/v1/messages" \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "content-type: application/json" \
-d '{
"model": "claude-sonnet-5-5",
"max_tokens": 64,
"messages": [{"role": "user", "content": "只回复 OK"}]
}'
这条命令返回 200,说明 Key、Base URL 和模型名三项都通。如果还报 401,可以把同一个 Key 换到另一个入口再测一次,区分是 Key 本身的问题,还是网关配置或网络层的问题。模型名以模型价格为准。
三、429:限流不是“余额不足”
429 表示请求超过了速率或配额限制。常见触发场景:
- 每分钟请求数或 Token 数超限。
- 并发突增,短时间打满配额。
- 多个服务共用一把 Key,互相挤占额度。
- 重试没有退避,越失败越发,形成重试风暴。
- 长输出占用了较多输出 Token,留给并发的空间变小。
| 现象 | 可能原因 | 处理 |
|---|---|---|
| 高峰期集中 429 | 流量脉冲 | 排队、平滑发送 |
| 单 Key 多服务 429 | 配额被共享 | 按项目拆 Key |
| 重试后更严重 | 无退避重试 | 指数退避加抖动 |
| 长请求先 429 | 输出 Token 占用高 | 降 max_tokens 或并发 |
先看响应里的 retry-after(如果有),再决定等多久。SDK 会区分 RateLimitError 和普通 APIStatusError,用类型判断,不要用字符串匹配错误消息。
import random
import time
from anthropic import Anthropic, APIStatusError, RateLimitError
client = Anthropic()
def ask(prompt: str, retries: int = 4) -> str:
for attempt in range(retries):
try:
resp = client.messages.create(
model="claude-sonnet-5-5",
max_tokens=1024,
messages=[{"role": "user", "content": prompt}],
)
return resp.content[0].text
except RateLimitError:
wait = min(2 ** attempt, 20) + random.random()
print(f"429,第 {attempt + 1} 次重试,等待 {wait:.1f}s")
time.sleep(wait)
except APIStatusError as exc:
if exc.status_code >= 500:
wait = min(2 ** attempt, 20) + random.random()
print(f"{exc.status_code},{wait:.1f}s 后重试")
time.sleep(wait)
continue
raise
raise RuntimeError("重试次数已用完")
重试只适合瞬时错误。已经产生副作用的业务,先用幂等键或状态检查确认是否执行过,再决定要不要重发。
四、529 overloaded:服务端过载,不是你的配额
529 的 overloaded_error 表示服务端当前负载过高,通常和你自己的用量无关。它和 429 的处理方式不同:429 要先看自己的并发和配额,529 要先看服务状态并降低压力。
- 确认错误类型是
overloaded_error,不要把它当成 Key 失效。 - 保留
request-id和发生时间,便于服务方定位。 - 指数退避加随机抖动,设置最大重试次数,不要固定间隔猛重试。
- 降低并发、排队削峰,必要时暂时关闭非核心任务。
- 准备降级模型或备用通道,但要在业务上允许输出质量变化。
- 如果持续时间超出预期,联系服务方并附上请求 ID。
固定 1 秒重试会把小故障放大成雪崩。重试策略要有上限,也要有告警,不能无限循环。
五、上下文超限:先量,再拆
上下文超限通常返回 400 invalid_request_error,错误消息里会出现 prompt is too long。原因不是模型坏了,而是输入加输出的预算超过了模型的上下文窗口。
常见来源包括:历史消息没有裁剪、工具返回了整段日志、文档整本塞入、图片过多、system prompt 太长。处理顺序是:
- 请求前用
count_tokens量化输入,不要凭字数猜。 - 裁剪最早的历史,只保留 system、最近几轮和一份摘要。
- 文档先用检索召回相关片段,不要整库放入。
- 长文档按章节拆分,分段处理后再合并结果。
- 压缩工具输出,只返回必要字段,不要把完整响应反复带回。
- 给输出留空间。
max_tokens是输出上限,但输入加输出要一起装进上下文。
import os
from anthropic import Anthropic
client = Anthropic()
MODEL = "claude-sonnet-5-5"
LIMIT = int(os.environ.get("CONTEXT_BUDGET", "200000")) # 自设预算,不是模型上限
def fit_messages(messages):
while client.messages.count_tokens(model=MODEL, messages=messages).input_tokens > LIMIT:
if len(messages) <= 2:
raise ValueError("单条消息已超过预算,需要拆分文档")
messages = messages[2:] # 去掉最早的一轮 user/assistant
return messages
这里的 LIMIT 是团队自设的预算,不是模型规格。把预算设得比模型上限低一些,能给输出和工具调用留出余量。
六、一张排查顺序表
- 记录状态码、错误类型、
request-id、模型名和发生时间。 - 401、403 查凭证和权限;404 查路径和模型名。
- 400 查参数、上下文长度、图片格式和请求体大小。
- 429 查配额、并发、共享 Key 和重试风暴。
- 529 查服务状态,退避、降并发、准备降级。
- 500 先退避重试,持续出现再找服务方并附请求 ID。
- 每次故障后补监控和告警,不要靠用户反馈才发现。
常见问题
429 和 529 有什么区别?
429 是你的请求超过了速率或配额,应该先查自己的并发、Key 和用量;529 是服务端过载,应该退避、降并发并查看服务状态。两者都需要重试,但排查方向不同。
为什么加了重试还是失败?
可能没有退避、并发太高、多个服务共用一把 Key,或者请求本身就是 400。重试只解决瞬时错误,解决不了参数错误和权限问题。
prompt is too long 是模型坏了吗?
不是。它表示输入超过了上下文窗口。先用 count_tokens 量化,再裁剪历史、拆分文档或做检索,不要继续加提示词。
应该重试几次?
没有统一数字,按业务容忍度设置上限,例如 3–5 次,超过就降级或告警。重试间隔要递增并带随机抖动,避免同时重发。
网关报错和官方报错怎么区分?
先看错误类型和 request-id,再用同一条请求分别打官方入口和网关入口。能快速区分是 Key、网络、网关配置还是上游服务的问题。
下一步
先在中商起航 AI 网关创建测试 Key,把 401、429、529 和上下文超限各演练一次,再接入生产监控。模型可用性与价格以模型价格为准。
相关阅读:
