十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Codex本地代理配置实战:接入DeepSeek并解决reasoning_content报错

Codex本地代理配置实战:接入DeepSeek并解决reasoning_content报错 最近在折腾 Codex 的同学估计不少人都撞上过这串报错cc switch local proxy failed while handling codex endpoint /responses. provider: deepseek; model: deepseek-v4-flash; upstream_status: http 400; cause: the reasoning_content in the thinking mode must be passed back to the api.我第一次看到它的时候下意识以为是自己配置文件写错了翻来覆去查了两小时最后才发现问题根本不在 Codex 这边而是出在“本地代理”这一层——代理把 Codex 的请求转发给 DeepSeek 时没有把模型返回过的思考内容reasoning_content原样回传于是上游直接甩了个 400。这次折腾让我彻底把“Codex 本地代理”这件事摸透了。简单说就是把 Codex CLI 默认连官方云端的流量改指到本机跑的一个代理服务上比如 CC Switch、one-api、LiteLLM 这类东西再由这个代理帮你转发到任意兼容的模型服务最典型的就是 DeepSeek。这么一搞模型可以随便换计费可控请求链路透明还能顺手解决官方模型在某些场景下不支持、连接不稳的问题。这篇把我配置 Codex Proxy 的全过程、用到的配置模板、以及踩过的那几个经典坑都整理出来适合手里有 Codex CLI、又想接 DeepSeek 或本地模型的开发者参考。1. 为什么非要把 Codex 变成本地 API1.1 原生 Codex 到底卡在哪Codex 默认的用法是登录官方账号、走官方云端推理模型和额度都是别人定好的。实际用下来有几个点会让人很别扭。首先是模型选择太少。Codex 内置了严格的白名单逻辑你甚至能看到类似的报错{detail:the gpt-5.6-sol model is not supported when using codex with a...}意思就是 Codex 在做某些操作时会强制校验模型名你不在这张白名单里它就拒绝执行。我明明只是想用自己的 API Key 调一个别家的模型Codex 偏偏不认这就很浪费感情。其次是成本和网络链路。官方接口按量计费做点小工具、跑几个批量任务账单走得飞快。而且对不少用户来说直连官方服务的网络链路并不总是顺畅响应时快时慢周末高峰期甚至能卡到怀疑人生。把流量导到本地代理后起码请求链路是你自己能控制的。最后是数据流向不透明。默认模式下你的代码片段、对话上下文一股脑全发到远端中间发生了什么你完全不知道。有了本地代理你可以随时看日志、做拦截、甚至加一层缓存或脱敏心里踏实很多。1.2 本地代理到底帮你做了什么我打个比方。Codex 是司机模型服务是餐厅你本来只能去指定的那家“官方餐厅”吃饭。但你把 Codex 指到本地代理后等于在司机和餐厅之间加了一个“美食中转站”司机只认这一个中转站中转站再根据你当天的口味帮你把餐送到不同餐厅。请求链路变成这样Codex CLI ↓ 本地地址http://127.0.0.1:代理端口 本地代理CC Switch / one-api / LiteLLM ↓ 真实地址https://api.deepseek.com 或 http://localhost:11434 上游模型服务DeepSeek / Ollama / vLLM ...代理的好处归纳起来就四条模型可插拔。换模型时只改代理配置Codex 侧的 base_url 永远不用动。协议能转换。Codex 默认走 Responses APIDeepSeek、Ollama 很多只支持 Chat Completions代理可以帮你做格式互转。明细可观测。每个请求的耗时、token 用量、成功失败一目了然。Key 集中管理。不同服务商的 Key 都放在代理里Codex 只需要知道代理这一个地址不用到处塞 Key。这四点在直连模式下都做不到。尤其是“协议转换”那是后面reasoning_content报错的根源也是本地代理最重要的功能之一。2. 动手前的环境准备2.1 装好 Codex CLICodex CLI 的安装不算复杂最推荐的方式是用 npm 全局安装npm install -g openai/codex装完验证一下版本codex --version如果命令找不到八成是 Node.js 没装或者版本太旧。Codex 对 Node 版本有要求建议直接上 Node.js 20 LTS 或更新版本。Windows 用户要注意 npm 全局目录在不在 PATH 里装完以后如果提示“codex 不是内部或外部命令”去把C:\Users\你的用户名\AppData\Roaming\npm加进环境变量再重开终端。除了 npm 包OpenAI 也出了桌面版客户端但 CLI 版本配置起来更直观而且和本地代理配合最顺。我个人建议用 CLI所有配置收敛在一个config.toml文件里出问题也好排查。2.2 先搞清楚 Codex 的配置读取逻辑Codex 的配置文件路径在macOS / Linux~/.codex/config.tomlWindows%USERPROFILE%\.codex\config.toml这个 TOML 文件是核心负责指定默认模型、默认 provider、以及每个 provider 的地址和鉴权方式。Codex 启动时会按“命令行参数 环境变量 配置文件”的顺序去解析配置所以如果发现改了配置文件没生效先想想是不是有环境变量把配置覆盖掉了。和代理配置相关的几个环境变量OPENAI_API_KEY # 通用 Key很多 provider 没单独配置时会读它 OPENAI_BASE_URL # 通用 API 地址优先级低于 config.toml 里的 base_url DEEPSEEK_API_KEY # provider 里通过 env_key 指定的 Key需要特别注意的是Codex 的配置模型和普通 OpenAI SDK 不完全一样。它不是只读一个OPENAI_BASE_URL就完事而是要求你在[model_providers.xxx]里明确定义 provider再用顶层model_provider字段指向它。这个设计一开始我也觉得多余但用熟了才发现它更适合多模型场景你能在同一个配置文件里放好几个 provider随时切换。2.3 准备 API Key 和上游服务既然要走代理上游得有货。最常见的两个选择一是 DeepSeek 开放平台。注册后在控制台创建 API Key按量充值。模型名以官方控制台为准通常有 deepseek-chat 这种通用对话模型也有带推理能力的 reasoning 模型。这个 reasoning 模型就是我们后面要重点注意的“大爷”它对请求格式要求很多。二是本地模型服务比如 Ollama 或 vLLM。Ollama 启动后默认监听http://localhost:11434vLLM 则是你启动时指定的端口。它们的好处是完全免费、数据不出本机坏处是模型能力相比云端大厂还是差点跑代码生成这种复杂任务会明显吃力。我个人建议刚上手时先用 DeepSeek 把链路跑通等确认没问题再换本地模型做对照测试。先用一个可靠的云端模型排查配置问题不然本地模型一慢你分不清是网络问题还是配置问题。3. Codex Proxy 配置实战3.1 一份可以直接抄的 config.toml先给一个通用模板跑通本地代理最核心的配置就这些# ~/.codex/config.toml model deepseek-chat model_provider local-proxy [model_providers.local-proxy] name Local Proxy base_url http://127.0.0.1:1568 env_key LOCAL_PROXY_API_KEY wire_api chat逐行拆开说。model是告诉 Codex“我这个会话默认用哪个模型名”。这里填的模型名会出现在发往代理的请求体里所以它不一定要和上游官方名称完全一致取决于你的代理怎么映射。比如代理配的是“收到 deepseek-chat 就转发给 DeepSeek收到 llama3 就转发给 Ollama”那model填什么就变成了一种路由规则。model_provider是指定使用下面哪个 provider 块。[model_providers.local-proxy]是定义一个名为 local-proxy 的 provider。块里的name是给人看的展示名。base_url是本地代理地址这里注意CC Switch、one-api 这类工具启动后会在本机监听一个端口界面上会显示完整地址形如http://127.0.0.1:端口号以你实际看到的为准。如果代理服务托管在另一台机器上也可以填局域网 IP但跨机器用的时候要确认端口放行了。env_key是 Codex 读取 API Key 用的环境变量名。本地代理一般不做严格鉴权随便给个变量名、值随便填都行export LOCAL_PROXY_API_KEYsk-local-no-auth-needed如果你不想登录的时候还要手动 export也可以把 Key 写进 shell 的启动配置里。总之关键是让 Codex 在请求头里带上一个 Authorization否则某些代理会认为请求非法。wire_api是很容易被忽略但很重要的字段。它决定 Codex 用哪种协议格式和代理通信chatChat Completions 格式DeepSeek、Ollama、大部分国产模型都吃这套。responsesOpenAI Responses API 格式Codex 默认偏好但第三方模型大多不原生支持。当你走本地代理时代理通常已经帮你把协议处理好了所以这里填chat最稳。我在下一节会详细展开这个选择。3.2 用 CC Switch 管理多套代理配置CC Switch 是我目前用过最顺手的 Codex / Claude Code 代理切换工具桌面客户端Windows 和 macOS 都有。它的思路很简单把各家的 API 地址和 Key 存在客户端里启动一个本地代理你只需要把 Codex 指到代理地址就行。实际操作流程大概是下载安装 CC Switch打开后进配置页新增一个 Provider 配置。填上游服务商信息比如 DeepSeekbase_url 填https://api.deepseek.com模型列表里加上你想用的模型名再粘贴 API Key。打开本地代理开关界面会显示一个本地地址比如http://127.0.0.1:1568。把这个地址填进 Codex 的config.toml也就是前面那个base_url。在 CC Switch 里切换不同提供商时Codex 侧完全不用动因为 Codex 只认本地代理这一个地址。这个“只认一个地址”的设计真的省心。我之前用多个模型时经常要在 Config 文件里改 base_url改来改去就出错了。现在切换就是点一下鼠标的事。如果你用的是 one-api、new-api 或者 LiteLLM 这类服务思路一模一样区别只是代理地址是远程的、还是本机的配置字段完全兼容。3.3 验证配置从一行命令开始配置写好了先别急着开完整交互模式用一个非交互命令快速验证codex exec 用一句话介绍你自己如果配置正确你会看到模型返回一句话。如果失败Codex 会打印错误信息。这一步我强烈建议你认真看输出。很多问题从表面上看是“Codex 挂了”实际上错误信息里已经写清了是哪一层出了问题。比如upstream_status: http 400 cause: the reasoning_content in the thinking mode must be passed back to the api.意思就是代理已经把请求转发到了上游DeepSeek但上游拒绝执行原因是请求缺少reasoning_content。这是“代理层转换不完整”的问题不是 Codex 配置的问题。还可以直接用 curl 打一次代理看代理本身是否正常curl http://127.0.0.1:1568/v1/chat/completions \ -H Content-Type: application/json \ -H Authorization: Bearer sk-test \ -d { model: deepseek-chat, messages: [{role: user, content: hi}] }如果代理正常这一步会返回完整的 JSON 响应这也方便你确认返回里有没有reasoning_content字段。4. 把 DeepSeek 等第三方模型接进来4.1 DeepSeek 配置API Key 与模型选择把 DeepSeek 接到本地代理这一步不复杂核心是搞明白它提供的两类模型通用对话模型如 deepseek-chat速度快、价格低适合日常问答、代码解释、简单重构。推理模型reasoning 系列会先输出一段“思考过程”再给出答案复杂代码生成、算法题、架构设计这类任务明显更强。热搜里那个deepseek-v4-flash就带推理能力。为什么这点很重要因为带推理能力的模型在通过代理接入 Codex 时会额外引入一个“思考内容回传”的问题。DeepSeek 的接口约定是在多轮对话中只要上一轮模型返回过reasoning_content你下一轮请求就必须带上它否则直接 400。这不只是 Codex 会碰到任何客户端接 reasoning 模型都要处理这条规则。我建议初次调试时先用不带推理的 deepseek-chat 把链路跑通等稳定了再切到 reasoning 模型。这样起码能把“配置问题”和“推理内容处理问题”分开排查。4.2 wire_api 选 chat 还是 responses这是配置里最容易懵的地方。Codex CLI 本身是 OpenAI 的产物默认偏向使用较新的 Responses API。但 DeepSeek、Ollama、以及市面上大多数模型服务只实现了 Chat Completions API两者请求体结构不一样不能混用。如果你选择直连上游那 Codex 的wire_api必须和你目标服务支持的一致。DeepSeek 官方只支持 chat 风格所以你要是把 Codex 直连 DeepSeekwire_api就得填chat同时祈祷 Codex 的响应解析逻辑能和 DeepSeek 返回的字段兼容。如果你走本地代理情况就灵活多了。代理能做协议互转它可以把 Codex 发来的 Responses 请求转成 Chat Completions 再发给 DeepSeek。但“能转”不等于“转得好”区别恰恰在reasoning_content这个字段上好的代理会把请求里的推理上下文完整透传也会把模型返回的reasoning_content保存下来在后续轮次里塞回去。一般的代理简单做个格式映射丢三落四一旦遇到推理模型就报 400。所以wire_api填chat能避开不少麻烦因为 chat 请求本身就是 DeepSeek 的“母语”代理不需要做复杂转换。如果代理固化了 Responses 到 chat 的转换路径而转换逻辑又没处理好那就按我后面第 5 节的方法去排查。4.3 其他上游Ollama、vLLM等 DeepSeek 链路稳定了再塞一个本地模型作为免费备选就很有性价比了。Ollama 的接入很简单。先启动服务ollama serve确认默认端口 11434 在监听然后在 CC Switch 或 one-api 里加一个 providerbase_url 填http://localhost:11434模型填qwen2.5-coder:14b这类你本地已经拉取的模型Codex 侧的配置不用动。vLLM 也类似你启动时指定好端口比如vllm serve Qwen/Qwen2.5-Coder-14B-Instruct --port 8000然后在代理里对应填http://localhost:8000/v1就行。用本地模型最大的好处是免费、离线、私密适合拿来做一些敏感代码的预处理。但话说回来本地小模型的代码生成质量和 Codex 官方模型还是有差距尤其是复杂的跨文件重构本地模型容易答非所问。所以我的用法是日常快速任务走 DeepSeek需要离线或隐私保护时才切本地模型。5. 常见问题与排查技巧实录5.1 reasoning_content 报错一个 400 的完整排查这是我最想详细写的一个问题因为它太有代表性了。报错原文长这样cc switch local proxy failed while handling codex endpoint /responses. provider: deepseek; model: deepseek-v4-flash; upstream_status: http 400; cause: the reasoning_content in the thinking mode must be passed back to the api.拆解一下cc switch local proxy failed while handling codex endpoint /responsesCC Switch 的本地代理在处理 Codex 发来的 /responses 请求时出错了。provider: deepseek; model: deepseek-v4-flash代理把请求转给了 DeepSeek模型是推理模型。upstream_status: http 400DeepSeek 返回了 400也就是请求格式不合法。cause: the reasoning_content ... must be passed back to the apiDeepSeek 明说了缺少推理内容回传。根因就像前面说的推理模型第一轮会返回reasoning_content里面是思考链内容。DeepSeek 为了保证多轮推理的连贯性要求客户端在下一轮请求里把这个内容原样带上。但本地代理从 Responses 格式转成 chat 格式时没有保留这个字段于是第二轮请求一到 DeepSeek 就被 400 弹回来了。解决方向有这么几个按优先级排列升级 CC Switch 到最新版。这种兼容性 bug 属于代理的高频修复点新版本大概率已经处理了。换不带推理的模型。把 model 换成 deepseek-chat 这类通用模型彻底绕开这个问题。在代理里关掉 thinking mode。部分代理在 model 配置里支持开关推理模式默认开着关掉即可。如果你用的是其他网关one-api、LiteLLM去查一下它们对reasoning_content的透传配置通常有相关的兼容开关。我最开始不知道这个逻辑一直在 Codex 配置里打转浪费了很多时间。后来用 curl 手动模拟请求一步一步加字段才定位到是代理丢弃了reasoning_content。5.2 gpt-5.6-sol model is not supported 是怎么回事这个报错全文通常是{detail:the gpt-5.6-sol model is not supported when using codex with a ...}出现这个错误通常是模型名触发了服务端或代理的某种校验。比如有些网关为了让 Codex 走通某些链路会在模型名上做手脚自动追加-sol、-think这种后缀一旦上游模型列表里没有这个“被加工过”的名字就会直接拒绝。处理办法把 Codex 配置文件里的model改回真正的模型名比如deepseek-chat不要带奇怪的后缀。如果是 CC Switch 这类代理自动改写模型名导致的代理设置里应该有关闭模型名改写或透传的选项关掉。在代理后台的“模型列表”里确认你填的模型真的存在大小写也要一致。这种问题本质上就是“名字对不上”模型路由是走名称匹配的差一个字符都不行。5.3 401、404、超时的通用定位思路除了上面两个特色报错剩下的 HTTP 状态码基本都是常规操作我整理了一个个人用的排查顺序401 UnauthorizedKey 没传对。先检查环境变量是否真的 export 了再看 provider 块里的env_key是否和变量名一致。如果走本地代理确认代理本身的鉴权规则有时候代理要求固定填某个 Key 才能放行。404 Not Found地址不对。最常见的是 base_url 少了/v1路径或者上游接口路径调整了。先用 curl 手动打一次上游地址确认地址本身可用。连接拒绝 / ECONNREFUSED本地代理没启动。先看 CC Switch 的代理开关是不是绿色的再telnet 127.0.0.1 端口测一下端口通不通。超时先确认是“连接超时”还是“响应超时”两者排查方向不同。连接超时多半是地址不通或防火墙拦截响应超时则是模型生成速度慢推理模型尤其明显可以把超时时间调大或者换更快的模型试试。排查这类问题我的习惯是先绕过 Codex直接 curl 打代理确认代理正常再 curl 打上游确认上游正常最后才回来查 Codex 配置。逐层剥离问题一定定位在某一层里。5.4 一份避坑清单最后把常见坑汇总成一张速查表方便你直接对照现象可能原因解决办法Codex 报 400提示 reasoning_content 必须回传代理丢弃推理内容字段升级代理版本 / 换非推理模型 / 关 thinking modegpt-5.6-sol model is not supported模型名被代理改写或服务器不支持改回真实模型名关闭模型名透传401 UnauthorizedAPI Key 缺失或不对检查 env_key、环境变量、代理的鉴权 Key404 Not Foundbase_url 路径少 /v1 或有误curl 手动验证上游地址连接被拒绝代理服务没启动检查端口监听状态确认代理开关打开改了配置不生效环境变量优先级高于配置文件检查 OPENAI_BASE_URL / OPENAI_API_KEY 是否残留推理模型回复质量差thinking mode 被误关在代理里重新打开推理开关模型返回内容被截断max tokens 太小在 Codex 配置里调整 max_tokens 或者看代理侧限制还有一些实操细节改完config.toml后有些 Codex 版本需要重启终端才生效别改完就盯着终端看半天。走代理时模型名既是“发给上游的名字”也是“路由规则”命名前想清楚别乱填。不要在团队共享的电脑上把 Key 写死在配置文件里用环境变量管理否则一次误提交 Key 就泄露了。最后再分享一个小技巧算是这次折腾里最值的一个心得在 CC Switch 里我常年放两套 DeepSeek 配置一套 deepseek-chat 用于日常问答和快速原型一套推理模型用于复杂代码生成。日常用前一档遇到硬骨头再切后一档成本和质量平衡得刚刚好。把 Codex 变成本地 API 后这些切换都是点鼠标的功夫再也不用来回改配置、重启终端了。你完全可以把这篇文章当成一个起点照着把链路跑通后再按自己的使用习惯去调模型路由和协议转换逻辑用起来会顺手很多。
返回列表