大模型API刚接入时,每天调用量不大,成本通常不会受到关注。客服、知识库、内容生成和内部研发工具陆续接入后,账单开始上涨,但团队往往只能看到总金额,不清楚费用来自哪个项目。
成本治理不等于一律换成便宜模型。更有用的指标是“每个成功任务的成本”,它同时考虑价格、成功率、重试和人工返工。
输入和输出要分开计算
文本模型通常分别计算输入Token和输出Token,部分模型还提供缓存创建与缓存读取价格。
请求费用 =
输入Token ÷ 1,000,000 × 输入单价
+ 输出Token ÷ 1,000,000 × 输出单价
+ 缓存创建Token ÷ 1,000,000 × 缓存创建单价
+ 缓存读取Token ÷ 1,000,000 × 缓存读取单价
Token不等于固定数量的汉字或英文单词。中文、英文、代码和标点的切分结果不同,正式统计应使用接口返回的用量。
业务内部可以写一个简单的估算函数:
def estimate_cost(
input_tokens,
output_tokens,
input_price_per_m,
output_price_per_m,
cache_read_tokens=0,
cache_read_price_per_m=0,
):
return round(
input_tokens / 1_000_000 * input_price_per_m
+ output_tokens / 1_000_000 * output_price_per_m
+ cache_read_tokens / 1_000_000 * cache_read_price_per_m,
6,
)
价格参数不宜长期写死。模型单价发生变化后,历史账单需要保留原来的价格版本,才能正确复算。
先检查重复输入
很多费用来自反复发送同一批内容。常见情况包括完整历史对话、过长的系统提示词、与问题无关的检索文档,以及每次请求都附带的大段格式示例。
知识库问答不需要把整份文档发送给模型。可以先检索相关段落,再把少量候选内容作为上下文。对话历史也可以在达到一定长度后做摘要,而不是一直累加。
压缩上下文不能只看Token数量。删掉关键条件后,模型需要反复追问或重新生成,实际费用可能更高。
缓存要看命中率
提示词缓存适合固定规则加变化问题的场景,例如固定系统指令、同一份长文档的连续问答、重复使用的工具说明。
如果每次提示词都不同,或者缓存创建后没有再次读取,缓存不会带来实际收益。不同模型的缓存长度、有效时间和计费方式也不同,需要按当前文档配置。
评估时至少记录两个数:缓存命中率,以及每次命中减少的费用。只记录是否开启缓存,无法判断它有没有作用。
输出长度通常更容易控制
部分应用没有设置最大输出Token,简单问题也可能生成很长的内容。可以按功能设置不同上限:分类任务几十Token,摘要几百Token,长文任务再单独提高。
上限过低会造成内容截断,用户重新生成一次,费用可能更高。可以根据历史请求的P90或P95输出长度设定,再观察截断率。
比较模型要算成功任务成本
文本分类、关键词提取和格式转换可以先测试轻量模型,复杂推理和高风险内容再使用能力更强的模型。
模型比较可以使用下面的指标:
每个成功任务成本 = 总调用费用 ÷ 成功完成的任务数量
单价较低的模型如果错误率较高,造成频繁重试和人工检查,最后并不一定便宜。费用、任务成功率、响应时间和复核成本应放在一起评估。
重试需要单独记账
客户端请求超时,不代表服务端一定没有执行。请求可能已经产生Token,只是响应没有及时返回。
临时网络错误、429和部分5xx可以有限重试,通常控制在一到两次。400、401、403和404属于参数或权限问题,不应自动重复。
每条业务记录需要保存retry_count。如果一个用户动作触发了三次模型请求,成本分析也应看到三次,而不是只保留最后一次成功结果。
预算要在余额耗尽前处理
预算可以按照项目、用户和模型三个维度管理。项目限制每天或每月费用,用户限制请求量和Token量,模型策略负责在接近预算时限制高成本任务。
可以在预算使用到70%和90%时分级告警。达到上限后,暂停批量实验和非核心任务,核心业务使用单独额度。具体比例需要根据业务峰值调整,不必所有项目使用同一套数字。
每周至少查看项目Token用量、成功任务成本、缓存命中率、重试占比、模型成功率和预计月底费用。先知道钱花在哪个任务上,再处理上下文、缓存、模型选择和预算,成本才会真的下降。