近在整理一批大模型 API 的报价,本来以为是个算术活,结果光「对齐口径」就花了两天。
同一个模型,六家给的价长这样(数字做了脱敏,量级是真实的):
| 供应商 | 输入(元/1M) | 输出(元/1M) | 缓存读(元/1M) | 按 3:1 输入输出比算的混合成本 |
|---|---|---|---|---|
| D | 1.60 | 8.00 | 0.160 | 3.12 |
| F | 12.00 | 48.00 | — | 22.80 |
| E | 14.91 | 74.55 | 1.49 | 29.04 |
| A | 21.30 | 106 | 2.13 | 41.49 |
| B | 21.00 | 105 | — | 46.20 |
| C | 24.85 | 124 | 2.48 | 48.41 |
最便宜和最贵差 15.5 倍。但把每一栏拆开看,你会发现没有一家是真的「贵 15 倍」——差的是口径。
坑一:percent_off = 90 不是九折
我第一次看到这个字段,下意识按「九折」算,也就是乘 0.9。算完发现比自己直连官方还贵。
正确理解是「便宜了 90%」,即乘 0.1 —— 一折。
这个字段名几乎所有人都能看懂,但真正写代码的时候,1 - 90 和 1 - 0.9 只差一个小数点,结果差十倍。我当时是拿官方价和自己的账单对了一遍才发现的。
坑二:币种要带日期,不能用一个固定汇率
报价单里有人写 USD,有人写 CNY。用 7.1 还是 6.7,直接决定排名先后。我现在的做法是汇率跟着日期存,脚本里显式传 --rate,让每次比价都能复现。
坑三:报价单只写 input / output,把缓存藏起来了
现在稍微正经一点的厂商都有四五个价:输入、输出、缓存读、缓存写(有的还有 1 小时缓存写、更长 TTL 的档)。报价单上往往只写前两个。
如果你的业务缓存命中率有 40%,那缓存读的价格对总成本的影响比输出价还大。只按 input/output 比,等于把最便宜的那家排到最后。
坑四:长上下文是阶梯价,小字里藏着翻倍
很多模型在 32K / 128K 处有一条分界线,超过之后整单换价(不是超出部分),有的直接翻倍。
比价时如果按短上下文的价排,长文档场景会完全选错。
坑五:按次、按张、按秒、按 token 混在一起排
图像模型按张、视频按秒、音乐按首、语音按千字符、文本按 token。
这几种单位放进同一张「价格排行榜」里没有任何意义。我现在的做法是先按计费方式分组,组内才排序。
归一化之后,就十行
说到底就是把所有报价换算成同一个单位(元 / 百万 tokens),再按你自己的用量结构加权:
out_share 和 cache_hit 这两个参数,比任何一家厂商的定价都更能决定你最终花多少钱。同一个模型,这两个参数不同,排名能翻过来。
一个反直觉的结论
「便宜」不是一个价格属性,是一个用量属性。
同一批模型,做短对话(输出占比高)和做批量摘要(输入占比高、缓存命中高),最优选择经常不是同一家。所以任何不问你用量结构的「最便宜榜单」,看看就好。
工具
上面这些逻辑我整理成了一个只依赖 Python 标准库的脚本,读一个 CSV、输出一张排好序的表:
CSV 七列(供应商/模型/币种/输入/输出/缓存读/缓存写),缺的留空,跑:
没有依赖,不用装环境。
顺带说一下背景:我自己在做一个小平台(ai.dijinlong.com/),把不同卖家挂出来的…
有踩过别的坑的欢迎补充,尤其是阶梯价和图片 token 折算这两块,我到现在还是手工处理。