大模型 API 成本怎么算:Token 计费原理与 5 个降本手段
成本公式只有一行,但大部分人都算错
月成本 = 日调用量 × 30 × (输入token × 输入单价 + 输出token × 输出单价)
看起来简单,但三个地方最容易错:
- 漏算输出 token:输出单价通常是输入的 2~4 倍,而长回复的输出量可能超过输入
- 漏算系统提示词:每次请求都带的 system prompt 和 few-shot 示例,会重复计费
- 用平均单价估:长文本、缓存、批处理都有不同价格,混在一起算不准
一、Token 到底是什么
Token 是模型处理文本的最小单位,不等于字,也不等于词。
| 文本 | 大致 token 数 | 规律 |
|---|---|---|
| 英文 | 4 字符 ≈ 1 token | 0.75 词 ≈ 1 token |
| 中文 | 1 汉字 ≈ 1~1.5 token | 视 tokenizer 而定 |
| 代码 | 3~4 字符 ≈ 1 token | 空格和标点也占 token |
| emoji / 生僻字 | 可能 2~4 token | 分词器切碎了 |
中文比英文"贵":同样信息量下中文 token 更多——英文一句话 20 个词约 27 token,翻成中文 30 个字约 40 token。做中英文成本对比时必须按 token 算,不能按字数。
精确值要用目标模型的 tokenizer 算(OpenAI 有 tiktoken,各家也有工具)。工程上用「中文 1.3 token/字」估量级就够了。
二、输入和输出为什么价差这么大
自回归生成的特点:输入可以并行处理(一次前向),输出必须逐 token 串行生成。所以输出更贵、更慢。
这带来两个直接影响:
- 让模型少说话 = 直接省钱。一句「请简洁回答,不超过 50 字」可能省下 30% 输出成本
max_tokens必须设。不设上限,模型偶尔的"长篇大论"会变成账单上的意外
resp = client.chat.completions.create(
model=MODEL,
messages=msgs,
max_tokens=800, # 兜底,防止跑飞
temperature=0.2, # 低温度也减少无谓发散
)
三、五个真正有效的降本手段
1. 模型分级(效果最大)
用贵模型做难的事,便宜模型做简单的事。典型分层:
| 任务 | 建议档位 |
|---|---|
| 意图分类、打标、简单抽取 | 最便宜的小模型 |
| 常规问答、摘要、改写 | 中等模型 |
| 复杂推理、代码生成、关键决策 | 最强模型 |
实测经验:把 70% 的简单请求下沉到小模型,总成本能降 50%~80%,效果几乎无损。前提是你有评测集能验证"几乎无损"。
2. 上下文缓存(长 system prompt 的救命稻草)
如果你的 system prompt 很长(角色设定 + 规则 + few-shot,动辄几千 token),每次请求都重复计费。
主流厂商都提供提示词缓存:相同前缀的内容在有效期内复用,命中部分按远低于正常的单价计费(通常是原价的 10%~25%,各家不同)。
关键规则:缓存命中靠前缀匹配——把稳定不变的内容(system、示例)放最前面,把变化的内容(用户输入)放最后。顺序反了就永远命中不了。
[稳定的 system + few-shot] ← 放前面,可命中缓存
[变化的用户输入] ← 放最后
3. 批处理接口(离线任务打对折)
不需要实时返回的任务(每天跑一次的数据清洗、历史数据打标、批量摘要),用批处理 API:异步提交、几小时内返回,价格通常是实时价的一半甚至更低。
判断标准很简单:用户不在等结果 → 用批处理。
4. 控制上下文的长度(RAG 优于全塞)
把整份文档塞进上下文,token 是 O(n),成本也是 O(n),而且准确率会下降。
正确做法:先检索出相关段落(通常 1~3K token),再喂给模型。同样的任务,检索方案的 token 消耗可能只有全塞的 5%~10%。
5. 结果缓存(重复问题直接返回)
用户的问题大量重复("怎么退款""营业时间")。对确定性任务(低 temperature),相同输入可以直接缓存响应:
key = hashlib.sha256((model + json.dumps(msgs)).encode()).hexdigest()
if cached := cache.get(key):
return cached
resp = call_model(msgs)
cache.set(key, resp, ttl=86400)
这一步经常被忽略,但客服类场景命中率能做到 30% 以上,等于白省三分之一。
四、算一个真实例子
假设客服机器人:日请求 2 万次,每次输入 1200 token(含 800 的 system)、输出 200 token。
日输入 = 20000 × 1200 = 2400 万 token
日输出 = 20000 × 200 = 400 万 token
不做任何优化时,输入里 800×20000 = 1600 万 token 是重复的 system prompt——占输入的 67%。
开缓存后(假设命中部分按 20% 计价):
优化前输入成本 ≈ 2400 万 × 单价
优化后输入成本 ≈ (800 万 + 1600 万×0.2) × 单价 = 1120 万 × 单价
光这一项,输入成本就砍掉一半以上。再叠加模型分级(70% 简单请求下沉)和结果缓存,总成本降到原来的 25%~30% 是常见水平。
五、容易被忽略的三笔成本
- 失败重试:JSON 校验失败重试、超时重试,都会翻倍计费。重试率 10% 就是 10% 的额外成本
- 开发与调试:调试期的调用量常常比生产还高,记得给开发环境单独的限额
- 向量库与嵌入:RAG 方案的 embedding 调用和向量库存储,是模型之外的独立账单
检查清单
上线前把这五项对齐,成本预估基本不会差:
- [ ] 输入 token 含 system prompt,按「每次都算」估
- [ ] 输出 token 按 P90 而不是平均值估(长尾回复拉高均值)
- [ ] 输出单价用的是真实单价,不是输入的 1 倍
- [ ]
max_tokens已设置 - [ ] system prompt 在前、用户输入在后(为缓存留好结构)
- [ ] 离线任务走批处理
- [ ] 有重试率监控