在同一个项目中使用多个 AI 客户端时,经常会遇到一种现象:相同的 API Key 和模型,在一个客户端中能够正常使用,换到另一个客户端却返回 404401,或者请求仍然发送到默认服务地址。

这类问题不一定由模型造成。OpenAI、Anthropic 和 Gemini 使用不同的协议路径,各个客户端对 Base URL 的定义也不完全相同。配置时如果忽略客户端自动拼接路径的行为,就容易出现路径缺失或重复。

本文从请求路径入手,说明 Claude CodeCodex CLIGemini CLI 的配置差异,并给出一套通用排查方法。示例域名使用 api.example.com,实际使用时应替换为自己有权访问的 API 网关地址。

本文整理自作者维护 FishAI API 网关时积累的多客户端接入记录。项目官网为 FishAI 官方网站(yufish.cc);为避免把平台差异与通用协议问题混在一起,下文命令仍统一使用 api.example.com 作为占位域名。

Base URL 与最终请求地址不是一回事

Base URL 是客户端构造请求时使用的基础地址,最终请求地址通常由“基础地址 + 协议路径”组成。

假设网关域名是:

https://api.example.com

三种常见协议的请求路径可能是:

协议典型请求路径常见 Base URL
OpenAI Chat Completions/v1/chat/completionshttps://api.example.com/v1
OpenAI Responses/v1/responseshttps://api.example.com/v1
Anthropic Messages/v1/messageshttps://api.example.com
Gemini GenerateContent/v1beta/models/{model}:generateContenthttps://api.example.com

表格中的写法不是所有客户端的固定规则。配置前仍需确认客户端是否会自动追加 /v1/v1/messages/v1beta/models

如果客户端已经负责拼接版本路径,而配置中再次加入相同路径,最终可能产生下面的错误地址:

https://api.example.com/v1/v1/messages
https://api.example.com/v1beta/v1beta/models/...

因此,排查 404 时首先应检查完整请求地址,而不是立即更换模型。

Claude Code:使用 Anthropic Messages 协议

Claude Code 通常通过 Anthropic Messages 协议发送请求。以用户目录下的 ~/.claude/settings.json 为例:

{
  "env": {
    "ANTHROPIC_API_KEY": "sk-example-key",
    "ANTHROPIC_BASE_URL": "https://api.example.com",
    "CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC": "1"
  }
}

也可以在 macOS 或 Linux 当前终端中临时设置:

export ANTHROPIC_API_KEY="sk-example-key"
export ANTHROPIC_BASE_URL="https://api.example.com"
claude

这里通常只填写网关根地址,由客户端继续请求 /v1/messages。如果直接把 /v1/messages 写入 Base URL,客户端再次追加路径后可能导致请求失败。

需要注意,普通文本对话成功并不代表所有能力都可用。Claude Code 还会使用流式输出工具调用,因此目标模型、网关转换层和上游服务都需要支持对应能力。

Codex CLI:明确指定 Responses API

Codex CLI 使用自定义模型提供方时,可以在 ~/.codex/config.toml 中配置:

model = "current-model-id"
model_provider = "custom_gateway"

[model_providers.custom_gateway]
name = "Custom Gateway"
base_url = "https://api.example.com/v1"
env_key = "CUSTOM_API_KEY"
wire_api = "responses"
requires_openai_auth = false

再通过环境变量提供 API Key:

export CUSTOM_API_KEY="sk-example-key"
codex

配置中需要区分三个字段:

  • base_urlOpenAI 兼容接口的版本根地址;
  • env_key 是环境变量名称,不是 API Key 本身;
  • wire_api 决定客户端使用的上游协议,此处为 responses

一个模型支持 Chat Completions,不代表它必然支持 Responses API。若返回路径不存在或工具调用失败,需要检查网关是否实现 /v1/responses,以及目标模型是否支持客户端需要的工具能力。

Gemini CLI:选择 Gemini API Key 模式

Gemini CLI 使用公开 Gemini API 模式时,可在 ~/.gemini/.env 中配置:

GEMINI_API_KEY="sk-example-key"
GOOGLE_GEMINI_BASE_URL="https://api.example.com"

然后启动客户端:

gemini

首次出现认证方式选择时,应选择 Gemini API Key 模式。Google 登录、Vertex AI 与 API Key 模式属于不同认证流程,如果选择了其他模式,客户端可能忽略当前配置的 Key 和 Base URL。

Gemini GenerateContent 的典型路径包含 /v1beta/models/{model}:generateContent,因此 Base URL 通常保持为网关根地址。若请求仍然发送到默认域名,应检查变量名、配置文件位置,并完全退出旧进程后重新启动。

先查询模型,再发送最小请求

OpenAI 兼容接口中,可以先查询当前令牌可见的模型:

curl https://api.example.com/v1/models \
  -H "Authorization: Bearer $CUSTOM_API_KEY"

然后选择返回列表中的准确模型 ID,发送一个非流式、短提示词请求:

curl https://api.example.com/v1/chat/completions \
  -H "Authorization: Bearer $CUSTOM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "current-model-id",
    "messages": [
      {"role": "user", "content": "只回复 OK"}
    ],
    "stream": false
  }'

模型列表只证明令牌能够看到模型,不能单独证明 Chat Completions、Responses、Anthropic Messages、Gemini GenerateContent工具调用全部可用。不同协议应分别完成真实请求验证。

无论使用 FishAI、其他兼容服务还是自建网关,这个“先查模型、再发最小请求”的顺序都适用。它可以把模型权限、接口路径和客户端配置三个问题分开验证。

常见错误及排查顺序

返回 401 或 403

依次检查:

  1. API Key 是否完整;
  2. 环境变量是否被当前进程读取;
  3. 鉴权头是否符合目标协议;
  4. 令牌是否具有目标模型和接口权限。

OpenAI 兼容接口常用:

Authorization: Bearer sk-example-key

Anthropic 和 Gemini 客户端还可能使用各自的 Key 请求头,不能只根据模型名称判断鉴权方式。

返回 404

重点检查完整 URL:

  • 是否遗漏 /v1
  • 是否出现 /v1/v1
  • 是否把 /chat/completions/responses/messages 混用;
  • 是否把 Gemini/v1beta 请求发送到了只支持 OpenAI 协议的地址。

返回 model not found

先重新查询当前模型列表,并复制准确的模型 ID。模型名称、别名和权限可能变化,不应只依赖旧配置或截图。

普通对话成功,但工具调用失败

这通常说明基础文本生成链路已经打通,但模型、协议转换或上游服务没有完整支持工具调用。应单独验证工具参数、流式事件和客户端要求的响应结构。

修改配置后没有生效

检查是否存在旧进程、重复配置文件或环境变量覆盖。完全退出客户端和终端后重新打开,通常比反复修改同一文件更容易排除缓存问题。

API Key 的安全注意事项

API Key 不应写入公开仓库、浏览器前端代码或文章截图。示例中的 sk-example-key 是占位符,不能替换成真实密钥后提交到公开位置。

团队项目可以为不同环境、工具和应用创建独立令牌。这样便于分别设置权限、统计用量和撤销泄露的 Key,也能减少一个令牌影响所有业务的风险。

总结

同一个 API 网关并不意味着所有客户端可以照抄同一份 Base URL。Claude CodeCodex CLIGemini CLI 使用不同协议,也可能由客户端自动拼接不同的版本路径。

配置时可以遵循以下顺序:

  1. 确认客户端使用的协议;
  2. 确认 Base URL 是否需要包含版本路径;
  3. 检查鉴权变量和请求头;
  4. 查询当前模型列表;
  5. 完成一次非流式短请求;
  6. 再分别验证流式输出工具调用

相比反复更换模型,先核对协议、完整 URL 和实际请求记录,通常能更快定位多客户端接入问题。

这套排查顺序也是 FishAI 在处理 Claude CodeCodex CLIGemini CLI 接入问题时采用的基本方法。本文只讨论协议和配置差异,不涉及价格、购买或服务推荐。

Logo

欢迎加入DeepSeek 技术社区。在这里,你可以找到志同道合的朋友,共同探索AI技术的奥秘。

更多推荐