KV Cache 原理:提示词缓存如何省钱,长上下文为何占内存
KV Cache 为什么能降低大模型推理成本,却不能消除长上下文的内存压力?本文从预填充与解码讲起,拆解提示词缓存的计费逻辑、KV 内存估算公式,以及 Anthropic、OpenAI、Google Gemini 的读写与保留规则,并介绍 vLLM 的前缀复用、量化和卸载方法,帮助你排查命中率、延迟与成本问题。
发布于

缓存输入之所以便宜,是因为模型可以复用已经完成的计算。KV Cache 保存键(key)和值(value)这 2 组注意力数据,让大语言模型延续对话时,无须重新计算此前每个 token 的状态。重复上下文的处理成本因此降低,但长对话仍然占用内存,也会让每个新 token 需要关注更多上下文。
先保留有用的前缀,再控制历史内容的保留量。 这是两件事。前缀是请求开头保持不变的部分;缓存前缀可以减少输入处理,却不会让智能体的其他工作一并消失。
下文的厂商价格和缓存规则已于 2026 年 10 月 15 日对照各厂商当时的官方价格页和文档核实。内存计算依据文档中的张量形状推导,并非某款 GPU 的实测结果。
KV Cache 是什么?重复提示词背后有哪些计算
KV Cache 保存的是注意力状态。 Transformer 通过注意力机制,把前文中的相关信息用于当前预测。token 是文本或其他模型输入的基本单位,会在每个注意力层中生成数值表示。缓存保留各层的键和值,供后续计算使用。Hugging Face 的缓存原理文档解释了这种逐层存储方式。
可以借一座资料图书馆,理解注意力中的三种角色:
- **查询(query)**说明当前位置正在寻找什么。
- **键(key)**让此前的位置能够被检索和匹配。
- **值(value)**提供匹配后可以利用的信息。
设想写报告前,先整理好一套带索引的研究笔记。每写一句新内容,都可以查阅这些笔记。如果每写一句就重建索引、重整笔记,会反复做同样的工作;把它们留下来,则要占用空间。但这个比喻不能直接套到实现上:模型保存的是数值数组,并非人能阅读的索引卡片,也不是文档摘要。
当前查询会与此前的键进行比较,再用得到的注意力权重组合对应的值。在因果 Transformer 中,先前位置无法看到未来。因此,添加后续 token 时,不必修改此前位置已经算好的状态。这正是能够复用的原因。PagedAttention 原论文介绍了这些注意力计算和生成过程。
这也解释了为什么常规缓存保存 K 和 V,而不保存所有旧查询。预测下一个 token 时,需要的是当前查询,以及已经积累的键和值;旧查询已经完成了自己的任务。
对于客服智能体,这些保留的状态可能对应指令、工具定义、政策文档和截至当前的对话。它们取决于具体模型和前文,既不是模型训练得到的权重,也不是永久保存客户信息的记忆数据库。
缓存前缀,也不等于缓存答案。 模型仍会生成新的后续内容。针对同一份文档提出新问题,可以复用处理文档后得到的状态,而不是返回上一次的答案。
KV Cache 原理:Prefill 和 Decode 分别在做什么
Prefill 负责处理输入,Decode 负责在此基础上继续生成。 分清这两个阶段,就能理解为什么缓存命中后,请求可能更快开始输出,却仍要花时间才能完成。
对于常规自回归 Transformer,可以用下面的流程来理解:
Prefill(预填充): 提示词 token → 处理提示词 → 保留各层的键和值 → 预测第一个输出 token。
Decode(解码): 最新生成的 token + 已保留的键和值 → 处理该 token 并关注上下文 → 预测下一个 token;追加新算出的键和值。
重复解码: 持续复用不断增长的缓存,直到生成结束。
预填充阶段可以一起处理已经确定的提示词位置。解码则需要逐步推进,因为后续要生成哪些 token 还没有确定。PagedAttention 论文中的生成与执行流程解释了这一区别。

KV Cache 降低了生成下一个 token 的成本,比较对象是重新计算整个前缀。这并不意味着下一个 token 的计算与上下文长度无关。在常规全注意力机制下,它的查询仍要与保留的键和值交互。留下的上下文越多,需要参与计算的注意力数据就越多。Hugging Face 文档说明了每一步仍需完成的注意力计算。
这里还要区分两种复用。在一次响应内部,KV 缓存避免了生成过程中反复计算已有状态。在不同请求之间,前缀缓存会保留符合条件的状态,让后续调用跳过一部分预填充计算;托管 API 通常称之为提示词缓存(prompt caching)。仅有一个会话标识,并不能证明这些状态仍然可用。
假设智能体先阅读一份政策文档,再调用工具,随后让模型判断该如何处理工具结果。下一次请求可以保留之前的指令和文档作为公共前缀,再把工具结果追加到后面。如果缓存符合复用条件且仍然可用,服务商就不必重新处理这段相同的开头。
因此,使用 API 开发应用时,既要观察首个 token 返回前的等待时间,也要观察生成整段响应所用的时间。首 token 延迟改善,并不能证明解码更快。vLLM 的自动前缀缓存文档明确区分了预填充节省的计算与解码耗时。
提示词缓存怎样影响输入费用
折扣对应的是已复用的输入计算,具体按服务商的计费规则执行。 各家没有统一的折扣比例,一次请求命中缓存,也不代表其中每个 token 都能享受折扣。
对于区分普通输入、缓存写入和缓存读取的 API,输入费用可以写成:
输入费用 = (U × p_input + W × p_write + R × p_read) / 1,000,000
其中,U 是普通输入 token 数,W 是按缓存写入计费的 token 数,R 是按缓存读取计费的 token 数。每个 p 对应这一类别每百万 token 的价格。这几个类别必须互斥:已经按写入计费的 token,不能再收一次普通输入费。这个算式依据 OpenAI 和 Anthropic 的价格分类,按单位换算得到。
之后还要加上输出费、适用的工具费用,以及单独计费的缓存存储费用。Google 的显式缓存还涉及保留时长,因此仅计算写入和读取并不够。以下示例用于说明各家的计费规则,并非模型排名。
Anthropic:标记可复用前缀的终点
Anthropic 通过 cache_control 提供提示词缓存:可以把它设在请求顶层,由系统自动管理断点,也可以设在单个内容块上。断点标记要保留的前缀在哪里结束。价格文档介绍了这两种方式。
价格示例,标准 Claude API: Claude Sonnet 5.5 每百万 token 的输入价格为 $2,缓存读取为 $0.10,保留 5 分钟的缓存写入为 $2.50,保留 1 小时的缓存写入为 $4。Anthropic 价格。
该模型可缓存前缀的最低长度是 512 个 token。从开头到缓存边界,内容必须完全一致。读取会刷新缓存有效期,无须再付写入费;但计时从请求开始时算起,因此响应生成也会消耗一部分有效期。其他 Claude 模型的最低长度和读取折扣有所不同。Anthropic 提示词缓存规则。
文档智能体如果需要等待用户较长时间后再继续,缓存保留时长就可能决定下一次调用是读取已有前缀,还是重新写入。应查看用量中的 cache_creation_input_tokens 和 cache_read_input_tokens;仅仅再次发送同一份文档,不足以证明这次享受了读取折扣。用量字段说明。
OpenAI:先看具体模型的写入规则
OpenAI 在支持的模型上默认启用提示词缓存,较新的模型同时支持隐式和显式断点。具体行为因模型而异。OpenAI 提示词缓存文档。
价格示例,Standard 短上下文档位: GPT-6.1 Sol 每百万 token 的输入价格为 $2.00,缓存输入为 $0.10,缓存写入为 $2.50;超过 272K 个输入 token 后,整个请求的输入及缓存费率翻倍。OpenAI 价格、模型阈值。
GPT-5.6 及后续模型的最低门槛为 1,024 个可见输入 token,文档规定的缓存有效期为最近一次写入或复用后至少 30 分钟。这些 token 按缓存写入费率计费,替代普通输入费率,并不是在整笔输入账单上再加收一份。更早的模型采用不同的写入和保留规则。当前缓存规则。
使用 Responses API 时,应查看 usage.input_tokens_details.cached_tokens 和 cache_write_tokens。保留会话并不保证命中缓存。需要排查请求布局和返回的用量数据时,可以参考本站的 GPT-6 提示词缓存诊断指南。
Google Gemini:隐式复用与显式存储要分开看
Google Gemini 提供自动隐式缓存,命中后会把节省的费用体现到计费中。以 Gemini 3.8 Flash 为例,文档规定的最低门槛是 4,096 个输入 token。把公共内容放在开头,并让请求在较接近的时间发出,有助于提高复用概率。Google 上下文缓存指南。
价格示例,付费 Standard Gemini Developer API: Gemini 3.8 Flash 每百万 token 的输入价格为 $0.75,缓存输入为 $0.075,显式缓存存储费为每百万 token 每小时 $0.50,这些价格适用至 2026 年 12 月 31 日。Google 价格。
显式缓存使用一个命名的缓存内容资源,并设置过期时间,后续 generateContent 请求再引用该资源。由于存在存储费用,即使文档没有被使用,继续保留它也可能产生费用。Google 缓存 API 参考文档。
选择哪种 API 很关键:Interactions API 只支持隐式缓存。Google 当前指南也明确,Gemini 4 Argon 及后续模型不支持显式缓存;支持显式缓存的 Gemini 3 和 2.5 模型通过 generateContent 使用该功能。对于 Interactions API,应按指南检查 usage.total_cached_tokens。Google 各 API 的具体规则。
对于 API 服务运营者,实际区别在于:是在观察自动缓存命中,还是主动付费保留一个资源。设计跨厂商的缓存抽象时,不应把这两种方式视为相同的生命周期。
KV Cache 的内存占用为何随上下文增长
对于常规全注意力层,原始 KV 数据占用的内存与保留的 token 数呈线性关系。 长对话意味着工作集不断扩大,即使对话开头已经满足计费折扣条件,也不会改变这一点。
在序列等长、各注意力层结构一致的情况下:
KV bytes ≈ 2 × B × T × L × H_kv × D × S
2:一组键数组,加上一组值数组。B:并发序列数,假设各序列不共享缓存数据。T:每条序列中已经处理并保留的 token 数,包括提示词和已生成的 token。L:保留此类缓存的注意力层数。H_kv:每层的键值头数。D:每个头中的标量数量。S:存储每个标量所需的字节数。
这个公式依据文档中的逐层缓存形状,以及 vLLM 的键值头布局,通过统计元素数量推导而来。它估算的是原始张量大小,并非设备总内存占用。
头数不能用错。分组查询注意力让多个查询头共享键值头,因此公式中应填入的是 KV 头数。如果误用通常更大的查询头数,就会高估缓存大小。
保持模型和存储精度不变,让 T 翻倍,原始稠密缓存就会翻倍。如果 T 和相互独立的并发序列数同时翻倍,缓存就会变为原来的四倍。这是代数推导,不代表某款 GPU 的容量或实测吞吐量。
对于自托管的客服服务,这个公式可以引出一个实用的容量问题:所有客户同时活跃的上下文中,一共保留了多少 token?模型本身能放进内存只是起点,服务器还必须容纳这些客户持续变化的推理状态。
Hugging Face 的缓存策略文档说明了窗口式注意力层的上限,vLLM 的前缀缓存设计则介绍了可复用的物理块。如果所用架构的状态布局不同于这些常规的稠密键值数组,应以该架构的文档为准。
对于托管 API 用户,同样的增长会以另一种方式体现:即使命中率稳定,每轮按缓存读取计费的 token 仍可能越来越多。单价降低,乘上不断扩大的输入量,费用依然会增长。生成输出时也仍需关注上下文,费率档位的阈值还可能取决于完整输入长度。
用 vLLM 优化 KV Cache:先找出瓶颈
vLLM 是开源的大语言模型推理服务引擎,为自托管用户提供缓存分配、复用和存储表示方面的控制能力。 调整部署之前,先确定哪种手段对应当前瓶颈。
PagedAttention:对话增长时,按需分配内存块
PagedAttention 让注意力计算可以使用分散在不同物理块中的 KV 数据。一条逻辑序列不必为了未来可能达到的长度,预先占住一整片连续空间。最初的设计既减少了分配浪费,也支持共享。PagedAttention 论文。
仍然可以用图书馆来理解:为不断扩展的研究项目分配可用的书架区块,再用一张映射表记录它们的顺序。还不知道会产生多少资料时,无须先预留一整条巨大的空书架通道。
分页本身不会减少每个 token 所需保存的信息。它改善的是这些信息如何放进现有内存。此外,vLLM 已把 Paged Attention 内核页面标记为历史资料;可以借它理解思路,但不应把旧内核说明当作当前实现。
前缀缓存:跳过与此前请求重复的计算
Automatic Prefix Caching 会复用匹配前缀的 KV 状态。vLLM 文档提供了 enable_prefix_caching=True 配置;如果多次文档问答或智能体的多轮调用总以相同内容开头,这就是相应的功能。自动前缀缓存文档。
判断缓存是否相同,需要包含它之前的前缀,而不只是查看某个独立块中的文本。因此,同一段文字如果前面的指令不同,就不能直接假定其缓存可以互换。vLLM 的基于哈希的缓存设计明确体现了这种依赖关系。
收益受工作负载限制:互不相关的提示词几乎没有可共享的计算,而长答案的耗时仍可能主要落在解码阶段。如果你还在选择推理引擎,可以参考 vLLM 与 SGLang 对比,了解更完整的选型考量。
KV Cache 量化:减少每个数值的存储字节数
KV Cache 量化会降低缓存数值的存储精度。vLLM 支持通过 kv_cache_dtype="fp8" 使用 FP8 缓存,并建议基于数据集校准缩放因子,以保障质量。具体可用方案取决于注意力后端。vLLM 缓存量化文档。
从 16 位降到 8 位,在不计缩放元数据和内存分配开销时,公式中原始标量数据的大小会减半。这不代表服务器的全部内存占用都减半,也不能据此宣称获得了某个实测加速效果。模型权重量化与注意力状态量化,是两项独立的选择。
对于生产环境中的智能体,应评估真正重要的长任务:能否记住约束、选对工具,以及找回早先消息中的细节。只有任务仍能完成,缩小状态才有意义。不能因为服务器成功启动,就推断质量没有变化。
KV Cache 压缩:降低精度与减少内容是两回事
保留精度更低的数值,与保留更少的位置,涉及不同的取舍。 量化改变数值的表示方式;有界注意力窗口改变该层仍可访问哪些位置。两者可能导致的问题不同,不应笼统归为一种“压缩”效果。Hugging Face 缓存策略。
一个实用的起点,是停止发送无关的工具输出。这会从源头缩小后续上下文,但属于应用层面的决策:优化保留状态之前,先确保智能体所需的依据没有被丢掉。
KV Cache 卸载:用数据传输换取更多状态保留空间
卸载会把可复用状态移到其他内存层级。 vLLM 的 OffloadingConnector 可以把已完成的块保留在 CPU 主机内存或支持的其他存储层级中,命中后再按需搬回 GPU。vLLM 卸载指南。
如果有用的前缀在离开 GPU 驻留空间后仍有复用价值,这种方式可能有帮助,但也会引入数据搬运。应针对自己的工作负载,比较省去重算的收益与传输开销;不存在适用于所有场景的延迟改善幅度。
当活跃请求的 KV 状态造成内存压力时,vLLM 可以抢占请求,并在之后重新计算。优化指南建议,抢占频繁时应检查并发量和内存分配。对运维人员来说,抢占次数持续上升,比单纯看到 GPU 显存占满更能指明下一步行动。
缓存命中率高,就代表智能体高效吗?
高命中率不等于高效率。 命中率衡量的是复用,而业务真正需要的是:在可接受的时间和预算内,成功完成任务。
一段对话即使复用了几乎全部历史输入,仍可能每轮都变长。它也可能只是在反复以折扣价读取无关材料。还有一种情况是,大部分时间都花在输出生成上,而前缀复用无法直接省掉这部分工作。
不要只为维持一个缓存指标,就保留臃肿的对话记录。旧材料不再有帮助时,应压缩上下文或重新开始,并接受前缀变化后可能需要重新处理。决策应围绕任务质量和总工作量展开。本站的上下文工程指南介绍了如何判断哪些内容值得放进工作上下文。
对于使用付费 API 的开发者,如果多个请求反复共享大量内容,现在就值得优化提示词布局;如果工作负载很少重复同一前缀,就不必急着设计复杂的缓存管理。自托管服务的运营者应先检查内存分配压力和抢占情况,再判断模型是否需要更多算力。短小、互不相关的一次性请求,几乎没有可挖掘的跨请求复用空间。
大模型 KV Cache 常见问题
ChatGPT 使用 KV Cache 吗?
OpenAI 的文档介绍了其 API 基于 KV 的提示词缓存。这说明了公开 API 功能如何工作,并未揭示 ChatGPT 内部推理服务部署的全部细节。开发应用时,应以所选 API 模型公开的缓存规则和用量字段为准。OpenAI 文档。
应该把 KV Cache 卸载到 GPU 显存吗?
GPU 推理中,活跃的注意力状态就在 GPU 上使用。vLLM 的卸载功能会把可复用块移到主机内存或其他受支持的存储层级,再按需搬回。当多保留一些前缀的价值足以抵消传输开销时,可以考虑这一方案。vLLM 卸载文档。
怎样减少 KV Cache 的占用?
可以缩短保留的上下文、减少并发序列、复用符合条件的共享前缀,或评估更低精度的缓存存储。卸载改变的是状态存放位置,不一定减少总大小。评估效果时,除了内存占用,还要看任务质量和实际延迟。缓存策略。
提高智能体缓存命中率的三个习惯
任务进行期间,让开头保持稳定,把变化内容追加在后面。 请求结构可预测,才有利于精确前缀复用;同时仍须满足服务商对最低长度、保留时长和可用性的要求。

把稳定的系统提示词放在前面
在 API 规定的消息结构内,把长期有效的指令、工具定义和可复用的参考材料放在会变化的任务数据之前。措辞、工具顺序和序列化方式都要保持稳定。Anthropic 的层级顺序是工具、系统提示词、消息;工具集合变化,可能让后续内容无法复用。Anthropic 缓存结构。
追加历史记录,不要反复改写前文
保留已有消息,把新的用户消息、助手工具调用或工具结果追加到后面。避免每次调用都用变化的摘要或格式重建此前的轮次。确实需要压缩上下文时,应把它作为一次明确的切换,并在之后建立新的稳定前缀。这符合每个块依赖其前面 token 的机制。vLLM 前缀标识规则。
不要把时间戳放在最开头
把当前时间、请求标识以及其他会变化的元数据放在可复用材料之后。开头的时间戳一旦变化,后面的上下文就可能无法复用。使用显式断点时,应把断点设在稳定前缀的末尾、变化后缀的前面。Anthropic 断点指南。
下一个工作日,可以挑一段有代表性的智能体对话,从实际发出的请求入手检查。逐字比较连续调用的前缀,再把服务商报告的缓存写入、读取量,与总输入、输出和延迟放在一起看。更换服务商之前,先修正不稳定的前缀。如果命中情况已经良好,智能体仍然很慢,再检查保留的上下文、输出长度和服务器资源争用。
订阅邮件通讯,了解 AI 智能体背后各类系统的实用原理。
- 发布日期
- 分类
- Build
- 语言











