提示词压缩与缓存:用 Prompt Caching 把长上下文成本打下来
长上下文模型让我们可以把一整本手册、一份合同、一个代码仓库一次性塞进提示词。但「塞得进」不等于「用得起」:每次调用都按 token 计费,而很多业务里,同一段系统提示词和大段参考资料在成千上万次请求中被原样重发。Prompt Caching(提示词缓存,也常叫前缀缓存)正是为这个问题而生——它让模型服务端把「前缀」算过一遍后缓存起来,后续请求只要前缀一致,就直接复用,既省成本又降延迟。本文先讲清长上下文为何贵,再拆解缓存原理,对比三大厂商实现,最后给出可落地的实践要点与一段调用示例。
长上下文为何贵
要理解缓存的价值,先看清账单是怎么来的。主流大模型 API 普遍按 token 计费,且把一个请求拆成「输入 token」与「输出 token」分别计价,其中输入价格往往不低,长上下文场景下输入更是成本大头。贵在三个地方:
第一,系统提示词被反复发送。一个客服助手、一个 SQL 生成器,往往带着几百到几千 token 的固定指令。假设系统提示词 2000 token,每次用户问一句话都要把这 2000 token 重发一遍,一天十万次调用就是两千万 token 的重复输入。
第二,参考资料被反复发送。做检索增强生成(RAG)时,检索到的文档片段每次都要拼进提示词;做代码问答时,整个仓库的上下文每次都要带上。这些内容对同一次会话或同一批任务高度稳定,却被一次次重新计费、重新计算。
第三,注意力计算是「从头再来」。即使服务端不收你缓存的钱,没有缓存时模型仍要对前缀做一次完整的 prefill(预填充)计算,token 越多,首字延迟(TTFT)越高。缓存命中后,这段计算可以跳过,延迟随之下降。
一句话:长上下文的成本,主要来自「稳定不变的内容被反复传输、反复计算」。Prompt Caching 的本质,就是把这些稳定内容识别出来、算一次、然后复用。
Prompt Caching 原理
不同厂商的接口细节不同,但内核是同一套思路:前缀缓存(prefix caching)。
前缀缓存与缓存键
模型处理提示词时,是从前往后逐 token 计算注意力状态的。如果两次请求的开头完全一致,那么「开头这段」的计算结果也可以完全一致。服务端把这段一致前缀对应的内部状态(KV cache 等)按一个缓存键存起来,下次请求来时先比对前缀:前缀一致就直接取出缓存状态接着算,不必从零开始。
缓存键通常是「前缀内容的哈希」。关键点在于:它要求完全匹配。只要前缀里任意一处文本(甚至一个空格、一个图片块)发生变化,哈希就不同,缓存便无法命中。所以缓存对「前缀的稳定性」极其敏感——这也决定了后面实践里的摆放顺序。
最小缓存块
不是任意长度的前缀都能缓存。厂商通常设一个最小可缓存长度阈值,太短的前缀即使标记了缓存也会被静默忽略(不报错,只是不缓存)。这个阈值因模型和厂商而异,常见量级在 1024 token 到几千 token 之间。换言之,只有「足够长且稳定」的前缀才值得缓存,零碎小段收益有限。
TTL 与失效
缓存不是永久的。每条缓存条目有一个生存时间(TTL,Time To Live)。超过 TTL 没有被复用,条目就会被淘汰,下次命中需重新写入。TTL 一般从「写入或最后一次读取该条目的请求开始」计时,期间每次命中会刷新计时。不同的 TTL 档位往往对应不同的写入价格:时间越长,写入越贵。除此之外,前缀内容一旦变化、或请求里影响前缀的字段(如工具定义、部分采样参数)改变,也会让对应缓存整体失效。
不同厂商实现要点
下面三家的实现以官方文档为准。需要提醒:官方文档会随模型迭代更新,具体模型名、阈值与单价请以下方参考链接中的最新页面为准;本文对版本敏感的数字统一标注「待核实」。
Anthropic(Claude)Prompt Caching
机制上用 cache_control 在提示词里标记「缓存断点」(breakpoint)。你可以:
- 在请求顶层放一个
cache_control,系统自动把断点放在最后一个可缓存块; - 或在单个内容块上显式放
cache_control,最多支持 4 个断点。
缓存前缀的构建顺序是 tools 到 system 到 messages:也就是说工具定义、系统提示词优先进入前缀,最适合放稳定内容。缓存命中的要求是前缀 100% 一致,包括断点之前的所有文本与图片。
TTL 方面,默认 5 分钟,且每次命中免费刷新;也可付费延长到 1 小时,写法是 "cache_control": {"type": "ephemeral", "ttl": "1h"}(具体字段名与是否仅支持 ephemeral 类型,待核实)。
定价倍数(基于基础输入价,待核实):5 分钟写入约 1.25 倍,1 小时写入约 2 倍,缓存读取约 0.1 倍(即一折,省九成)。最小可缓存长度按模型不同,常见为 1024 到 4096 token 不等(具体数值待核实)。是否命中可通过响应里的缓存创建与读取用量字段判断。
OpenAI Prompt Caching
OpenAI 的提示词缓存以自动前缀缓存为主:对满足条件的请求默认开启,无需改代码。文档称默认对 1024 token 及以上的提示启用自动缓存(早期模型最小阈值在 1024 到 2048 token 之间浮动,刚过线的短前缀可能命中不稳定)。命中条件是提示词存在精确前缀匹配,因此官方建议把静态内容(指令、示例)放开头,把变量内容(用户数据)放末尾。
检查命中情况看 API 响应用量:usage.prompt_tokens_details.cached_tokens(Chat Completions)或 usage.input_tokens_details.cached_tokens(Responses API)表示命中缓存的 token 数;较新模型家族还会报告 cache_write_tokens(写入数)。
关于价格:官方文档的通用规则是「缓存输入 token 按未缓存输入价格的折扣计费」。需要特别标注——不同来源对折扣比例说法不一(既有「五折」的通用描述,也有实时文档返回「0.1 倍」的表述),且实时文档中出现了尚不存在的模型版本号,存在数字被污染的可能,因此 OpenAI 的精确折扣比例与写入是否收费,本文统一标注「待核实」,请以官方定价页为准。
Google Gemini Context Caching
Gemini 提供隐式缓存与显式缓存两种。隐式缓存对 Gemini 2.5 及更新模型默认开启,无需改代码;想提高命中率,建议把大而公共的内容放提示词开头,并尽量在短时间内发送前缀相近的请求。命中 token 数可在响应的 usage.total_cached_tokens 字段查看。各模型最小缓存 token 数不同,例如 Gemini 2.5 Flash / Pro 约 2048,更新的部分模型约 4096(具体数值待核实)。
显式缓存(手动创建并管理缓存对象)走 cachedContent 接口,常见于 Gemini 1.5 时代,当时最小 token 门槛约 32768,TTL 可配置(默认与上限以官方文档为准,待核实),计价包含「按 token 小时计的存储费」加上「更低的缓存输入 token 单价」(具体存储与读取价格待核实)。若使用 Interactions API,则只支持隐式缓存,显式缓存需切换到 generateContent API。
适用场景
Prompt Caching 在「前缀稳定、请求量大」的场景收益最大:
- 固定系统提示词:客服、助理、分类器等,系统指令长期不变,是缓存的最佳落点。
- 长文档 RAG:同一份手册、合同、论文被多轮或多用户反复询问,把文档放前缀缓存,只换问题。
- 多轮对话:把会话历史作为稳定前缀,新消息只追加在末尾,历史部分可复用。
- Few-shot 示例:固定的一批示例放在提示词开头,后续请求只换输入样本。
- 工具定义:把一组 function/tool 定义作为前缀,调用同套工具时不必反复计费。
反过来说,如果每次请求前缀都完全不同(例如把用户实时输入放最前面),缓存几乎无法命中,这时缓存帮助有限。
实践要点
把稳定内容放前缀
这是最重要的一条。缓存按前缀匹配,因此「越稳定、越长、越贵」的内容越要靠前:顺序建议为工具定义、系统提示词、参考资料、few-shot 示例,最后才是每轮变化的用户输入。不要在前缀里掺入时间戳、随机 ID、每次不同的会话变量,否则哈希一变,整段缓存失效。
控制缓存失效
- 避免在前缀中放易变字段:日期、随机数、用户专属 token、请求级 debug 信息都应后置或移到前缀之外。
- 谨慎调整系统提示词:改一个字就会让该前缀的缓存全部失效,需要重新写入。大版本更新提示词时,预期会有一次写入成本尖峰。
- 注意会影响前缀的接口字段:例如修改工具定义、切换某些采样或思考参数,可能使
system与messages前缀整体失效(具体字段清单以厂商文档为准,待核实)。 - 并发预热:缓存条目通常在首次响应开始后才可用。若要对并行请求命中同一缓存,应先等首条响应返回,再发后续请求,否则并行请求可能都未命中。
监控命中率
把命中情况纳入可观测性。每次响应都记录缓存读取 token 数与写入 token 数,按请求量计算命中率:命中率 = 缓存读取 token 数 / (缓存读取 + 未缓存输入 token 数)。命中率低通常意味着:前缀不稳定、最小长度没达到、或请求间隔超过了 TTL。用监控数据反向优化摆放顺序与 TTL 档位,才能把成本真正打下来。
上下文压缩与摘要作为补充手段
缓存解决的是「重复计算」问题,但当前缀本身就长到离谱(比如整个仓库、整本书),即便命中缓存,每次仍要传输这些 token 并占用上下文窗口。此时应叠加「压缩」手段:
- 摘要前置:把长文档先让模型或规则压缩成要点摘要,再把摘要而非原文放进系统前缀。
- 检索裁剪:RAG 不要整库进提示词,只检索最相关的少数片段,且对片段做去重与截断。
- 分层缓存:稳定不变的「元指令」走缓存,易变的长资料走按需检索,两者解耦。
- 滚动压缩:多轮对话里,定期把早期历史压缩成一段摘要替代原文,避免历史无限增长。
缓存与压缩是互补的:压缩减小「要传什么」,缓存减小「要算几次」。二者结合,长上下文成本才能同时降下来。
Python 调用示例
下面是一段 Anthropic 风格的占位示例,演示如何把长系统提示词标记为缓存断点。API key、endpoint、模型名与返回字段均为占位,请以官方最新文档为准(标注「待核实」)。
import os
import anthropic # 占位示例,需先执行 pip install anthropic
client = anthropic.Anthropic(api_key=os.environ.get("ANTHROPIC_API_KEY", "YOUR_API_KEY")) # 占位 API key,正式环境请通过环境变量注入,不要硬编码
SYSTEM_PROMPT = (
# 一段很长的系统提示词:至少达到最小可缓存长度(常见 1024 token 起)才稳定命中缓存
"你是一个严谨的技术支持助理。"
"以下是产品知识库全文……(此处放数千 token 的稳定资料,"
"内容在批量请求间保持不变,才能被缓存复用)"
)
def ask(question: str):
# 把长系统提示词作为前缀,并用 cache_control 标记缓存断点
resp = client.messages.create(
model=os.environ.get("MODEL_NAME", "claude-sonnet-4"), # 模型名待核实
max_tokens=1024,
system=[
{
"type": "text",
"text": SYSTEM_PROMPT,
"cache_control": {"type": "ephemeral"}, # 标记缓存断点
}
],
# 每轮变化的用户问题放在 messages 里,不影响前缀缓存命中
messages=[{"role": "user", "content": question}],
)
# 通过用量字段判断缓存是否命中(字段名与结构待核实)
print("用量:", resp.usage)
return resp.content[0].text
if __name__ == "__main__":
print(ask("这份合同里的违约责任条款对我方是否有利?"))
要点回顾:稳定内容(系统提示词)放在 system 前缀并用 cache_control 标记;易变内容(用户问题)放在 messages;通过响应的用量字段观察 cache_creation(写入)与 cache_read(读取)来确认是否命中。换成 OpenAI 时无需显式标记,只要保证 1024 token 以上的前缀稳定、静态内容在前即可,命中情况看 usage.prompt_tokens_details.cached_tokens;换成 Gemini 时优先保证大段公共内容在提示词开头、短时间内的请求前缀相近,命中数看 usage.total_cached_tokens。
小结
长上下文的成本主要来自「稳定内容被反复传输与计算」。Prompt Caching 通过前缀缓存,把足够长且稳定的前缀算一次、缓存住、后续直接复用,从而同时降低输入成本与首字延迟。落地时有三条铁律:把工具定义、系统提示词、参考资料等稳定内容放在最前面;绝不在前缀里掺入随机或每次变化的字段;把缓存读取与写入 token 数纳入监控,用命中率反推优化。当前缀本身过长时,再叠加摘要、检索裁剪、滚动压缩等手段减小传输量。不同厂商在标记方式(显式 cache_control 还是自动)、最小长度、TTL 档位与单价上各有差异,接入时务必以官方文档的最新页面为准。
参考与延伸阅读
-
Anthropic 官方文档「Prompt caching」:讲解
cache_control断点、前缀构建顺序、TTL 与定价倍数(读取约 0.1 倍、写入约 1.25 至 2 倍)。本文核心机制已核验;具体模型名、最小可缓存长度与单价随版本变动,标注待核实。链接:https://docs.anthropic.com/en/docs/build-with-claude/prompt-caching (已核验,访问于 2026-08-18;版本相关数字待核实) -
OpenAI 官方文档「Prompt caching」:讲解自动前缀缓存、1024 token 最小阈值、通过
usage字段查看命中。机制已核验;精确折扣比例与写入是否收费存在来源冲突,标注待核实。链接:https://platform.openai.com/docs/guides/prompt-caching (已核验,访问于 2026-08-18;折扣比例待核实) -
Google Gemini 官方文档「Context caching」:讲解隐式缓存(Gemini 2.5+ 默认开启)与显式
cachedContent缓存、最小 token 数与usage.total_cached_tokens。隐式缓存机制已核验;显式缓存的 TTL 上限、存储费与读取单价待核实。链接:https://ai.google.dev/gemini-api/docs/caching (已核验,访问于 2026-08-18;显式缓存价格待核实) -
各家官方定价页(Pricing):缓存写入与读取的具体单价、折扣比例请以下列页面实时数值为准,本文所有缓存单价与折扣均标注待核实:Anthropic Pricing、OpenAI Pricing、Gemini Pricing。(待核实)