Codex CLI 与桌面版
在 ~/.codex/config.toml 里加一个自定义 provider,让 OpenAI Codex CLI、Codex 桌面版和 IDE 插件都走 RouteMux。
Codex CLI 接第三方端点靠的是配置文件里的自定义 model provider,不是环境变量。 它只讲 OpenAI 的 Responses 协议。
Codex 桌面版和 IDE 插件跑的是同一套 Codex 引擎,读的也是同一个 ~/.codex/config.toml,
所以配一次三者都生效。桌面版有几处自己的行为,见下方「Codex 桌面版」一节。
配置
写进 ~/.codex/config.toml:
model_provider = "routemux"
model = "openai/gpt-5.5"
[model_providers.routemux]
name = "RouteMux"
base_url = "https://api.routemux.com/v1"
env_key = "ROUTEMUX_API_KEY"
wire_api = "responses"export ROUTEMUX_API_KEY="sk-..." # 你的 RouteMux keyprovider 这几个键只在用户级文件里生效
项目级的 .codex/config.toml 里,model_provider 与 model_providers 会被 Codex 忽略。
它们必须写在 ~/.codex/config.toml(或 $CODEX_HOME 下的 profile 文件)里。
放在项目目录下的 provider 段会被静默跳过 —— 表现和 base URL 填错一模一样。
wire_api 只有一个取值
responses 是唯一受支持的取值,省略该字段时默认也是它 —— Codex 没有 Chat Completions 模式。
RouteMux 提供 /v1/responses,所以这条路是通的;但也意味着 Codex 永远不会碰
/v1/chat/completions。
provider id 要自己起名:openai、ollama、lmstudio 是保留 id,不能覆盖。
base URL 的形状
base_url 要带 /v1。Codex 只追加操作路径,所以请求落在 /v1/responses。
多带一层 /v1 我们是容忍的(/v1/v1/responses 会路由到同一处),但反方向 —— 漏掉 /v1 —— 不行。
选模型
GET /v1/models 返回的正是这把 key 能调用的模型,slug 照抄。
这里最大的失败来源就是复制粘贴:model id 末尾多一个空格会得到一个 MODEL_NOT_FOUND,
而它给出的建议值看起来和你填的一模一样。
Codex 桌面版
桌面版不用单独配置 —— 它直接用上面那个 provider。和终端里用有三处不同:
- key 要 export 在 shell 配置文件里。 在某个终端里敲的
export只对从那个终端启动的程序生效。 macOS 上桌面版启动时会加载你 shell 配置文件(例如~/.zshrc)里 export 的变量, 所以把export ROUTEMUX_API_KEY=...这一行写进去。 - 改完要重启。 环境变量是在桌面版启动那一刻读进去的。改了 shell 配置文件或
~/.codex/config.toml之后,彻底退出桌面版(macOS 上按 Cmd+Q)再重新打开。 - 模型菜单是 Codex 内置的 OpenAI 列表。 里面显示的是
gpt-5.5这样的裸名; RouteMux 原样接受,和openai/gpt-5.5等价。菜单里没有的模型,在~/.codex/config.toml里设model,新开的对话就会用它。
验证
测 Codex 真正使用的协议,不要测 Chat Completions:
curl https://api.routemux.com/v1/responses \
-H "Authorization: Bearer $ROUTEMUX_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model":"openai/gpt-5.5","input":"ping"}'这条返回 200 而 codex 仍然失败,说明问题在配置文件,不在 key。
为什么手写的 curl 比你预期贵
Codex CLI 总会自己发 instructions。而一条省掉该字段的裸 curl 会拿到上游默认的 Codex
系统提示词 —— 实测 21,334 个字符,让一个 11 token 的提示烧掉 4,393 input tokens。
那是这条测试调用本身贵,不是接入有问题。想省着探测就带上 instructions 字段。
长任务的超时
Codex 自己的 stream_idle_timeout_ms 默认 300000 毫秒。RouteMux 文本档的空闲看门狗是
180 秒,所以先触发的是我们这边:上游连续 180 秒没有新 chunk,请求会被中止并记为超时。
我们这边对流式没有总时长上限 —— 只要 token 一直在来,一个跑好几分钟的 agent 回合是正常的。
带图片的长会话
Codex 的长会话会在历史里堆积截图,而每一轮都会把整个历史重发一遍。有两道限制:
- 请求体超过 64 MiB 直接拒绝。
- 等上游第一个响应头的预算随请求体大小放宽 —— 因为预填时间随之增长。 27 MB 的请求体拿到的宽限远长于 1 MB 的。
如果短提示正常、长会话开始固定时长超时,清一下会话而不是反复重试 —— 变量是请求体。
排查
| 现象 | 原因 |
|---|---|
Error loading config.toml: wire_api = "chat" is no longer supported | 你照的是旧教程。改成 wire_api = "responses"。这是配置加载期报错,所以在修好之前所有 codex 命令都会失败 —— 包括和这个 provider 无关的命令。 |
codex 表现得像没配过 | provider 段写在了项目级 .codex/config.toml 里,那里会忽略这些键。挪到 ~/.codex/config.toml。 |
终端里的 codex 正常,桌面版报认证错误 | key 只在那个终端会话里 export 过。把它写进 shell 配置文件,再重启桌面版。 |
| 每条请求都 404 | base_url 漏了 /v1,或指到了某个具体路径而不是 API 根。 |
400 AUTH_AMBIGUOUS_API_KEY | 两个 header 字段里发了两个不同的 key 值。把没在用的那个清掉。 |
422 BILLING_INSUFFICIENT_CREDITS | 钱包余额不足。失败请求不计费。 |
| 模型被拒 | 这把 key 没开通 —— 以 GET /v1/models 为准。 |
| 长会话固定时长超时、短提示正常 | 是请求体大小,不是 key。见上。 |
出图
Codex CLI 内置的 $imagegen 跟着你的 ChatGPT 订阅态走,不看上面配的 base_url ——
所以一旦 Codex 指向 RouteMux(或任何第三方网关),那个内置工具就不工作了。
配置里没有东西可以修。
改装 routemux-images skill:它直接用 HTTP 打
POST /v1/images/generations,不受内置工具的影响。
npx skills add https://routemux.com -g -a codex没装 Node.js?用安装脚本:
curl -fsSL https://routemux.com/.well-known/agent-skills/install.sh | sh -s -- --agent codex两种方式都装到 ~/.agents/skills,Codex 从这里找用户级 skills。重启 Codex,然后输入
$routemux-images 调用 —— 或者直接用大白话说,比如「画一个极简风格的咖啡店 logo,存到 ./logo.png」。
skill 直接用上面那个 RouteMux provider 的 key —— env_key 指向的变量,或者 experimental_bearer_token ——
不用另外再配。