OpenAI API 的报错看起来五花八门,真正需要先分的只有五层:请求有没有发出去、身份对不对、地址和模型对不对、参数是否合法、额度和限流是否触顶。只要按顺序排查,大多数问题几分钟内就能定位。
本文按状态码拆解 401、403、404、400、429 和 5xx,给出最小复现命令、重试策略和一套固定排查顺序。模型名与网关配置以站内模型价格和接入文档为准。
说明:OpenAI、GPT、ChatGPT 是其权利人的商标。本文以 2026 年 10 月的常见接口行为为例,错误码和限额规则以官方文档与实际返回为准。
一、先保留三样证据
排查之前,先把这三样东西保存下来:
- HTTP 状态码;
- 响应体里的
error.type、error.code、error.message; - 响应头里的
x-request-id。
请求 ID 是跟服务方沟通时最有用的信息。没有它,只能描述“大概什么时候失败了一次”;有它,才能查到具体请求、具体上游和具体计费。
| 状态码 | 常见类型 | 第一判断 |
|---|---|---|
| 400 | invalid_request_error |
参数、JSON 或上下文长度有问题 |
| 401 | authentication_error |
Key 缺失、错误或已失效 |
| 403 | permission_error |
Key 无权访问该模型或项目 |
| 404 | not_found_error |
Base URL 或模型名不对 |
| 429 | rate_limit_error / insufficient_quota |
限流,或余额不足 |
| 500/502/503/504 | server_error |
上游故障或网络中断 |
二、401 和 403:身份与权限
401 的核心是“服务端不认这把 Key”。常见原因:
- 请求头没带
Authorization: Bearer; - Key 复制时多了空格、换行,或被截断;
- Key 已被删除、轮换或所属项目被停用;
- 把网关 Key 发到了官方地址,或把官方 Key 发到了网关地址;
- 环境变量拼写错误,实际发送的是空字符串。
403 更多是“认得出你,但不让你做”。比如 Key 没有该模型的权限、组织被限制、项目未开通对应能力。遇到 403 不要反复重试,先看 Key 所属项目和控制台里的模型权限。
一个快速自检:
curl -sS "https://api.zhongshangqihang.com/v1/models" \
-H "Authorization: Bearer $ZSQH_API_KEY" \
-w "\nHTTP %{http_code}\n"
能列出模型,说明 Key 和地址基本正确;仍然 401,优先检查 Key 本身和环境变量。
三、404:地址或模型不存在
404 不一定是“接口下线”,更多是路径拼错。常见情况:
| 现象 | 原因 | 处理 |
|---|---|---|
404 page not found |
Base URL 多了 /v1 或少了 /v1 |
按文档统一写成 https://api.zhongshangqihang.com/v1 |
model_not_found |
模型名拼错或未开通 | 从模型价格页复制模型名 |
| 404 且路径带双斜杠 | 拼接 URL 时多了 / |
去掉重复斜杠 |
| SDK 报 404 | base_url 与接口路径重复 |
只保留一个 /v1 |
排查时先用 curl 发一条最小请求,排除 SDK 的 URL 拼接问题。curl 通、SDK 不通,问题通常在 base_url、代理或 SDK 版本。
四、400:参数和上下文
400 表示请求本身不合法,重试没有意义。高频原因包括:
- JSON 格式错误,比如尾逗号、单引号、未转义换行;
- 传了模型不支持的参数,比如某些模型不接受特定的采样参数;
max_tokens超过模型上限;- 输入超过上下文窗口,返回
context_length_exceeded; - 图片格式、尺寸或 URL 无法访问;
- 工具 schema 不合法,缺少必填字段。
处理顺序是:先删到最小请求,再逐项加回参数。不要一次改五个地方,否则报错消失也不知道是哪一项起的作用。
五、429:限流还是余额不足
429 是最容易被误判的一类。它至少有两种含义:
| 错误码 | 含义 | 处理 |
|---|---|---|
rate_limit_exceeded |
请求频率、Token 速率或并发超限 | 降并发、排队、指数退避 |
insufficient_quota |
余额不足或额度用尽 | 充值、换 Key、检查项目额度 |
先看响应体和响应头。retry-after 告诉你建议等待多久;x-ratelimit-remaining-requests 和 x-ratelimit-remaining-tokens 能看出还剩多少额度。如果剩余量是 0,退避再久也没用,要等窗口重置或提升限额。
一段可用的重试逻辑:
import random
import time
from openai import OpenAI
client = OpenAI(
api_key="sk-你的密钥",
base_url="https://api.zhongshangqihang.com/v1",
)
def chat(prompt: str, retries: int = 4) -> str:
for attempt in range(retries):
try:
resp = client.chat.completions.create(
model="gpt-5.5",
messages=[{"role": "user", "content": prompt}],
max_tokens=500,
timeout=60,
)
return resp.choices[0].message.content
except Exception as exc:
status = getattr(exc, "status_code", None)
if status not in (429, 500, 502, 503, 504) or attempt == retries - 1:
raise
wait = min(2 ** attempt, 16) + random.random()
print(f"{status},{wait:.1f} 秒后重试:{exc}")
time.sleep(wait)
raise RuntimeError("unreachable")
重试只对 429、5xx 和网络错误有效。400、401、403、404 重试只会浪费时间和额度。
六、5xx:上游故障与网络问题
500、502、503、504 通常不是你的请求写错了,而是上游服务异常、网关超时或网络中断。处理原则:
- 先重试一到两次,使用指数退避和随机抖动;
- 流式请求要判断是否已经收到部分内容,部分输出可能已经计费;
- 幂等业务可以自动重试,非幂等操作要加去重键;
- 大面积 5xx 时看服务方状态页,不要盲目提高并发;
- 记录请求 ID,便于服务方定位。
如果只有你的请求 5xx,而其他团队正常,优先检查请求体大小、超时设置和代理链路。
七、一套固定排查顺序
遇到报错,按下面顺序走,不要跳步:
- 用 curl 发最小请求,确认地址和 Key。
- 对比官方地址和网关地址,确认没有混用 Key。
- 检查 Base URL 是否只保留一个
/v1。 - 检查模型名是否从价格页复制、是否已开通。
- 删除可选参数,确认最小请求能通。
- 检查余额、项目额度和 Key 上限。
- 检查 429 响应头,区分限流和余额。
- 查服务方状态页,确认是否上游故障。
- 保存请求 ID、状态码和响应体,再联系支持。
八、常见问题
429 一定是调用太快吗?
不一定。429 既可能是频率或并发超限,也可能是余额不足。看 error.code 和响应头,不要一律降速。
401 换一把 Key 就好了吗?
换 Key 能排除 Key 本身的问题,但如果是地址混用、环境变量为空或项目无权限,换多少把都没用。先确认请求实际发到了哪里。
404 是模型下线了吗?
多数情况是 Base URL 或模型名写错。先用 curl 调 /v1/models,再对照价格页确认模型名。
5xx 可以无限重试吗?
不可以。设置最大重试次数和总超时,避免故障期间堆积请求。流式请求还要考虑部分输出已经计费。
网关报错和官方报错怎么区分?
先看响应体格式和请求 ID,再用同一把 Key、同一模型分别请求官方地址和网关地址。能稳定复现的那一层,才是问题所在。
下一步
把最小请求、用量日志和重试策略先搭好,再接业务流量。需要人民币充值和统一多模型入口,可以先注册中商起航 AI 网关;模型名与价格以模型价格为准。
相关阅读:
