几乎所有「统一 API」的接入都栽在同一个地方:base_url **差一点点**。它的取值取决于**你用哪个 SDK**,而不是调哪个模型、哪家厂商 —— 因为每个官方 SDK 自己会往后拼一段不同的路径。填错了只会拿到一个 404,不会告诉你错在哪一半。
一句话版本:**OpenAI SDK 填 `https://api.apimodels.app/v1`**,因为它自己会拼 `/chat/completions`;**Anthropic SDK 填光秃秃的根域名 `https://api.apimodels.app`**,因为它自己会拼 `/v1/messages` —— 你再加一个 `/v1` 就变成 `/v1/v1/messages`,404。**Gemini 原生**走 `/v1beta/models/{model}:generateContent`。三种写法和两种错法都在 2026-09-06 对生产环境实测过。
为什么会有这个差别:这不是我们定的规矩,是两个官方 SDK 各自的约定。OpenAI 的客户端把 base_url 理解成「一直到 API 版本号为止的部分」,Anthropic 的客户端把它理解成「主机名」。一个**原生支持两套协议**(而不是把 Claude 转译成 OpenAI 形状)的网关,就会同时继承两套约定 —— 这是让 Claude Code、Anthropic SDK 和 Cursor 不用改代码就能跑的代价。
有个办法能判断任何一家的 Claude 端点是**原生**还是**转译**的:发一个请求看返回体。原生返回 `{"type":"message","content":[...]}`,转译层返回 `{"choices":[...]}`。如果你用到 thinking 块、原生 tool_use 结构或完整的流式事件类型,这个区别就很关键 —— 转译会把它们丢掉或拍平。
Base URL by SDK — verified against production 2026-09-06
SDK / 调用方式 base_url SDK 自己拼的路径
──────────────────────────────────────────────────────────────────────────────
OpenAI (python / node) https://api.apimodels.app/v1 /chat/completions
Anthropic (python/node) https://api.apimodels.app /v1/messages
Gemini 原生 (REST) https://api.apimodels.app /v1beta/models/{m}:generateContent
Claude Code ANTHROPIC_BASE_URL=https://api.apimodels.app
Cursor Anthropic base URL = https://api.apimodels.app
最常撞的两个 404
──────────────────────────────────────────────────────────────────────────────
❌ OpenAI SDK 漏了 /v1 → POST /chat/completions 404
❌ Anthropic SDK 多写了 /v1 → POST /v1/v1/messages 404
鉴权对所有路径一致:Authorization: Bearer <APIMODELS_API_KEY>
Anthropic 风格的端点也接受 x-api-key。cURL
# OpenAI 兼容:base_url 带 /v1
curl https://api.apimodels.app/v1/chat/completions \
-H "Authorization: Bearer $APIMODELS_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model":"gpt-5.6-luna","max_tokens":32,"messages":[{"role":"user","content":"hi"}]}'
# 原生 Anthropic:注意路径里的 /v1 是【端点】的一部分,不是 base_url 的
curl https://api.apimodels.app/v1/messages \
-H "Authorization: Bearer $APIMODELS_API_KEY" \
-H "Content-Type: application/json" \
-H "anthropic-version: 2023-06-01" \
-d '{"model":"claude-sonnet-5","max_tokens":32,"messages":[{"role":"user","content":"hi"}]}'
# Gemini 原生
curl "https://api.apimodels.app/v1beta/models/gemini-3.1-flash-lite:generateContent" \
-H "Authorization: Bearer $APIMODELS_API_KEY" \
-H "Content-Type: application/json" \
-d '{"contents":[{"role":"user","parts":[{"text":"hi"}]}]}'Python
# 同一把 key,两个 SDK,两种 base_url —— 差别只在 SDK 自己拼什么路径
from openai import OpenAI
import anthropic
KEY = "YOUR_APIMODELS_KEY"
# OpenAI SDK:带 /v1(它会拼 /chat/completions)
oai = OpenAI(api_key=KEY, base_url="https://api.apimodels.app/v1")
print(oai.chat.completions.create(
model="gpt-5.6-luna", max_tokens=32,
messages=[{"role": "user", "content": "hi"}]).choices[0].message.content)
# Anthropic SDK:不带 /v1(它会拼 /v1/messages)
ant = anthropic.Anthropic(api_key=KEY, base_url="https://api.apimodels.app")
print(ant.messages.create(
model="claude-sonnet-5", max_tokens=32,
messages=[{"role": "user", "content": "hi"}]).content[0].text)取决于 SDK,不取决于模型。OpenAI SDK 要 `https://api.apimodels.app/v1`,因为它会在你给的值后面拼 `/chat/completions`;Anthropic SDK 要**不带 /v1** 的 `https://api.apimodels.app`,因为它自己会拼 `/v1/messages`。给 Anthropic 客户端加上 /v1 会变成 `/v1/v1/messages`,返回 404 —— 2026-09-06 实测。
绕开 SDK,直接用 curl 打你以为它在调的那个完整 URL。如果 `POST https://api.apimodels.app/v1/chat/completions` 返回 200,说明你的 base_url 少了 `/v1`;如果 `POST https://api.apimodels.app/v1/messages` 返回 200 但 Anthropic 客户端仍然 404,说明你的 base_url 多了一个 `/v1`。大多数 SDK 打开 debug 日志也会打印它最终请求的 URL。
Claude Code 认两个环境变量,不用改配置文件:\n\nexport ANTHROPIC_BASE_URL="https://api.apimodels.app"\nexport ANTHROPIC_AUTH_TOKEN="YOUR_KEY"\n\nCursor:在设置里把 Anthropic 的 base URL 和 key 换成同样的值。因为跑的是**原生 Anthropic Messages API** 而不是套一层 OpenAI 形状的转译,工具调用、thinking 块和流式事件结构都不变,业务代码一行不用改。
发一个请求看返回体。原生 Anthropic 返回 `{"type":"message","content":[...]}`,转译层返回 `{"choices":[...]}`。如果你依赖 thinking 块、原生 tool_use 结构或完整的流式事件类型,这个区别很关键 —— 转译会把它们丢掉或拍平,而且通常是某个功能悄悄失效时你才发现。
一样:所有路径都用 `Authorization: Bearer <YOUR_KEY>`。Anthropic 风格的端点**额外**接受 `x-api-key`,所以原本设置那个头的 Anthropic 客户端不用改也能跑。
可以。一把 key 同时覆盖 OpenAI 兼容路径、原生 Anthropic Messages 路径和 Gemini 原生,共用同一个美元余额 —— 图片、视频、音频模型也在同一个余额里。不需要按协议分别持有 key 或分别充值。