让 Codex 使用 DeepSeek 模型的两种方法:本地网关和 OpenRouter BYOK

整理 Codex CLI 连接 DeepSeek 的两种可行思路:用本地网关做协议桥接,或借助 OpenRouter BYOK 做线上转发,并说明直接改 base_url 为什么容易失败。

想让 Codex 使用 DeepSeek,第一反应通常是改 ~/.codex/config.toml

1
2
model = "deepseek-chat"
base_url = "https://api.deepseek.com"

这个思路在一些旧版本或普通 OpenAI SDK 场景里确实成立,但放到当前 Codex CLI 上,很容易撞到一个底层问题:Codex 的自定义模型供应商走的是 OpenAI Responses 协议,而 DeepSeek 官方接口主要提供 OpenAI 兼容的 Chat Completions 调用方式。

我本机当前是 codex-cli 0.111.0codex --help 里可以看到它支持 --config--model--profile 这些配置入口;OpenAI 官方 Codex 配置参考也写得很明确:model_providers.<id>.wire_api 目前只支持 responses,省略时也默认是 responses

DeepSeek 官方文档则给出的调用路径是 https://api.deepseek.com/chat/completions,示例也是 client.chat.completions.create(...)。所以问题不在于 DeepSeek 不能被 OpenAI SDK 调用,而在于 Codex 发出去的请求语义和 DeepSeek 原生接口能理解的语义不完全是一套东西。

这就是为什么直接把 base_url 改成 https://api.deepseek.com 后,可能出现下面这些现象:

  • 请求路径不匹配,直接 404 或返回格式不对。
  • 多轮对话、工具调用、补丁生成时解析失败。
  • tool_calls 顺序、消息结构、流式事件格式对不上。
  • 看起来模型能回一句话,但一到 Codex 真正干活就开始报错。

更稳的办法,是在 Codex 和 DeepSeek 之间放一个“翻译层”。常见有两种路线。

方法一:用本地网关桥接 DeepSeek

本地网关的作用不是简单转发,而是把 Codex 侧的 Responses 风格请求,转换成 DeepSeek 能处理的 Chat Completions 风格请求,再把 DeepSeek 的结果转换回 Codex 能吃的格式。

如果你用的是 ccx 一类本地网关,配置思路大致是这样:

1
2
3
4
5
6
7
8
[profiles.deepseek-ccx]
model = "deepseek-v4-flash"
model_provider = "ccx-bridge"

[model_providers.ccx-bridge]
name = "Local CCX Gateway"
base_url = "http://localhost:3000/v1"
env_key = "DEEPSEEK_API_KEY"

然后在终端里设置 DeepSeek Key,再用这个 profile 启动:

1
2
export DEEPSEEK_API_KEY="your-deepseek-key"
codex --profile deepseek-ccx

PowerShell 里是:

1
2
$env:DEEPSEEK_API_KEY="your-deepseek-key"
codex --profile deepseek-ccx

这里有两个细节要注意。

第一,base_url 要指向网关暴露给 Codex 的地址,不是 DeepSeek 官方地址。网关背后再去调用 DeepSeek。

第二,env_key 写什么取决于网关怎么鉴权。有的网关直接读取 DeepSeek 官方 Key,有的网关会要求你给它一个本地代理 Key,再由网关自己的后台保存 DeepSeek Key。遇到这种情况,env_key 就应该改成网关要求的环境变量名。

这条路的优点是本地可控,延迟和成本也更容易算清楚。缺点是你必须确认网关真的支持 Codex 当前使用的 Responses 语义,而不是只做了普通 Chat Completions 代理。

方法二:用 OpenRouter BYOK 做线上桥接

如果不想在本地部署网关,可以考虑 OpenRouter 的 BYOK。BYOK 的意思是把你自己的上游供应商 Key 绑定到 OpenRouter,由 OpenRouter 负责路由和转发。

这里最容易写错的是环境变量。Codex 访问的是 OpenRouter,所以 env_key 通常应该是 OPENROUTER_API_KEY,不是 DEEPSEEK_API_KEY。DeepSeek Key 要在 OpenRouter 的 BYOK 或 provider key 设置里添加。

配置示例:

1
2
3
4
5
6
7
8
[profiles.deepseek-openrouter]
model = "deepseek/deepseek-chat"
model_provider = "openrouter"

[model_providers.openrouter]
name = "OpenRouter"
base_url = "https://openrouter.ai/api/v1"
env_key = "OPENROUTER_API_KEY"

