上周我把手上这个基于大模型 API 的智能问答项目做了一次例行预算梳理,发现官方把轻量款 5.5 的价格整体下调了 90%。说实话,第一反应不是“省钱了”,而是“我之前那版模型选型是不是站得住”。因为这个项目一天要处理几万次请求,价格一个点波动都会直接影响月底账单,更别说一次 90% 的降幅。我花了两天时间重新梳理了模型选型、Token 成本核算、灰度切换和回滚方案,踩了几个坑也补上了一些经验,这里完整记录一下整个决策过程。
这篇文章适合谁看:手上正在做 LLM API 集成、对 token 成本敏感、需要在大模型 API 的不同档位之间做取舍的开发者或技术负责人。哪怕你的项目量级没有我这个大,只要你想搞清楚“降价之后我要不要换模型”“每月 token 账单到底从哪里来的”,这篇里面的算账思路和方法都能直接拿过去套用。
1. 项目背景:为什么一次降价能让我推翻原方案
1.1 项目画像与调用量
先说项目本身。这是一个企业内部的客服知识库问答助手,逻辑上大致是:用户提问题,系统把问题向量化,先做检索,再把检索到的片段拼进提示词,发给大模型 API 生成回答。它不是一个高难度推理场景,但对响应时长有要求,用户等不了太长时间。
这个项目的调用画像非常稳定:每天大约是四万次请求。每次请求拼进去的内容包括:系统提示词、当前对话上下文、检索到的 3 到 5 段知识库片段、用户的提问。算下来平均输入 Token 大概在 1200 个左右;模型生成的回答平均输出 Token 约 400 个。也就是说,光是每天的主调用部分,就要烧掉约 48M 输入 Token 和 16M 输出 Token。
还有一部分容易被忽略的用量:工具调用、内容审核、失败重试。这个项目挂了两个工具函数,一个是查订单状态,一个是查库存,工具定义会反复塞进每次请求里。单次请求的系统提示加工具定义大约固定消耗 600 个 Token,这部分属于“不吃任何成果也要付费”的固定开销。之前上线时我没太在意,后来看账单明细才发现,这笔钱占比不低。
这还只是主链路。开发测试环境、灰度环境、定时任务、后台批量摘要,全都走同一个 API。如果把所有入口的 Token 都加在一起,生产环境每天的实际消耗会比主链路估算多出 20% 左右。这也是为什么我每次做成本核算时,都不会只按“单次请求 Token × 日请求量”这个粗略公式来算,宁可先跑一周日志统计数据。
1.2 旧选型方案是怎么定下来的
项目上线时,我采用的是“轻度保守”的选型策略:主力调用使用中档的“均衡款”模型,理由是当时轻量款在复杂多轮问答上的准确率确实差一截,经常出现检索到了正确信息但回答组织得不够完整的情况。客服场景里用户对错误的容忍度很低,一个答非所问就会拉低信任分,所以当时不敢用最便宜的档位。
但均衡款的价格并不便宜。按当时的价目表,输入约 3 美元 / 百万 Token,输出约 15 美元 / 百万 Token。我们每天生产环境约 48M 输入和 16M 输出,粗算一下:48 × 3 + 16 × 15 = 144 + 240 = 384 美元。一个月按 22 个工作日算,光这一项就是 8448 美元。后面再加上缓存命中费用、开发测试环境费用、重试费用,月均账单一度冲到一万美元左右。
这个成本对一个大企业项目来说不算致命,但也不是可以无视的数字。期间我尝试过把一部分简单请求切到轻量款,但那时轻量款的上下文窗口小,工具调用能力也弱,很多请求需要降级处理,降级逻辑写起来很复杂。后来权衡了一下,干脆统一用均衡款,省事,但贵。
1.3 降价公告里哪些信息值得细读
这次官方公告的标题很直接:轻量款 5.5 价格大幅下调,综合成本下降 90%。大部分人看到 90% 这个数字,第一反应就是“赶紧切过去”。但我在读这种公告时会多问三件事:
第一,降的是“输入价”还是“输出价”,还是全部降了?很多 API 的输入和输出价格是不同步变化的,有时候输入降得很猛但输出没怎么动。这个问题会直接影响算账结果,尤其是我们这种输出 Token 量并不低的业务。
第二,模型的实际能力是不是同步提升了?这次轻量款 5.5 不仅降价,还把上下文窗口从原来的 128K 提升到了 256K,工具调用能力和指令跟随能力也有明显增强。这说明它不是简单促销,而是新一代架构带来的成本结构优势,意味着原本那些“轻量款做不了”的任务可能现在能做了。
第三,官方有没有附加限制条件?比如新模型是否必须配合缓存使用才能拿到这个价格,是否有最低用量要求,是否有速率限制变化。这些信息都会影响最终成本模型。
把这三个问题拆完,我的结论是:好消息,但不能盲切,需要重新做一轮完整的选型和成本核算。
2. 模型选型方法:不再只看“最强”
2.1 三档模型的角色定位
这个 API 厂商基本形成了三个档位:旗舰款、均衡款、轻量款。每档都有自己的强项和代价,而且不同档位之间的价格差可以到几十倍。这种分层非常像物流里面的三档快递:顺丰空运、普通快递、经济件。你要寄一份合同,可能倾向顺丰;寄一箱卫生纸,就老实选经济件。问题是,很多团队在调用大模型时,不管包裹里是什么内容,一律用最贵的“顺丰空运”。
我的做法是先把业务场景拆成两个维度:任务复杂度和成本敏感度。简单来说就是,这个请求要真正“想一想”才能回答,还是“查一下资料就能答”?客服场景里有相当一部分请求是查库存、查物流、问退换货政策,这类问题其实不需要很强推理能力,知识库片段给到位,轻量款完全应付得来。真正需要复杂推理的是那种“用户描述了一个现象,要判断原因”的问题,绝大多数请求其实落不到这个层次。
2.2 用三个评测集代替主观感受
模型选型最忌讳的是靠“我感觉”做判断。人的直觉很容易被一两次糟糕输出带偏。我这次从生产环境里抽了三组数据,做成一个小评测集,专门用来对比轻量款 5.5 和均衡款。
第一组是“检索问答集”,大约 300 条,全是知识库能够直接覆盖的常见问题,评估标准是“答案是否正确 + 是否直接命中检索片段里的关键信息”。第二组是“复杂推理集”,大约 100 条,模拟客服场景里需要结合多条知识做推理判断的问题。第三组是“工具调用集”,大约 50 条,要求模型按指令调用查订单或查库存的工具函数,评估标准是“参数抽取是否正确 + 是否在需要调用时不乱调用”。
跑完评测的结果很有意思。在检索问答集上,轻量款 5.5 的准确率已经和均衡款基本持平,差距在 1 个百分点以内,这个差异在统计上几乎没意义。在复杂推理集上,轻量款 5.5 仍然落后约 6 个百分点,但已经不是之前那种“烂得没法用”的差距。在工具调用集上,轻量款 5.5 正确率反而略高,而且响应更快。
这个结果直接推翻了我原来的假设:原来我以为“均衡款在几乎所有任务上显著优于轻量款”,现在发现这个结论只对复杂推理成立。如果只做知识问答和工具调用,轻量款在质量上已经够用。
2.3 延迟、并发和配额维度
模型选型不能只看质量和价格,还要看延迟和配额。客服场景对延迟的要求是“尽量快”,但不是毫秒级。我实测下来,轻量款 5.5 的首 token 延迟比均衡款快大约 20% 到 30%,在低并发下差别感受不明显,但在高并发时段,均衡款的排队现象明显更严重。
更关键的是配额。降价的模型往往会伴随更严格的速率限制。我专门查了这个 API 的限流文档,发现轻量款 5.5 的每分钟请求上限确实低于均衡款,但我们的单请求 Token 量不算大,而且可以分散到不同时区处理,所以这个限制对我们影响不大。如果是一个对吞吐要求极高、动辄每秒几十个请求的场景,就需要特别注意配额风险。
我通常会把“配额”这类隐形指标和价格放在一起去评价。有些模型很便宜但你根本抢不到量,这种便宜是假的。反过来,一个模型哪怕贵一点,但如果并发配额稳定、排队少,综合成本可能反而更低。
2.4 一张表决定切换策略
把质量、价格、延迟、配额四个维度综合起来以后,我画了一张切换策略表:
| 任务类型 | 原模型 | 建议模型 | 切换理由 |
|---|---|---|---|
| 知识库检索问答 | 均衡款 | 轻量款 5.5 | 质量基本持平,价格降幅大 |
| 复杂推理判断 | 均衡款 | 均衡款(观察) | 轻量款仍有一定质量差距 |
| 工具调用 | 均衡款 | 轻量款 5.5 | 工具调用正确率达标,延迟更好 |
| 后台批量摘要 | 均衡款 | 轻量款 5.5 | 非实时场景,成本敏感 |
最终策略不是“全部切到轻量款”,而是“先按任务类型分流”。这比我预想的方案更合理,也避免了为了省钱而把复杂推理任务的准确率拉低。
3. Token 成本核算:从报价到最终账单的完整路径
3.1 理清计费口径和单位
做成本核算的第一步,不是打开计算器,而是把厂商的计费口径搞清楚。这里有个很容易踩的坑:API 价格表上写的“X 美元 / 百万 Token”,通常指的是输入输出分别计价,而且不同计费模式(标准输入、缓存命中输入、缓存写入、输出)价格完全不同。
拿这次价格调整来说,我整理了一个简化版的价目表:
| 计费项 | 轻量款旧价 | 轻量款 5.5 新价 | 均衡款现价 |
|---|---|---|---|
| 输入(美元 / 百万 Token) | 1.5 | 0.15 | 3.0 |
| 输出(美元 / 百万 Token) | 8.0 | 0.80 | 15.0 |
| 缓存命中输入(美元 / 百万 Token) | 0.15 | 0.02 | 0.30 |
| 工具调用解析 | 已包含 | 已包含 | 已包含 |
很多人看到“轻量款 5.5 降价 90%”,以为所有账单项都打了 1 折。实际上输入和输出的确降了 90%,缓存命中价也降了 90%,但有些附加服务、特殊字段、更高阶的推理特性可能不在降价范围内。如果只是拿“输入价”这一个数字去算总账,最后出来的成本会和实际账单差不少。
另外,所谓“百万 Token”不是一个绝对的字符数。同样的中文文本,按不同 tokenizer 算出来的 token 数可能差 10% 到 20%。厂商计费时通常按自己的 tokenizer 来算,你本地用字符长度估算往往偏低。我一般直接用厂商的 Token 统计接口或者 SDK 自带的计算函数来统计实际 Token 数,不要自己拿英文单词数或者中文字数去猜。
3.2 建立日用量模型
有了单价,下一步是建立用量模型。我前面提到,我们的主链路是每天四万次请求,平均输入 1200 Token、输出 400 Token。在这个基础上做一个基础测算:
- 日输入 Token:40000 × 1200 = 48M
- 日输出 Token:40000 × 400 = 16M
- 系统提示和工具定义固定开销:40000 × 600 = 24M(这部分已经包含在平均输入 Token 里,但为了讲清楚,单独拿出来看)
如果全部走均衡款,日成本是:
48 × 3 + 16 × 15 = 144 + 240 = 384 美元
如果全部走轻量款 5.5,日成本是:
48 × 0.15 + 16 × 0.8 = 7.2 + 12.8 = 20 美元
如果按“检索问答走轻量款、复杂推理走均衡款”的分流策略,假设 70% 的请求走轻量款、30% 走均衡款,日成本是:
轻量款部分:(0.7 × 48) × 0.15 + (0.7 × 16) × 0.8 = 5.04 + 8.96 = 14 美元 均衡款部分:(0.3 × 48) × 3 + (0.3 × 16) × 15 = 43.2 + 72 = 115.2 美元 总成本约 129.2 美元
这个数字仍然比全部走均衡款的 384 美元低很多,但因为复杂推理请求本身数量不大,全部走轻量款的 20 美元也很有吸引力。不过要注意,那 30% 的复杂推理请求如果切错模型,可能引发用户体验下降,所以质量损失要换算成隐形成本。
3.3 把成本算到每 100 万 Token 的细节
这里我应该多说一点“单位换算”的细节。很多人算账的时候容易把“百万 Token”和“一次请求”混在一起。其实可以更直观一点:把费用算到每次请求上。
总成本 20 美元 / 40000 次请求,约等于每次请求 0.0005 美元,也就是半美分。这个粒度对我们做产品决策很有用:如果一个功能每次调用需要消耗的 Token 量是现在的 3 倍,那每次调用成本会变成 1.5 美分,仍然在可接受范围。
我还会额外算一个“月成本”:
按 22 个工作日计算,全部走轻量款 5.5 的月成本大约是 440 美元。对比之前的平滑估算是 8448 美元,这个降幅不仅覆盖了 API 费用,还让我们有余力去做一些之前不敢做的功能,比如给每次请求附加更长的历史记录,或者对高质量回答做二次校验。
3.4 容易被漏算的成本项
成本核算里最翻车的部分,往往不是主价格表,而是那些默认开启的隐藏项。
第一个是缓存。官方现在普遍支持 Prompt 缓存,但缓存不是免费的。缓存写入有价格,缓存命中也有价格,只是比普通输入便宜很多。我们项目里的知识库片段其实是高度重复的,缓存命中率可以达到 60% 以上。这意味着实际成本比裸算的 20 美元还要低。但如果代码里没有开启缓存参数,这些片段每次都会按完整输入价格计算,那就亏大了。
第二个是工具调用。工具函数的 schema 定义是每次请求都会发送的,这些 Token 会计入输入 Token。如果你的工具定义写得很长,比如几百行 JSON Schema,这部分固定开销会非常夸张。我之前见过一个项目,工具定义占了总输入 Token 的 40%,业务内容反而只占 60%。遇到这种情况,应该把工具 schema 精简、只保留必要字段,或者启用缓存来消化这部分重复输入。
第三个是失败重试。大模型 API 在高并发时会出现超时或者限流,重试意味着同一段输入要反复计费。如果重试率是 3%,相当于总账单额外增加 3%。更糟的是,有些 SDK 的重试逻辑是“从头再来”,不会复用缓存,所以每次重试都是全价输入。我后来把超时重试次数从 3 次降到 2 次,同时把单次请求的超时时间调长了一点,账单立刻变得稳定。
第四个是输出 Token 的“隐藏长度”。模型可能在你要求 200 Token 时输出 400 Token,尤其是没有设置 max_tokens 或设置得过高的时候。输出价格通常是输入的 5 到 20 倍,所以输出长度控制变相就是成本控制。
4. 实操落地:切换、灰度与止损
4.1 应用侧增加模型路由
既然策略是“按任务类型分流”,代码层面就不能写死一个模型名,而是要做一个模型路由层。这个路由层的作用是根据请求特征决定调用哪个模型。
我简化后的代码逻辑大致是这样的:
MODEL_POOL = { "light": { "model": "轻量款5.5", "price_in_per_m": 0.15, "price_out_per_m": 0.8, "max_tokens": 4096, }, "balanced": { "model": "均衡款", "price_in_per_m": 3.0, "price_out_per_m": 15.0, "max_tokens": 4096, }, } def route_model(request): # 复杂推理:涉及多个知识片段且需要因果判断 if request.requires_reasoning: return "balanced" # 工具调用类:只要参数抽取准确就可以 if request.is_tool_call: return "light" # 默认知识库检索问答 return "light"这里需要解释一下“复杂推理”是怎么判断的。我没有用太复杂的规则,就是四个字:问题里是否出现“为什么”“如果”“比较”“分析”这类词,同时检索结果命中了多于两段知识片段。命中太多片段往往意味着问题需要跨段落整合,这种情况交给均衡款更稳。
这个路由层还可以接一个远程配置,比如通过配置文件控制“轻量款占比”这个参数,这样不用每次改代码就能调整比例。
4.2 切换过程中的灰度验证
我不敢一天之内把所有流量都切过去。灰度节奏是这样的:
第一天,切 1% 的流量到轻量款 5.5。观察两个指标:用户负反馈率和请求成功率。这里不要只看平均响应时间,要看 p95 和 p99,因为长尾延迟对体验影响最大。
第二天,把比例提高到 10%。同时把轻量款 5.5 的生成结果和原来均衡款在评测集上的输出做一次离线对比,确认没有出现系统性质量下降。
第三天到第五天,逐步提高到 50%,再全量。每提高一档,都要检查一个隐性问题:工具调用是否能正确触发。
我这次灰度期间遇到一个怪问题:轻量款 5.5 在工具调用测试集上表现很好,但生产环境里的调用成功率反而偏低。排查发现是因为生产环境的工具定义包含了更多返回字段,模型在解析时偶发漏参。这个问题通过精简工具定义解决,而不是回滚模型。
4.3 回滚方案和旧模型保留策略
任何选型决策都要有回滚通道。我这里的做法是:
第一,保留均衡款的 API Key 和配置入口,不直接删除。第二,在路由层加入紧急开关,如果线上质量指标下降,可以一键把“轻量款”的配置指向均衡款。第三,设置一个简单的“质量探针”任务:每天凌晨自动跑一批历史问题,把轻量款 5.5 的输出和均衡款输出做对比,一旦发现一致率低于某个阈值,就发告警。
这套回滚方案不复杂,但在关键时候能救命。因为模型行为是可以悄悄变化的,同一个轻量款 5.5,可能今天和明天的输出风格就不同了。有探针兜底,我心里会踏实很多。
4.4 上线一周后的实际成本
切完一周后,我拉了一次真实账单一。情况比预估还略好一点:
- 每天实际调用量约 4.2 万次
- 平均输入 Token 从 1200 降到了约 980,原因是精简了一部分系统提示词
- 平均输出 Token 约 390
- 缓存命中率约为 55%
- 每天的 API 成本约在 15 美元到 18 美元之间
对比之前的日均 384 美元,实际降幅超过了 95%。更重要的是,业务指标没有下降,用户负反馈率基本持平。
这个结果让我意识到一个规律:当模型能力整体上了一个台阶,很多过去的保守策略都需要重新审视,不能假设“贵的等于对的”。
5. 常见问题与排查实录:这次踩过的坑
5.1 常见问题速查表
我把这次操作中遇到以及同组同事经常问的问题整理成了一个速查表:
| 问题 | 可能原因 | 解决办法 |
|---|---|---|
| 账单降幅没有 90% 那么大 | 输出 Token 占比高,缓存没有启用 | 开启 Prompt 缓存,控制 max_tokens |
| 切换后质量波动明显 | 复杂推理请求也被路由到轻量款 | 收紧路由规则,加关键词和片段数判断 |
| 工具调用偶发失败 | 工具定义太长,有歧义字段 | 精简工具 schema,不要塞无关字段 |
| 限流报错增多 | 轻量款 5.5 的 RPS 配额低于均衡款 | 调整并发策略,增加本地队列 |
| 模型输出变短了 | 轻量款更倾向于简洁回答 | 在 Prompt 中明确要求回答长度 |
| 缓存命中率很低 | 请求之间片段顺序不一致 | 固定知识片段排序规则 |
5.2 账单高于预期时的排查路径
如果下一步有人遇到“切换之后成本还是偏高”,我建议按这个顺序排查:
第一,先看缓存命中率。命中率低于 30%,基本等于没开缓存。要检查请求参数里是否加了缓存控制字段,以及 Prompt 前缀是否每次都完全一致。缓存是按“前缀”命中的,只要前面任何一个字符变了,缓存就失效。
第二,看输出 Token 长度。日志里统计一下实际输出 Token 的平均值和中位数,对比你预期的数字。如果中位数比预期高很多,说明 max_tokens 或 Prompt 里的输出约束没用对。
第三,看重试率。如果重试率超过 5%,问题不在模型价格,而在你自己的服务稳定性。可能是上游超时时间设得太短,导致本来能成功的请求被重复发送。
第四,看开发测试环境的消耗。很多团队生产环境成本是降下来了,但测试环境每个版本都在反复跑大量 Prompt,测试环境成本反而掩盖了生产优化的效果。
5.3 什么时候不要用轻量款
虽然这次价格调整让我把大部分流量切到了轻量款 5.5,但我也明确划定了一些“不要用”的场景。
第一个是法律或医疗建议类输出。这类输出出错的代价极高,必须保留更高推理能力的模型,同时加人工审核。不要因为降了 90% 就把安全底线也降了。
第二个是长链路多智能体协作场景。当一个任务被拆成多个步骤,每一步的错误都会累积,轻量款的错误率在单步上只差几个点,但累积下来可能差距很大。
第三个是低资源环境下的离线批处理。如果本身请求量不大,切换带来的成本节约有限,反而可能因为模型行为变化导致结果不一致,这时候不如保持不变。
区分这些场景,比“一律使用最便宜模型”重要得多。省钱的方式不是无脑选低价,而是给每个任务找到性价比合适的档位。
最后再分享一个我自己的体会
这次模型选型让我最有感触的一点是:成本核算不只是一个算账过程,更是一个重新理解业务的过程。你要真正看清自己的请求结构,看清哪些是重复的、哪些是复杂的、哪些是可以被工具调用来替代的,才能做出合理的分流决策。单纯盯着价格表里的“90%”来回换算,往往会在真实账单面前翻车。
另外,我自己踩过几次坑之后的习惯是:每次价格调整,不管降幅多吸引人,都给自己留一周的观察期。先用小流量验证,再把比例拉起来。这个节奏虽然慢一点,但比一次性全量切换稳妥得多。模型能力在快速迭代,我们手里的选型标准也不能一成不变,每隔一段时间把旧结论拿出来重新验证,其实是一件性价比很高的事。