Codex CLI 接自定义 API 后,报错大多集中在凭证、路径、模型、限流、上下文和本地沙箱六层。看到红色提示就换模型、重装工具,往往把十分钟的问题拖成半天。更有效的做法是固定变量:同一个 Key、Base URL 和模型 ID,一次只改一项。本文按状态码拆解,并给出日志位置、诊断命令和错误处理示例。

说明:OpenAI、Codex 是 OpenAI, Inc. 的商标。本文仅作技术说明,与上述公司无隶属或合作关系。配置与文案随版本调整,以官方文档和当前版本为准;模型与价格以站内模型价格页为准。

一、先看状态码,再动配置

现象 常见含义 先查什么 是否重试
401 Key 缺失、错误或失效 env_key 变量、Key 状态、余额 不重试
403 Key 无权限或策略拦截 模型权限、账户状态、团队策略 不重试
404 路径错误或接口不存在 Base URL、/responses 支持情况 不重试
model not found 模型 ID 错误或未开通 模型标识、账号权限 不重试
429 频率、并发或配额超限 用量、共享 Key、重试设置 退避后重试
400 context_length_exceeded 上下文超过模型上限 输入体积、工具输出、压缩设置 改请求后重试
沙箱或审批失败 本地权限边界拦截 沙箱模式、可写目录、审批策略 调整策略后重试
超时或流中断 代理、TLS、空闲超时、服务端过载 网络链路、超时与重试参数 视情况重试

建议按下面的顺序排查:

  1. 在项目目录执行 codex doctor,先看安装、配置、认证和运行环境。
  2. 会话内用 /status 看模型、审批策略、可写目录和 Token 用量。
  3. 用 /debug-config 看最终生效值,确认改的不是没被加载的文件。
  4. 用最小请求验证 Base URL、Key 和模型。
  5. 最后再调整模型、上下文或沙箱策略。

二、401 与 403:Key 没有进到进程里

Codex 的自定义 provider 通过 env_key 指定环境变量名,例如:

[model_providers.zsqh]
name = "ZSQH AI Gateway"
base_url = "https://ai.zhongshangqihang.com/v1"
env_key = "ZSQH_API_KEY"
wire_api = "responses"

配置写对,不等于进程能读到 Key。常见原因:shell 里导出的变量名和 env_key 不一致;在 A 终端导出,却在 B 终端启动;图形界面启动的应用没继承环境变量;Key 前后带空格、换行或引号;Key 属于另一个平台或环境;Key 已删除、禁用或余额不足。

无头环境可以用 CODEX_API_KEY 传入 Key,但不要同时保留多套来源,否则很难判断最终用的是哪一把。403 更多是权限或策略问题,先看响应体,再查网关控制台,不要反复重试。

三、404 与 model not found:地址、协议和模型 ID

Codex 当前的自定义 provider 只接受 wire_api = "responses",请求会打到 /v1/responses。这带来几类高频 404:

  • base_url 少写 /v1,请求打到网页路由。
  • base_url 已包含 /responses,客户端又拼一次,路径重复。
  • 网关只提供 /v1/chat/completions,没有实现 Responses 协议。
  • 域名拼错,或把控制台地址当成了 API 地址。

base_url 一般填到 /v1 为止,不要自己拼完整接口路径。模型不存在时,不同网关可能返回 404,也可能返回 400,错误码字段常见为 model_not_found,判断以响应体为主。模型 ID 必须和站内模型价格页的 API 标识完全一致,包括大小写、连字符和版本后缀。

codex debug models 导出的是本地或内置目录,不代表网关实际开放了哪些模型。还要确认 model_provider 与 [model_providers.xxx] 名称一致;对不上时,Codex 可能回落到默认 provider,表现就像“配置没生效”。

四、429:先降并发,再谈重试

429 表示请求超过了速率、并发或 Token 配额。Codex 会连续读文件、跑命令,比普通聊天更容易触发。常见场景:每分钟请求数或 Token 数超限;多人共用一把 Key;在大仓库里连续读取大量文件;重试没有退避,形成风暴;长上下文请求挤占并发空间。

Codex 的 provider 配置里有 request_max_retries(默认 4)和 stream_max_retries(默认 5)。它们能提高稳定性,但在持续 429 时会放大请求量,排查阶段可以临时调低。

还要区分限流和欠费:错误体出现 insufficient_quota 一类字段时,重试没有意义,应去控制台检查余额或配额。真正的限流则看 Retry-After,没有该响应头就做指数退避加随机抖动。按项目或按人拆 Key,比全组共用一把更容易定位。

五、上下文超限:先减输入,再谈换模型

上下文超限常见错误码是 context_length_exceeded,文案里可能出现 “maximum context length”。Codex 的请求不只有你的提问,还包括系统提示、AGENTS.md、读入的文件、工具输出和历史记录。长任务跑久了,前面每一步的输出都会留在上下文里。

处理顺序建议如下:

  1. 缩小工作目录,只让 Codex 读相关模块。
  2. 在提示里限定文件范围,避免整仓库扫描。
  3. 排除构建产物、依赖目录、日志和密钥文件。
  4. 用 tool_output_token_limit 限制单个工具输出的 Token 数。
  5. 新开会话,把已完成的结论写成简短摘要再继续。
  6. 确有必要时,再换上下文更长的模型。

model_context_window 要和真实窗口一致,填大数字仍会被服务端拒绝;model_auto_compact_token_limit 设得过高可能先撞上硬上限。实际窗口以官方文档和价格页为准。

六、沙箱与审批失败:这不是 API 错误

