在 Paseo 中同时使用 OpenAI Codex 与 DeepSeek

今天(2026 年 7 月 31 日),DeepSeek 更新了 DeepSeek-V4-Flash 的正式版本,官方公告如下:

deepseek-v4-flash 原生支持 Responses API 并完全适配 Codex(配置细节见官方文档),正好可以直接接进 Paseo 使用。

Paseo 内置支持 Codex。通过派生 Provider,可以在保留官方 OpenAI GPT 的同时,增加一个使用 DeepSeek 的 Codex Provider。

最终效果:

  • Codex:使用 OpenAI GPT 和 Codex 登录状态。
  • Codex (DeepSeek):使用 DeepSeek 或兼容 Responses API 的网关。
  • 两个 Provider 在 Paseo 中独立显示,可以按任务选择。

2026 年 8 月 11 日更新:最初版本只配置了 DeepSeek Provider。这样可以调用模型,但不会自动加载 DeepSeek 官方 Model Catalog 中的系统提示词、上下文窗口和工具元数据。下面已更新为完整方案。

1. 准备 DeepSeek Model Catalog

DeepSeek 官方的 Codex 配置不只有 API 地址和模型 ID,还包含一份 models.json。这份 Model Catalog 会告诉 Codex:

  • 模型的基础/系统指令 model_messages.instructions_template
  • 1,048,576 tokens 的上下文窗口,以及 95% 的有效上下文比例
  • lowhighmax 三档 reasoning,默认 high
  • apply_patch、Web Search、并行工具调用等工具格式
  • compaction、truncation 和 multi-agent 等运行时元数据

DeepSeek 官方 Codex 集成文档 复制完整 catalog,保存为:

1
~/.codex/deepseek_models.json

本文不直接复制 catalog 内容,因为其中的模型提示词和能力声明可能随版本更新。升级 DeepSeek 或 Codex 后,应重新对照官方版本。

可以先独立确认 Codex 能读取它:

1
2
3
4
5
6
7
8
9
10
codex \
-c 'model_catalog_json="~/.codex/deepseek_models.json"' \
debug models \
| jq '.models[] | {
slug,
context_window,
default_reasoning_level,
reasoning: [.supported_reasoning_levels[].effort],
instructions_chars: (.model_messages.instructions_template | length)
}'

预期能看到 deepseek-v4-flash、1,048,576 context window、默认 highlow/high/max,并且 instructions_chars 大于 0。

2. 配置 Paseo

Paseo 配置文件位置:

  • 正常安装:~/.paseo/config.json
  • 仓库开发环境:.dev/paseo-home/config.json

加入两个 Provider:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
{
"version": 1,
"agents": {
"providers": {
"codex": {
"enabled": true,
"order": 10
},
"codex-deepseek": {
"extends": "codex",
"label": "Codex (DeepSeek)",
"description": "Codex using DeepSeek",
"order": 20,
"command": [
"codex",
"-c",
"model_catalog_json=\"~/.codex/deepseek_models.json\""
],
"env": {
"OPENAI_BASE_URL": "https://api.deepseek.com/",
"OPENAI_API_KEY": "<your-api-key>"
},
"models": [
{
"id": "deepseek-v4-flash",
"label": "DeepSeek",
"isDefault": true,
"thinkingOptions": [
{
"id": "low",
"label": "Low"
},
{
"id": "high",
"label": "High",
"isDefault": true
},
{
"id": "max",
"label": "Max"
}
]
}
]
}
}
}
}

如果 Paseo daemon 的 PATH 中找不到 codex,将 command 的第一个元素改成 command -v codex 返回的绝对路径。

重启 Paseo 并新建会话后,Provider 列表中会同时出现:

1
2
Codex
Codex (DeepSeek)

其中:

  • Codex 使用 OpenAI 登录和 GPT 模型。
  • Codex (DeepSeek) 继承 Paseo 的 Codex adapter,但使用独立的 API 地址、密钥和模型。

Paseo 会把 command 中的参数放在 app-server 前面,实际启动:

1
codex -c model_catalog_json="~/.codex/deepseek_models.json" app-server

整个配置的职责分工是:

  • Paseo Provider 的 env:DeepSeek endpoint 和 API Key
  • Paseo 创建线程时注入的配置:model_providermodel_providers 和模型 ID
  • Provider command 中的 -c:让 Codex app-server 在启动时加载 Model Catalog
  • Model Catalog:系统指令、context、reasoning、工具和 compaction 元数据

这里有一个容易混淆的点:Paseo Provider 的 models 只是模型选择界面的静态列表,只支持 ID、标签、默认项和简化的 thinkingOptions;它不能替代 Codex Model Catalog。保留静态 Flash 模型可以避免把 catalog 中尚未正式支持 Codex 的模型显示出来,但 Codex 运行时仍会加载完整 catalog。

3. 为什么不用 Codex profile

我们最初尝试过用 codex --profile deepseek 启动 Paseo,但没有跑通。原因是两层配置存在所有权冲突:

  • profile 可能设置 model_provider = "deepseek" 和默认模型。
  • Paseo 的派生 Provider 会在线程启动时显式注入自己的 Provider ID,例如 model_provider = "codex-deepseek"
  • Paseo 还会显式传入用户在界面中选择的模型。

因此,即使 profile 被选中,其中的 Provider 和模型也不一定是最终值。把 profile 缩减为只加载 catalog 虽然可行,但仍多了一层命名和优先级关系。

Provider command 直接传入:

1
-c model_catalog_json="~/.codex/deepseek_models.json"

会更简单:Paseo 继续控制 Provider、认证和模型选择,Codex 只负责加载 catalog。-c/--config 的优先级也高于 profile 和用户配置。

如果只想在终端直接使用 DeepSeek,仍然可以单独维护 profile,但它不是 Paseo 方案的一部分。此时至少要包含:

1
2
3
4
5
6
7
8
9
10
11
model = "deepseek-v4-flash"
model_provider = "deepseek"
model_reasoning_effort = "high"
model_catalog_json = "~/.codex/deepseek_models.json"

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

设置 API Key:

1
export DEEPSEEK_API_KEY="<your-api-key>"

运行:

1
codex --profile deepseek

4. 验证是否真正加载了 Catalog

验证需要区分三层。

第一层是 catalog 文件本身。前面的 codex -c ... debug models 应该能读到系统指令、context 和 reasoning 元数据。

第二层是 Paseo 是否按新参数启动 app-server。重启 Paseo、创建一个新的 codex-deepseek 会话,并在会话仍在运行时执行:

1
ps -ef | rg '[c]odex.*model_catalog_json=.*deepseek_models\.json.*app-server'

应该能看到 model_catalog_json 参数位于 app-server 前面。

第三层是检查真实 Codex rollout。一次实际测试中,会话记录显示:

  • Provider 为 codex-deepseek
  • 模型为 deepseek-v4-flash,reasoning 为 high
  • 会话中的 17,730 字符基础指令与 catalog 对应条目的 SHA-256 完全一致
  • 实际 context window 为 996,147,正好是 1,048,576 的 95%
  • comp_hash = "3000"multi_agent_version = "v2" 与 catalog 一致

这比询问模型“你的系统提示词是什么”更可靠。模型的回答只能作为行为观察,rollout 中的元数据和指令哈希才是确定性证据。

Paseo 的模型列表可以这样检查:

1
paseo provider models codex-deepseek --thinking --json

它应该显示 low/high/max,默认 high。但这些内容来自 Paseo 的静态 models 配置,所以不能单独证明 catalog 已加载。

5. 排查问题

检查 Codex 版本:

1
codex --version

DeepSeek 当前 catalog 声明的最低 Codex 客户端版本是 0.144.0。本文实测版本为 0.147.0

检查 Paseo Provider 和模型:

1
2
paseo provider ls
paseo provider models codex-deepseek --thinking

查看日志:

1
tail -f ~/.paseo/daemon.log

常见问题:

  • 修改 config.json 后必须重启 Paseo,并创建新会话;旧会话不能用于验证。
  • JSON 中 model_catalog_json 的双引号需要转义。
  • 如果相对路径或 ~ 展开异常,换成 catalog 的绝对路径。
  • 如果 codex 不在 Paseo daemon 的 PATH 中,在 command 中使用 Codex 的绝对路径。
  • DeepSeek 官方文档目前只明确支持 deepseek-v4-flash 接入 Codex。即使 catalog 中包含其他模型,也不要直接设为默认值。
  • API Key 保存在 Paseo 配置中时,确保文件权限至少为 0600,不要把真实配置或 daemon 日志提交到仓库。

最终结构如下:

1
2
3
4
5
6
7
8
9
10
11
OpenAI Codex
├── codex login
└── Paseo 内置 codex Provider

DeepSeek Codex
├── ~/.codex/deepseek_models.json
└── ~/.paseo/config.json
└── codex-deepseek Provider
├── env: endpoint + API Key
├── models: Paseo UI 模型与 reasoning 选项
└── command -c: Codex 启动时加载 Model Catalog