启动方式:

1
2
export OPENROUTER_API_KEY="your-openrouter-key"
codex --profile deepseek-openrouter

PowerShell:

1
2
$env:OPENROUTER_API_KEY="your-openrouter-key"
codex --profile deepseek-openrouter

然后在 OpenRouter 后台把 DeepSeek 的 provider key 加进去。OpenRouter 的 BYOK 文档说明,绑定的 provider key 会被加密保存,并用于路由到对应供应商。

这条路的优点是省掉本地网关维护成本,配置起来更像普通第三方 API 代理。缺点是中间多了一层线上服务,排障时要同时看 Codex、OpenRouter、DeepSeek 三边的错误信息。

要不要继续用 deepseek-chat 这个模型名?

DeepSeek 官方文档在 2026 年 5 月的说明里,推荐模型名已经出现 deepseek-v4-flashdeepseek-v4-pro,并提示 deepseek-chatdeepseek-reasoner 兼容别名会在 2026-07-24 之后废弃。

所以新配置里更建议优先测试:

1
model = "deepseek-v4-flash"

如果走 OpenRouter,则要按 OpenRouter 的模型命名来写,例如:

1
model = "deepseek/deepseek-chat"

实际可用名称以你所用网关或 OpenRouter 模型页为准。模型名不对时,错误通常会表现为 model not found、404,或者 provider 找不到对应 endpoint。

直接改 DeepSeek 官方 base_url 为什么不推荐

你当然可以试着写:

1
2
3
4
5
6
7
8
[profiles.deepseek-direct]
model = "deepseek-v4-flash"
model_provider = "deepseek"

[model_providers.deepseek]
name = "DeepSeek"
base_url = "https://api.deepseek.com"
env_key = "DEEPSEEK_API_KEY"

但这更像排错实验,不适合作为稳定方案。因为 Codex 会按 Responses 协议去和自定义 provider 说话,而 DeepSeek 官方示例走的是 /chat/completions。如果 DeepSeek 或 Codex 未来补齐了兼容层,这种直连才可能变得简单;在此之前,桥接层更靠谱。

改完配置后还是走 OpenAI 怎么办

先确认配置文件位置。全局配置应该在:

1
~/.codex/config.toml

项目里的 .codex/config.toml 不适合放 model_providermodel_providers 这类机器级 provider 配置。OpenAI 官方文档也提醒,项目级配置不会覆盖这些本地 provider 和认证相关字段。

如果 Codex 仍然要求网页登录,或者看起来还在走默认 OpenAI 模型,可以先退出当前登录态:

1
codex logout

有些旧教程会写成交互界面里的 /logout。在当前 CLI 里,更稳的是直接在终端执行 codex logout

还可以用临时参数做一次快速验证:

1
codex --profile deepseek-ccx

或者:

1
codex -c model_provider=ccx-bridge -c model=deepseek-v4-flash

如果这样能生效,说明配置本身可读;如果不生效,优先检查 profile 名称、TOML 语法、环境变量是否只在当前 shell 里有效。

排障清单

  • 401:Key 不对,或者 env_key 指向了错误的环境变量。
  • 404base_url 或模型名不对,也可能是把 Responses 请求打到了只支持 Chat Completions 的地址。
  • tool_calls、patch、流式解析报错:大概率是协议桥接不完整。
  • 仍然提示登录 OpenAI:执行 codex logout,再确认是否用了正确 profile。
  • PowerShell 设置环境变量后新开窗口失效:$env:... 只对当前会话生效,需要长期保存就改用户环境变量。
  • OpenRouter BYOK 没走自己的 DeepSeek Key:检查 OpenRouter 后台 provider key 是否绑定、是否允许当前 OpenRouter API Key 使用,以及是否开启了 fallback。

结论

让 Codex 使用 DeepSeek,不是不能改 config.toml,而是不能只改 base_url 就指望一切自动兼容。

当前更稳的两条路是:

  1. 用本地网关做协议桥接,Codex 连本地网关,网关再连 DeepSeek。
  2. 用 OpenRouter BYOK 做线上转发,Codex 连 OpenRouter,DeepSeek Key 绑定在 OpenRouter 后台。

如果只是想快速试用,OpenRouter 路线更省事;如果你希望 Key、成本、日志都尽量掌握在自己手里,本地网关更适合长期折腾。

参考资料:

记录并分享
使用 Hugo 构建
主题 StackJimmy 设计