使用 CLIProxyAPI, 让最新的 Codex 能够支持国内的各大模型

第一部分:CLIProxyAPI

cover

简介

CLIProxyAPI 是一个轻量级 AI API 代理服务器,核心功能是在 OpenAI Responses API 和 Chat Completions API 之间做双向格式转换。它使得仅支持 Responses API 的客户端(如 OpenAI Codex CLI)能够访问仅提供 Chat Completions API 的模型(DeepSeek、GLM、Kimi 等)。

工作原理

工作原理

1
2
3
4
5
6
7
8
Codex CLI
│ POST /v1/responses (Responses API)

CLIProxyAPI ← 自动格式转换
│ POST /v1/chat/completions (Chat Completions API)


DeepSeek / GLM / Kimi / ...
  • 请求方向:Responses → Chat Completions(instructions → system message,inputmessages
  • 响应方向:Chat Completions 响应/流式 SSE → Responses 响应/流式 SSE
  • 支持流式和非流式两种模式

安装

1
2
3
4
cd ~/ai/codex-proxy
git clone https://github.com/router-for-me/CLIProxyAPI.git
cd CLIProxyAPI
go build -o cliproxyapi ./cmd/server/

启动与停止

1
2
3
4
cd ~/ai/codex-proxy/CLIProxyAPI
./start.sh # 启动
./start.sh stop # 停止
./start.sh status # 查看状态

代理默认运行在 http://127.0.0.1:8317

配置文件

配置架构

配置文件位于 ~/ai/codex-proxy/CLIProxyAPI/config.yaml,修改后代理会自动热加载,无需重启。

当前配置

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
host: "127.0.0.1"
port: 8317
debug: false
api-keys:
- "sk-codex-proxy" # 客户端认证 key
request-retry: 2

openai-compatibility:
# Provider 1: oneapi-comate (百度内部网关)
- name: "oneapi-comate"
prefix: "comate"
base-url: "https://oneapi-comate.baidu-int.com/v1"
api-key-entries:
- api-key: "sk-xxxxxxxxxxx"
models:
- name: "DeepSeek-V4-Flash"
alias: "deepseek-v4-flash"
# ... 更多模型

# Provider 2: 智谱 GLM 官方直连
- name: "glm-direct"
prefix: "glm-direct"
base-url: "https://open.bigmodel.cn/api/coding/paas/v4"
api-key-entries:
- api-key: "xxxxxxxxxxxxx"
models:
- name: "glm-5.1"
alias: "glm-5.1"
# ... 更多模型

添加新 Provider

openai-compatibility 下新增一段:

1
2
3
4
5
6
7
8
9
openai-compatibility:
- name: "my-provider" # provider 名称
prefix: "my" # 前缀路由,用 model my/xxx 访问
base-url: "https://api.example.com/v1"
api-key-entries:
- api-key: "sk-xxxxx" # API Key
models:
- name: "upstream-model-name" # 上游真实模型名
alias: "my-model" # 客户端使用的别名

添加新模型到已有 Provider

在对应 provider 的 models 下追加:

1
2
3
models:
- name: "New-Model-Name" # 上游模型名(需与 provider 端一致)
alias: "new-model" # 客户端使用的别名

选择 Provider

当配置了多个 provider 时,有两种方式指定使用哪个:

方式1:prefix 前缀路由(显式指定)

1
2
comate/deepseek-v4-flash    # 走 oneapi-comate
glm-direct/glm-5.1 # 走 glm-direct

方式2:alias 自动路由(省略 prefix)

当 alias 在所有 provider 中唯一时,可省略 prefix:

1
2
deepseek-v4-flash           # 自动匹配到 comate
glm-5.1 # alias 重名时需加 prefix 消歧

如果多个 provider 有相同 alias(如 glm-5.1 同时在 comate 和 glm-direct 中存在),必须用 prefix 显式指定,否则路由不确定。

关键配置项

配置项 说明 默认值
host 绑定地址,127.0.0.1 仅本地 空(所有接口)
port 端口 8317
api-keys 客户端认证 key 列表
request-retry 请求失败重试次数 2
debug 调试日志 false
proxy-url 全局代理(支持 socks5/http/https)

可用模型

Provider: oneapi-comate(百度内部网关,prefix: comate

alias 上游模型名 说明
deepseek-v4-flash DeepSeek-V4-Flash DeepSeek 快速
deepseek-v4-pro DeepSeek-V4-Pro DeepSeek 推理
glm-5 GLM-5 智谱 GLM-5
glm-5-turbo GLM-5-Turbo 智谱 GLM-5 快速
glm-5.1 GLM-5.1 智谱 GLM-5.1
kimi-k2.5 Kimi-K2.5 月之暗面 Kimi
kimi-k2.6 Kimi-K2.6 月之暗面 Kimi
minimax-m2-stable MiniMax-M2-Stable MiniMax 稳定版
minimax-m2.1 MiniMax-M2.1 MiniMax
minimax-m2.7 MiniMax-M2.7 MiniMax
claude-sonnet-4.5 Claude Sonnet 4.5 Claude (中转)
claude-sonnet-4.6 Claude Sonnet 4.6 Claude (中转)
claude-opus-4.6 Claude Opus 4.6 Claude (中转)
claude-haiku-4.5 Claude Haiku 4.5 Claude (中转)

Provider: glm-direct(智谱官方直连,prefix: glm-direct

alias 上游模型名 说明
glm-5.1 glm-5.1 智谱官方直连
glm-5-turbo glm-5-turbo 智谱官方直连

验证与调试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 查看所有可用模型
curl http://127.0.0.1:8317/v1/models \
-H "Authorization: Bearer sk-codex-proxy"

# 测试 Responses API 桥接(非流式)
curl http://127.0.0.1:8317/v1/responses \
-H "Authorization: Bearer sk-codex-proxy" \
-H "Content-Type: application/json" \
-d '{"model":"deepseek-v4-flash","input":"你好"}'

# 测试流式
curl http://127.0.0.1:8317/v1/responses \
-H "Authorization: Bearer sk-codex-proxy" \
-H "Content-Type: application/json" \
-d '{"model":"deepseek-v4-flash","input":"你好","stream":true}'

# 测试 Chat Completions 直通(不走 Responses 转换)
curl http://127.0.0.1:8317/v1/chat/completions \
-H "Authorization: Bearer sk-codex-proxy" \
-H "Content-Type: application/json" \
-d '{"model":"deepseek-v4-flash","messages":[{"role":"user","content":"你好"}]}'

如果你嫌自己配置麻烦,你还可以将 https://github.com/router-for-me/CLIProxyAPI/ 扔给智能体如Claude, 让它帮你按照和配置。


第二部分:Codex CLI 配置

为什么要使用 CLIProxyAPI z做一层代理呢,原因是 codex CLI 自 0.84.0 版本后就不再支持 Chat Completions 格式,而只支持 OpenAI 的 Responses API。因此,CLIProxyAPI 充当了一个中间层,将 Codex 的 Chat Completions 请求转换为 Responses API 格式。

codex这个影响还是巨大的,如果你使用智谱、Minimax、Kimi、Deeepseek 等模型,必须使用 CLIProxyAPI 才能正常使用 最新版的 codex CLI, 而一些新特性比如/goal斜杠命令只能在最新版的codex CLI 中才支持。

还好厂内的同学给我推荐了CLIProxyAPI, 解决了最近一直困扰我的问题。

前提

  • CLIProxyAPI 已启动(参见第一部分)
  • 代理运行在 http://127.0.0.1:8317

配置文件

Codex配置流程

我以厂内的大模型服务为例,演示如何使用CLIProxyAPI的代理服务配置codex。

编辑 ~/.codex/config.toml

1
2
3
4
5
6
7
8
9
10
11
12
model_provider = "oneapi"
model = "comate/deepseek-v4-pro"
disable_response_storage = true
model_reasoning_effort = "xhigh"
model_context_window = 1000000
model_auto_compact_token_limit = 900000

[model_providers.oneapi]
name = "oneapi"
wire_api = "responses"
requires_openai_auth = false
base_url = "http://127.0.0.1:8317/v1"

配置项说明

顶层配置

配置项 说明
model_provider "oneapi" 使用下方 [model_providers.oneapi] 定义的 provider
model "comate/deepseek-v4-pro" 默认模型,可随时通过 --model 切换
disable_response_storage true 不在 OpenAI 端存储响应(通过代理时无意义)
model_reasoning_effort "xhigh" 推理努力程度:low / medium / high / xhigh
model_context_window 1000000 上下文窗口大小(token 数)
model_auto_compact_token_limit 900000 自动压缩上下文的阈值

Provider 配置

配置项 说明
name "oneapi" provider 名称,需与 model_provider 一致
wire_api "responses" 必须设为 responses。这是桥接的核心——让 Codex 发出 Responses API 格式请求,由 CLIProxyAPI 转换为 Chat Completions
requires_openai_auth false 不需要 OpenAI 官方认证,代理用自己的 api-key
base_url "http://127.0.0.1:8317/v1" 指向本地 CLIProxyAPI 代理地址

环境变量

Codex 需要 API key 做认证,值需与 CLIProxyAPI 的 config.yamlapi-keys 列表里的某一项一致:

1
2
echo 'export OPENAI_API_KEY="sk-codex-proxy"' >> ~/.zshrc
source ~/.zshrc

或者配置 ~/.codex/auth.json:

1
2
3
{
"OPENAI_API_KEY": "sk-codex-proxy"
}

切换模型

临时切换(单次会话):

1
2
3
codex --model deepseek-v4-flash
codex --model glm-5-turbo
codex --model comate/claude-sonnet-4.6

永久切换:修改 ~/.codex/config.toml 中的 model 字段,例如:

1
model = "glm-direct/glm-5.1"

常见问题

常见问题

Q: Codex 报 model not found
A: 检查 CLIProxyAPI 的 config.yaml 中是否为该模型配置了 alias,且 alias 与 Codex 传入的 --model 参数一致。

Q: 两个 provider 有同名 alias 怎么办?
A: 使用 prefix 前缀消歧:comate/glm-5.1 vs glm-direct/glm-5.1。或者给其中一个换一个不同的 alias。

Q: Codex 连接代理报认证错误?
A: 确保 config.tomlrequires_openai_auth = false,并设置环境变量 export OPENAI_API_KEY="sk-codex-proxy"

Q: wire_api 设为 chat 还是用 responses
A: 必须设为 "responses"。CLIProxyAPI 的工作方式就是接收 Responses API 请求再转为 Chat Completions,如果 Codex 直接发 Chat Completions 格式就不需要这个代理了。

Q: 如何开启调试日志?
A: 将 CLIProxyAPI 的 config.yaml 中 debug 改为 true,代理会自动热加载。

Q: 如何通过代理访问外网 API?
A: 在 CLIProxyAPI 的 config.yaml 中设置 proxy-url: "socks5://127.0.0.1:1080",或在单个 api-key-entry 上设置 proxy-url

Q: 配置修改后需要重启吗?
A: CLIProxyAPI 的 config.yaml 修改后自动热加载,无需重启。Codex 的 config.toml 修改后下次启动 Codex 生效。


start.sh

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
49
50
#!/bin/bash
# CLIProxyAPI 启动脚本
# 使用方法: ./start.sh [stop|status]

SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
PID_FILE="$SCRIPT_DIR/cliproxyapi.pid"
CONFIG_FILE="$SCRIPT_DIR/config.yaml"
BINARY="$SCRIPT_DIR/cliproxyapi"

case "${1:-start}" in
start)
if [ -f "$PID_FILE" ] && kill -0 "$(cat "$PID_FILE")" 2>/dev/null; then
echo "CLIProxyAPI already running (PID $(cat "$PID_FILE"))"
exit 0
fi
echo "Starting CLIProxyAPI on http://127.0.0.1:8317 ..."
"$BINARY" -config "$CONFIG_FILE" &
echo $! > "$PID_FILE"
sleep 2
if kill -0 "$(cat "$PID_FILE")" 2>/dev/null; then
echo "Started successfully (PID $(cat "$PID_FILE"))"
else
echo "Failed to start, check config.yaml"
rm -f "$PID_FILE"
exit 1
fi
;;
stop)
if [ -f "$PID_FILE" ]; then
kill "$(cat "$PID_FILE")" 2>/dev/null
rm -f "$PID_FILE"
echo "Stopped"
else
echo "Not running"
fi
;;
status)
if [ -f "$PID_FILE" ] && kill -0 "$(cat "$PID_FILE")" 2>/dev/null; then
echo "Running (PID $(cat "$PID_FILE"))"
else
echo "Not running"
rm -f "$PID_FILE"
fi
;;
*)
echo "Usage: $0 [start|stop|status]"
;;
esac