1. Codex 报 Chat/Completions 不支持的真实场景与定位思路
你打开终端,敲下codex准备让它读一下当前仓库,结果它没进交互界面,而是甩出一段红字:Chat/Completions API is not supported或者unsupported endpoint /v1/chat/completions。这时候大多数人第一反应是去翻 API Key 是不是过期了、余额是不是没了、网络是不是不通。我一开始也这么怀疑,后来发现方向完全错了——问题出在 Codex 客户端本身使用的协议端点上。
先把这件事讲清楚。OpenAI Codex 这个 CLI 工具在版本演进中做了一次协议切换:较新的版本默认走 Responses API(/v1/responses),而 0.80.0 及更早的版本走的是 Chat Completions(/v1/chat/completions)。如果你的接入端(也就是你配置的 Base URL 指向的服务)只实现了 Chat Completions 语义,而客户端却按 Responses 的格式发请求,服务端就会返回端点不支持、字段解析失败之类的错误。反过来,如果你把客户端锁在旧版本,但接入端只认 Responses,也会报错。所以这个报错本质上是客户端协议版本和接入端能力没对齐,跟你的业务代码关系不大。
那这篇要解决的核心问题就明确了:当 Codex 因为 Chat/Completions 端点不兼容而报错时,怎么通过调整 endpoint 配置和auth.json,把它改到 TaoToken 的接入地址上,让请求真正跑通。适合谁看?正在用 Codex CLI 做本地开发、遇到端点不兼容报错、想快速定位而不是盲目换 Key 的开发者。下面我会按“先确认版本与协议 → 再配 Base URL 和 Key → 再验证请求 → 最后排错”的顺序走一遍,每一步都给可复制的片段。
先给一个判断表,帮你 30 秒内定位自己属于哪种情况:
| 现象 | 大概率原因 | 先查什么 |
|---|---|---|
报Chat/Completions API is not supported | 客户端版本与接入端协议不匹配 | codex --version与 Base URL 端点 |
报401 Unauthorized | Key 没带上或格式不对 | auth.json里的 key 字段 |
报local proxy failed/ 连接被拒 | Base URL 写错或端口不通 | 用 curl 直连测端点 |
报reading choices/ 解析字段为空 | 返回体不是预期 JSON 结构 | 看原始响应体 |
| 报 OAuth 相关错误 | 走了登录态而非 API Key 模式 | 是否误用了交互登录 |
这张表不是让你背,而是让你在终端报错的第一时间知道往哪看。很多人卡在“以为是网络问题”上,反复换网络环境,其实只要codex --version一看是 0.9x 的新版本,而接入端只支持 Chat Completions,答案就已经出来了。接下来的章节会把每一类都拆开讲,重点是给出能直接粘贴的配置和验证命令,而不是停留在“检查一下配置”这种空话上。
2. TaoToken 前置准备:拿到 Base URL、API Key 与模型 ID 三件套
在改 Codex 配置之前,得先把接入端的三样东西备齐:Base URL、API Key、Model ID。这三件套缺一个,后面auth.json就填不全,报错会从“端点不支持”变成“认证失败”,反而更难排查。TaoToken 的入口在官网 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= ,API 根地址是 https://taotoken.net/api ,注意这个 API 地址后面不加任何查询参数,配置里就写这个干净的根路径。
第一步,登录后在控制台创建 API Key。入口是 https://taotoken.net/console?utm_source=taotoken_aicg_blog_end&utm_content=console&utm_campaign=rewrite ,进去之后找 API Keys 管理页,新建一个 Key。这里有个细节:Key 只在创建时完整显示一次,复制下来存到本地安全的地方,别直接贴进会提交到 Git 的配置文件里。我一般会先export到当前 shell 环境变量里做测试,确认通了再写进auth.json。
第二步,确认你要用的 Model ID。Codex 这类编码工具通常需要一个支持代码补全和长上下文的模型,具体可用模型以控制台模型列表为准。把 Model ID 记下来,后面auth.json里的model字段要填它。如果你不确定填哪个,先去模型对话页 https://taotoken.net/chat?utm_source=taotoken_aicg_blog_end&utm_content=model_chat&utm_campaign=rewrite 手动发一条消息,确认这个模型在你的账号下能正常返回,再回来配 Codex。这一步很关键,因为如果模型本身不可用,Codex 报的错会和端点不兼容混在一起,干扰判断。
第三步,理解 Base URL 的拼接规则。Codex 的配置里通常填的是根地址,客户端会自己在后面拼/v1/responses或/v1/chat/completions。所以你在auth.json或环境变量里写的应该是https://taotoken.net/api,而不是https://taotoken.net/api/v1/chat/completions。多写一段路径,客户端再拼一次,就会变成/api/v1/chat/completions/v1/chat/completions这种畸形地址,直接 404。这个坑我见过不止一次,报错信息还特别含糊。
把三件套整理成一张对照表,配置时对着填:
| 配置项 | 值 | 说明 |
|---|---|---|
| Base URL | https://taotoken.net/api | 根地址,不带/v1后缀 |
| API Key | 控制台生成的sk-开头字符串 | 只显示一次,妥善保存 |
| Model ID | 控制台模型列表中的编码模型名 | 与对话页验证一致 |
如果你打算长期跑编码任务、频繁调用,可以顺带看一下 Coding Plan 页面 https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=coding_plan&utm_campaign=rewrite ,了解配额和调用方式,避免跑到一半额度不够又回头排查。但这一步不是必须的,先把单次请求跑通更重要。三件套备齐后,进入下一节改配置。
3. 可复制配置:auth.json 与 endpoint 片段怎么写
这一节是全文的核心,直接给能粘贴的片段。Codex CLI 的认证信息一般放在用户目录下的~/.codex/auth.json(Windows 是%USERPROFILE%\.codex\auth.json)。不同版本字段名略有差异,但核心是base_url、api_key、model三项。下面这份 JSON 是通用写法,你按自己的 Key 和 Model ID 替换占位符即可:
{ "base_url": "https://taotoken.net/api", "api_key": "sk-你的实际Key粘贴在这里", "model": "你的模型ID", "provider": "openai" }注意几个容易写错的地方。第一,base_url结尾不要带斜杠,也不要带/v1,就写https://taotoken.net/api。第二,api_key是字符串,别写成数字或漏引号。第三,provider字段有的版本需要,有的不需要,写上openai一般兼容性更好,因为它告诉客户端按 OpenAI 兼容协议发请求。如果你的 Codex 版本读的是config.toml而不是auth.json,对应写法是:
model = "你的模型ID" model_provider = "openai" [model_providers.openai] base_url = "https://taotoken.net/api" api_key = "sk-你的实际Key粘贴在这里"TOML 里base_url同样只写根地址。有些同学会把base_url写成https://taotoken.net/api/v1,然后客户端再拼/chat/completions,结果请求打到/api/v1/chat/completions,如果接入端只认/api/chat/completions就会 404。所以统一原则:配置里只写根,路径交给客户端拼。
除了文件配置,也可以用环境变量临时覆盖,适合快速验证而不动全局配置:
export OPENAI_BASE_URL="https://taotoken.net/api" export OPENAI_API_KEY="sk-你的实际Key" export OPENAI_MODEL="你的模型ID"环境变量的优先级通常高于配置文件,所以如果你改了auth.json没生效,先echo $OPENAI_BASE_URL看看是不是被环境变量盖掉了。这个排查动作能省很多时间。
再强调一下版本与端点的对应关系,因为这是报错的根源:
| Codex 版本 | 默认协议端点 | 接入端需要支持 |
|---|---|---|
| 0.80.0 及以下 | /v1/chat/completions | Chat Completions 语义 |
| 0.9x 新版本 | /v1/responses | Responses 语义 |
如果你的接入端只实现了 Chat Completions,而客户端是新版本,就会报“不支持”。这时候有两条路:一是把客户端锁到 0.80.0,二是确认接入端是否支持 Responses。TaoToken 的接入地址按 OpenAI 兼容方式提供,具体走哪个端点取决于客户端版本,所以配置正确后,关键是让版本和端点对齐。锁版本的命令是:
npm uninstall -g @openai/codex npm install -g @openai/codex@0.80.0 codex --version输出0.80.0就说明锁成功了。这一步不是让你永远停在旧版,而是在接入端协议没对齐前,先用能跑通的组合把任务推进下去。配置写完后别急着开交互界面,下一节先用一条 curl 验证请求是否真的通。
4. 验证请求:从 curl 到 Codex 交互的逐步确认
配置写完不代表通了,必须分层验证。我习惯先用 curl 直接打接入端,排除 Codex 客户端本身的干扰,确认 Base URL、Key、Model 三件套没问题,再让 Codex 去调。这样一旦出错,能立刻判断是接入端问题还是客户端配置问题。
第一步,用 curl 测 Chat Completions 端点:
curl -sS https://taotoken.net/api/v1/chat/completions \ -H "Authorization: Bearer sk-你的实际Key" \ -H "Content-Type: application/json" \ -d '{ "model": "你的模型ID", "messages": [{"role": "user", "content": "ping"}], "max_tokens": 16 }'如果返回体里有choices数组且content非空,说明接入端、Key、Model 都正常。如果返回 401,是 Key 问题;返回 404,是路径拼错;返回 400 且提示模型不存在,是 Model ID 写错。这一步的返回体要完整看,别只看 HTTP 状态码。
第二步,如果你的客户端是新版本、走 Responses 端点,对应测一下:
curl -sS https://taotoken.net/api/v1/responses \ -H "Authorization: Bearer sk-你的实际Key" \ -H "Content-Type: application/json" \ -d '{ "model": "你的模型ID", "input": "ping" }'两个端点哪个通,就说明你的接入端支持哪种语义,再据此决定 Codex 用哪个版本。这就是为什么前面要你先确认版本——不是让你盲目降级,而是让客户端发的端点和接入端能接的端点对上。
第三步,回到 Codex 本身验证。先看版本:
codex --version再跑一个非交互的单次任务,避免直接进交互界面卡住:
codex exec "用一句话说明当前目录是什么项目"如果这条命令能返回模型输出,说明整条链路通了。如果报reading choices或解析为空,多半是返回体结构和客户端预期不一致,回去看 curl 的原始返回体,对比字段名。如果报local proxy failed,检查是不是本地配了额外的转发端口,把base_url指回了本地。
第四步,进交互界面做一次真实任务:
codex进去后让它读一个文件、改一行代码,观察是否有流式输出、是否有中断。实测下来,curl 通但 Codex 不通的情况,八成是auth.json里的base_url多了/v1或者环境变量覆盖了文件配置。把这两点排掉,基本就顺了。
5. 常见报错对照排查:401、local proxy failed、reading choices、OAuth
这一节按真实报错逐条拆,每条给“现象 → 原因 → 动作”,你对着终端输出找就行。
401 Unauthorized。现象是 curl 或 Codex 都返回 401。原因通常是 Key 没带上、Key 前后有空格、或者用了控制台里已删除的旧 Key。动作:先echo $OPENAI_API_KEY看环境变量是否为空或带空格;再确认auth.json里api_key字段是完整字符串;最后去控制台 API Keys 页 https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=api_keys&utm_campaign=rewrite 核对 Key 是否还有效。注意别把 Key 贴进公开仓库,测试用环境变量,稳定后再写文件。
local proxy failed / 连接被拒。现象是 Codex 报本地代理失败或 connection refused。原因一般是base_url指向了127.0.0.1某个端口,但本地并没有起对应服务;或者公司网络环境有额外的转发设置。动作:把base_url改回https://taotoken.net/api直连,去掉任何本地端口;用curl -v看实际连接的地址是不是你预期的。这一步不要靠猜,-v的输出会明确告诉你请求打到了哪。
reading choices / 解析字段为空。现象是客户端报读取choices失败或返回体解析异常。原因是客户端按 Chat Completions 结构解析,但接入端返回的是 Responses 结构(或反过来)。动作:用第 4 节的 curl 分别打两个端点,看哪个返回choices、哪个返回output;然后让客户端版本和端点语义对齐。新版本客户端配 Responses 端点,旧版本配 Chat Completions 端点,别交叉。
OAuth 相关错误。现象是提示登录态失效或 OAuth token 无效。原因是 Codex 走了交互登录模式,而不是 API Key 模式。动作:确认配置里用的是api_key而非登录凭据;清理~/.codex下可能残留的登录缓存文件(先备份再删);重新用 Key 方式启动。如果你之前登录过官方账号,缓存可能优先于auth.json,这一步要清干净。
端点 404。现象是404 Not Found。原因几乎都是base_url多写了/v1或/chat/completions,客户端又拼了一次。动作:把base_url改回https://taotoken.net/api,只保留根路径。这个错最容易犯,也最容易改。
把这几条整理成速查表贴在终端旁边:
| 报错关键词 | 首查项 | 修复动作 |
|---|---|---|
| 401 | Key 是否为空/带空格 | 重设环境变量或改 auth.json |
| local proxy failed | base_url 是否指向本地端口 | 改回根地址直连 |
| reading choices | 端点语义与版本是否错配 | 对齐版本与端点 |
| OAuth | 是否误用登录态 | 清缓存,改用 api_key |
| 404 | base_url 是否多写路径 | 只保留根地址 |
排查顺序建议从 curl 开始,因为 curl 排除了客户端变量,能最快定位是接入端还是客户端的问题。每修一项就重跑一次 curl,别一次改多处,否则通了也不知道是哪处起的作用。
6. 把 Codex 稳定跑在 TaoToken 上的收尾动作
配置通了之后,还有几个收尾动作能让它稳定跑,而不是今天通明天又报错。第一,锁版本。如果你确认当前接入端走 Chat Completions 语义,就把 Codex 固定在 0.80.0,并关掉全局自动升级,避免某次npm update把它升到新版本后又报端点不支持。锁版本的命令前面给过,这里补一个检查是否被自动升级覆盖的动作:每次开工前codex --version扫一眼,版本变了就重新锁。
第二,把配置集中管理。auth.json里的 Key 不要散落在多个项目里,统一放用户目录一份,项目里用环境变量覆盖只在临时测试时用。这样换 Key 只改一处,不会出现“这个项目能跑那个项目 401”的怪现象。环境变量和文件的优先级要心里有数,改完用echo确认实际生效的值。
第三,验证习惯化。每次改完配置,先 curl 打一次端点,再codex exec跑一句短任务,最后才进交互界面做长任务。这个顺序能把问题挡在成本最低的环节。长任务跑到一半报错,排查成本比开头高得多。
第四,遇到新报错先看原始响应体。Codex 的报错信息有时会包装一层,真正的错误在返回 JSON 的error.message里。用 curl 复现一次,把完整返回体打出来,比盯着客户端那行红字有效。这也是为什么第 4 节坚持先用 curl 验证——它给你的是未经包装的原始信息。
如果你后续要长期做编码和 Agent 类任务,可以到 Coding Plan 页面 https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=coding_plan&utm_campaign=rewrite 看配额方案;需要新建或轮换 Key 就去 API Keys 页 https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=api_keys&utm_campaign=rewrite ;接入细节和字段说明在文档 https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_content=doc&utm_campaign=rewrite 里能查到;想先手动验证模型是否可用,模型对话页 https://taotoken.net/chat?utm_source=taotoken_aicg_blog_end&utm_content=model_chat&utm_campaign=rewrite 发一条消息最快。把这些入口存进书签,下次报错时按“先 curl、再对版本、再查 Key”的顺序走一遍,基本不用再从头摸索。