团队降低 LLM API 成本时,通常会去找更便宜的行项、更小的模型或者折扣。真正把成本降下来的工程师把它当成一套有顺序的流程:先测量,去掉浪费,缩减发送出去的内容,把可延后的工作挪到更便宜的执行路径,把缓存稳定下来,在质量护栏后面做模型尺寸调整,再对照你起步时的基线做验证。顺序很重要,因为后面每一步都依赖前面几步所证明的东西。跳过测量直接把模型降级,结果掉进质量回退,你就既说不清省了多少钱,也说不清质量去哪儿了。本文是这条序列的枢纽,它引用的每一个机制都在按步骤链接的姊妹文章里深入讲过。
第零步:测量与 API 成本归属
在你用一句话回答“哪些功能在消耗账单”之前,别的都别开始。没有测量的 LLM 成本优化计划就是在猜,而猜会产生两种经典失败:砍掉了并非问题的东西,或者为了省下四舍五入级别的误差而牺牲质量。用三组信号建立基线。第一,按功能、团队和客户分组的支出与用量,让最大的行项可见,使用用量与成本追踪指南里的归属方法。第二,缓存相关的用量字段,因为它们在你去动缓存之前就能告诉你缓存到底有没有生效。第三,重试次数和被拒请求率,因为看起来像需求的一部分其实是浪费,详见重试预算指南。把基线写下来。后面每一步都会对照它来评判。
第一步:先消灭浪费,再谈优化
最便宜的 token 是你从不发出的那个,而最常见的成本问题都是浪费,不是定价:
- 重试风暴。对本不可重试的错误(比如 403 这一类或硬性消费上限)应用退避重试,只是在反复发送永远不会成功的请求。更糟的是叠加重试:一个带自动重试的 SDK 加上应用层的重试包装,可以让每次逻辑调用的请求量成倍放大。测一下你的栈有没有这种嵌套。
- 静默失效的缓存。如果 prompt 前缀里有时间戳或随机 ID,或者动态内容排在稳定内容之前,或者工具定义每次部署都被改动,缓存就永远不会命中。于是你在每个请求上都付一次新的缓存写入,却永远拿不到一次读取。机制在缓存指南里,而这个模式值得专门检查一遍。
- 失控的 agent 循环。工具定义占用 prompt 空间,而每一次循环迭代都会重发不断变长的对话。没有轮次上限、没有 token 预算的循环就是一个开着的龙头;工具调用指南讲了循环的设计。
- 重复的上下文。同一份长文档被粘贴进许多次调用,而一个缓存前缀或一个文档引用就够用,这就是纯粹的重复。
第二步:缩减每个请求的 token
OpenAI 的成本优化指南把杠杆归为三种策略:减少请求、最小化 token、选择更小的模型。它还指出成本与延迟是相关联的,所以这里的大部分工作会付两次回报。具体来说:把总是成对出现的调用合并成一个请求而不是两个;在长答案对谁都没用的时候限制输出长度,因为输出才是贵的方向;要求结构化输出只包含下游代码真正读取的字段;去掉不影响答案的上下文。输出长度限制同时也是一个可靠性特性:有界的答案更容易校验,而校验不花钱。
第三步:可延后的工作用 batch API 还是 flex 处理
有些工作不需要即时响应,这个事实应该被计入价格。存在两条官方路径:
- Batch API。对 OpenAI 来说,Batch API 异步处理作业:你把请求收集到一个文件里,启动一个 batch 作业,在请求执行时查询它的状态,完成后取回收集好的结果。对 Anthropic 来说,Message Batches API 的工作方式相同:提交大量请求做异步处理,轮询状态,完成后取回。大多数批次在 1 小时内完成,你可以在所有消息完成时或 24 小时后(以先到者为准)访问结果,如果处理在 24 小时内没有完成,批次就会过期。适用性测试很简单:量大、不需要即时响应、能容忍小时级的周转。
- flex 处理。OpenAI 的成本指南把 flex 描述为对 Chat Completions 或 Responses 请求显著更低的成本,代价是响应更慢、偶尔资源不可用,定位在非生产或较低优先级的工作,比如模型评估、数据富集或异步负载。边界不言自明:面向用户的交互流量不属于这里,因为偶发的不可用是一个产品决策,而不是一个工程细节。
第四步:正确处理 prompt 缓存的 TTL
缓存是顺序纪律最能见效的一步,也是小错误最能毁掉收益的一步。Anthropic 的 prompt 缓存文档里的规则是:缓存引用整个 prompt、工具、system 和 messages,按这个顺序,直到并包含你指定的那个块。所以设计原则是稳定优先:把很少变化的内容放在前面,把易变内容移到断点之后,并在稳定性结束的地方放显式标记。有两个细节会咬住那些把缓存当成设完就忘的开关的团队。第一,TTL 默认是 5 分钟,另有 1 小时的选项但要额外付费,指导建议是对使用频率高于每 5 分钟的 prompt 保留 5 分钟默认值(它会持续刷新),而把 1 小时版本留给使用频率低于每 5 分钟但高于每小时的 prompt。第二,边界情况:如果最后一个块已经带有相同 TTL 的显式缓存标记,自动缓存就是空操作;如果标记的 TTL 不同,API 会返回 400 错误。缓存写入和缓存读取的定价与基础输入 token 不同,而且这些倍数会与其他定价修饰项叠加,所以计价算账属于官方定价页面,不属于估算。还有一条运维说明:缓存命中不计入你的限流额度,所以修好缓存既改善成本也改善余量。机制,包括如何从用量字段核实命中,见缓存实践指南。
第五步:更小的模型,配上质量护栏
第三种官方策略是选择更小的模型,OpenAI 把它表述为在降低成本和延迟与保持准确率之间取得平衡。“保持”是关键的那个词,而它不会自己发生。按每个任务的约束来选模型,而不是按名气,使用模型选择指南里的框架:这个具体工作负载到底需要什么准确率、延迟和能力?然后守住护栏:一套回归测试,用同一批任务跑更小的模型,并把输出与当前基线比较,这样降级就是一个被测量过的决定,而不是一个悄悄发生的决定。悄悄拿质量换成本是能做的最糟的交易,因为账单下降的同时产品在退化,而没人能把哪项改动归因到哪个后果。
第六步:对照基线验证
在第零步的基线确认之前,上面每一个动作都只是假设。用三项检查闭环,一起评估,绝不单独看一项:
- 成本曲线。改动之后,按功能和按团队的支出是否真的在往下走?
- 缓存行为。命中率上升了吗,还是某次前缀改动把它悄悄归零了?
- 质量。拒绝率、校验失败率,以及对输出做抽样人工评审,都与改动前的同一样本对比。
如果三项里任何一项变差,就回退那一个动作,保留其他动作。一次只改一处,才让归因成为可能;这和事故日志对待证据是同一种纪律,只是提前了一步,用在了决策本身上。
那条基线循环是发布前模型验证在成本侧的版本;测试手册描述了针对模型和 prompt 改动的同一套纪律。
顺序检查清单
- 先测量:按功能划分的支出、缓存字段、重试与被拒率。把基线写下来。
- 消灭浪费:不对不可重试的错误重试,不叠加重试层,不留不稳定的缓存前缀,不放任 agent 循环,不重复上下文。
- 缩减 token:更少的请求、更短的输出、更紧的 schema、更少的无关上下文。
- 挪走可延后的工作:大批量异步作业用 batch API;非生产或低优先级负载用 flex;绝不用在交互流量上。
- 修缓存并注意 TTL 细节:稳定优先的前缀、显式断点、清楚空操作和 400 这两个边界情况,计价算账放在官方页面上。
- 按回归套件而不是按希望来调整模型尺寸。
- 事后验证三项信号,任何让其中一项回退的改动都回退掉。
- 保留回滚开关:上面每一步都应该是你能单独撤销的配置变更。
这就是全部的诀窍。在支出上打赢的团队把它当作一条两端都有测量的工程序列,而你调用的任何端点的端点级事实都在该平台自己的文档里。