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 表示身份没有通过验证,和余额、模型能力无关。按下面顺序排查:

  1. 是否用 x-api-key,而不是 Authorization: Bearer。Claude Messages API 的鉴权头不是 Bearer。
  2. 是否带 anthropic-version: 2023-06-01。版本头缺失有时会表现成 400,但先补齐更省事。
  3. Key 前后是否有空格、换行或多余引号。从聊天窗口复制最常见这个问题。
  4. 环境变量是否真的加载。可以只看前缀,不要把完整 Key 打印到日志。
  5. Key 是否被吊销、是否属于当前组织或项目。
  6. 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 要先看服务状态并降低压力。

  1. 确认错误类型是 overloaded_error,不要把它当成 Key 失效。
  2. 保留 request-id 和发生时间,便于服务方定位。
  3. 指数退避加随机抖动,设置最大重试次数,不要固定间隔猛重试。
  4. 降低并发、排队削峰,必要时暂时关闭非核心任务。
  5. 准备降级模型或备用通道,但要在业务上允许输出质量变化。
  6. 如果持续时间超出预期,联系服务方并附上请求 ID。

固定 1 秒重试会把小故障放大成雪崩。重试策略要有上限,也要有告警,不能无限循环。

五、上下文超限:先量,再拆

上下文超限通常返回 400 invalid_request_error,错误消息里会出现 prompt is too long。原因不是模型坏了,而是输入加输出的预算超过了模型的上下文窗口。

常见来源包括:历史消息没有裁剪、工具返回了整段日志、文档整本塞入、图片过多、system prompt 太长。处理顺序是:

  1. 请求前用 count_tokens 量化输入,不要凭字数猜。
  2. 裁剪最早的历史,只保留 system、最近几轮和一份摘要。
  3. 文档先用检索召回相关片段,不要整库放入。
  4. 长文档按章节拆分,分段处理后再合并结果。
  5. 压缩工具输出,只返回必要字段,不要把完整响应反复带回。
  6. 给输出留空间。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 是团队自设的预算,不是模型规格。把预算设得比模型上限低一些,能给输出和工具调用留出余量。

六、一张排查顺序表

  1. 记录状态码、错误类型、request-id、模型名和发生时间。
  2. 401、403 查凭证和权限;404 查路径和模型名。
  3. 400 查参数、上下文长度、图片格式和请求体大小。
  4. 429 查配额、并发、共享 Key 和重试风暴。
  5. 529 查服务状态,退避、降并发、准备降级。
  6. 500 先退避重试,持续出现再找服务方并附请求 ID。
  7. 每次故障后补监控和告警,不要靠用户反馈才发现。

常见问题

429 和 529 有什么区别?

429 是你的请求超过了速率或配额,应该先查自己的并发、Key 和用量;529 是服务端过载,应该退避、降并发并查看服务状态。两者都需要重试,但排查方向不同。

为什么加了重试还是失败?

可能没有退避、并发太高、多个服务共用一把 Key,或者请求本身就是 400。重试只解决瞬时错误,解决不了参数错误和权限问题。

prompt is too long 是模型坏了吗?

不是。它表示输入超过了上下文窗口。先用 count_tokens 量化,再裁剪历史、拆分文档或做检索,不要继续加提示词。

应该重试几次?

没有统一数字,按业务容忍度设置上限,例如 3–5 次,超过就降级或告警。重试间隔要递增并带随机抖动,避免同时重发。

网关报错和官方报错怎么区分?

先看错误类型和 request-id,再用同一条请求分别打官方入口和网关入口。能快速区分是 Key、网络、网关配置还是上游服务的问题。

下一步

先在中商起航 AI 网关创建测试 Key,把 401、429、529 和上下文超限各演练一次,再接入生产监控。模型可用性与价格以模型价格为准。

相关阅读: