信息层级:【有据可查】= 附官方文档或可信来源链接;【社区共识】= 社区用户普遍经验,未经官方确认;【待考察/推测】= 推测或暂未能核实,请谨慎对待。
1. 先学会看报错的三个层次
【社区共识】只看状态码不够。例如 OpenAI 的 429 既可能是"请求太快",也可能是"额度用完",处理方式完全不同。【有据可查:OpenAI Error codes】
2. 总表:状态码 → 含义 → 能否重试 → 怎么处理
| 状态码 | 通用含义 | 能否直接重试 | 常见原因(AI API 场景) | 处理建议 |
|---|---|---|---|---|
| 400 Bad Request | 请求格式/参数错误 | ❌ | JSON 格式错、字段名不对、模型不支持某参数、协议方言不兼容 | 读错误正文,对照官方文档改请求 |
| 401 Unauthorized | 认证失败 | ❌ | Key 错/过期/被撤销、Header 写错(Bearer 拼写)、用了别家 Key |
检查 Key 与 Authorization 头 |
| 402 Payment Required | 需要付费 | ❌ | 余额不足(如 DeepSeek 明确用 402 表示余额不足) | 充值;不要重试 |
| 403 Forbidden | 无权限 | ❌ | 地区不受支持(OpenAI 用 403 表示不支持的国家/地区)、项目/组织无权访问该模型、权限被拒 | 检查权限、账户状态与地区政策;不要尝试绕过 |
| 404 Not Found | 路径或资源不存在 | ❌ | Base URL 多/少了 /v1、端点拼错、模型已退役 |
核对 URL 与模型 ID |
| 408 / 超时 | 请求超时 | ⚠️ 可有限重试 | 网络不稳、上下文过长、输出过长 | 缩短请求、增加超时、检查网络 |
| 413 Payload Too Large | 请求体过大 | ❌ | 文件/图片/上下文超限 | 压缩、分块 |
| 422 Unprocessable | 参数语义错误 | ❌ | DeepSeek 用 422 表示参数无效 | 按提示修正参数 |
| 429 Too Many Requests | 速率或额度限制 | ⚠️ 看类型 | 请求/Token 速率超限、并发超限;或额度/预算用完 | 速率类:按 Retry-After 指数退避;额度类:不要重试,去充值/调预算 |
| 500 Internal Server Error | 服务端内部错误 | ✅ 有限重试 | 服务端故障 | 退避重试;持续则查官方状态页 |
| 502 / 504 Bad Gateway / Timeout | 网关/上游问题 | ✅ 有限重试 | 中间代理、网关或上游超时 | 检查自建网关/本机代理设置(见 magpie 使用:来源配置、模型切换与恢复 的 127.0.0.1 直连问题) |
| 503 Service Unavailable | 服务暂不可用/过载 | ✅ 有限重试 | OpenAI server_is_overloaded、DeepSeek 服务器繁忙 |
按 Retry-After 稍后重试,准备降级方案 |
| 529 Overloaded(Anthropic) | API 整体过载 | ✅ 有限重试 | Anthropic 全局流量高峰 | 指数退避;非你的账户问题 |
来源:
- OpenAI:Error codes、429 排查
- Anthropic:Claude API errors
- DeepSeek:Error Codes
各厂商同一状态码的细分含义不同,以上为综合整理;遇到具体厂商时请打开其错误码页面。
3. 决策流程图:遇到报错先别慌
4. 重试的正确姿势【有据可查(各家文档的共同建议)】
import random, time
def call_with_retry(do_request, max_retries=5):
for attempt in range(max_retries):
resp = do_request()
if resp.status_code < 400:
return resp
# 不可重试:认证/权限/参数/余额/额度用尽
if resp.status_code in (400, 401, 402, 403, 404, 422):
raise RuntimeError(resp.text)
if resp.status_code == 429 and "quota" in resp.text.lower():
raise RuntimeError("额度用尽,请充值或调整预算: " + resp.text)
# 可重试:429 速率、5xx、529
retry_after = resp.headers.get("Retry-After")
wait = float(retry_after) if retry_after else min(60, (2 ** attempt) + random.random())
time.sleep(wait)
raise RuntimeError("重试次数用尽")
要点:
- 有上限(不要无限重试,费钱也可能触发更严格限流);
- 加随机抖动,避免多个进程同时重试;
- 区分可重试与不可重试。
5. Agent 场景下的"伪报错"
| 你看到的 | 实际原因 | 参考 |
|---|---|---|
MISSING_CREDENTIAL / UNKNOWN_MODEL(dsh) |
本地配置问题,非 API 返回 | DSH 日常工作流、profile 与进阶用法 |
| 网关拒绝所有请求但 Key/URL 都对 | 协议方言差异(developer role、max_tokens 字段等) | DSH 添加模型:协议、地址、密钥与模型 ID |
| 本机网关 502 且无日志 | 本机代理软件劫持了 127.0.0.1 请求 | magpie 使用:来源配置、模型切换与恢复 |
| "动作被拒"但不是安全原因 | 分类器不可达(Qoder auto 模式) | Qoder 使用:IDE、CLI、权限与自定义模型 |
| Linux 每条命令都要审批 | 沙箱不可用后回退 | Cursor 使用:项目规则、执行模式与自带 Key |
6. 本篇无法核实/需谨慎的点
- 各厂商 400/403/429 的全部细分错误码(会新增/调整)。
- 中转站/聚合网关可能改写上游错误码,导致含义与官方不一致。
- 示例代码为通用示意,未针对某一 SDK 测试。
小白练习:把本文流程逐项走通
练习目标:从错误信息判断该改配置、查额度还是有限重试。
上文已介绍概念、配置和操作示例。下面侧重第一次实际操作时的顺序、检查点和结果核对;需要查具体参数时回到对应小节。命令逐条输入,看到上一条的结果后再继续。
-
先记录请求时间、供应商、HTTP 状态码和错误正文;把 Key、Cookie、账号标识和私人内容遮掉。
-
查错误正文中的 error.type 或 error.code。429 需要继续区分速率限制与余额、预算不足。
-
401 先检查凭据所属平台与请求头,404 先检查地址和接口路径;一次只修正一个字段。
-
若属于允许重试的临时错误,先读取 Retry-After。它可能是秒数,也可能是 HTTP 日期,不能一律直接转成浮点数。
-
设置最大尝试次数和总等待上限,再用同一最小请求验证;请求已可能到达上游时,重试可能重复产生用量。
-
恢复后记录具体修正项。原文 Python 代码是简化示意,接到生产 SDK 前还需处理超时、连接异常和供应商错误类型。
