中转站模型真假怎么验证:五项自己能做的一致性检查
中转站模型真假,没有一种方法能百分之百确认:你只能看到请求和响应,响应里的 model 字段、错误信息、甚至“你是谁”的回答都可以被中间层改写。能做的是一致性检查,把同样的请求分别发给官方接口和中转接口,比较 token 计数、上下文边界、工具调用格式、延迟吞吐和固定提示的输出分布,几项都对得上,掉包的可能性就很低;有一项明显对不上,就值得追问。
为什么不能直接问模型“你是谁”?
模型的自我介绍来自训练数据和系统提示,不是运行时读取的身份信息。几个常见情况:
- 中转层可以在系统提示里写“你是某某模型”,大部分模型会照说。
- 很多模型训练语料里混有其他模型的对话,自己会报错名字。
- 响应 JSON 里的
model字段是服务端填的,中转层改一个字符串就行。
所以“问一句看回答”只能排除特别粗糙的替换。真正有用的信号来自模型难以伪装的部分:分词器、上下文上限、协议细节和推理速度。
中转站常见的“不一致”有哪几种?
先分清楚问题类型,检查才有方向。读者遇到的“不像官方”,大致是下面四种,只有第一种是真正的掉包:
| 类型 | 说明 | 能否用一致性检查发现 |
|---|---|---|
| 换成了另一个模型 | 请求名是 A,实际调用 B(通常更便宜) | 大多能,分词器和上下文上限差异明显 |
| 同一模型,不同量化 | 开源模型由不同推理供应商部署,fp8、fp4、int4 都有 | 部分能,输出分布和速度会有差别 |
| 同一模型,改了参数 | 压低了最大输出长度、改了 temperature、截断了上下文 | 能,边界测试可以测出来 |
| 加了系统提示或缓存 | 中转层注入提示词,或对相同请求返回缓存结果 | 部分能,token 计数会多出来 |
第二种情况在开源模型上很普遍,而且不一定是有意为之。cdnping 在 2026-10-17 采集的 OpenRouter 公开数据快照里(窗口为当天单次采集,数据见 /models),一个 DeepSeek 轻量模型的 id 下有 36 个供应商端点,其中 17 个标注 fp8、3 个 fp4、1 个 mxfp4,另外 15 个没有标注精度;一个 Kimi 新模型的 id 下有 26 个端点,9 个 fp4、7 个 mxfp4、2 个 fp8、8 个未标注。同一个模型名,背后可能是精度差别很大的部署。量化对输出的影响和怎么锁定精度,可以看模型变笨还是换了供应商:推理供应商与 fp8、fp4 模型量化。
闭源模型的情况不同。同一份快照里,Anthropic、OpenAI、Google、xAI 的模型端点精度全部是“unknown”,供应商只有官方自己和几家大云厂商。闭源模型的权重不对外发布,第三方无法自行部署。中转站如果声称提供某个闭源模型,不管中间转了几手,最终的推理只能来自官方或这类授权云平台,这一点是检查的出发点。
五项一致性检查怎么做?
准备工作:拿到一个官方 API Key 作为基准(下面的检查请求量不大),再拿中转站的 Key。下面的命令以 OpenAI 兼容格式为例,<模型 id> 换成你要验证的模型名。中转站的接口地址怎么配,可参考 Claude Code 自定义 API 与 Codex、OpenCode 接口地址配置。
先写一个小函数,后面反复用:
# 用法:ask <BASE_URL> <API_KEY> <JSON 请求体文件>
ask() {
curl -s "$1/v1/chat/completions" \
-H "Authorization: Bearer $2" \
-H "Content-Type: application/json" \
-d @"$3"
}
检查一:输入 token 计数对得上吗?
不同模型家族用不同的分词器,同一段文本切出来的 token 数不一样。这是最难伪装的一项,因为中转层要伪造就得重新实现目标模型的分词器。
做法:
- 准备一段固定文本,最好中英文、代码、emoji 混合,长度一千字左右,保存为
probe.txt。 - 构造请求体,
max_tokens设为 1,只看输入计数:
jq -n --arg t "$(cat probe.txt)" --arg m "<模型 id>" \
'{model:$m, max_tokens:1, messages:[{role:"user",content:$t}]}' > req.json
ask https://官方地址 $OFFICIAL_KEY req.json | jq '.usage.prompt_tokens'
ask https://中转地址 $RELAY_KEY req.json | jq '.usage.prompt_tokens'
- 两个数字应该完全相同或只差几个 token(消息模板的固定开销)。如果中转返回的数字多出几十上百,通常是中转层注入了系统提示;如果差出一个比例(比如多了 20%),很可能分词器根本不是同一家。
Anthropic 官方还提供不消耗额度的 token 计数接口(Messages API 的 count_tokens),OpenAI 系模型可以用官方开源的 tiktoken 在本地算。注意 usage 字段本身也可以被改写,所以要配合下面几项一起看。
检查二:上下文长度的边界在哪里?
每个模型有公开的上下文上限。中转站如果换成了上限更小的模型,或者在中间截断了长对话,边界测试能直接测出来。
- 查官方文档里该模型的上下文上限。
- 构造一个接近上限(例如上限的 90%)的输入,在开头写一个随机字符串,最后问“开头的字符串是什么”。
- 再构造一个明显超过上限的输入。
判断:官方接口在超限时会返回明确的错误;如果中转对超限请求也能正常回答,说明它悄悄截断了内容。如果 90% 的请求答不出开头的字符串,说明实际可用上下文比宣称的小。
检查三:工具调用的格式和行为一致吗?
工具调用(function calling)的细节各家不同:参数 JSON 的写法、并行调用时一次返回几个、tool_call 的 id 格式、stop_reason 或 finish_reason 的取值。这些是协议层面的东西,模型换了很容易露出来。
做法:定义两个简单工具(例如查天气、查时间),发一个需要同时调用两者的问题,各跑 5 次,记录:
- 是否一次返回两个调用,还是分两轮
- 调用 id 的前缀和长度
- 结束原因字段的值
- 参数里有没有多余的字段或格式错误
官方和中转的结果放在一起对比,结构上的差异比内容差异更说明问题。
检查四:延迟和吞吐像不像?
不同模型、不同部署的生成速度有明显特征。用流式输出测两个数:首 token 时间(TTFT)和每秒输出 token 数。
# 记录首字节时间和总耗时;BASE、KEY 分别换成官方或中转的地址与 Key
jq '. + {stream:true, max_tokens:500, stream_options:{include_usage:true}}' req.json > stream.json
curl -s -N "$BASE/v1/chat/completions" \
-H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
-d @stream.json -o out.txt \
-w "首字节 %{time_starttransfer}s 总耗时 %{time_total}s\n"
# 最后一个数据块里的 usage.completion_tokens 是输出 token 数
grep -o '"completion_tokens":[0-9]*' out.txt | tail -1
吞吐大致等于输出 token 数 ÷(总耗时 − 首字节时间)。有些服务会先返回响应头再开始生成,首字节时间只能近似看作 TTFT。stream_options 是 OpenAI 兼容格式的参数,个别中转可能不支持,这时可以去掉它,改用非流式请求的 usage 来数输出 token。
TTFT 会受网络影响,中转多一跳,慢几百毫秒是正常的,不能单凭这个下结论。连接建立、网关往返和首 token 怎么拆开看,见 AI API 延迟拆解:连接建立、网关往返与首 token 时间。更有区分度的是吞吐:网络只影响开头,不影响生成过程中的速度。如果中转的每秒 token 数比官方快很多,反而要怀疑是更小的模型。
网络这一段可以先用 cdnping 的在线测速看一下你本地到各家官方 API 入口的首次连接和往返时间,把网络因素和模型因素分开。
检查五:固定提示的输出分布一致吗?
单次回答没有可比性,但多次回答的分布有。选几个有确定答案、又有一定难度的题(例如一道需要多步推理的算术题、一段有固定输出的代码题),temperature 设为 0,各跑 10 次:
- 统计正确率
- 看输出长度的范围
- 看措辞习惯,比如是否习惯用列表、开头是否有固定句式
同一个模型在 temperature 为 0 时输出通常高度相似(不一定完全一致)。中转的结果如果正确率明显偏低、或者风格完全不同,结合前几项一起看。这一项受量化影响较大,开源模型出现小幅差异不一定是掉包。
结果怎么判断?
| 检查项 | 一致 | 轻微差异 | 明显不一致 |
|---|---|---|---|
| 输入 token 计数 | 正常 | 多出固定数量:可能注入了系统提示 | 按比例偏差:分词器不同,高度怀疑换模型 |
| 上下文边界 | 正常 | 实际上限略低 | 超限不报错或长文本失忆:存在截断 |
| 工具调用 | 正常 | 个别字段不同:可能是协议转换 | 结构不同:怀疑换模型 |
| 吞吐 | 正常 | 首 token 慢:多一跳网络 | 吞吐明显更快或更慢:怀疑换模型或换部署 |
| 固定提示 | 正常 | 开源模型小幅波动:可能是量化 | 正确率和风格都偏离:结合前几项判断 |
经验上,前三项最可靠,后两项用来佐证。只要 token 计数和工具调用都对得上,基本可以排除换模型;剩下的问题多半是量化、参数或网络。
检查完之后还要持续关注什么?
一次检查只说明当下。中转站的上游可能随时调整,官方模型本身也会更新。几个低成本的做法:
- 把上面的脚本保存下来,每周或每次觉得“变笨”时跑一遍,和第一次的结果对比。
- 在 /models 看开源模型在各推理供应商上的量化精度和可用率变化。同一份 2026-10-17 快照里,那个 DeepSeek 轻量模型的 36 个端点,过去 24 小时可用率最低约 88.1%,有 4 个低于 90%,22 个为 100%,详细分析见同一模型换个 OpenRouter 供应商,可用率能差多少。
- 在 /changes 跟踪官方更新日志和价格页。官方换了默认版本,你看到的差异可能来自上游而不是中转。
- 遇到“突然变笨”,先在 /down 看有没有其他人报告“变笨了”或故障,再判断是不是自己的通道有问题。
选中转站时能提前问清楚的事,比事后检测更省事:上游是谁、是否注入系统提示、是否做缓存、用量怎么计。完整的检查清单见 AI API 中转站怎么选:可用率、计费、数据政策 8 项检查,Claude 相关的风险点见 Claude API 中转靠谱吗:主要风险与自查方法。
最后提醒一点:通过任何第三方渠道使用模型,都应该遵守上游服务的使用条款和当地法规,这些检查只用来核实你买到的服务是否名实相符。