怎么检测你调的 API 是不是被偷换成了蒸馏/低配模型(附可复现脚本)

不要再用"你是谁"来验证了

问模型"你是什么模型"是最没用的方法——只要在 system prompt 里写一句"你是 GPT-5.6",任何模型都会照着答。有效的检测都基于一个原则:问身份可以伪造,但行为特征很难伪造

下面四个测试先后顺序从易到难,全部脚本化,任何 OpenAI 兼容接口都能跑。

测试一:知识截止日期探针

每个模型的训练截止日期是固定的硬指标。拿"官方模型截止日期之前不久发生的具体事件"提问,真模型答得出,被偷换的旧模型/小模型答不出或胡编。

from openai import OpenAI

client = OpenAI(base_url="https://147ai.com/v1", api_key="sk-xxx")  # 换成你要测的站

PROBES = [
    # 按被测模型的官方 knowledge cutoff 定制,示例:
    "不要联网。凭训练知识回答:2025 年 4 月 xx 事件的结果是什么?如果你的训练数据不包含此事,明确说不知道。",
    "不要联网。你训练数据中最新的 Python 稳定版是哪个?",
]

for p in PROBES:
    r = client.chat.completions.create(model="待测模型", messages=[{"role":"user","content":p}], temperature=0)
    print(p[:30], "=>", r.choices[0].message.content[:200])

判读:和同一问题打在官方 API 上的结果对比。旧模型冒充新模型时,这个测试的命中率最高。

测试二:logprobs 指纹(最难伪造,但仅限支持的模型)

不同模型的 tokenizer 和输出分布不同。对同一个强约束 prompt(temperature=0),同一个模型每次返回的 top logprobs 高度一致,不同模型则明显不同。

先说适用范围,免得你白跑:这个测试只对官方 API 本身就支持 logprobs 的模型有效(GPT 系等)。Anthropic 官方 API 压根不提供 logprobs,所以 Claude 系模型不管在哪个站都拿不到——返回的 logprobsNone,这是正常现象,不是掺假信号。

所以测 Claude 系请用测试一、三、四。

r = client.chat.completions.create(
    model="待测模型",
    messages=[{"role": "user", "content": "The capital of France is"}],
    max_tokens=5, temperature=0,
    logprobs=True, top_logprobs=5,
)
lp = r.choices[0].logprobs
if lp is None or lp.content is None:
    print("该模型/该站不返回 logprobs,跳过此测试")   # Claude 系必然走到这里
else:
    for tok in lp.content:
        print(repr(tok.token), round(tok.logprob, 4),
              [(t.token, round(t.logprob, 3)) for t in tok.top_logprobs])

判读:先在官方 API 上跑 20 组固定 prompt 存下指纹,再在中转站上跑同样的组。logprob 数值不会完全相等(上游硬件/批处理有抖动),但 top-5 候选 token 的集合与排序应当基本一致。如果候选 token 集合都对不上,基本可以断定不是同一个模型。注意:对于官方支持 logprobs 的模型(如 GPT 系),有的站不透传 logprobs——不透传本身不等于作假,但意味着你失去了最强的验证手段,可以把这一点计入选型。

测试三:长上下文行为差异

蒸馏小模型最藏不住的短板是长上下文。构造一个 50K+ tokens 的文档,把三个"针"(特定编号、日期、人名)埋在开头/中部/结尾,要求模型全部找出来。

# 构造 50K+ tokens 的干草堆:填充文本里按 10% / 50% / 90% 位置插入三根"针"
filler = "这是一段用于填充上下文的普通文本。" * 6000
needles = ["编号 X-7749", "日期 2024-11-30", "联系人 郑十一"]
pos = [len(filler)//10, len(filler)//2, len(filler)*9//10]
needle_doc = filler[:pos[0]] + needles[0] + filler[pos[0]:pos[1]] + needles[1] \
             + filler[pos[1]:pos[2]] + needles[2] + filler[pos[2]:]

r = client.chat.completions.create(
    model="待测模型",
    messages=[{"role":"user","content": needle_doc + "\n\n请列出文中出现的全部编号、日期、人名。"}],
    temperature=0,
)

判读:旗舰模型三针全中是基本功;被换成小模型时典型表现是中部的针丢失(“lost in the middle”)。同时看 usage.prompt_tokens——如果一个号称 200K 上下文的模型在 60K 输入时报错或明显截断,这也是一个信号。

测试四:计费对账(防"汇率刺客"和暗改倍率)

模型是真的,账也可能是假的。

方法:本地累加每次响应的 usage,乘以平台公示价格,和后台扣费对比。

147AI 为例,价格完全公开:

  • 浏览器看网页版 https://147ai.com/pricing
  • 脚本对账抓 JSON 接口 https://147ai.com/api/pricing(两者同源,都无需登录)。

计价公式 :

  • 输入$/1M = model_ratio × 2 × group_ratio
  • 输出乘 completion_ratio,充值汇率 1$=¥1.0。

你算出来的数和后台对不上,就是问题。任何不公开完整价格接口、或标价和实扣对不上的站,直接跑。

把四段代码拼成你的体检脚本

上面四段代码就是全部了——没有额外的代码仓库,也没有藏着的"完整版"。把它们按顺序拼进一个文件、包一层循环和计数,就是你的体检脚本,你只需要依赖 openai 库,改一行 base_url 就能测任何站。跑完你会得到类似这样的结果:

[1] 知识截止探针   : 5/5 与官方一致
[2] logprobs 指纹  : top-5 重合率 96%(阈值 80%)
                     (若测 Claude 系模型,此项显示"不返回 logprobs,跳过",属正常)
[3] 长上下文三针   : 3/3
[4] 计费对账       : 本地估算 ¥12.4 vs 后台扣费 ¥12.4 ✓

可以先测147AI,再测一波你正在用的。拼装时踩到坑就贴到评论区,我们来负责填坑。

关于147AI,我们想说:

  • 目前我们没有免费试用,最低充值 ¥100,这可能是你需要考虑的验证我们的成本
  • 有些分组是特价渠道,倍率低、稳定性预期也低(分组说明里写着"企业勿选"的就是字面意思),同一模型不同分组价格能差 7.5 倍——选组前可以先把定价看一遍(网页版 /pricing 或 JSON 接口 /api/pricing 都行),别只看最低价。这条对所有中转站适用。
  • 希望可以以脚本代替信任——测完不管结果如何,行业里多一个会验货的用户,掺假的生意就难做一分。

本文脚本可自由转载使用,无需署名。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值