一个 API Key 调通 GPT-5.6 / Claude / Gemini:OpenAI 兼容网关接入实战(附计费自查方法)
> 本文所有代码均在 2026-09-05 实跑验证,usage 输出为真实返回值,未做美化。
> 涉及的价格为当日实查,**AI API 降价频繁,自己用之前请重新核对**——文末有核价方法。
## 目录
- [一、什么场景下需要网关](#一)
- [二、路径一:OpenAI 兼容端点](#二)
- [三、路径二:原生 Anthropic Messages(Claude Code / Cursor)](#三)
- [四、流式与 usage 回传](#四)
- [五、四个实测踩到的坑](#五)
- [六、计费自查:用 usage 反算账单](#六)
- [七、核价方法](#七)
---
<h2 id="一">一、什么场景下需要网关</h2>
先说不需要的场景:**只用一家模型、账号已经开好、不在意跨家切换**,那直接用官方 SDK 就行,加一层网关只是增加故障点。
真正需要的是这几种:
1. **同时要 GPT / Claude / Gemini 三家**,不想维护三套账号、三套计费、三套额度告警;
2. **拿不到官方账号**——OpenAI 的图像模型要组织认证,Anthropic 的付费额度要海外支付方式;
3. **要做 A/B 或成本比较**,希望换模型只改一个字符串;
4. **国内直连**,不想为每个环境配代理。
网关的核心价值就一句:**把"换模型"从一次改造降级成一次改字符串**。
本文以 OpenAI 兼容网关为例,代码里的 base URL 换成任何一家同类服务都成立,不绑定具体厂商。
---
<h2 id="二">二、路径一:OpenAI 兼容端点</h2>
这是覆盖面最广的一条路。只要对方实现了 `/v1/chat/completions`,官方 openai SDK 就能直接用,**改两行**:
### 2.1 Python
```python
from openai import OpenAI
client = OpenAI(
api_key="YOUR_KEY",
base_url="https://api.apimodels.app/v1", # 只改这一行
)
r = client.chat.completions.create(
model="gpt-5.6-luna",
max_tokens=16,
messages=[{"role": "user", "content": "用一个词回答:1+1"}],
)
print(r.model) # gpt-5.6-luna
print(r.choices[0].message.content) # 二
print(r.usage)
```
实跑返回:
```
model: gpt-5.6-luna
reply: 二
usage: prompt=14 cached=0 completion=5
```
### 2.2 curl
```bash
curl https://api.apimodels.app/v1/chat/completions \
-H "Authorization: Bearer $YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-5.6-luna",
"max_tokens": 20,
"messages": [{"role": "user", "content": "用一个词回答:你好"}]
}'
```
### 2.3 换模型 = 换字符串
```python
for m in ["gpt-5.6-sol", "gpt-5.6-terra", "gpt-5.6-luna",
"claude-sonnet-5", "gemini-3.8-flash", "glm-5.3"]:
r = client.chat.completions.create(
model=m, max_tokens=8,
messages=[{"role": "user", "content": "hi"}])
print(m, r.usage.prompt_tokens, r.usage.completion_tokens)
```
**注意 Node 侧有个常见错误**:`baseURL` 要带 `/v1`,而且不要再手动拼一次:
```javascript
import OpenAI from "openai";
const client = new OpenAI({
apiKey: process.env.YOUR_KEY,
baseURL: "https://api.apimodels.app/v1", // ✅
// baseURL: "https://api.apimodels.app", // ❌ 会 404
});
```
---
<h2 id="三">三、路径二:原生 Anthropic Messages(Claude Code / Cursor)</h2>
Claude 有个容易被忽略的点:**很多网关是把 Claude 套成 OpenAI 形状转译的**,这会丢掉 thinking 块、原生 tool_use 结构和部分流式事件类型。如果你要接的是 Claude Code、Anthropic 官方 SDK 或 Cursor,**必须走原生 `/v1/messages`**,不能走转译层。
判断方法很简单:看返回体是 `{"type":"message","content":[...]}`(原生)还是 `{"choices":[...]}`(转译)。
### 3.1 Python(anthropic SDK)
```python
import anthropic
client = anthropic.Anthropic(
api_key="YOUR_KEY",
base_url="https://api.apimodels.app", # 注意:这里不带 /v1
)
m = client.messages.create(
model="claude-sonnet-5",
max_tokens=16,
messages=[{"role": "user", "content": "Reply with one word"}],
)
print(m.model, m.stop_reason)
print(m.content[0].text)
print(m.usage)
```
实跑返回:
```
model: claude-sonnet-5 | stop: max_tokens
reply: Sure.
usage: in=29 out=13 cache_read=0
```
⚠️ **两条路径的 base URL 写法不一样**,这是最容易踩的低级错误:
| 路径 | base_url | 端点 |
|---|---|---|
| OpenAI 兼容 | `https://api.apimodels.app/v1` | `/chat/completions` |
| 原生 Anthropic | `https://api.apimodels.app` | `/v1/messages` |
因为 anthropic SDK 自己会拼 `/v1/messages`,openai SDK 只拼 `/chat/completions`。
### 3.2 curl
```bash
curl https://api.apimodels.app/v1/messages \
-H "Authorization: Bearer $YOUR_KEY" \
-H "Content-Type: application/json" \
-H "anthropic-version: 2023-06-01" \
-d '{
"model": "claude-sonnet-5",
"max_tokens": 20,
"messages": [{"role": "user", "content": "Reply with one word"}]
}'
```
### 3.3 Claude Code 指过来
Claude Code 认两个环境变量,不需要改配置文件:
```bash
export ANTHROPIC_BASE_URL="https://api.apimodels.app"
export ANTHROPIC_AUTH_TOKEN="YOUR_KEY"
claude
```
Cursor 同理,在设置里把 Anthropic 的 base URL 和 key 换掉即可。因为走的是原生协议,**tool use、thinking、流式事件形状都不变**,不需要改任何业务代码。
---
<h2 id="四">四、流式与 usage 回传</h2>
流式的坑在于:**默认不返回 usage**,你会拿不到 token 数,没法对账。OpenAI 协议要显式打开:
```python
stream = client.chat.completions.create(
model="gpt-5.6-luna",
max_tokens=64,
stream=True,
stream_options={"include_usage": True}, # 关键
messages=[{"role": "user", "content": "写一句话"}],
)
usage = None
for chunk in stream:
if chunk.choices and chunk.choices[0].delta.content:
print(chunk.choices[0].delta.content, end="", flush=True)
if chunk.usage: # 最后一个 chunk 才带
usage = chunk.usage
print("\n", usage)
```
curl 验证:
```bash
curl -N https://api.apimodels.app/v1/chat/completions \
-H "Authorization: Bearer $YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"model":"gpt-5.6-luna","max_tokens":10,"stream":true,
"stream_options":{"include_usage":true},
"messages":[{"role":"user","content":"hi"}]}'
```
最后一个 SSE 事件里能看到:
```json
"usage":{"prompt_tokens":4387,"completion_tokens":14,"total_tokens":4401,
"prompt_tokens_details":{"cached_tokens":3840}}
```
---
<h2 id="五">五、四个实测踩到的坑</h2>
### 坑 1:`input_tokens` 会莫名其妙很大,而且不稳定
同一个 `"hi"`,两次调用的 usage 可能差 300 倍:
```
第一次(curl): prompt_tokens = 4387,其中 cached_tokens = 3840
第二次(SDK): prompt_tokens = 14, 其中 cached_tokens = 0
```
原因是上游会给请求注入系统前缀,**大小取决于你被路由到哪个池子**。我们线上记录里,同一个模型的最小输入 token 从个位数到四千多都出现过。
**影响**:对高频短请求(批量分类、抽取、改写)这个量级会实打实进账单。好消息是前缀绝大部分走缓存命中、按缓存价计费,真实成本没有数字看上去那么吓人。
**结论:不要按固定下限估算成本,读每次响应的 `usage`。** 任何"每次调用最少 N 个 token"的说法都别当真——包括厂商自己文档里写的。
### 坑 2:长上下文有阶梯计价,而且是整单生效
GPT-5.6 三档都有这条:**单次请求输入超过 272,000 token 时,该请求整体按输入 2 倍、输出 1.5 倍计费。**
注意是**整单**,不是超出部分。272,001 个 token 的请求,全部 272,001 个都按 2 倍算。
这条在做长文档处理时特别容易翻车——分块阈值卡在 27 万附近的话,成本会在某个输入长度上突然跳一倍。**分块上限建议压到 25 万以内留余量。**
### 坑 3:推理深度后缀已经不存在了
网上很多教程还在写 `gpt-5.6-sol-high`、`gpt-5.6-terra-max` 这种带推理深度后缀的模型名。**这批 id 已经下架**,现在只有三个基础 id。
好的实现应该给你一个明确的 404,而不是悄悄映射到别的模型上——**如果某个网关对不存在的模型名不报错、还正常返回,那你根本不知道自己在用什么模型,也不知道在按什么价计费**。这是选网关时值得实测一下的点:故意传一个不存在的模型名,看它是报错还是装作没事。
### 坑 4:缓存命中要自己核,别信"支持缓存"四个字
缓存价通常是输入价的 1/10,但**只有真命中才便宜**。核对方法是看 usage 里的字段:
- OpenAI 协议:`prompt_tokens_details.cached_tokens`
- Anthropic 协议:`cache_read_input_tokens` 和 `cache_creation_input_tokens`
⚠️ Anthropic 这边有个额外的坑:**cache_creation(写缓存)是要额外收钱的**,通常是输入价的 1.25 倍。如果你的 prompt 每次都变一点点,会变成"每次都写缓存、从不命中",**比不用缓存还贵**。
自查方法:统计一段时间内 `cache_read / (cache_read + cache_creation)` 的比值。低于 50% 说明缓存策略是负收益,该调 prompt 结构了。
---
<h2 id="六">六、计费自查:用 usage 反算账单</h2>
无论用哪家网关,**都建议自己算一遍**。下面这个脚本对任意 OpenAI 兼容端点都成立:
```python
# cost_check.py —— 用 usage 反算单次调用成本,和账单对照
PRICES = { # $/1M tokens, 2026-09-05 实查,用前请重新核对
"gpt-5.6-sol": {"in": 1.324, "out": 6.618, "cached": 0.132},
"gpt-5.6-terra": {"in": 0.551, "out": 3.309, "cached": 0.055},
"gpt-5.6-luna": {"in": 0.16, "out": 0.96, "cached": 0.016},
"claude-sonnet-5": {"in": 1.60, "out": 8.00, "cached": 0.10},
}
def cost(model, usage):
p = PRICES[model]
cached = (usage.prompt_tokens_details.cached_tokens
if usage.prompt_tokens_details else 0) or 0
fresh = usage.prompt_tokens - cached
return (fresh * p["in"] + cached * p["cached"]
+ usage.completion_tokens * p["out"]) / 1_000_000
r = client.chat.completions.create(
model="gpt-5.6-luna", max_tokens=64,
messages=[{"role": "user", "content": "写一句话"}])
print(f"本次约 ${cost('gpt-5.6-luna', r.usage):.8f}")
```
**对账时最容易误判的两件事**(我自己就误判过一次):
1. **忘了算缓存命中**。把全部 `prompt_tokens` 按输入价乘,会算出一个远高于实际的数,然后误以为对方少收了。
2. **忘了账号折扣**。很多平台有邀请折扣、阶梯折扣,实扣是"理论价 × 折扣",直接比对不上。
正确做法是:`理论成本 = (未命中输入 × 输入价 + 命中输入 × 缓存价 + 输出 × 输出价) / 1e6 × 折扣系数`,再和账单比。
另外注意**四舍五入位数**:很多平台按 4 位小数记账,单次成本低于 $0.00005 的调用可能记成 0,别拿单条对账,拿一天的汇总对。
---
<h2 id="七">七、核价方法(比价目表本身更重要)</h2>
AI API 降价太频繁,**任何写死的价格表都会过期**。2026 年 8 月 21 日 OpenAI 就把 GPT-5.6 全线降了一次(Sol $5/$30 → $4/$20,Luna $1/$6 → $0.20/$1.20),两周后仍有大量文章和汇总站在用旧价目。
我现在的核价顺序:
1. **模型厂商官方定价页**——最权威,但要注意看有没有"限时价""即将调整"这类注记;
2. **真按这个价结算的市场**(比如 OpenRouter 的模型页)——它标错价自己要赔钱,所以比汇总站可靠;
3. **汇总站 / 评测文**——默认不信。我遇到过页面顶上写着"3 天前更新"、给的却是一整套降价前旧价目的情况。
还有两个具体教训:
- **只跟官方普通挂牌价比,别跟促销价比。** 某模型当时在市场上挂着 50% off,拿促销价当基准写"我们更便宜",促销一结束就变成假话。
- **注意"被取消的涨价"。** Claude Sonnet 5 现价是 $2/$10,但网上大量内容按 $3/$15 写——那是原定 2026-09-01 生效、后来被官方明确取消的涨价。它不是谣言,是**一个作废了的真事实**,最难防。
---
## 附:2026-09-05 实测价目(每百万 token)
| 模型 | 输入 | 输出 | 缓存命中 |
|---|---|---|---|
| gpt-5.6-sol | $1.324 | $6.618 | $0.132 |
| gpt-5.6-terra | $0.551 | $3.309 | $0.055 |
| gpt-5.6-luna | $0.16 | $0.96 | $0.016 |
| claude-fable-5-1 | $5.00 | $25.00 | $0.22 |
| claude-opus-5 | $3.00 | $15.00 | $0.391 |
| claude-sonnet-5 | $1.60 | $8.00 | $0.10 |
| gemini-3.8-flash | $0.450 | $2.250 | $0.172 |
以上为 [apimodels.app](https://apimodels.app) 的实测价,完整清单和各家官方挂牌价的逐档对照在 [GPT-5.6 价格对比页](https://apimodels.app/access/gpt-5-6-api-pricing) 和 [Claude 价格对比页](https://apimodels.app/access/claude-api-pricing),里面也写了不适合用网关的情况——比如 OpenAI 和 Anthropic 的 Batch API 都打五折而我们不转售,大批量离线任务直接走官方更便宜。
本文代码全部实跑验证于 2026-09-05。价格会变,方法不会变——**照着第七节自己核一遍,比抄任何一张表都可靠。**
更多推荐


所有评论(0)