
在这篇文章里,我们会学习 Prompt Caching 是怎么工作的。我们还会看到为什么需要它、它在大语言模型内部到底怎么运作,以及它在 AI 助手和 agent 这类真实系统里会用在哪里。
我们会讲这些内容:
- 什么是 prompt
- 简单回顾一下 LLM 如何读取 prompt
- 什么是 Prompt Caching
- 为什么需要 Prompt Caching
- Prompt Caching 的核心思路
- 精确前缀规则
- cache write、cache read 和 TTL
- 应该把什么放进缓存
- Prompt Caching 的好处
- 真实世界里的 Prompt Caching
我是 Amit Shekhar,Outcome School 创始人。我教过并辅导过很多开发者,他们靠自己的努力拿到了高薪技术岗位;我也帮助过许多科技公司解决各自独特的问题,并创建过很多被顶级公司使用的开源库。我热衷于通过开源、博客和视频分享知识。
我在 Outcome School 教 AI and Machine Learning。
我们开始吧。
什么是 prompt
在讨论 Prompt Caching 之前,我们必须先理解什么是 prompt。
prompt 就是我们发送给大语言模型的文本。
大语言模型,也就是 LLM,是 ChatGPT、Claude 这类工具背后的技术。我们给它一段文本,它会返回一段文本。
简单说,prompt 就是我们输入进去的全部内容。模型读取我们的 prompt,然后写出回复。
假设我们正在构建一个客服助手。我们发送给模型的文本通常包含几个部分:
- 一组告诉模型该如何表现的指令,比如“你是一家鞋店礼貌的客服代表。”
- 也许还有一份很长的鞋类退货政策文档。
- 用户实际提出的问题,比如“买了 40 天以后还能退鞋吗?”
所有这些文本合在一起,就是 prompt。
这里有一点很重要。指令和政策文档对每个用户来说都是一样的。只有用户的问题会变化。我们很快还会回到这一点,因为它正是 Prompt Caching 的核心。
简单回顾一下 LLM 如何读取 prompt
要理解 Prompt Caching,我们必须先理解 LLM 读取 prompt 时的一件事。
当我们发送 prompt 时,模型并不是按完整单词来读取它。模型会先把文本拆成一些叫作 token 的小片段。token 是一小块文本,大致可以是一个词,也可以是词的一部分。比如 support 这样的短词通常是一个 token,而 returning 这样的长词往往会被拆成两个 token。
于是,prompt 就变成了一串 token。
我们有一篇详细介绍 Byte Pair Encoding(BPE)的文章,解释了这种 token 切分是怎么工作的。
接下来,模型会逐个处理这些 token,并为每个 token 建立内部理解。模型在写出回复的第一个词之前,需要先读取整个 prompt,并处理其中每个 token;这个第一步叫作 prefill。
简单说,prefill 就是模型读取并消化整个 prompt。
在 prefill 过程中,模型会为每个 token 计算一些内部值并把它们存起来。这些存下来的值保存在一个叫作 KV cache 的东西里。
我们用大白话理解一下 KV cache。模型读取每个 token 时,会为这个 token 创建一小份摘要,有点像是在记录这个 token 在前文上下文里意味着什么。KV cache 就是所有这些记录的集合,每个 token 对应一组记录。模型需要这些记录来写回复,并且在生成每个新词时也会反复复用它们。
这里要记住一个关键点:
为一个很长的 prompt 构建 KV cache 是实打实的工作。模型必须逐个 token 做大量计算。
所以,如果我们的 prompt 有 5,000 个 token,模型在写出任何内容之前,就必须先为这 5,000 个 token 全部做完这项工作。prompt 越长,prefill 这一步花的时间和钱就越多。
有了这层基础,我们就可以理解真正的问题了。
什么是 Prompt Caching
现在我们已经知道模型如何读取 prompt,接下来理解 Prompt Caching。
Prompt Caching 是一种技术:模型会保存它已经为 prompt 中重复部分做过的工作,这样下次就可以复用这些保存下来的工作,而不是全部重做一遍。
简单说,Prompt Caching 的意思就是:重活做一次,以后直接复用。
“cache”这个词的意思很简单:找一个地方把东西存起来,以后需要时可以快速拿到,不用从头再做。
把它和前面讲的内容连起来看。模型做的“重活”,就是在 prefill 阶段构建 KV cache。Prompt Caching 会保存 prompt 中重复部分对应的 KV cache。下一次我们发送一个以同样重复部分开头的 prompt 时,模型会加载已经保存的 KV cache,跳过所有重复计算。
所以,Prompt Caching 的核心,是复用 prompt 开头重复部分对应的内部计算结果。
接下来的问题是:我们为什么需要它?继续看。
为什么需要 Prompt Caching
回到前面的鞋店客服助手例子。
每个用户都会发送一个问题。但别忘了,每个问题都会和相同的指令、相同的长退货政策文档一起发送。用户的问题很短,但指令和文档很长。
也就是说,模型会为每个用户、每条消息,一遍又一遍地读取同样的长指令和同样的长文档。
为了方便理解,我们给它加一点数字。假设:
- 指令和政策文档一共有 5,000 个 token。
- 用户的问题有 50 个 token。
用户每问一次,模型都要对 5,050 个 token 做 prefill。其中 5,000 个 token 和上一次完全相同,只有 50 个 token 是新的。
这很浪费。模型正在对 5,000 个完全没变的 token 做重复的重活。
这会带来两个实际问题:
- 慢。 一遍又一遍处理 5,000 个 token,会增加用户看到回复之前的延迟。
- 贵。 我们付费通常取决于模型处理了多少 token。每次都重新处理同样的 5,000 个 token,就意味着我们在为同一份工作反复付钱。
在真实应用里,这个问题会变得更严重。想想那些很长的系统指令、大型文档,以及每次请求都会带上的大量示例。我们反复发送同一大块文本,模型也不断重复做同样的工作。
于是,Prompt Caching 就派上用场了。
Prompt Caching 的核心思路
我们一步一步理解它的核心思路。
前面说过,在 prefill 过程中,模型会构建 KV cache,也就是为每个 token 生成内部记录。Prompt Caching 做的是一个简单但很有用的动作。
它会保存 prompt 中固定、重复部分的 KV cache。下一次请求如果以同样的部分开头,模型就加载已经保存的 KV cache,从那里继续处理,跳过重复计算。
我们沿用前面的例子走一遍。
第 1 步: 用户发送第一个问题。prompt 是 5,000 个 token 的指令和文档,再加上 50 个 token 的问题。模型会对全部 5,050 个 token 做 prefill,并构建 KV cache。在这个过程中,它会保存前 5,000 个 token 的 KV cache,因为我们标记了这部分可以缓存。
第 2 步: 新用户发送了另一个问题。prompt 仍然是相同的 5,000 个 token 的指令和文档,只是后面接了一个新的 50 个 token 的问题。现在,模型不需要再为前 5,000 个 token 重做计算,而是直接加载它们已经保存的 KV cache。它只需要为新的 50 个 token 做新计算。
也就是说,模型直接跳到了缓存部分结束的位置,从那里继续往下处理。它不会把已经理解过的 5,000 个 token 再浪费时间处理一遍。
下面用一个简单图示说明:
WITHOUT prompt caching (every request):
[ 5,000 tokens: instructions + document ] + [ 50 tokens: question ]
process all of this again process this
(slow, costly, repeated) (new work)
WITH prompt caching (after the first request):
[ 5,000 tokens: instructions + document ] + [ 50 tokens: question ]
load from cache (fast, cheap) process this
skip the heavy work (new work)
问题解决了。模型现在只需要对重复部分做一次重活。
如果想深入理解 LLM 内部机制和 KV Cache,可以看看 Outcome School 的 AI and Machine Learning Program。
精确前缀规则
这里有一条非常重要的规则必须理解,因为大多数错误都出在这里。
Prompt Caching 基于匹配前缀工作。缓存部分必须位于 prompt 的开头,并且必须逐字符完全一致。
先理解一下 prefix 这个词。prefix 指的是某个东西的开头部分。在我们的场景里,缓存部分就是 prompt 的开头,也就是用户问题之前的那部分。
只有新的 prompt 开头和已缓存 prompt 的开头完全相同时,模型才能复用缓存。一旦文本出现不同,缓存从那个位置开始就不再有用了。
可以把它想成下面这样:
Cached prompt: You are a polite support agent. Return window is 30 days.
New prompt: You are a polite support agent. Return window is 45 days.
|--------------- matches exactly ---------------|
read from cache
^ differs from here, so this part is redone
这里可以看到,两段 prompt 在某个位置之前完全相同,所以前面匹配的部分可以从缓存中读取。从第一个不同的 token 开始,前缀就不再匹配,因此模型必须重新计算之后的所有内容。
这里一定要特别小心:
只要 prompt 前面很早的位置有一个字符变化,这个变化之后的缓存就全都失效。
举个例子。假设我们在指令最顶部加了一行“今天的日期是 2026-06-07”。这行每天都会变。因为它位于 prompt 最开头,所以每天的前缀都不一样。昨天构建的缓存,今天就复用不了了。模型必须重新做所有工作。
这是一个非常常见的错误。我们无意中把会变化的东西放在 prompt 顶部,比如当前日期、随机 ID 或用户名。这个很小的变化会悄悄破坏整个缓存。
所以要记住的规则很简单:
把稳定部分放在前面,把变化部分放在最后。
如果 prompt 的开头保持不变,缓存就能继续工作。如果开头一直变化,缓存就毫无用处。别急,我们马上会看到哪些部分应该保持稳定,以及应该把它们放在哪里。
给你一个小提示
无论你在哪个技术领域工作,都应该熟悉这些主题:
- LLM
- RAG
- MCP
- Agent
- Fine-tuning
- Quantization
我们把它们整理进了一个视频:
AI Engineering Explained: LLM, RAG, MCP, Agent, Fine-Tuning, and Quantization
不用现在停下来去看——先收藏,等有时间再看。未来的你会感谢现在的你。
现在,我们回到主题。
cache write、cache read 和 TTL
接下来理解两个简单术语:cache write 和 cache read。
cache write 发生在第一次。 也就是模型处理重复部分,并把它的 KV cache 保存下来。我们是在第一次把结果写入缓存。
cache read 发生在之后。 也就是后续请求复用已经保存的 KV cache,而不是重新计算。我们是在从缓存里读取。
把它和成本联系起来看,这里就很有意思了。
cache write 的成本会比普通处理稍高一点,因为模型不仅要完成计算,还要把结果存起来。粗略理解,cache write 的成本大约是这部分普通价格的 1.25 倍。
但 cache read 非常便宜。从缓存读取的成本大约只有普通价格的十分之一。也就是对重复部分来说,大约能省下 90%。
所以,第一次请求会多付一点成本来写入缓存。之后每个请求都会便宜很多,因为它们是从缓存读取。缓存复用次数越多,省得越多。
流程大概如下:
Request 1 --> process the stable part --> save it (cache WRITE, ~1.25x cost)
|
v
+-------------+
| cache |
+-------------+
^ ^ ^
Request 2 ----------------------------------+ | | (cache READ, ~0.1x cost)
Request 3 -------------------------------------+ | (cache READ, ~0.1x cost)
Request 4 ----------------------------------------+ (cache READ, ~0.1x cost)
这里可以看到,只有第一个请求会做重活并把结果写入缓存。之后每个以相同稳定部分开头的请求,都只是从缓存读取,所以每次成本都会远低于从头重做。
下一个问题是:缓存会永远保留吗?答案是否定的。
缓存有一个 TTL,全称是 存活时间(time to live)。简单说,TTL 就是缓存过期并被移除之前能存活多久。
常见的默认 TTL 是 5 分钟。也可以选择更长的 TTL,比如 1 小时。实际含义如下:
- 如果一个带有相同前缀的新请求在 TTL 窗口内到达,它就可以从缓存读取。
- 如果 TTL 窗口内没有任何请求到达,缓存就会过期。下一次请求就必须重新做一次 cache write。
所以,当很多请求共享同一个开头,并且在时间上比较接近地到达时,Prompt Caching 的效果最好。
注意: 更长的 TTL 可以让缓存保留更久,当请求分布比较分散时会有帮助;但更长 TTL 的 cache write 成本也会稍高一些。因此,我们要根据具体用例选择 TTL。
应该把什么放进缓存
现在我们知道,缓存作用在 prompt 开头的稳定部分。自然的问题就是:到底应该把什么放在那里?
答案很简单。把会在很多请求之间保持不变的部分放在前面,把会变化的部分放在最后。
下面这些部分很适合缓存,因为它们通常不会变化:
- 系统指令。 这些指令描述模型应该如何表现,比如“你是一名礼貌的客服代表。”它们对每个用户都一样。
- 大型文档。 例如完整的退货政策、产品手册或知识库文章。它们很长,而且会重复出现,所以缓存它们能省很多。
- 工具定义。 当我们允许模型使用工具时,需要向模型描述每个工具。这些描述通常是固定的。
- few-shot 示例。 这些是我们提供给模型的示例问题和答案,用来让模型学会我们想要的风格。“few-shot”的意思很简单,就是给模型几个示例来引导它。这些示例每次都一样。
下面这部分会变化,必须放在最后:
- 用户实际提出的问题或消息。 每次请求都不同,所以它要放在最末尾,也就是所有可缓存部分之后。
用一个简单图示来看这个顺序:
ORDER OF A WELL-DESIGNED PROMPT
FIRST -> Tool definitions |
System instructions | stable part: cache this
Large documents |
Few-shot examples |
LAST -> User's question changing part: do not cache
这个顺序就是关键。稳定块位于前面,可以被缓存。变化的问题位于后面,不会破坏缓存。
到这里,我们就知道到底应该缓存什么,以及应该把它们放在哪里了。
决定 prompt 里放什么、按什么顺序放,本身就是一门学问。我们有一篇详细介绍 Context Engineering 的文章,专门深入讲这个话题。
Prompt Caching 的好处
我们快速把好处汇总一下,因为这些正是我们使用这项技术的原因。
- 更低延迟。 延迟指的是用户拿到回复之前的等待时间。因为模型跳过了重复部分的重新处理,所以可以更快开始回复。
- 更低成本。 缓存 token 的读取价格要便宜得多,大约只有普通价格的十分之一。当我们一遍又一遍发送同一大块文本时,这种节省会累积成很大的差异。
简单说,Prompt Caching 可以让我们的应用同时更快、更便宜,而且不会改变答案质量。模型仍然看到了完整 prompt,只是避免重复做已经做过的工作。
这就是 Prompt Caching 的妙处。
真实世界里的 Prompt Caching
接下来看看 Prompt Caching 在真实系统里用在哪里。
主要 AI 提供商都把 Prompt Caching 做成了内置功能。例如 Claude 背后的 Anthropic、GPT 模型背后的 OpenAI,都支持 Prompt Caching。我们只需要标记 prompt 中稳定的部分,让它可以被缓存,提供商会负责保存和复用。我们也可以检查响应,看看有多少 token 被写入缓存、多少 token 是从缓存读取的,这样就能确认缓存确实在生效。
Prompt Caching 在两类系统里尤其有用。
第一类是 RAG。RAG 是 Retrieval-Augmented Generation 的缩写。简单说,它是一种系统:先取回一些相关文档,再把它们和用户问题一起发送给模型。这些取回的文档和固定指令通常很长,而且会在请求之间重复出现。缓存稳定指令,以及任何会重复发送的文本,可以降低成本和延迟。在同一条流水线的更前面,文档 embedding 也可以被缓存;我们有一篇详细介绍 Embedding Cache 如何工作的文章,解释了它如何避免每次查询都重新计算 embedding。
第二类是 agent 系统。agent 是一种 AI 程序,会一步一步处理任务,通常会调用工具,并通过多个回合完成工作。在 agent 系统里,同一大块指令、工具定义和早前文本,会在每一步都发送一次。步骤可能很多,所以同一个开头会被大量复用。这正是 Prompt Caching 最适合发挥作用的场景,因为缓存前缀会被一遍又一遍读取。
在规模化场景下服务这些重复前缀,是推理引擎的工作。我们有一篇详细介绍 vLLM 的文章,逐步解释它如何在请求之间共享相同前缀。另一个推理引擎 SGLang 也做同样的事,它使用基数树(radix tree)更精确地匹配共享前缀。
所以,只要我们不断发送同一个很长的 prompt 开头,Prompt Caching 就能带来很大帮助。
如果想深入学习 RAG、向量数据库和 AI Agent,我们有一套完整课程——可以看看 Outcome School 的 AI and Machine Learning Program。
这就是 Prompt Caching 的工作方式。我们为 prompt 中固定、重复的开头保存模型内部做过的工作,让这个开头保持完全相同并放在最前面,然后不断复用它,从而获得更快、更便宜的响应。
准备 AI 工程面试可以看这里:AI Engineering Interview Questions
这次就到这里。
谢谢
Amit Shekhar Outcome School 创始人