1. 为什么要把 Codex 接到 DeepSeek 上
Codex 这个命令行工具,用过的人都知道它的好:终端里直接对话、能读写文件、能跑命令、能理解整个项目上下文。但官方默认走的是 OpenAI 的模型,token 消耗一上去,账单就有点肉疼。而 DeepSeek 的 API 价格,说实话,用过的都懂——同样一段代码补全或者重构任务,成本能压到原来的零头,而且中文理解还更顺。
所以“Codex 接入 DeepSeek”这件事,本质上就是:保留 Codex 的交互体验和工程能力,把背后的推理引擎换成 DeepSeek。你依然在终端里敲codex,依然用自然语言让它改代码、查 bug、写测试,但请求实际发到 DeepSeek 的 API 端点,按 DeepSeek 的价格计费。
这件事适合谁?三类人最需要:
- 已经在用 Codex,但想控制成本的个人开发者;
- 团队里想统一用 DeepSeek 做代码助手,又不想放弃 Codex 工作流的;
- 单纯想折腾一下配置、搞清楚 Codex 的
config.toml到底怎么写的技术爱好者。
需要提前说清楚的是,Codex 和 DeepSeek 的 API 并不是“插上就能用”的。Codex 默认走的是 OpenAI 的 Responses API 格式,而 DeepSeek 提供的是兼容 OpenAI Chat Completions 的接口。这两者之间有差异,所以配置的核心难点就在于:让 Codex 把请求发到正确的端点,并且用正确的格式。下面我会把整个流程拆开讲,包括我踩过的坑。
2. 动手前的环境与账号准备
2.1 Codex 的安装与版本确认
Codex 的安装方式取决于你用的平台。目前主流的是通过 npm 全局安装,也有独立的安装包。我建议优先用 npm,因为升级方便,配置路径也统一。
npm install -g @openai/codex装完之后先确认版本:
codex --version这里有个经验:Codex 的配置格式在不同版本之间改过。早期版本和现在版本的config.toml字段名不完全一样,如果你照着半年前的教程配,很可能出现codex is ignoring 1 unrecognized configuration setting这种警告。所以第一步一定是确认版本,然后以你当前版本的文档为准。我实测下来,较新的版本对model_providers这块的支持更完整。
安装完成后,Codex 会在用户目录下生成配置文件夹。Windows 下是C:\Users\你的用户名\.codex\,macOS 和 Linux 下是~/.codex/。这个目录里最关键的文件就是config.toml,后面所有配置都围绕它展开。
注意:如果你之前登录过官方账号,
~/.codex/下可能还有auth.json之类的凭证文件。接入第三方 API 时,这些文件有时会干扰认证流程,建议先备份再处理。
2.2 DeepSeek API Key 的获取与验证
DeepSeek 的 API Key 在它的开放平台控制台里创建。创建时注意两点:一是 Key 只在创建时完整显示一次,务必当场复制保存;二是要确认账户里有余额,否则请求会直接返回 401 或 402。
拿到 Key 之后,不要急着往 Codex 里填,先用 curl 单独验证一下这个 Key 是活的:
curl https://api.deepseek.com/chat/completions \ -H "Content-Type: application/json" \ -H "Authorization: Bearer sk-你的key" \ -d '{ "model": "deepseek-chat", "messages": [{"role": "user", "content": "ping"}] }'如果返回正常的 JSON 补全结果,说明 Key 和网络都没问题。如果返回401 unauthorized: incorrect api key provided,那就是 Key 本身的问题,别往下折腾 Codex 了,先把 Key 搞定。这一步能帮你排除掉一大半“配置了半天发现是 Key 错了”的情况。
2.3 网络与端点的基础认知
DeepSeek 的 API 基础地址是https://api.deepseek.com,兼容 OpenAI 的调用格式。它的对话模型主要是deepseek-chat,推理模型是deepseek-reasoner。这两个模型在 Codex 里的表现不太一样:deepseek-chat响应快、适合日常改代码;deepseek-reasoner会先输出思考过程,适合复杂逻辑,但延迟高一些。
Codex 这边,它默认期望的是一个支持 Responses API 的端点。Responses API 是 OpenAI 推出的一套新接口规范,和传统的 Chat Completions 在请求体结构上有区别。DeepSeek 目前提供的是 Chat Completions 兼容接口,所以配置时需要通过model_providers显式指定wire_api,告诉 Codex 用哪种协议去对话。这是整个配置里最容易出错的地方,后面会详细讲。
3. config.toml 的核心配置拆解
3.1 配置文件的结构与关键字段
config.toml用的是 TOML 格式,结构上分几块:顶层设置(比如默认模型、默认 provider)、model_providers表(定义每个 API 提供方)、以及可选的mcp_servers等扩展配置。
一个能跑通 DeepSeek 的最小配置大概长这样:
model = "deepseek-chat" model_provider = "deepseek" [model_providers.deepseek] name = "DeepSeek" base_url = "https://api.deepseek.com" env_key = "DEEPSEEK_API_KEY" wire_api = "chat"逐行解释一下为什么这么写:
model指定默认使用的模型名,这里填 DeepSeek 的模型标识;model_provider指向下面定义的 provider 名称,必须和[model_providers.xxx]里的xxx一致;base_url是 API 根地址,注意不要在后面加/chat/completions,Codex 会自己拼接路径;env_key是环境变量的名字,Codex 会从这个环境变量里读 Key,而不是把 Key 明文写在配置里;wire_api = "chat"是关键,它告诉 Codex 用 Chat Completions 协议而不是 Responses 协议。
3.2 wire_api 为什么是成败关键
很多人配置完遇到cc switch local proxy failed while handling codex endpoint /responses这类报错,根源就在wire_api上。Codex 默认会往/responses这个路径发请求,这是 Responses API 的端点。但 DeepSeek 没有/responses这个端点,它只有/chat/completions。如果你不设置wire_api = "chat",Codex 就会傻乎乎地往一个不存在的地址发请求,然后失败。
我一开始就是漏了这一行,折腾了快一个小时,日志里全是 endpoint 相关的错误。加上wire_api = "chat"之后,Codex 就会改用 Chat Completions 的路径和请求体格式,DeepSeek 那边就能正常接收了。
提示:不同版本的 Codex 对
wire_api的可选值可能略有差异,常见的是chat和responses。如果你填了chat还报错,检查一下版本,看看是不是字段名变了。
3.3 API Key 的安全注入方式
把 Key 直接写进config.toml是能跑,但非常不推荐——配置文件容易被同步到云盘、被 git 提交、被截图分享。正确做法是用环境变量。
macOS / Linux 下,在~/.zshrc或~/.bashrc里加一行:
export DEEPSEEK_API_KEY="sk-你的key"Windows 下用 PowerShell:
setx DEEPSEEK_API_KEY "sk-你的key"设置完记得重开终端,或者 source 一下配置文件。然后在config.toml里用env_key = "DEEPSEEK_API_KEY"引用。这样 Key 就不会出现在任何会被分享的文件里。
如果你确实想图省事直接写 Key,Codex 也支持api_key字段,但请务必确认这个文件不会被同步或提交。我个人是坚决用环境变量的,踩过一次把 Key 提交到仓库的坑,虽然及时撤销了,但那种心惊肉跳不想再来一次。
4. 完整实操流程与验证
4.1 从零到跑通的完整步骤
把前面的内容串起来,完整流程是这样的:
- 安装 Codex 并确认版本;
- 获取 DeepSeek API Key 并用 curl 验证;
- 设置环境变量
DEEPSEEK_API_KEY; - 编辑
~/.codex/config.toml,写入 provider 配置; - 启动 Codex,发一条测试消息;
- 观察日志,确认请求打到了 DeepSeek。
第 4 步的配置文件,我建议先写最小版本,跑通之后再逐步加东西。最小版本就是 3.1 节里那段。写完之后,在终端里直接运行:
codex进入交互界面后,输入一句简单的话,比如“用 Python 写一个快速排序”。如果配置正确,你会看到 DeepSeek 返回的结果。这时候可以去看一下 DeepSeek 控制台的用量统计,确认确实有请求进来,费用也在扣。这一步的交叉验证很重要,能确认请求真的走了 DeepSeek 而不是别的地方。
4.2 验证请求是否真的走了 DeepSeek
光看 Codex 有输出还不够,因为有可能它还在走默认的官方端点。验证方法有两个:
一是看 DeepSeek 控制台的调用记录和余额变化。如果调用次数增加了,说明请求确实到了 DeepSeek。
二是临时把环境变量里的 Key 改成一个错误的字符串,重启 Codex 再发消息。如果报401 unauthorized: incorrect api key provided,说明 Codex 确实在用你配置的这个 Key 去请求 DeepSeek。这个反向验证很管用,我每次配新 provider 都会这么测一下。
4.3 模型选择与参数微调
跑通之后,可以根据任务类型切换模型。日常改代码、写注释、解释逻辑,用deepseek-chat就够了,响应快。遇到需要多步推理的复杂重构,可以切到deepseek-reasoner,它会先输出一段思考过程再给答案,质量更高但慢一些。
切换方式有两种:一是改config.toml里的model字段;二是在 Codex 交互界面里用命令临时切换(具体命令看版本,有的是/model)。我习惯把常用的写在配置里,临时需要推理模型时再手动切。
另外,DeepSeek 的上下文窗口很大,官方标称能到 100 万 token 级别。但要注意,Codex 在组装请求时会把项目文件、历史对话都塞进去,如果项目特别大,还是可能触发maximum context length的报错。遇到这种情况,要么精简上下文,要么在 Codex 里限制它读取的文件范围。
5. 常见报错与排查速查
5.1 认证类报错
unexpected status 401 unauthorized: incorrect api key provided是最常见的。原因无非三种:Key 写错了、Key 过期了、环境变量没生效。排查顺序是:先用 curl 单独测 Key,确认 Key 本身没问题;再检查环境变量是否在当前终端可见(echo $DEEPSEEK_API_KEY);最后确认config.toml里的env_key名字和实际环境变量名完全一致,大小写都不能错。
还有一种情况是api error: 400 this organization has been disabled,这通常是账号层面的问题,和配置无关,需要去 DeepSeek 控制台看账户状态。
5.2 端点与协议类报错
cc switch local proxy failed while handling codex endpoint /responses这个报错,前面提过,核心就是wire_api没设成chat。Codex 在往/responses发请求,而 DeepSeek 没这个端点。
{"detail":"the 'gpt-5.6-sol' model is not supported when using codex with a..."}这类报错,说明model字段填了一个 DeepSeek 不认识的模型名。检查一下是不是把 OpenAI 的模型名填进去了,DeepSeek 这边要用deepseek-chat或deepseek-reasoner。
5.3 配置解析类报错
codex is ignoring 1 unrecognized configuration setting是警告不是致命错误,但值得处理。它说明你的config.toml里有一个字段当前版本不认识,可能是拼写错误,也可能是废弃字段。比如mcp_servers.node_repl.type is ignored就是典型的字段不被识别。解决办法是对照当前版本文档,把不认识的字段删掉或改名。
chatgpt 无法加载 config.toml 因此此对话串无法继续这种报错,通常是 TOML 语法错误导致的,比如少了个引号、括号没闭合。TOML 对语法比较严格,建议用支持 TOML 高亮的编辑器写,能提前发现大部分语法问题。
5.4 排查速查表
| 报错关键词 | 最可能原因 | 解决方向 |
|---|---|---|
| 401 unauthorized | Key 错误或未生效 | curl 验证 Key,检查环境变量 |
| endpoint /responses failed | wire_api 未设为 chat | 配置里加wire_api = "chat" |
| model is not supported | model 字段填错 | 改为 deepseek-chat |
| unrecognized configuration setting | 字段拼写错误或废弃 | 对照版本文档删改字段 |
| 无法加载 config.toml | TOML 语法错误 | 用编辑器检查语法 |
| maximum context length | 上下文超限 | 精简项目文件或对话历史 |
6. 我踩过的坑和几条实用经验
第一个坑是配置文件路径搞错。Windows 下.codex文件夹是隐藏的,很多人找不到,就自己在别处建了一个config.toml,结果 Codex 根本不读。正确路径一定是用户主目录下的.codex。Windows 上可以在文件资源管理器地址栏直接输入%USERPROFILE%\.codex快速定位。
第二个坑是改了配置不重启。Codex 在启动时读取config.toml,运行中改文件不会热加载。改完配置一定要退出重进。我有一次改完没重启,对着旧配置排查了半天,纯属浪费时间。
第三个坑是环境变量在 IDE 内置终端里不生效。如果你在 VS Code 的内置终端里跑 Codex,而环境变量是在系统层面设置的,有时候需要完全重启 IDE 才能读到。遇到 Key 读不到的情况,先试试在系统终端里跑,排除 IDE 环境的干扰。
第四个经验是保留一份能跑通的最小配置。折腾过程中难免会加各种字段,加着加着就乱了。我习惯把最初跑通的那份最小配置单独存一份,出问题就回滚到它,能快速定位是哪次改动引入的故障。
最后一个建议:善用日志。Codex 在报错时会输出请求的端点和状态码,这些信息比错误消息本身更有价值。看到 401 就往认证方向查,看到 404 就往端点方向查,看到 400 就往请求体格式方向查。养成看状态码的习惯,排查效率会高很多。
这套配置我目前在两个项目里稳定用着,日常改代码、写单测、解释老代码都靠它,成本比之前用官方模型低了一大截。如果你也配通了,建议把config.toml里加个注释记录每行是干嘛的,过几个月回头看还能秒懂。