大模型推理成本优化:从提示缓存到模型路由
当你把大模型接入生产系统,第一道拦路虎往往不是效果,而是账单。一个每天处理数十万次请求的应用,若按官方标价全价调用旗舰模型,月度开销可能轻松突破六位数人民币。好消息是,推理成本并非铁板一块:缓存、路由、批量、量化等手段叠加使用,通常能把单位成本压低一半以上,而服务质量几乎不受影响。本文系统梳理这些方法的原理、命中条件与落地要点,并给出一段可直接复用的成本测算代码。
先看清成本构成
要优化成本,先得知道钱花在哪。一次典型的 LLM 调用,账单由三部分组成:
- 输入 token(prompt tokens):你发送给模型的全部内容,包含系统提示、对话历史、检索到的上下文。
- 输出 token(completion tokens):模型生成的内容,单价通常是输入 token 的 2 到 5 倍。
- 缓存相关计费:部分厂商对命中缓存的前缀额外按缓存读取价计费,写入缓存还可能收取写入费。
以「每百万 token」为单位的公开标价为例(具体数字随厂商调整,请以其官网定价页为准):
模型档位示意(每百万 token,美元计):
旗舰大模型 输入 ~5 输出 ~25
中端模型 输入 ~2 输出 ~10
轻量小模型 输入 ~0.25 输出 ~1.25
缓存读取价 约为输入价的 0.1 倍
关键认知有三点。第一,输出远比输入贵,所以「让模型少说废话」同等重要。第二,输入里往往有大量可复用内容(系统提示、知识库片段、工具定义),这些正是缓存的用武之地。第三,并非所有请求都需要旗舰模型,把简单任务分流给小模型,是性价比最高的杠杆之一。
提示缓存:复用前缀,省下输入钱
提示缓存(prompt caching)的核心思想是:如果多次请求的前缀内容相同,厂商会把这段前缀的「键值缓存(KV cache)」保留在显存中,后续请求只需为「前缀命中缓存」支付远低于原价的缓存读取费,而不必重新计算整段前缀。
命中条件
不同厂商的阈值不同,但原则一致:
- 前缀必须稳定且足够长。OpenAI 对近期模型默认在提示达到 1,024 tokens 时启用自动缓存;更早模型阈值在 1,024 到 2,048 tokens 之间浮动。Anthropic 的最小缓存长度因模型而异,常见为 1,024 tokens,部分模型为 2,048 或 4,096,少量模型低至 512。
- 前缀字节级一致。系统提示、工具定义、少量示例(few-shot)必须跨请求完全相同;任何改动(包括顺序、空格、换行)都会让缓存失效。
- 缓存有存活时间(TTL)。OpenAI 近期模型默认约 30 分钟;Anthropic 可选 5 分钟或 1 小时。请求间隔超过 TTL,缓存自动失效。
计费与折扣
两家厂商对缓存读取的折扣高度一致:
- OpenAI:缓存读取按未缓存输入价的 0.1 倍计费,即相当于 9 折优惠(90% off)。早期模型写入免费,近期部分模型写入按 1.25 倍计费。
- Anthropic:缓存读取同样是基础输入价的 0.1 倍;写入费为 5 分钟档 1.25 倍、1 小时档 2 倍(倍数叠加在其他折扣之上)。
这意味着:只要你的前缀稳定且被高频复用,输入成本可以降到原先的一成。对「固定系统提示加长上下文」类的应用(如客服、文档问答),这一项往往贡献最大的节省。
实操要点
把不变的内容放到提示最前面,把易变的部分(用户问题)放在末尾。需要精细控制时,可在内容块上显式设置缓存断点。例如在 Anthropic 的请求中:
{
"model": "claude-sonnet-4-5",
"system": [
{
"type": "text",
"text": "你是企业知识库助手,以下是固定规范与术语表……",
"cache_control": { "type": "ephemeral" }
}
],
"messages": [
{ "role": "user", "content": "请解释退货流程。" }
]
}
验证是否命中,请读取响应里的用量字段:OpenAI 关注 prompt_tokens_details.cached_tokens,Anthropic 关注 usage.cache_read_input_tokens 与 usage.cache_creation_input_tokens。两者大于 0 即代表缓存生效或已写入。
模型路由:让小模型干大部分活
模型路由(model routing)指根据任务难度动态选择模型:简单、高频、容错性高的请求交给轻量小模型,只有真正复杂或高风险的请求才升级到旗舰模型。
常见的分级策略有三层:
- 轻量层:分类、抽取、改写、短摘要等结构化任务,使用小模型,成本可降至旗舰模型的一成到两成。
- 中端层:多轮对话、常规问答,使用性价比均衡的中端模型。
- 旗舰层:复杂推理、代码生成、需要高准确率的场景,使用旗舰模型。
路由的判定可以由规则驱动(如按输入长度、是否含代码块、是否命中关键词),也可以由一个小模型做「难度分类器」自动分流。下面是一个基于规则的最小实现:
def route_model(prompt: str, has_code: bool) -> str:
length = len(prompt)
if has_code or length > 1500:
return "flagship-model"
if length > 400:
return "mid-model"
return "mini-model"
路由要避免过度升级。经验法则是:先默认小模型,仅在评测显示质量不达标时再升级。多数业务流量中,七成以上请求其实可以由小模型稳妥处理。
批量接口:异步任务直接打五折
对于不需要即时返回结果的任务(离线评估、大规模摘要、数据标注、嵌入生成),批量接口(batch API)是最省心的折扣来源。
- OpenAI Batch API:相较同步接口享 50% 成本折扣,单个批次在 24 小时内完成,每批最多 5 万条请求。
- Anthropic Message Batches:同样按标准价 50% 计费,多数批次 1 小时内完成、上限 24 小时,单批最多 10 万条请求,且可与提示缓存折扣叠加。
批量接口适合「攒一波再发」的模式。把白天产生的离线任务收集起来,定时提交一个批次,单位成本立刻减半。需要注意:批量接口不占用同步请求的速率配额,因此也是提升整体吞吐的利器。
上下文裁剪与历史压缩
输入 token 里很大一部分是对话历史与检索上下文,但并非每一句都必要。裁剪可以从三个方向入手:
- 对话历史截断:只保留最近 N 轮,更早的内容做摘要后压缩为一条。
- 检索裁剪:对召回的文档片段做重排序,只把最相关的 Top-K 送入提示,而非全量上下文。
- 冗余去除:合并重复信息,剔除与当前问题无关的系统提示段落。
一个常见的做法是「滑动窗口加摘要」:保留最近若干轮原文,把窗口外的内容定期压缩成摘要回写。这样既控制长度,又不丢失长期信息。注意裁剪要配合评测,避免误删关键约束导致质量下降。
量化与本地小模型替代
当数据敏感或调用规模极大时,本地部署小模型是另一条降本路径:
- 量化(quantization):把模型权重从 16 位浮点压缩到 8 位甚至 4 位,显存占用与推理成本显著下降,质量损失通常在可控范围。常见方案有 GPTQ、AWQ、GGUF 等。
- 本地小模型:对分类、抽取、改写等任务,使用 1B 到 14B 级别的本地模型(如各类指令微调小模型),单卡即可承载高并发,边际成本趋近于零。
- 推理引擎优化:vLLM、TensorRT-LLM 等通过 PagedAttention、连续批处理(continuous batching)提升吞吐,等效降低每 token 成本;其底层的 KV cache 管理思想,与上文的提示缓存一脉相承。
本地方案的取舍在于运维成本与峰值质量。建议把「高频、低难度、可离线」的请求尽量本地化,把「低频、高难度、需联网知识」的请求保留给云端旗舰模型。
成本测算示例
下面这段代码把上述手段组合起来,估算一个混合策略下的月度成本,并对比「全量旗舰模型」的基线。参数单位统一为美元每百万 token,你可以按自己的真实单价与流量填入。
PRICE = {
"flagship_in": 5.0, "flagship_out": 25.0,
"mid_in": 2.0, "mid_out": 10.0,
"mini_in": 0.25, "mini_out": 1.25,
"cache_read": 0.5, # 约为旗舰输入价的 0.1 倍
}
def baseline_cost(reqs, avg_in, avg_out):
# 全部走旗舰模型
in_cost = reqs * avg_in / 1_000_000 * PRICE["flagship_in"]
out_cost = reqs * avg_out / 1_000_000 * PRICE["flagship_out"]
return in_cost + out_cost
def optimized_cost(reqs, avg_in, avg_out):
# 路由分布:70% 小模型,20% 中端,10% 旗舰
mini = reqs * 0.70
mid = reqs * 0.20
flag = reqs * 0.10
# 旗舰部分 60% 输入命中缓存
flag_in = flag * avg_in / 1_000_000
flag_in_cached = flag_in * 0.60 * PRICE["cache_read"]
flag_in_uncached = flag_in * 0.40 * PRICE["flagship_in"]
flag_out = flag * avg_out / 1_000_000 * PRICE["flagship_out"]
mid_cost = mid * avg_in / 1_000_000 * PRICE["mid_in"] + mid * avg_out / 1_000_000 * PRICE["mid_out"]
mini_cost = mini * avg_in / 1_000_000 * PRICE["mini_in"] + mini * avg_out / 1_000_000 * PRICE["mini_out"]
return flag_in_cached + flag_in_uncached + flag_out + mid_cost + mini_cost
reqs = 1_000_000 # 月度请求数
avg_in = 2000 # 平均输入 token
avg_out = 500 # 平均输出 token
base = baseline_cost(reqs, avg_in, avg_out)
opt = optimized_cost(reqs, avg_in, avg_out)
print("基线月度成本:", round(base, 2))
print("优化月度成本:", round(opt, 2))
print("节省比例:", str(round((base - opt) / base * 100, 1)) + "%")
运行后你会看到,仅靠「路由分流加缓存命中」,月度成本通常就能下降六成以上;再叠加批量接口的 50% 折扣处理离线流量,进一步压缩空间可观。需要强调的是,示例中的单价与分布均为示意,落地时请替换为厂商官网的实时标价与你的真实流量结构。
小结
降低大模型推理成本不是单点技巧,而是一套组合拳:用提示缓存吃掉稳定的长前缀,用模型路由把简单请求分流给小模型,用批量接口为离线任务直接打五折,用上下文裁剪和量化压缩每一分冗余。实践顺序建议为:先接缓存与路由(见效快、改动小),再引入批量处理离线流量,最后对高频低难度场景评估本地小模型。任何优化都应配合离线评测,确保成本下降不以质量显著退化为代价。
参考与延伸阅读
- OpenAI 官方文档「Prompt caching」:说明缓存自动启用、缓存读取按未缓存输入价 0.1 倍计费、最小前缀约 1,024 tokens。核验于 2026-08-18。链接 https://platform.openai.com/docs/guides/prompt-caching
- Anthropic 官方文档「Prompt caching」:说明缓存读取为基础输入价 0.1 倍,5 分钟写入 1.25 倍、1 小时写入 2 倍,最小缓存长度因模型而异(512 到 4,096 tokens)。核验于 2026-08-18。链接 https://docs.anthropic.com/en/docs/build-with-claude/prompt-caching
- OpenAI 官方文档「Batch API」:说明相较同步接口 50% 成本折扣,单批 24 小时内完成。核验于 2026-08-18。链接 https://platform.openai.com/docs/guides/batch
- Anthropic 官方文档「Message Batches」:说明按标准价 50% 计费,多数批次 1 小时内完成、上限 24 小时,可与提示缓存叠加。核验于 2026-08-18。链接 https://docs.anthropic.com/en/docs/build-with-claude/batch-processing
- vLLM 官方文档:介绍 PagedAttention 与连续批处理对 KV cache 与吞吐的优化,是本地推理降本的重要参考。链接 https://docs.vllm.ai
- Google Cloud 文档「Vertex AI batch prediction」:提供云端批量推理与折扣说明,可作为多云批量策略的对照。链接 https://cloud.google.com/vertex-ai/docs/predictions/batch-predictions