把Codex接入DeepSeek这件事,我前前后后折腾了快一周。一开始以为就是换个API地址的事,结果什么gpt-5.6-sol model is not supported、cc switch local proxy failed while handling codex endpoint /responses、codex ran out of room in the model's context,一个比一个难搞。这篇就把Codex CLI接入DeepSeek第三方模型的完整过程写清楚,重点讲V4 Flash、Pro、Vision三个模型的定位、配置方法和切换方式,同时把我用ccswitch、harness适配层、直接改config.toml这三条路的实测经验和踩坑记录都放出来。适合手里已经装了Codex但不想被官方账号锁死模型、想切换到DeepSeek跑任务的开发者,也适合刚接触Codex还不知道怎么配第三方模型的新手。
1. 为什么非要把Codex和DeepSeek绑在一起
1.1 官方Codex的账号模式有多拧巴
Codex CLI本身是个好工具,但如果你走的是ChatGPT账号登录模式,模型基本是锁死的。它在签名请求时会复用账号绑定模型的固定配置,你想在配置里把模型名改成DeepSeek,CLI一校验就直接报the 'gpt-5.6-sol' model is not supported when using codex with a chatgpt account这种错,意思是当前账号上下文里根本不认这个模型名。这就逼着人必须在API Key模式下走自定义provider,才能绕开账号层那套固定校验逻辑。
说白了,官方CLI的账号模式是为ChatGPT订阅用户准备的,你想让它"用别人的引擎跑自己的车",就得从配置层面把整个模型提供方替换掉。再加上很多人反映官方接口在部分网络环境下延迟偏高,链接不稳定,就更有理由把模型源切到DeepSeek这类国内访问更顺畅的服务上。
1.2 DeepSeek V4系列三个模型怎么选
DeepSeek开放平台目前主推的三个模型,对应不同使用场景,我简单整理了一张表:
| 模型 | 定位 | 适合场景 |
|---|---|---|
| V4 Flash | 低延迟、高吞吐 | 日常代码补全、快速问答、批量小任务、多轮对话 |
| V4 Pro | 高推理能力 | 复杂架构设计、跨文件重构、疑难Bug排查、长链路逻辑分析 |
| V4 Vision | 多模态视觉理解 | 截图传代码、UI稿还原、把报错图片变成可读错误信息 |
Flash和Pro的区别很像"日常代步车"和"越野车":改个函数、写段脚本,Flash完全够用,响应快还便宜;但你要让它分析整个项目的依赖关系、设计模块拆分方案,Flash经常给出来的是"看似合理但经不起推敲"的方案,这时候切Pro明显稳得多。Vision则是单独一个赛道,适合我这种习惯把报错截图直接丢给终端的用户。
这里提醒一句,不同时间DeepSeek的模型命名可能会有调整,配置时以开放平台后台实际返回的模型名为准。
1.3 三条接入路线,各自解决什么问题
我实测下来,把Codex接到DeepSeek一共有三条主流路线:
- 路线A:直接改config.toml。Codex CLI原生支持自定义
model_provider,把base_url指到DeepSeek的API地址,再配上DeepSeek的API Key就行。优点是步骤最少、最快跑通;缺点是一个配置同时只能挂一个模型,想切换得手动改配置。 - 路线B:ccswitch本地代理。Codex原生走的是OpenAI的Responses协议,不少第三方模型只支持Chat Completions协议,ccswitch这类工具在本地起一个代理端口,把
/responses请求转成DeepSeek认识的格式。适合需要在多套模型、多套环境之间来回切换的人。 - 路线C:harness适配层插件。社区的harness方案会在Codex CLI外面包一层适配器,处理协议转换之外,还能做请求扩展、上下文压缩、会话恢复,适合高强度连续使用的场景。
先别急着选,往下看每一步的实操,你就知道该走哪条了。
2. 动手前备齐四样东西:CLI、API Key、Node环境和连通性
2.1 安装Codex CLI并确认版本
Codex CLI是npm包,安装方式很简单:
npm install -g @openai/codex codex --version如果codex命令找不到,多半是npm全局bin目录没加到PATH里。可以用npm config get prefix看安装路径,把对应的bin目录导进shell配置。我装的时候遇到一个坑是Node版本太老,CLI直接报语法错误,升级到Node 18以上就好了。
装完之后先别登录ChatGPT账号,直接保持未登录状态,后面我们用API Key模式跑第三方provider,这样能避开账号模型锁定的问题。
2.2 申请DeepSeek API Key并搞清楚模型名
去DeepSeek开放平台注册账号,创建一个API Key,创建完只显示一次,记得立刻复制保存。计费是预付费模式,先充值再调用,建议第一次少充一点测试用。
拿到的Key是sk-开头的长字符串,后面配置里会用到。同时去平台文档里确认你当前可选模型的确切名称,比如deepseek-v4-flash、deepseek-v4-pro、deepseek-v4-vision这类命名。我见过太多人栽在模型名上,填了个旧的或者不存在的名字,DeepSeek那边直接返回model not found。
2.3 环境变量、协议选择和连通性自检
我习惯把Key放到环境变量里,而不是直接写死在config.toml中,这样配置文件可以提交到仓库、也不会不小心泄露凭证。在~/.bashrc或~/.zshrc里加一行:
export DEEPSEEK_API_KEY="sk-你的key"然后source ~/.bashrc或重开终端。接下来用一个最简单的curl请求验证Key和网络连通性,注意DeepSeek的API地址通常兼容OpenAI格式,路径一般是/v1/chat/completions:
curl -N https://api.deepseek.com/v1/chat/completions \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $DEEPSEEK_API_KEY" \ -d '{"model":"deepseek-v4-flash","messages":[{"role":"user","content":"ping"}],"stream":true}'如果返回一串SSE格式的内容,说明Key、网络、模型名都没问题。这一步我强烈建议先做,跳过它直接去配Codex,后面报错时你根本分不清是Codex的问题还是API的问题。
3. 改config.toml直连DeepSeek:最快跑通主流程
3.1 认识~/.codex/config.toml的结构
Codex CLI的全局配置在~/.codex/config.toml,可以使用codex --config查看加载路径。这个文件遵循TOML格式,核心就是两块:一块是顶层设置项(当前模型、当前provider、沙箱模式),一块是[model_providers.xxx]这样的provider定义。
一个最简配置长这样:
model = "deepseek-v4-flash" model_provider = "deepseek" [model_providers.deepseek] name = "DeepSeek" base_url = "https://api.deepseek.com/v1" env_key = "DEEPSEEK_API_KEY" wire_api = "chat"model指定模型,model_provider指定走哪个provider,[model_providers.deepseek]里的base_url是API地址,env_key告诉CLI从哪个环境变量读Key,wire_api决定协议类型。这里wire_api = "chat"是核心,Codex默认走Responses协议,但DeepSeek的兼容接口一般走Chat Completions,一定得显式标出来。
3.2 为什么wire_api要设成chat
Codex CLI原生跟OpenAI通信时用的是/responses端点,这个端点在协议层面做了很多新东西,比如更结构化的输入输出、内置工具调用格式等。但第三方模型服务很多只实现了更通用的/chat/completions,也就是传统Chat Completions格式。
wire_api = "chat"就是让Codex在发请求时把载荷改写成Chat Completions的格式发出去,同时把返回结果再翻译回CLI能理解的结构。不设这个字段,Codex会默认走responses,然后DeepSeek侧不认这个路径,返回404或者400,表现就是请求发出去石沉大海,或者直接报/responses端点错误。
如果DeepSeek官方文档明确说支持Responses协议,那你可以把wire_api留空或改成responses,但以我当前的实测经验,Chat模式兼容性最稳。
3.3 三个模型的切换:直接改model字段就够
配置一次provider之后,切换模型就是改一个字段的事:
model = "deepseek-v4-flash" # model = "deepseek-v4-pro" # model = "deepseek-v4-vision"- 写脚本、改Bug、跑测试:用
deepseek-v4-flash,响应速度快,能明显感觉到对话有来有回。 - 设计架构、大规模重构、分析复杂日志:切换成
deepseek-v4-pro,思考链路更长,给出来的方案更完整。 - 需要看截图、描述图片内容:切换成
deepseek-v4-vision。在Codex里可以直接把图片路径塞进对话,也可以复制截图后在终端粘贴,模型会解析图片内容,把报错截图里的堆栈信息读出来,这个在排查前端问题时特别好用。
3.4 项目级配置:不同目录用不同模型
全局配置对所有目录生效,但如果你有不同的项目想用不同的模型,可以在项目根目录下单独放一份config.toml,Codex启动时会优先读取当前目录的配置,覆盖全局配置。
我实际使用中会同时建两个配置文件样板,比如一个config.toml默认Flash跑日常,一个config.pro.toml作为Pro的备用,想切换时复制替换即可。也可以用CODEX_HOME环境变量指向不同配置目录,适合场景隔离更严格的情况。
3.5 直连模式的局限
这条路线唯一的痛点是:一次只能挂一个模型。虽然切换模型只是改一行配置,但对于高频切换Vision和Pro的场景还是有点烦。而且直连模式下做不了上下文压缩、自动续传这类高级处理,对话一长就容易撞上长度上限。所以如果你只是轻量使用,直连足够了;一旦用成日常主力工具,ccswitch或harness的路子更省心。
4. ccswitch本地代理与harness适配:多环境切换的进阶玩法
4.1 ccswitch到底干了件什么事
ccswitch这类工具的思路很直接:在你本地起一个代理服务,你把它当成一个假的OpenAI API服务端配给Codex,它收到Codex发来的/responses请求后,内部转换成DeepSeek能处理的/chat/completions请求,再把结果转回Responses格式返回给Codex。
之所以需要这么一层,是因为Codex在协议层面对/responses有强校验,而第三方模型服务千差万别。本地代理的好处是你可以把多套provider配置集中管理,想要切换模型时不用改Codex的config.toml,直接在ccswitch界面里切就行,对频繁跨模型工作的场景友好得多。
4.2 ccswitch配置中的经典报错:local proxy failed
很多人在ccswitch里添加DeepSeek provider后,Codex一发起请求,ccswitch界面或Codex日志里就出现:
cc switch local proxy failed while handling codex endpoint /responses. provider ...这个报错我排查了很久,最终定位到三个原因,按出现频率排序:
- 模型名不匹配:ccswitch里配置的模型名跟DeepSeek实际模型名不一致。Codex会把
model字段原样发给代理,代理再转发给DeepSeek,任何一边名字对不上都会失败。 - 协议映射错误:ccswitch把
/responses转成Chat Completions后,model字段没做映射,或响应格式里缺少必要字段。可以先把ccswitch日志打开,看它转发出去的真实请求体和返回内容。 - 代理端口没监听:Codex配置的base_url写的是
http://127.0.0.1:xxxx,但ccswitch的代理端口没启动或端口号填错。
排查链路建议这样走:
# 1. 确认代理端口在监听 lsof -i :端口号 # 2. 模拟Codex发起responses请求(注意是responses端点) curl -N http://127.0.0.1:端口号/v1/responses \ -H "Content-Type: application/json" \ -H "Authorization: Bearer dummy" \ -d '{"model":"deepseek-v4-flash","input":"hello"}' # 3. 看返回是代理层的错,还是转发到DeepSeek后返回的错如果是代理层直接抛错,多半是ccswitch版本和Codex版本不兼容,升级ccswitch或换一个release版本;如果是DeepSeek返回的错误,问题在模型名或base_url上。
4.3 DeepSeek Harness适配层怎么装
社区里常说的harness适配层,本质是一个给它加扩展的插件系统,让Codex除了原生协议之外,还能挂各种自定义行为,比如请求扩展、上下文压缩、自动续传讨论。安装步骤一般是:
- 从仓库下载对应平台的harness安装包,解压到本地方便管理的目录。
- 找到harness的插件目录,在配置里启用DeepSeek相关plugin。
- 设置你的DeepSeek Key(通常会复用
DEEPSEEK_API_KEY环境变量)。 - 在Codex的config.toml里把base_url指向harness暴露的本地地址。
- 重启Codex,运行一条简单指令验证。
装好后最能感受到区别的是上下文管理:普通直连模式跑长任务,对话一长就容易撞到限制;harness会自动做压缩,把之前的讨论精简后再送进模型,相当于变相延长了单次会话的可用深度。
4.4 本地代理和harness的取舍建议
我的实际感受是:
- 只想要"能用DeepSeek",走直连。
- 想要"多个模型切换方便",上ccswitch。
- 想要"连续干一天的活不炸上下文",harness的收益最大。
这三者不是互斥关系,有人用ccswitch做协议桥接,同时用harness做上下文管理,叠加使用效果最好,但配置复杂度也相应上升。新手建议先从直连跑通,再逐步加层。
5. 高频报错排查手册:每一个我都踩过
5.1 "model is not supported"——账号锁定模型的锅
报错里带model is not supported when using codex with a chatgpt account,几乎可以断定你当前登录的是ChatGPT账号模式。这个模式下CLI会校验模型是否在当前订阅允许列表中,自定义模型名自然过不了。
解决方法是退出账号登录状态,改用API Key + 自定义provider。如果退出之后依然报,检查config.toml里是不是还有残余的账号配置字段,直接清掉重写。
5.2 "ran out of room in the model's context"——上下文放不下了
完整报错是error running remote compact task: codex ran out of room in the model's context。这个发生在Codex尝试远程压缩上下文时,模型上下文窗口已经满了,连压缩用的临时空间都不够。
常见触发场景是:一个会话里做了大量文件检索、贴了超长日志、连续多轮代码生成且没清理。解决顺序是:
- 立刻
/new开新对话,别在旧会话里硬撑。 - 旧对话里确实还有要用的信息,手动把关键内容提炼出来贴到新对话。
- 调整Codex配置里的上下文窗口参数,比如设置更大的上下文窗口值,但注意第三方模型本身的真实上限。
- 减少每次丢给模型的文本量,别一次性把整个日志文件塞进去,先截断再贴。
5.3 "request extension preparation failed"与"正在重新连接"
这个报错我在用harness扩展时遇到过:deepseek request extension preparation failed。含义是harness在把请求交给模型前,准备阶段就失败了。原因多数是harness插件版本和Codex版本不匹配,或者插件的配置项缺失。
排查思路:
- 查看harness日志,确认是插件加载失败还是请求构造失败。
- 确认你启用的DeepSeek插件需要哪些配置项,逐一补齐。
- 尝试临时禁用harness,用直连模式跑同一条指令,如果直连正常,问题基本锁定在harness扩展上。
Codex终端一直转圈显示"正在重新连接",一般是请求超时或连接被重置。先确认网络到DeepSeek的连通性,再检查是不是有HTTP_PROXY/HTTPS_PROXY这类终端环境变量导致流量被转到了异常地方,必要时临时unset这些变量再试。
5.4 DeepSeek返回"达到对话长度上限,请开启新对话"
这个不是Codex的报错,是DeepSeek接口返回的明确提示。意思是当前请求的token总量(输入+输出)超过了模型单次处理的长度上限。别想着调参数绕过去,直接新开对话。把旧对话里重要的结论复制出来作为新对话的背景信息,是最务实的做法。
5.5 连接类错误与超时调优
代码里最常见的是dial tcp、connection refused、EOF这类网络错误:
connection refused:看base_url是不是少写了端口或路径不对。dial tcp: i/o timeout:确认服务器地址能否访问,也可以在provider里加长超时时间。- 请求发出去后一直没有响应直到超时:用curl先测试接口,如果curl没问题,多半是Codex侧的流式解析出了问题,重启CLI或升级到新版本。
5.6 "出问题先重启、先看日志"的通用排查套路
我总结了一个排查顺序,省了很多冤枉时间:
- 先用curl直连DeepSeek,排除Key和模型名问题。
- 看Codex日志,通常在
~/.codex/log或通过--verbose参数输出。 - 看代理/harness日志,确认请求有没有被正确转发。
- 做最小化复现:清掉自定义配置,只保留provider和模型名,把额外的插件全部禁用。
按这个顺序排查,大多数问题十分钟内能定位。
6. 用了一个月后的实际建议
6.1 日常组合怎么定
我现在固定用Flash做日常编码,响应快、跑小任务几乎没有等待感;遇到要梳理项目结构、设计调用链、做代码评审时切Pro;截图里的报错信息直接丢给Vision。如果你也是刚配好,建议也按这个组合用,别拿Flash硬扛复杂任务,也别拿Pro跑简单问答浪费钱。
6.2 活用"新对话"而不是硬续
Codex的对话不是越长越好。我见过很多人在同一个会话里跑了几小时后模型开始"答非所问",还在继续纠缠。其实上下文一长,模型注意力会被大量早期内容稀释,回答质量断崖式下降。正确做法是定期开新对话,把旧对话的关键结论带过去,让模型轻装上阵。
6.3 给API Key设置消费上限
用第三方API接Codex有一个感受很明显:烧钱速度比想象快。特别是开thinking功能跑Pro模型,一次复杂任务可能消耗巨大。一定要在DeepSeek后台设置单日消费上限,避免测试时忘关导致一夜跑光余额。
6.4 配置改了不生效?先怀疑缓存
我遇到过好几次改了config.toml,重启Codex还是旧配置,甚至出现模型名明明改了却依然报旧模型的错。解决方式是确保Codex完全退出再重启,或者用codex --config确认当前加载的配置路径,有时路径不对,改了也没人看。
另外一个细节:如果你用了ccswitch或harness,Codex侧base_url指向的是本地代理端口,而不是DeepSeek的公网地址,配置的时候一定分清这一层。改错地方是排查中最常见的人为失误。
最后分享一个我个人的习惯:把模型配置、测试命令和常见报错记在项目根目录的CODEX_NOTES.md里,换机器时照着从头配一遍,十分钟就能恢复全套环境。这套流程跑顺之后,Codex配上DeepSeek真正成了我日常开发里顺手得很的搭档,希望你也能尽快跑到这一步。