← 返回资讯

大模型 API 成本优化 10 招:从选模型到监控的完整清单

2026-06-17

大模型 API 成本失控通常不是因为”模型太贵”,而是因为没有针对性地优化每一个环节。以下 10 招覆盖从架构设计到运营监控的全链路,每一招都可以独立落地,叠加使用效果更佳。

招式一:开启 Prompt Caching

怎么做: 把固定的 system prompt、文档、few-shot 示例放到输入最前面,并在支持显式标记的 API(如 Anthropic)上打上 cache_control 标记;在 OpenAI 上确保前缀足够长(通常 ≥1,024 token)以触发自动缓存。

效果: 缓存命中时,重复前缀部分的成本降至原价的 10%–25%,是单次效果最大的优化。

我踩过的坑: 缓存命中要求前缀逐字节完全一致,哪怕只是多了一个换行符或者把时间戳塞进了 system prompt 里,都会导致 miss。我第一次上线缓存的时候,把”当前时间:2026-06-17 10:23:01”这种动态字段写在了 system prompt 最前面,结果每次请求前缀都不一样,缓存命中率长期是 0,还以为是接口不支持。后来把动态字段挪到 system prompt 末尾(缓存标记只覆盖前面固定部分),命中率才从 0 冲到 90% 以上。排查方法很直接:看响应里的 cache_read_input_tokens(Anthropic)或 prompt_tokens_details.cached_tokens(OpenAI),如果这个数字长期是 0,先怀疑前缀里混了变量。

缓存有效期也要注意: Anthropic 默认缓存 TTL 是 5 分钟,超时未命中会重新写入(写入本身还要多付一点成本,通常是基础价的 1.25 倍);如果你的请求间隔经常超过 5 分钟,缓存反而会变成”写入成本 + 未命中的原价”的叠加,得不偿失。这种场景要么改用更长 TTL 的档位(如果厂商提供,一般贵一点但换命中率),要么干脆放弃缓存这一招,改走应用层缓存(见招式七)。

详见 Prompt Caching 省钱原理与实践

招式二:用 Batch API 处理非实时任务

怎么做: 对于不需要实时响应的任务(数据标注、批量摘要、离线分类),改用 Batch API 或异步接口提交,通常可享受约 50% 的价格折扣。

适用场景: 夜间跑批、离线数据处理、定时报告生成。

实操细节: Batch API 不是同步返回,你提交一批任务后拿到一个 batch id,要靠轮询(或 webhook,如果厂商支持)去查状态,通常几分钟到 24 小时内完成,具体时长厂商不承诺精确 SLA,只保证在窗口内完成。结果返回时顺序和提交顺序不一定一致,必须靠你自己传入的 custom_id 去匹配每条结果对应哪条输入,我见过团队直接假设”第几条返回就是第几条输入”,上线后偶发对错行,排查了好几天才发现是这个假设错了。另外批处理里单条任务失败不会拖垮整批,失败的那几条会单独标记,你需要写一段兜底逻辑把失败的挑出来走一次同步重试,不要整批重跑——重跑等于把已经成功的部分也重新付费。

什么时候别用 Batch: 如果你的”批量任务”里其实混了少量需要马上看到结果的请求(比如运营临时要一条数据),别为了省这一点钱把它塞进 Batch 队列里等半天,这时候直接同步调用更划算,时间成本比 50% 的折扣更贵。

招式三:按任务复杂度路由到对应模型

怎么做: 用一个轻量模型先做意图分类(“这个问题是简单问答还是复杂推理?”),简单任务直接用轻量模型回答,只有复杂任务才转发给旗舰模型。

效果: 如果 70% 的请求属于简单任务,整体成本可降低 50–80%。路由模型本身的调用成本极低,通常是值得的开销。

路由分类器怎么写: 不需要单独训练模型,用便宜的轻量模型(如某个厂商的最小规格模型)做一次分类调用就够,输出限定成一个词,比如:

system: 你是一个任务分类器,只输出 SIMPLE 或 COMPLEX 两个词之一,不要输出其他内容。
SIMPLE:事实性问答、简单改写、格式转换。
COMPLEX:多步推理、代码生成、需要长上下文理解的任务。

拿到 SIMPLE/COMPLEX 之后再决定转发给哪个模型。这一步的关键不是分类准确率要多高,而是误判的代价要算清楚:把复杂任务误判成简单任务,省下来的钱远不够弥补用户拿到烂答案后的重试成本和投诉成本;反过来把简单任务误判成复杂任务,无非是多花了点钱,代价小得多。所以路由阈值应该往”宁可多送一点去旗舰模型”的方向偏,而不是死磕分类器的绝对准确率。

验证方法: 上线前先跑一周”影子模式”——路由分类器照常判断,但两边模型都真实调用,你只对比结果不对外返回,统计一下如果真的按分类结果路由,质量下降的比例有多少,能接受再切正式流量。

招式四:压缩上下文历史

怎么做: 不要无限累积对话历史。设定最大历史轮数(如保留最近 5 轮),超出后用摘要代替全文。摘要本身也可以用便宜的轻量模型生成。

为什么重要: 历史对话是输入 token 的最大隐形来源,每多一轮就多带入一轮内容,而且是指数级摊销——第 20 轮对话要把前面 19 轮全部原样带上,输入 token 早就比第 1 轮膨胀了几十倍,但很多团队只盯着单次调用的价格表,没意识到这笔账是在对话轮数上累加的。

具体做法(滑动窗口 + 摘要混合): 保留最近 5 轮原文,第 6 轮开始,把更早的历史压缩成一段摘要,摘要和最近 5 轮拼在一起作为上下文。摘要生成本身用便宜模型跑,prompt 大致是”用不超过 200 字总结以下对话的关键信息和用户已确认的事实,忽略寒暄”。每新增 5 轮就重新生成一次摘要(把旧摘要也当作输入的一部分参与压缩),避免摘要本身无限增长。

一个真实的反面案例: 我见过一个客服机器人上线三个月后账单涨了 4 倍,排查发现是产品经理要求”记住用户这次会话里说过的所有话,方便后续引用”,于是历史对话被完整保留,平均对话轮数从 3 轮涨到了 15 轮,输入 token 单次调用从两千多涨到接近两万。换成滑动窗口 + 摘要之后,账单直接砍掉了 60% 以上,而且用户完全感觉不到差异,因为摘要保留了关键事实(订单号、诉求类型),寒暄和重复确认那部分本来就是无效 token。

招式五:精简 System Prompt

怎么做: 定期审查 system prompt,删除重复的、自相矛盾的、实际没有作用的指令。把”角色扮演式”的长篇背景故事换成简洁的行为规则。

测试方法: 逐段注释掉 system prompt 的不同部分,看输出质量是否有可感知的下降,没有下降的部分可以删除。

具体怎么落地这个测试: 准备一份你实际业务里有代表性的测试用例集(20–50 条足够,太少容易漏掉边界情况),对每一段 system prompt 内容分别做”保留版”和”删除版”两次批量跑,人工或用另一个模型打分对比两组输出。我一般是按段落编号做二分:先删掉后一半,如果质量没掉就继续删,掉了就恢复这一半再去试前一半,比一段段试快得多。常见能删掉却没人删的内容:反复强调”请认真思考""请仔细回答”这类没有实际约束力的鼓励式话术(模型不会因为你说了”认真”就真的更认真,这类话纯粹是浪费 token)、以及针对边缘 case 写的大段免责声明(如果业务上这个 case 一年遇不到几次,完全可以放到代码兜底逻辑里处理,不用让每一次调用都背着它)。

招式六:控制输出长度

怎么做: 在 prompt 中明确指定输出格式和长度(“用不超过 3 句话回答”、“输出 JSON,只包含以下字段”),并在 API 参数中设置 max_tokens 上限。

原理: 输出 token 单价通常是输入的 3–5 倍,减少不必要的输出直接降低成本。

一个反直觉的坑: max_tokens 不是只用来省钱的开关,设得太小会直接把回答从中间截断,响应里的 finish_reason 会是 "length" 而不是 "stop",这时候你拿到的其实是一个不完整的答案——如果是 JSON 输出,大概率因为少了收尾的括号而解析报错(json.decoder.JSONDecodeError: Expecting ',' delimiter),如果是自然语言,读者会看到一句话说到一半戛然而止。我建议的做法是:先估算你这个任务正常输出需要多少 token(可以用 token 计算器 对着历史样本测一下分布),把 max_tokens 设成比 P95 略高一点的值,而不是拍脑袋给一个”看起来够用”的数字;同时代码里一定要检查 finish_reason,一旦是 length 就要有降级策略(提示用户”内容较长已截断”或自动发起续写请求),不能默认它一定跑完了。

招式七:缓存应用层结果

怎么做: 对于相同输入的调用,在应用层(Redis、内存缓存等)缓存 API 的输出结果,完全跳过 API 调用。

适用场景: FAQ 问答、固定模板填充、用户频繁问同类问题的场景。这一招能把成本从”按调用计费”变成”首次调用后免费”。

缓存 key 别踩这个坑: 如果直接把用户的原始输入字符串当作缓存 key,命中率会低得离谱——“帮我写一份周报”和”帮我写份周报”在字符串层面是两个不同的 key,但语义上是同一个请求,这种情况下缓存基本形同虚设。至少要做一层归一化:去除首尾空格、统一大小写、把多个空格压成一个,能再进一步的话对输入做分词后排序或者简单的模板抽取(把可变的具体值抽出来,剩下的模板部分才作为 key)。如果你的场景里语义相近但字面不同的请求很多(比如客服问答),可以考虑上 embedding 相似度缓存(GPTCache 这类工具的思路),对新请求算一次向量,和缓存里已有的向量做相似度比对,超过阈值就直接复用缓存结果——注意这一步本身也要花一次 embedding 调用的成本,只有当命中率提升带来的节省明显大于这个开销时才划算,量小的场景没必要上这么重的方案。

招式八:用结构化输出减少解析重试

怎么做: 使用 response_format: json_object 或 JSON Schema 约束输出格式,避免因格式不对而需要重试调用。

为什么重要: 每次 retry 都是额外成本。格式约束让一次调用成功的概率大幅提升。

真实报错案例: 不加约束的情况下,模型经常会在纯 JSON 前面加一句”好的,这是您要的结果:“,或者在结尾补一句解释,直接 json.loads(response) 会报 json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)。很多团队的第一反应是写正则去剥离前后缀,这种做法能顶一阵子,但模型换个说法(比如中英文混杂、加了 markdown 代码块包裹)正则就失效了,本质上是在跟模型的输出风格打地鼠。更稳的做法是直接用厂商提供的结构化输出能力(OpenAI 的 response_format: {"type": "json_object"} 或更强的 JSON Schema 约束、Anthropic 的 tool use 强制走工具调用格式),这些方式是在模型解码层面做的约束,不是靠”提示词里说清楚”去碰运气,稳定性完全不是一个量级。上了结构化约束之后,我们的一个批量抽取任务重试率从大约 8% 降到不到 0.5%,这部分省下来的重试调用本身也是纯利润。

招式九:设置用量预算与告警

怎么做: 在各厂商的控制台设置每日/每月用量上限和告警阈值(通常到 80% 触发告警);在代码层面对异常高频调用做限流(如每用户每分钟最多 N 次)。

重要性: 没有告警的系统一旦出现 Bug(如无限循环调用、prompt injection 触发异常行为),账单可能在几小时内爆炸。

限流怎么写: 最简单的做法是在应用层用滑动窗口计数器,比如用 Redis 的 INCR + EXPIRE 组合,对每个用户 ID 维护一个 60 秒的调用计数,超过阈值直接拒绝并返回明确的限流提示,不要静默丢弃请求(用户会以为系统卡住了反复重试,反而放大压力)。厂商侧也会有自己的限流,超限时你会收到 HTTP 429,响应头里通常带 retry-after 字段告诉你该等多久,代码里一定要读这个字段做退避重试,而不是收到 429 就立刻原样重发——立刻重发只会让 429 更密集,形成恶性循环。退避策略建议用指数退避加随机抖动(比如第一次等 1 秒,第二次 2 秒,第三次 4 秒,每次再加一个 0–1 秒的随机量避免多个请求同时重试撞在一起),大部分厂商的 SDK 已经内置了这套逻辑,先看看你用的 SDK 有没有自带,别自己重复造轮子。

告警不能只看总账单: 只监控月度总花费的话,等你收到告警的时候可能已经烧了大半个月的预算。更有效的是监控单位时间的消耗速率(比如”过去一小时花费是否超过日均的 3 倍”)和单用户异常调用频次,这两个指标能在异常刚冒头的时候就报警,而不是等到月末对账才发现。

招式十:定期用真实数据重新评估模型选型

怎么做: 每季度用生产数据的样本重跑一次主要模型的对比评测,因为模型在持续更新,价格在持续变化,上季度的最优选择可能已不是本季度的最优。

工具:价格对比表 跟踪最新定价,用 token 计算器 估算不同模型在你的典型 prompt 上的消耗差异。

一个简单的成本估算公式: 单次调用成本 ≈ 输入 token 数 × 输入单价 + 输出 token 数 × 输出单价,如果开了缓存,命中的那部分输入按缓存价重新算。把这个公式套到你日均调用量上,就能算出换模型或者换招式之后大致能省多少,不用等账单出来才知道。评估的时候别只看”这个模型便宜”就换,还要看质量是否达标——便宜但答案质量掉一个档次,导致人工复核或客诉增加,这部分隐性成本往往比 API 账单本身还高,评估表里最好把质量分和价格放在同一张表里对比着看,具体定价请始终以官方页面为准(截至 2026-06 各家仍在密集调价)。

优化优先级建议

优先级招式适用前提
最优先招式一(Prompt Caching)有固定且较长的系统提示
招式三(模型路由)任务类型多样,有明显简单/复杂分布
招式四(压缩历史)有多轮对话场景
招式二(Batch API)有批量离线任务
招式七(应用层缓存)有重复问题场景
保底招式九(告警预算)所有生产环境必须配置

常见问题

优化之后质量会下降吗?
大多数优化(缓存、批量、告警)不影响输出质量。模型路由和上下文压缩可能有轻微质量影响,需要在内部评测中验证可接受性后再上线。

从哪里开始最划算?
先查你的账单,找到消耗最多的调用类型,针对它选对应的优化招式。80% 的成本通常来自 20% 的调用场景。

有没有成本优化的自动化工具?
部分 LLM 可观测性平台(如 Langfuse、LangSmith)可以自动追踪每次调用的 token 消耗和成本,是建立成本意识的好起点。


延伸阅读: