OpenAI API 的报错看起来五花八门,真正需要先分的只有五层:请求有没有发出去、身份对不对、地址和模型对不对、参数是否合法、额度和限流是否触顶。只要按顺序排查,大多数问题几分钟内就能定位。

本文按状态码拆解 401、403、404、400、429 和 5xx,给出最小复现命令、重试策略和一套固定排查顺序。模型名与网关配置以站内模型价格和接入文档为准。

说明:OpenAI、GPT、ChatGPT 是其权利人的商标。本文以 2026 年 10 月的常见接口行为为例,错误码和限额规则以官方文档与实际返回为准。

一、先保留三样证据

排查之前,先把这三样东西保存下来:

  1. HTTP 状态码;
  2. 响应体里的 error.type、error.code、error.message;
  3. 响应头里的 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 通常不是你的请求写错了,而是上游服务异常、网关超时或网络中断。处理原则:

  1. 先重试一到两次,使用指数退避和随机抖动;
  2. 流式请求要判断是否已经收到部分内容,部分输出可能已经计费;
  3. 幂等业务可以自动重试,非幂等操作要加去重键;
  4. 大面积 5xx 时看服务方状态页,不要盲目提高并发;
  5. 记录请求 ID,便于服务方定位。

如果只有你的请求 5xx,而其他团队正常,优先检查请求体大小、超时设置和代理链路。

七、一套固定排查顺序

遇到报错,按下面顺序走,不要跳步:

  1. 用 curl 发最小请求,确认地址和 Key。
  2. 对比官方地址和网关地址,确认没有混用 Key。
  3. 检查 Base URL 是否只保留一个 /v1。
  4. 检查模型名是否从价格页复制、是否已开通。
  5. 删除可选参数,确认最小请求能通。
  6. 检查余额、项目额度和 Key 上限。
  7. 检查 429 响应头,区分限流和余额。
  8. 查服务方状态页,确认是否上游故障。
  9. 保存请求 ID、状态码和响应体,再联系支持。

八、常见问题

429 一定是调用太快吗?

不一定。429 既可能是频率或并发超限,也可能是余额不足。看 error.code 和响应头,不要一律降速。

401 换一把 Key 就好了吗?

换 Key 能排除 Key 本身的问题,但如果是地址混用、环境变量为空或项目无权限,换多少把都没用。先确认请求实际发到了哪里。

404 是模型下线了吗?

多数情况是 Base URL 或模型名写错。先用 curl 调 /v1/models,再对照价格页确认模型名。

5xx 可以无限重试吗?

不可以。设置最大重试次数和总超时,避免故障期间堆积请求。流式请求还要考虑部分输出已经计费。

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

先看响应体格式和请求 ID,再用同一把 Key、同一模型分别请求官方地址和网关地址。能稳定复现的那一层,才是问题所在。

下一步

把最小请求、用量日志和重试策略先搭好,再接业务流量。需要人民币充值和统一多模型入口,可以先注册中商起航 AI 网关;模型名与价格以模型价格为准。

相关阅读: