提示缓存(Prompt Caching)是如何工作的?

提示缓存(Prompt Caching)是一种技术:模型把 prompt 中重复出现的那部分已经算过的工作保存下来,下次直接复用这份保存的结果,而不必从头再算一遍。

本文我们来讲清楚提示缓存是怎么工作的。我们还会看到为什么需要它、它在大语言模型内部究竟如何运转,以及它在 AI 助手和智能体这类真实系统中用在哪些地方。

我们将覆盖以下内容:

  • 什么是 prompt?
  • 快速回顾:LLM 是如何读 prompt 的
  • 什么是提示缓存?
  • 为什么我们需要提示缓存
  • 提示缓存的核心思路
  • 精确前缀规则
  • 缓存写入与缓存读取,以及 TTL
  • 我们应该把什么放进缓存
  • 提示缓存带来的好处
  • 真实世界中的提示缓存

什么是 prompt?

在讲提示缓存之前,我们必须先搞明白 prompt 是什么。

prompt 就是我们发给大语言模型的那段文本。

大语言模型(large language model,简称 LLM)是 ChatGPT、Claude 这类工具背后的技术。我们给它一些文本,它还我们一些文本。

简单说,prompt 就是我们敲进去的所有内容。模型读了我们的 prompt,然后写出回复。

假设我们在做一个客服助手。发给模型的文本通常包含几个部分:

  • 一组指令,告诉模型该怎么表现,比如「你是一家鞋店的礼貌客服」。
  • 可能还有一份很长的文档,写着我们全部的鞋子退货政策。
  • 用户真正提的问题,比如「鞋子买了 40 天还能退吗?」

这些文本合在一起,就是 prompt。

现在有一点很值得注意:指令和那份政策文档,对每个用户都是不变的。只有用户的问题在变。我们很快会回到这一点,因为它是提示缓存的核心。

快速回顾:LLM 是如何读 prompt 的

要理解提示缓存,我们必须先理解 LLM 读 prompt 时的一件事。

我们发出 prompt 时,模型并不是按整词来读的。它先把文本切成小块,这些小块叫 token。token 是一小段文本,大致是一个词或词的一部分。比如 support 这样的短词通常是一个 token,而 returning 这样的长词往往会被切成两个 token(这套切分方式叫字节对编码,Byte Pair Encoding,BPE)。

于是,prompt 变成了一串 token。

接着,模型逐个处理这些 token,为每个 token 建立起内部理解。这第一步------模型读完整段 prompt、把每个 token 都处理一遍,之后才开始写回复的第一个词------叫做预填充(prefill)步骤。

简单说,预填充就是模型把我们的整段 prompt 读进去、消化掉。

在预填充过程中,对每一个 token,模型都会算出一些内部数值并保存起来。这些被保存的数值放在所谓的 KV 缓存(KV Cache)里。

用大白话说说 KV 缓存。模型读每个 token 时,会为这个 token 生成一份小摘要------相当于一条笔记,记下这个 token 在它前面所有内容的语境里意味着什么。KV 缓存就是这一堆笔记的集合,每个 token 对应一组笔记。模型写回复需要这些笔记,并且在生成每一个新词时也会复用它们。

这里有一个关键点要记住:

为一段很长的 prompt 构建 KV 缓存是要花真功夫的。模型必须逐个 token 做大量计算。

所以,如果我们的 prompt 有 5,000 个 token,模型就要在写下任何东西之前,为这 5,000 个 token 全部做完这些工作。prompt 越长,预填充这一步花的时间和钱就越多。

这就是我们需要的铺垫。现在可以来理解问题了。

什么是提示缓存?

既然知道了模型如何读 prompt,我们来看看提示缓存。

提示缓存是一种技术:模型把 prompt 中重复出现的那部分已经算过的工作保存下来,下次直接复用这份保存的结果,而不必从头再算一遍。

简单说,提示缓存就是:难的活只干一次,然后反复复用。

「缓存(cache)」这个词的意思很简单------一个存放东西的地方,方便我们之后快速取用,而不必从零再做一遍。

把它和我们刚学的连起来看:模型干的「难活」就是在预填充阶段构建 KV 缓存。提示缓存所做的,就是把 prompt 中重复那部分的 KV 缓存保存下来。下次我们发来的 prompt 开头是同一段重复内容时,模型就载入保存好的 KV 缓存,跳过重复计算。

所以,提示缓存的核心是复用 prompt 重复开头部分的内部计算结果。

这和语义缓存(semantic caching)不同:语义缓存是在新问题和旧问题意思相同(哪怕用词不同)时,直接复用最终答案。

那么问题来了,我们到底为什么需要它?接着看。

为什么我们需要提示缓存

回到我们的鞋店客服助手。

每个用户都会发来一个问题。但别忘了,每来一个问题,我们同时还会带上同样的指令和同样那份很长的退货政策文档。用户的问题很短,指令和文档却很长。

于是,模型为每个用户、每条消息,一遍又一遍地读同样的长指令和同样的长文档。

为了便于理解,我们给点数字。假设:

  • 指令和政策文档共 5,000 个 token。
  • 用户的问题有 50 个 token。

用户每问一次,模型就要对 5,050 个 token 做预填充。其中 5,000 个 token 和上一次完全一样,只有 50 个是新内容。

这是浪费。模型在 5,000 个根本没变的 token 上做着大量计算。

这带来两个真实的问题:

  • 慢。 把 5,000 个 token 一遍遍重新处理,会在用户看到回复之前不断增加延迟。
  • 贵。 我们是按模型处理了多少 token 来付钱的。每次都重新处理同样的 5,000 个 token,等于为同一份工作一遍遍付费。

在真实应用里,这个问题会大得多。想想那些长系统指令、大文档、以及我们每次请求都要带上的大量示例。我们反复发送同一个大文本块,模型就在反复重做同样的工作。

于是,提示缓存登场救场。

提示缓存的核心思路

我们一步步理解这个核心思路。

我们已经知道,预填充期间模型会构建 KV 缓存,也就是每个 token 对应的那组内部笔记。提示缓存做了一件简单却很有力的事。

思路是:把 prompt 中固定且重复的那部分的 KV 缓存保存下来。下一次请求的开头还是同一段内容时,模型载入保存好的 KV 缓存,从那里接着往下做,跳过重算。

我们用刚才的例子走一遍。

第 1 步: 一个用户发来第一个问题。prompt 是 5,000 个 token 的指令加文档,后面跟着 50 个 token 的问题。模型对这 5,050 个 token 做预填充并构建 KV 缓存。在这个过程中,它把前 5,000 个 token 的 KV 缓存保存了下来,因为那部分被我们标记为要缓存。

第 2 步: 另一个用户发来一个不同的问题。prompt 还是同样的 5,000 个 token 指令加文档,后面跟着新的 50 个 token 问题。此时,模型不再重做前 5,000 个 token 的工作,而是直接载入它们保存好的 KV 缓存。只有那 50 个 token 的新问题需要做新计算。

就这样,模型直接跳到了缓存部分结束的位置,并从那里继续。它没有在已经理解过的 5,000 个 token 上浪费时间。

下面这张简图把这件事说清楚。

复制代码
不开提示缓存时(每一次请求):

[ 5,000 个 token:指令 + 文档 ] + [ 50 个 token:问题 ]
        全部重新处理一遍              只处理这部分
     (慢、贵、重复计算)            (真正的新工作)

开启提示缓存后(从第二次请求起):

[ 5,000 个 token:指令 + 文档 ] + [ 50 个 token:问题 ]
        从缓存读取(快、便宜)        只处理这部分
        跳过这部分的重计算            (真正的新工作)

问题解决了。重复那部分的难活,模型现在只干一次。

精确前缀规则

这里有一条非常重要的规则必须理解,因为大多数坑都踩在这儿。

提示缓存是基于前缀匹配的。被缓存的部分必须是 prompt 的开头,而且必须逐字符完全一致。

先说「前缀」这个词。前缀就是某个东西的开头那段。在我们的场景里,被缓存的部分是 prompt 的开头,也就是用户问题之前的那段内容。

只要新 prompt 的开头与已缓存 prompt 的开头完全一致,模型就可以复用缓存。一旦文本出现差异,从那个位置往后的缓存就失效了。

可以这样画出来:

复制代码
已缓存的 prompt:你是一名礼貌的客服。退货窗口为 30 天。
新的 prompt:    你是一名礼貌的客服。退货窗口为 45 天。
                 |---------------- 完全一致 ----------------|
                              从缓存读取
                                             ^ 从这里开始不一致,这一段必须重算

这里可以看出,两段 prompt 在某个点之前是一样的,前面这段一致的部分就从缓存读取。而从第一个不一样的 token 起,前缀就不再匹配,后面所有内容模型都必须重算。

有一点我们必须格外小心:

只要 prompt 靠前的位置变了一个字符,那个位置之后的所有缓存全部失效。

举个例子说明。假设我们在指令的最顶部加了一行「今天是 2026-06-07」。这行每天都在变。因为它待在 prompt 的最开头,前缀就每天都不同。于是昨天建好的缓存今天用不了,模型只能把全部工作重做一遍。

这是非常常见的一个错误。我们不小心把会变的东西------比如当前日期、一个随机 ID、或者用户名------放在了 prompt 靠前的位置。就这一个小的变动,悄无声息地把整个缓存毁掉了。

所以要记住的规则很简单:

把稳定的部分放前面,把变化的部分放最后。

prompt 的开头不变,缓存就一直有效。开头一直在变,缓存就毫无用处。别担心,稍后我们会具体看清哪些部分该保持稳定、该放在哪里。

缓存写入与缓存读取,以及 TTL

接下来理解两个简单术语:缓存写入(cache write)和缓存读取(cache read)。

缓存写入发生在第一次。这时模型处理重复的那部分内容,并把它的 KV 缓存保存下来。我们是在第一次把结果写进缓存。

缓存读取发生在其后。这时后续请求复用保存好的 KV 缓存,而不是重新计算。我们是在从缓存里读。

把它和成本连起来看,这才是有意思的地方。

缓存写入比普通处理略贵一点,因为模型既要完成计算,又要把结果存下来。粗略地说,这部分的缓存写入成本大约是正常价格的 1.25 倍。

但缓存读取非常便宜。从缓存读取的成本只有正常价格的大约十分之一。也就是说,重复的那部分能省下差不多 90%。

所以,第一次请求多付一点写入成本,之后每一次请求都因为读缓存而便宜很多。复用次数越多,省得越多。

整个流程大致如下:

复制代码
请求 1 --> 处理稳定部分 --> 保存下来(缓存写入,约 1.25 倍成本)
                |
                v
        +-------------+
        |    缓存     |
        +-------------+
         ^     ^     ^
请求 2 ---+     |     |   (缓存读取,约 0.1 倍成本)
请求 3 ---------+     |   (缓存读取,约 0.1 倍成本)
请求 4 ---------------+   (缓存读取,约 0.1 倍成本)

这里可以看到,只有第一个请求做了重活并把结果写进缓存。之后每一个开头相同的请求,都直接从缓存读取,所以每一次都比从头重做便宜得多。

那么下一个问题:缓存会永久保留吗?答案是不会。

缓存有 TTL,全称 time to live,即存活时间。简单说,TTL 就是缓存能活多久,过了这个时间它就过期并被清除。

常见的默认 TTL 是 5 分钟。也可以选择更长的 TTL,比如 1 小时。TTL 在实际中的含义是:

  • 如果 TTL 窗口内又来了一个前缀相同的新请求,它可以读缓存。
  • 如果 TTL 窗口内没有请求进来,缓存过期。下一个请求必须重新做一次缓存写入。

所以,当大量请求共享同一个开头、且时间上挨得比较近时,提示缓存的效果最好。

注意:更长的 TTL 能让缓存活得更久,在请求比较分散时有用,但长 TTL 的缓存写入成本会略高一些。所以 TTL 要根据具体场景来选。

我们应该把什么放进缓存

现在我们知道,缓存作用于 prompt 中稳定的开头部分。那么自然要问:究竟该往那里放什么?

答案很简单。把在大量请求中保持不变的部分放前面,把会变的部分放最后。

以下这些非常适合缓存,因为它们通常不变:

  • 系统指令。 它们描述模型应该如何表现,比如「你是一名礼貌的客服」。这些对每个用户都一样。
  • 大文档。 比如我们完整的退货政策、产品手册、或知识库中的一篇文章。它们又长又会被重复带上,缓存它们能省很多。
  • 工具定义。 当我们允许模型使用工具时,需要把每个工具描述给它。这些描述通常是固定的。
  • 少样本示例(few-shot examples)。 这些是我们给模型的示例问答,让它学会我们想要的风格。「few-shot」的意思就是给模型几个例子作为引导。这些示例每次都一样。

而会变、必须放在最后的那部分是:

  • 用户真正的问题或消息。 它每次请求都不同,所以放在最末尾,在所有被缓存的部分之后。

用一个简图看看这个顺序。

复制代码
一个设计良好的 prompt 的顺序

  最前 -> 工具定义            |
          系统指令            | 稳定部分:缓存它
          大文档              |
          少样本示例          |

  最后 -> 用户的问题          变化部分:不要缓存

这个顺序就是全部的诀窍。稳定的块待在最前面并被缓存,变化的问题待在最后,不会破坏缓存。

到这儿,我们就明确知道了该缓存什么、该放在哪儿。

决定 prompt 里放什么、以什么顺序放,本身就是一门学问(即上下文工程,Context Engineering)。

提示缓存带来的好处

我们把好处快速汇总一下,因为它们才是我们用这项技术的理由。

  • 更低的延迟。 延迟就是用户拿到回复之前的等待时间。既然模型跳过了重复部分的重算,它就能更快开始回复。
  • 更低的成本。 缓存命中的 token 以便宜得多的价格计费,大约只有正常价格的十分之一。当我们反复发送同一个大文本块时,这笔节省会累积成很大的数目。

简单说,提示缓存在不改变答案质量的前提下,让我们的应用同时变得更快、更便宜。模型依然看到完整的 prompt,它只是避免了重做已经做过的工作。

这就是提示缓存的美妙之处。

真实世界中的提示缓存

接下来看看提示缓存用在哪些真实系统里。

主流 AI 服务商都把提示缓存做成了内置能力。比如 Claude 背后的 Anthropic、GPT 系列模型背后的 OpenAI,都支持提示缓存。我们只需把 prompt 中稳定的那部分标记为可缓存,服务商就会替我们完成保存与复用。我们还可以检查响应,看看有多少 token 被写入了缓存、有多少从缓存读取,这样随时能确认缓存确实生效了。

提示缓存在两类系统里尤其强大。

第一类是 RAG。RAG 是检索增强生成(Retrieval-Augmented Generation)的缩写。简单说,这类系统会先取回一些相关文档,再把它们连同用户的问题一起发给模型。这些取回的文档和固定指令往往很长,而且在多次请求间重复。缓存稳定的指令,以及任何我们会重复发送的文本,能同时降低成本和延迟。同样的技巧让上下文检索(Contextual Retrieval)变得负担得起------那种做法需要为文档的每个分块都把整篇文档发给模型一次,用来给该分块写一段简短的上下文注记。在同一流程更靠前的环节,文档的 embedding 也可以缓存起来,从而避免每次查询都重新计算。

第二类是智能体系统。智能体(agent)是一个 AI 程序,它一步步完成一项任务,过程中经常调用工具、来回多轮才能做完一件事。在智能体系统里,同一大块指令、工具定义和先前的文本,在每一步都会被发送。步骤可能很多,同一个开头会被复用极多次。这正是提示缓存大放异彩的场景,因为被缓存的 prefix 被一遍又一遍地读取。

在大规模场景下服务这些重复前缀,是推理引擎的职责。vLLM 在请求之间共享相同的前缀;另一个推理引擎 SGLang 用基数树(radix tree)更精确地匹配共享前缀;NVIDIA 的 TensorRT-LLM 也做同样的事,名字叫前缀复用(prefix reuse)。

所以,只要我们一直在发送同一个很大的 prompt 开头,提示缓存就能帮上大忙。

提示缓存就是这样工作的:我们把模型对 prompt 中固定且重复开头的内部计算结果保存下来,让这个开头保持完全一致并放在最前面,然后一遍又一遍地复用它,从而拿到更快、更便宜的响应。

常见问题

提示缓存和语义缓存有什么区别?

提示缓存复用模型对 prompt 重复开头的内部计算结果,也就是 KV 缓存。模型仍然要读新内容,并写出一份全新的回复。语义缓存则是在新问题与旧问题意思相同时(哪怕用词不同)直接复用最终答案。

提示缓存会改变答案质量吗?

不会。提示缓存在不改变答案质量的前提下,让应用变得更快、更便宜。模型仍然看到完整的 prompt,它只是避免重做那几个重复部分已经做过的工作。

为什么我们的提示缓存一直不命中?

最常见的原因是 prompt 顶部附近有会变的东西,比如当前日期、随机 ID 或用户名。被缓存的部分必须逐字符完全一致,所以哪怕靠前的位置只变了一处,后面所有缓存都会失效。我们应该把稳定部分放在前面,把变化部分放在最后。

提示缓存总是更便宜吗?

对第一次请求不是。缓存写入比普通处理略贵,大约是正常价格的 1.25 倍。省钱来自后续的缓存读取,大约是正常价格的十分之一。所以,当大量请求共享同一个开头、且都落在 TTL 窗口内时,缓存才是划算的。

我们怎么知道提示缓存真的生效了?

可以检查服务商返回的响应。它会显示有多少 token 被写入缓存、有多少从缓存读取。如果后续请求显示有 token 从缓存读取,就说明缓存生效了。

相关推荐
一级新生1 小时前
API 到底是什么?用点餐窗口讲明白
人工智能·大模型·api·编程入门
特别关注外国供应商1 小时前
Claroty Claire:OT 环境中的 AI 驱动型网络安全
人工智能·网络安全·ai安全·工业网络安全·claroty·ot网络安全·暴露面管理
一切皆是因缘际会1 小时前
大模型应用
前端·人工智能
YY362952381 小时前
Caravel 收费吗?是开源的吗?能离线用吗?关于 Caravel 的 6 个常见误会
人工智能·ai编程·claude code
gz927cool1 小时前
在 Harness 上搭建 Agent-Native 应用:可迁移经验
服务器·人工智能·ai·系统架构
深眸财经1 小时前
易观Q3办公智能体报告发布,WPS灵犀专业版入选典型案例
人工智能·wps
2601_954811821 小时前
人工智能实验室集群选型:32节点PB级存储架构实践
人工智能·架构
小淮AI1 小时前
批量生成小红书文案的流程梳理:工具分工与实践要点
人工智能
钱栈up1 小时前
GitHub 热榜上手|ArtCraft:+13,572 star 的 AI 创作 IDE
人工智能·github