多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

Codex-Bridge 实现 API 协议双向转换:把 Codex auth.json 改到 TaoToken 的配置与验证

Codex-Bridge 实现 API 协议双向转换:把 Codex auth.json 改到 TaoToken 的配置与验证 1. 为什么 Codex 客户端总在协议上卡壳Codex 这类客户端默认走的是 OpenAI Responses API请求体里input、tools、reasoning这些字段的组织方式和大多数模型服务商实际提供的 Chat Completions API 并不一样。你直接把 Codex 的 endpoint 指向一个只认/v1/chat/completions的服务最常见的结局就是 404 或者 400运气差一点还会收到一个结构完全对不上的响应客户端解析到一半直接崩掉。Codex-Bridge 解决的就是这个错位问题。它在本地起一个代理网关对外暴露 Codex 认识的 Responses API 形态对内把请求翻译成 Chat Completions 格式转发出去拿到响应后再翻译回来。整个过程对 Codex 客户端是透明的你只需要把auth.json里的 endpoint 和鉴权字段改到本地代理剩下的协议映射交给 Bridge 处理。这套链路适合几类人一是手里已经有 TaoToken 统一 Key想让 Codex CLI 或 Codex 桌面端直接复用这条通道二是本地同时跑着多个模型服务想用一个代理层做协议归一三是单纯想搞清楚 Responses API 和 Chat Completions API 之间到底差在哪拿 Bridge 当个可观测的中间层来调试。我试过把 Codex 的请求直接打到 Chat Completions 端点返回的 JSON 里choices[0].message.content是有的但 Codex 期望的是output数组结构字段名对不上客户端直接判定为空响应。Codex-Bridge 的价值就在于它把这层字段映射做掉了你不用去改客户端源码。下面按“先跑通链路再验证请求最后排错”的顺序来写。核心动作有三个改auth.json、启动 Bridge、用 curl 打一发验证。每一步都给可复制的片段。2. TaoToken 通道准备与 Codex-Bridge 部署在动auth.json之前先把 TaoToken 这边的通道信息拿到手。你需要三样东西Base URL、API Key、以及你要调用的 Model ID。Base URL 用https://taotoken.net/api这个地址是给程序调用的不要带任何查询参数。API Key 在控制台的 API Keys 页面生成建议单独建一个给 Codex-Bridge 用的 Key方便后面按用途区分额度。Model ID 这块要注意Codex 客户端本身对模型名不敏感它只负责把请求发出去真正决定路由的是 Bridge 转发时填的模型字段。所以你在 Bridge 的配置里写什么模型最终就打到什么模型。常见的选择是claude-sonnet-4-5这类支持长上下文和工具调用的模型具体以你账号下可用的列表为准。Codex-Bridge 本身是个 Node 项目跑起来需要 Node.js 18 以上。先确认版本node -v # 期望输出 v18.x 或更高如果版本不够去 Node 官网下 LTS 包装上。装好后把 codex-bridge 的源码拉到本地进入项目根目录复制一份环境变量模板cp env.example .env然后编辑.env填入 TaoToken 的 Key 和代理自身的认证 Key# .env TAOTOKEN_API_KEYsk-你的TaoTokenKey TAOTOKEN_BASE_URLhttps://taotoken.net/api PROXY_AUTH_KEYsk-proxy-local-替换成你自己的48位hex DEFAULT_MODELclaude-sonnet-4-5这里PROXY_AUTH_KEY是给 Codex 客户端连本地代理时用的和 TaoToken 的 Key 是两回事。你可以用openssl rand -hex 24生成一个 48 位十六进制串填进去。DEFAULT_MODEL是 Bridge 在请求里没带模型名时的兜底值。启动服务用一条命令node --env-file.env proxy.mjs服务默认监听http://127.0.0.1:4000。看到终端打印出监听日志就说明起来了。如果你想让它在后台常驻可以用nohup或者写个简单的 systemd unit但调试阶段建议前台跑方便看请求日志。这一步的关键点是TaoToken 的 Key 只出现在.env里不会写进auth.json。auth.json里放的是PROXY_AUTH_KEY这样即使配置文件被误传泄露的也只是本地代理的认证串不会直接暴露上游 Key。3. 可复制的 auth.json 与 settings 配置片段Codex 客户端的配置分两块一块是auth.json管鉴权和 endpoint另一块是模型相关的 settings管默认模型和请求参数。这两块要一起改只改一个会出现“认证过了但模型对不上”的情况。先看auth.json。它的默认位置在用户目录下的.codex/auth.jsonWindows 上是%USERPROFILE%\.codex\auth.json。改之前先备份一份cp ~/.codex/auth.json ~/.codex/auth.json.bak然后把内容改成指向本地 Bridge{ OPENAI_API_KEY: sk-proxy-local-替换成你的PROXY_AUTH_KEY, OPENAI_BASE_URL: http://127.0.0.1:4000/v1, tokens: { access_token: sk-proxy-local-替换成你的PROXY_AUTH_KEY, refresh_token: } }注意OPENAI_BASE_URL结尾要带/v1因为 Bridge 内部的路由是按/v1/responses和/v1/chat/completions来分发的。如果你只写到http://127.0.0.1:4000请求会打到根路径Bridge 找不到对应 handler直接返回 404。接下来是 settings。Codex 的模型配置一般在~/.codex/config.toml或者通过 CC Switch 这类工具管理。如果你用 CC Switch添加一个供应商字段这样填字段值名称codex-bridgeAPI 地址http://127.0.0.1:4000/v1API Keysk-proxy-local-你的PROXY_AUTH_KEY模型claude-sonnet-4-5如果你直接改config.toml对应的片段是model claude-sonnet-4-5 model_provider codex-bridge [model_providers.codex-bridge] name codex-bridge base_url http://127.0.0.1:4000/v1 env_key OPENAI_API_KEY wire_api responses这里wire_api responses是关键它告诉 Codex 用 Responses API 的格式发请求Bridge 收到后再转成 Chat Completions。如果你把它写成chatCodex 会直接发 Chat Completions 格式Bridge 的转换逻辑就不会触发等于绕过了协议映射。三件套对齐检查Base URL 是http://127.0.0.1:4000/v1Key 是PROXY_AUTH_KEYModel ID 是claude-sonnet-4-5。这三个值在auth.json、config.toml、Bridge 的.env里必须一致任何一处写错都会在验证阶段暴露出来。改完配置后重启 Codex 客户端让它重新读取auth.json。有些版本会缓存配置重启是最稳的做法。4. 用 curl 验证请求转发与响应回写配置改完不要急着在 Codex 里跑对话先用 curl 直接打 Bridge确认协议转换这一层是通的。这样出问题的时候你能快速判断是 Bridge 的问题还是 Codex 客户端的问题。第一条验证命令打 Responses API 形态的请求curl -sS http://127.0.0.1:4000/v1/responses \ -H Authorization: Bearer sk-proxy-local-你的PROXY_AUTH_KEY \ -H Content-Type: application/json \ -d { model: claude-sonnet-4-5, input: 用一句话说明什么是协议转换, stream: false }如果 Bridge 工作正常你会收到一个 Responses API 形态的响应结构里应该有output数组里面包含type: message的对象content里是模型返回的文本。这个响应是 Bridge 把上游的 Chat Completions 响应翻译回来的结果。第二条验证命令直接打 Chat Completions 端点确认 Bridge 的透传能力curl -sS http://127.0.0.1:4000/v1/chat/completions \ -H Authorization: Bearer sk-proxy-local-你的PROXY_AUTH_KEY \ -H Content-Type: application/json \ -d { model: claude-sonnet-4-5, messages: [{role: user, content: 回复 OK 两个字母}], stream: false }这条走的是直通路径Bridge 不做协议转换直接把请求转发到 TaoToken 的/v1/chat/completions。如果这条通而第一条不通说明问题出在协议映射逻辑上如果两条都不通说明是鉴权或者网络层的问题。流式请求也要验一下因为 Codex 默认是流式输出curl -N http://127.0.0.1:4000/v1/responses \ -H Authorization: Bearer sk-proxy-local-你的PROXY_AUTH_KEY \ -H Content-Type: application/json \ -d { model: claude-sonnet-4-5, input: 数到三, stream: true }-N参数关掉 curl 的缓冲你能看到 SSE 分块陆续打印出来。Bridge 需要正确处理分块转发把上游的data: {...}逐块翻译成 Responses API 的 SSE 事件格式。如果流式卡住不动多半是 Bridge 的流处理逻辑没适配好或者上游返回的 chunk 边界和预期不一致。验证通过后回到 Codex 客户端跑一次真实对话。如果客户端能正常出结果说明整条链路——Codex → Bridge → TaoToken → 模型 → 回写——已经打通。5. 401、协议不匹配与 reasoning_content 报错排查排错的核心思路是分层定位先确认鉴权再确认协议最后确认字段映射。下面按真实报错来拆。401 Unauthorized是最常见的。先看报错来自哪一层。如果 curl 打 Bridge 就返回 401说明PROXY_AUTH_KEY对不上。检查.env里的值和auth.json里的OPENAI_API_KEY是否完全一致注意有没有多余空格或者换行。如果 curl 打 Bridge 通了但 Codex 客户端报 401说明客户端没读到新的auth.json重启客户端或者检查文件路径是否正确。还有一种 401 是上游返回的Bridge 会把它透传回来。这种报错的响应体里通常带invalid_api_key字样。这时候要检查.env里的TAOTOKEN_API_KEY是否有效以及TAOTOKEN_BASE_URL是否写成了https://taotoken.net/api。如果 Base URL 写成了带/v1的地址Bridge 再拼一次路径就会变成/v1/v1/chat/completions上游会返回 404 而不是 401但表现上容易混淆。local proxy failed这类报错通常出现在 Codex 客户端侧意思是它连不上本地代理。先确认 Bridge 进程还在跑curl http://127.0.0.1:4000/v1/models能不能返回东西。如果连不上检查端口有没有被占用换一个端口要在.env和auth.json里同步改。防火墙一般不会拦本地回环但某些安全软件会临时关掉试试。reading choices 报错是协议不匹配的典型症状。Codex 期望响应里有output字段但拿到的是 Chat Completions 的choices解析器读不到就报错。这说明 Bridge 的响应转换没生效可能原因有两个一是请求走的是/v1/chat/completions直通路径没触发转换二是config.toml里wire_api写成了chat。把wire_api改回responses并确认 Codex 发的是/v1/responses请求。The reasoning_content in the thinking mode must be passed back to the API这个报错出现在带思考模式的模型上。模型在思考阶段返回了reasoning_content但下一轮请求里没有把这个字段带回去上游就拒绝。Bridge 需要在转换时保留reasoning_content并在后续请求的 messages 里回传。如果你遇到这个错检查 Bridge 版本是否支持 reasoning 透传或者临时在请求里关掉思考模式。OAuth 相关报错一般出现在 Codex 尝试刷新 token 的时候。因为auth.json里的refresh_token是空的Codex 可能会尝试走 OAuth 流程。解决办法是确保tokens.access_token有值并且OPENAI_API_KEY也填了让客户端优先用 API Key 认证而不是 OAuth。排查时养成看 Bridge 终端日志的习惯。每次请求进来日志里会打印请求路径、目标 URL、响应状态码。对照日志和 curl 的结果能快速定位是本地代理的问题还是上游的问题。6. 把链路固定下来的几个操作习惯跑通之后建议把 Bridge 做成开机自启或者用进程管理工具托管避免每次用 Codex 前手动起服务。Windows 上可以写个.cmd脚本丢进启动目录macOS 和 Linux 用 systemd 或者 launchd 都行。关键是让node --env-file.env proxy.mjs这条命令在后台稳定运行。.env文件不要提交到任何仓库里面既有 TaoToken 的 Key 也有代理认证串。如果多人共用一台机器给每个人分配不同的PROXY_AUTH_KEY这样在 Bridge 日志里能区分是谁的请求。模型切换通过改.env里的DEFAULT_MODEL或者在请求里显式带model字段来实现。Codex 客户端侧的模型名和 Bridge 实际转发的模型名可以不一致但建议保持一致减少排查时的认知负担。验证通道是否还活着最省事的办法是定时跑一条 curlcurl -sS -o /dev/null -w %{http_code} \ http://127.0.0.1:4000/v1/models \ -H Authorization: Bearer sk-proxy-local-你的PROXY_AUTH_KEY返回 200 就说明 Bridge 和上游通道都正常。把这个命令挂到 cron 里出问题能第一时间发现。需要生成新的 TaoToken Key 或者查看额度用量去控制台的 API Keys 页面操作。接入文档里有各语言 SDK 的调用示例如果你要在 Bridge 之外再写点脚本直接调 TaoToken可以参考文档里的 Base URL 和鉴权头格式。长期用 Codex 做编码和 Agent 任务的话Coding Plan 的额度模型比按量计费更适合高频调用场景。
返回列表