Codex CLI 和 Claude Code 都支持把请求指向"自建 / 第三方网关"(OpenAI 兼容或 Anthropic 网关),但两边的 URL 规则、鉴权变量名、协议开关都不一样,配错就是 401 / 404 / 流式中断。这篇把踩过的坑按客户端整理一遍,域名用占位符,照自己的网关替换即可。
一、先分清两种协议
| 协议 | 路径特征 | 典型客户端 |
|---|---|---|
| OpenAI 兼容 | base_url 通常带 /v1,走 /v1/chat/completions 或 /v1/responses |
Codex CLI、各类 OpenAI SDK、多数第三方客户端 |
| Anthropic 网关 | base_url 不带 /v1,走 /v1/messages |
Claude Code |
最常见的错误:把 OpenAI 的 .../v1 直接填给 Claude Code,或者反过来。两个客户端的 URL 规则不一样,不是"填同一个就行"。
二、Codex CLI
~/.codex/config.toml:
toml
[model_providers.mygw]
name = "MyGateway"
base_url = "https://api.example.com/v1"
wire_api = "responses" # 或 "chat",取决于网关实现了哪套
env_key = "MYGW_API_KEY"
model_provider = "mygw"
model = "<网关控制台里写的模型 id>"
要点:
wire_api必须和网关真正实现的端点对上:网关只实现了/v1/chat/completions却写responses,表现是启动就报错或首包就断。- 模型 id 照控制台抄,别按官方命名猜(很多网关的 id 带分组后缀)。
- key 放环境变量,不要写进 toml。
三、Claude Code
bash
export ANTHROPIC_BASE_URL="https://api.example.com" # 注意:不带 /v1
export ANTHROPIC_AUTH_TOKEN="<网关的 key>"
要点:
- 有的实现认
ANTHROPIC_API_KEY,有的认ANTHROPIC_AUTH_TOKEN;报 401 时两个都试一次,别急着怀疑 key。 - 网关如果做协议转换(把 Anthropic 请求转成 OpenAI 上游),流式事件的格式必须对齐,否则表现为"能出字但中途断"或工具调用失效。
四、通用客户端 / SDK
python
from openai import OpenAI
client = OpenAI(base_url="https://api.example.com/v1", api_key="<key>")
base_url 带 /v1、api_key 随便传一个非空字符串(很多网关不看这个字段),模型 id 用控制台里的。
五、常见报错对照
| 现象 | 大概率原因 |
|---|---|
| 401 Unauthorized | 鉴权变量名不对(API_KEY vs AUTH_TOKEN)、key 前后有空格、key 绑定的分组被停用 |
| 404 Not Found | base_url 多了/少了 /v1,或 wire_api 与端点不匹配 |
| 首包就断 / 流式截断 | 网关没实现 SSE,或中间有反向代理把流式缓冲了(proxy_buffering off) |
| "model not found" | 模型 id 不是官方命名,要照网关控制台写 |
| 用量对不上 | 分组倍率不同(同一网关里"自营组"和"混池组"计费可能差几倍) |
六、判断一个网关值不值得用
不看宣传语,看四件事:
- 协议一致性 :同一个请求,
/v1/chat/completions和/v1/messages的行为是否一致,工具调用是否都能用; - 上下文是否被改动:有些网关会往 system 里插自己的提示词,表现是"模型不太听话",用一段固定的 system 提示词对比输出就能看出来;
- 用量是否可查:控制台能不能看到逐笔 token 与账单,能不能按 key 拆;
- 分组是否透明:同一份钱买到的上游是否写清楚(自营 / 转发 / 混池),以及对应的倍率。
这四条都能自测,不需要信任何人。
七、小结
- OpenAI 兼容:
base_url带/v1; - Anthropic 网关(Claude Code):
base_url不带/v1,鉴权变量名两种都试; - 模型 id 一律照控制台抄;
- 排查顺序:先看 URL 规则 → 再看鉴权变量 → 再看流式与协议实现。