Prompt Cache技术详解:从KV Cache到Agent工程实践

系统解析Prompt Cache从底层KV Cache、PagedAttention到Agent工程实践的完整技术链条与落地方法。
本文以大模型API的价格差异为切入点,系统梳理了Prompt Cache背后的四层技术架构:PagedAttention负责显存分页管理,KV Cache保存Attention的Key/Value张量,Prefix Cache负责跨请求复用判断,Prompt Cache则是面向用户的产品层能力。文章详细解释了Prefill与Decode两阶段的延迟来源、KV Cache的显存计算方式、vLLM哈希链与SGLang RadixTree两种前缀复用实现,以及缓存命中的精确条件——不仅要求token前缀完全一致,还要求Tokenizer、模型版本等"计算身份"完全相同。在工程实践层面,文章给出了Agent场景下按稳定性排列上下文的具体方法,并指出缓存失效的五大原因和隐私侧信道风险,最终以"先测量、再重排、再定义隔离范围"的落地框架收尾。
在使用大模型API时,你可能注意到一个有趣的现象:同样的模型、同样的token,价格却可能相差一到两个数量级。这背后的关键就是 Prompt Cache(提示缓存)。当前主流模型的定价高度一致——缓存写入约为标准价格的1.25倍,而缓存读取仅需0.1倍左右。这种巨大的价格差异,正是理解大模型推理成本结构的入口。
本文基于B站UP主关于Prompt Cache的深度技术讲解,系统梳理从KV Cache、PagedAttention到Agent工程实践的完整技术链条。
四层技术架构:Prompt Cache、KV Cache、PagedAttention的区别
Prompt Cache、Prefix Cache、KV Cache、PagedAttention这四个词经常一起出现,但它们并不属于同一层级。从下往上理解,可以避免混淆。
从底层到产品层的完整链条
- PagedAttention(最底层):负责显存管理。它把逻辑上连续的KV序列映射到一堆离散的物理块上,负责分配、共享和回收。
- KV Cache:模型真正保存下来的状态,即每一层Attention的Key和Value张量数据。
- Prefix Cache:负责判断什么条件下可以跨请求复用。它按token前缀查找,查到第一个对不上的位置就停止。
- Prompt Cache(产品层):这是你在API文档和账单上看到的那层产品能力,包括自动缓存、显式热点、TTL、计费规则等。
关键在于,模型厂商卖给你的其实是对前缀计算的一种复用逻辑,它本质上并不承诺底层用的是哪套开源实现。理解这四层,只需记住四个问题:你买的是什么系统、命中条件如何判断、命中后复用什么信息、这些状态如何保存到显存。
Prefill与Decode:大模型推理延迟从哪里来
一次请求可以粗暴地切成两段:Prefill 和 Decode。
两个阶段的本质区别
Prefill拿到整段输入prompt,GPU可以并行处理这些输入token,做一轮大规模矩阵计算,把后续生成需要的内部状态建立起来。这段时间用户什么都看不到,一直在等第一个字——所以Prefill是**首Token延迟(TTFT)**中很重的一块。
第一个token被输出后进入Decode阶段,模型每一步只增加一个或一小批位置,读一遍历史KV再预测下一个token。你看到的实时逐字展示,其实就是 TPOT(每Token生成时间)。
总延迟大致等于:TTFT + 后续Token数 × 每步Decode时间。
Prompt Cache操作的正是Prefill这段计算,它砍掉了重复的前缀计算。但需要注意,Decode该生成还是要生成,这一点无法省略。此外,真实TTFT里还有排队、路由、网络和批处理的干扰,缓存并不会重置这些。

KV Cache原理:用显存换计算的核心思想
在每一层Attention中,隐藏状态会经过三组投影产生Q、K、V。生成下一个token时,新的Query要跟前面所有Key算相关性,再按权重汇总所有Value。
关键洞察在于:历史的Key和Value是固定的逻辑,追加新token并不会改变它们。既然不变,就没必要每一步从头计算。因此第一轮的Q用完就淡出,K和V留下来进入缓存。下一步只给新位置计算新的Q、K、V,新Q读整段历史KV,新KV再追加到尾巴上。
KV Cache显存容量的计算方式
KV Cache的容量是这样计算的:K和V两份张量数据 × 层数 × Token数 × KV Head数 × 每Head维度 × 数据类型字节数,随上下文长度线性增长。PagedAttention论文以OPT-13B、FP16举例,每个token约需800KB,2048个token就要约1.6GB。这也是为什么如今大家普遍采用GQA、MQA等技术来压缩这部分开销。
PagedAttention:借鉴操作系统分页的显存管理机制
早期做法是给每条序列预留一整块连续显存,但输出多长根本无法提前知道,结果造成内部浪费和大量外部碎片。
PagedAttention的思路直接照搬了操作系统的分页模型:逻辑上的KV(L0、L1、L2、L3)看起来是连续的,但底层的Block Table可以把它们映射到离散的物理块上。

PagedAttention的两大核心能力
第一,按固定大小的块逐步分配,不用为碎片化预留空间。第二,多条共享前缀的序列,Block Table可以指向同一批物理块,用引用计数管理生命周期。比如序列A和B共用某些物理块,读取时无需复制;只有其中一条要修改共享块时,系统才通过 Copy-on-Write 重新分配新块。
需要强调:PagedAttention首先是KV内存管理机制,Prefix Cache是另一层的事情。
缓存命中条件:不只是文字相同
一个容易踩坑的地方在于——两份文档你肉眼看着一样,并不能证明缓存可以复用。
设想三条请求:A和B从system到doc的token序列完全一致,这段状态可以共享;而C虽然带着同一份doc,但doc前面换成了另一段context。由于Transformer中当前位置的隐藏状态取决于它前面的token,还受位置编码影响,所以C算出的KV跟A、B已完全不同。
影响计算身份的多个维度
生产环境的匹配还要看很多维度:Tokenizer、Chat Template、模型和权重版本、原始多模态输入等,这些共同构成"计算身份"。自托管引擎一般按token ID加身份信息匹配,托管API通常要求序列化后的前缀保持一致。
一句话概括命中标准:完全相同的token前缀 + 完全相同的计算身份。
前缀哈希与RadixTree:vLLM和SGLang的两种复用实现
vLLM的Automatic Prefix Caching用的是跨块哈希链:先把token切成固定大小的block,第一块的哈希由自身token加额外信息算出,第二块要带上第一块的哈希,形成一条链。一个块只有在它前面所有内容也一致时,才拿得到可复用身份。截至vLLM 0.11版本,默认采用SHA-256降低碰撞和信息泄露风险,但它替代不了租户隔离——该隔离时仍需靠不可预测的salt或物理隔离。空闲缓存进入LRU,直到显存紧张才从队尾剔除。
SGLang的RadixAttention则把prompt和生成结果对应的KV组织成一颗 RadixTree:多轮对话场景下,公共前缀在最上层,消息开始不一样时路径自然分叉。新请求进来沿树查找最长匹配前缀。论文数据显示,在无前缀复用的负载下,这套结构额外开销低于0.3%(特定实验条件下)。
Prompt Cache失效的五大原因及排查方法
缓存不生效往往有几个瓶颈:

- 共享前缀不够长:太短可能达不到托管模型的最低缓存token门槛,海外厂商普遍要上千token,DeepSeek的缓存块相对小一些。
- 计算身份不一致:时间戳、Request ID、JSON键序列、Tokenizer、Chat Template、模型版本,任何一个变化,命中就在变化点提前结束。
- 缓存已被驱逐:TTL到期、LRU驱逐、显存紧张,都会让热路径变回冷路径。
- 路由未命中:请求没被路由到持有缓存的那台机器,一样要重算。
- Decode占大头:输出很长时Decode占主导,前缀命中对端到端提速有限。
因此排查时,缓存读写、未缓存输入token、命中/未命中的TTFT、路由目标、Decode占比需要一起记录,而不是只看单一请求的命中率。
Agent工程实践:如何组织稳定的缓存上下文
工具型Agent天然是一个循环,天然对缓存友好——只要旧内容的token序列稳定,上一轮绝大部分都能进入下一轮缓存前缀,只有新的Tool Result需要重新Prefill。
稳定性光谱:越稳定的内容越靠前
设计prompt时,把所有内容排到一条稳定性光谱上:
- 最前面:工具定义、系统规则、固定Few-shot(基本不变)
- 中间:知识库快照(按版本变化)
- 最后:对话历史、实时检索结果、Tool Result、用户问题(变化最快)

出问题的基本都在应用层的"顺手改写":有人把当前时间、随机Request ID插到开头,有人动态增删工具,有人让JSON Serializer自己决定Schema顺序——看着只改了几行,后面很长一段缓存全废。更合适的做法是追加成新消息,工具集合和模板按版本切换。
缓存共享的安全与隔离取舍
缓存共享还带来隐私风险:时间差是可观察的,攻击者若能反复猜测某段敏感前缀是否有更低TTFT,就可能推断内容是否被别人用过。vLLM支持把cache salt混进第一个块的哈希,并建议用不可预测的256位随机值,而非用户名或账号ID。隔离越细,跨用户共享率越低——这是一个需要显式接受的权衡。
总结:Prompt Cache的落地决策框架
Prompt Cache的价值在于安全地跳过重复的Prefill,但它伴随显存、写入、驱逐、路由、版本和隐私成本。是否值得缓存,取决于三个问题:共享前缀是否够长、复用次数能否覆盖成本、是否跨越了系列边界(跨边界时需先做命名空间和租户隔离)。
落地顺序也很清晰:先测量,再重排,再定义身份和隔离范围,上线后持续测试。没必要硬缓存每一个请求。
理解Prompt Cache的底层实现,不仅能帮你读懂大模型账单,更能指导Agent系统的上下文组织——让每一次生命周期里的旧前缀可预测地稳定复用,而不是放任不治理。
相关推荐

Treebar:Mac菜单栏管理Git工作树,一眼掌控所有AI编程Agent
Treebar是一款macOS菜单栏应用,专为AI编程多工作树场景设计。它将所有Git Worktree状态统一展示在MacBook刘海区域,让开发者实时监控Codex等AI Agent的工作进度,无需切换终端即可掌握全局。即将开源核心代码。

苹果确认Hide My Email域名永久保留,用户隐私获长期保障
苹果公司公开承诺iCloud+ Hide My Email功能使用的@icloud.com域名将永久保留,不会弃用或迁移。本文解析域名稳定性对邮箱转发隐私工具的关键意义,以及对用户账户安全的底层保障。

终端正在拖慢你:多任务时代的效率反思
终端是程序员的信仰工具,但在多任务并行的现代开发场景中,它的线性设计正在成为效率瓶颈。本文分析终端的心智负担模型为何在第六个任务时崩溃,以及开发者该如何重新评估工具选择。