Codex 有三档沙箱模式:read-only、workspace-write 和 danger-full-access。read-only 不能改文件;workspace-write 只能在可写根目录内修改,并可配置网络访问;danger-full-access 移除文件和网络边界,只适合受控环境。

典型表现是 Operation not permitted、Permission denied,或者命令执行到一半提示需要审批。先看 /status 显示的模式和可写目录,再确认项目是否在目录之外、命令是否需要网络、非交互的 codex exec 是否有审批入口。

审批策略方面,当前版本支持 on-request、never 和 granular。旧的 approval_policy = "untrusted" 已不再支持,继续保留可能导致 Codex 无法启动;on-failure 也已弃用。CI 里可以明确写 codex exec --sandbox workspace-write;只读任务可用 --sandbox read-only --ask-for-approval never。不要为了省事直接上 danger-full-access。

七、超时与流中断:代理、TLS 和空闲超时

流式请求对网络链路更敏感。公司代理、TLS 中间人、VPN 切换和不稳定的出口,都可能表现为“请求发出去了,但迟迟没有第一个 Token”,或者中途断流。

stream_idle_timeout_ms 默认 300000 毫秒(五分钟)。推理模型首 Token 较慢,调得过低会误伤;如果代理 60 秒断空闲连接,调大客户端超时也救不回来,需要同时查链路。

自签 CA 或 TLS 拦截可用 CODEX_CA_CERTIFICATE 指定 PEM 证书包,未设置时才回退 SSL_CERT_FILE;不要整体关闭证书校验。超时后先发一次非流式最小请求,确认 API 可用,再回 Codex 复现。

八、日志与诊断:先拿证据,再改配置

Codex 的日志目录由 log_dir 控制,默认是 $CODEX_HOME/log。只有显式设置 log_dir 时,才会额外生成明文 codex-tui.log,排查时建议在用户级配置里打开。

常用诊断入口:

  • codex doctor:输出安装、配置、认证、运行时和终端健康报告。
  • /status:会话内查看模型、审批策略、可写目录和 Token 用量。
  • /debug-config:查看配置来源、优先级和最终生效值。
  • codex exec --json:以 JSON 事件流输出非交互执行过程。
  • RUST_LOG:控制日志详细程度,例如 codex_core=debug,codex_tui=debug;codex exec 默认只显示 error 级别。

排查时对齐配置最终值与实际请求:Base URL、/responses 路径、模型名、审批策略。很多“配置不生效”是文件位置不对或环境变量未重载。

九、一段可复用的错误处理示例

下面的示例用于你自己调用网关的脚本,不替代 Codex CLI 内置的重试。原则是:认证和路径错误不重试,限流和 5xx 退避重试,上下文错误直接改请求。

import random
import time

import httpx

RETRYABLE = {429, 500, 502, 503, 504}


def call_gateway(payload: dict, key: str, url: str):
    for attempt in range(4):
        try:
            resp = httpx.post(
                url,
                json=payload,
                headers={"Authorization": f"Bearer {key}"},
                timeout=httpx.Timeout(180.0, connect=10.0),
            )
        except httpx.TimeoutException:
            if attempt == 3:
                raise
            time.sleep(min(30, 2 ** attempt) + random.random())
            continue

        # 认证、权限、路径、模型错误:改配置,不要重试
        if resp.status_code in (401, 403, 404):
            raise RuntimeError(f"{resp.status_code}: {resp.text[:300]}")

        if resp.status_code == 400:
            body = resp.text.lower()
            if "context" in body or "maximum context" in body:
                raise RuntimeError("上下文超限:先缩小输入或新开会话")
            raise RuntimeError(f"请求格式错误: {resp.text[:300]}")

        if resp.status_code in RETRYABLE:
            if "insufficient_quota" in resp.text:
                raise RuntimeError("配额不足:检查余额,不要重试")
            retry_after = float(resp.headers.get("Retry-After", 2 ** attempt))
            time.sleep(min(30, retry_after) + random.random())
            continue

        resp.raise_for_status()
        return resp.json()

    raise RuntimeError("重试次数已用完")

这段代码不处理沙箱和审批,那属于本地执行层。把 API 错误和本地权限错误分开看,排查会快很多。

常见问题

Key 在网页测试正常,Codex 却报 401?

先确认 Codex 读取的环境变量名,并在启动 Codex 的同一个 shell 里导出。图形界面启动的应用经常读不到刚设置的变量,重开应用或用 codex doctor 检查认证。

404 一定是模型下线了吗?

不一定。Codex 使用 Responses 协议,路径不对、网关没有 /v1/responses 入口都会返回 404。先确认地址填到 /v1,再核对模型 ID。

429 要不要把重试次数调大?

不建议。持续 429 说明已经超过限额,调大重试只会增加请求量。先降并发、拆 Key、看 Retry-After,确认是限流还是欠费。

Codex 能用 Chat Completions 接口吗?

当前只接受 wire_api = "responses"。只有 Chat Completions 的端点需要协议转换层,或改用其他客户端;不要靠安装旧版本绕过。

沙箱报错能不能直接关掉?

可以调整为 workspace-write 并配置可写目录,或在受控环境使用更高权限模式,但不建议默认使用 danger-full-access。先看 /status 确认边界。

下一步

Codex 的报错排查,顺序比技巧重要:先看状态码和响应体,再用 codex doctor 与 /debug-config 确认配置,最后才改模型或沙箱。需要统一 Key、用量和模型入口,可以注册中商起航 AI 网关,模型与接口范围以模型价格页为准。

相关阅读: