news 2026/10/28 1:53:14

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

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
提示缓存(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 从缓存读取,就说明缓存生效了。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/28 1:53:13

别只盯着mAP!工业无人机巡检YOLO落地的6大工程难题与实战解法

做过工业无人机巡检项目的人,大概率都有过这种落差: 实验室里训好的YOLO,测试集mAP冲到90%+,感觉效果稳了,拉到现场飞第一个架次,心直接凉了一半。逆光下缺陷漏检一半,阴影里杂物全被当成缺陷,几十米外的小缺陷根本看不见;一天飞下来几千张图,误报一堆,人工筛到半夜…

作者头像 李华
网站建设 2026/10/28 1:51:55

充值送token任务非异步设计下如何实现幂等性

L0.参数校验:幂等键必填 LiteflowComponent("validateCmp") class ValidateCmp extends NodeComponent {Override public void process() {RechargeContext ctx this.getContextBean(RechargeContext.class);if (ctx.getUserId() null || ctx.getAmoun…

作者头像 李华
网站建设 2026/10/28 1:51:11

纸箱打样一般有哪几种方式?为什么有的打样免费有的要收刀模费?

纸箱打样一般有哪几种方式?为什么有的打样免费有的要收刀模费?一、纸箱打样的常见方式纸箱打样是批量生产前确认尺寸、结构、印刷效果的关键环节,不同打样方式的精度、成本、周期各不相同,对应不同的确认需求。纸箱打样方式对比二…

作者头像 李华
网站建设 2026/10/28 1:50:27

RFID系统由哪些部分组成?

RFID系统由以下三个部分组成: ● 电子标签:附着在物品上,由芯片和天线组成,存储唯一标识或业务数据 。 ● 读写器:发射射频信号并接收标签返回的信息,分为固定式和手持式 。 ● 后台系统:接收读…

作者头像 李华
网站建设 2026/10/28 1:50:23

命令安全设置

本页位于 设置 -> 主机Agent -> 对话与主机 -> 命令安全,用于控制结构化命令写入终端前的检查。 命令安全适用于命令行、全局执行、快捷命令和 Agent 执行。用户在终端窗格内直接键盘输入,或通过右键、中键、上下文菜单和 CtrlShiftV 粘贴时&am…

作者头像 李华
网站建设 2026/10/28 1:48:10

WeChatMsg 依赖更新完整指南:3 步安全升级微信聊天记录分析工具

WeChatMsg 依赖更新完整指南:3 步安全升级微信聊天记录分析工具 【免费下载链接】WeChatMsg 提取微信聊天记录,将其导出成HTML、Word、CSV文档永久保存,对聊天记录进行分析生成年度聊天报告 项目地址: https://gitcode.com/GitHub_Trending…

作者头像 李华