一文说清大模型缓存命中机制,同样的token,命中和未命中价格相差120倍!不懂KV Cache的人,每个月都在白烧钱
公众号名称:sudden的AI日常
作者名称:是sudden哦
发布时间:2026-06-03 20:02
之前写了一篇LLM-Wiki逻辑优化的长文,提到了在LLM-Wiki实现过程中,使用DeepSeek-V4的token消耗,因为 KV Cache 缓存命中率高达90%而省下了不少费用,

收到了不少后台私信:
能不能讲讲 KV Cache 原理,以及提高缓存命中率的方法
OK!这篇文章就讲这些,开始啦~~❥(^_-)

TL;DR(本文摘要)
什么是 KV Cache 缓存命中?
为什么缓存命中的token更便宜?
影响缓存命中率的因素
如何提高缓存命中率,从而省钱

往期推荐
深度解析:Karpathy 的 LLM Wiki 隐藏陷阱,高效构建个人知识库(附最佳实践建议)
我用Andrej Karpathy的LLM wiki思路实现了“活”的个人知识库(附模板)
智能体搭建| 如何用OpenClaw搭建你的“一人公司”(附完整配置模板)
01
什么是 KV Cache 缓存命中?

2017年,Google扔下一颗炸弹
要讲清楚缓存命中,得先回到2017年,那一年,Google的研究团队发表了一篇论文,标题叫《Attention Is All You Need》[arXiv:1706.03762]

在这之前,AI处理语言用的是RNN(循环神经网络),你可以把RNN想象成一个逐字读书的人,必须一个字一个字挨着读,读完上一个才能读下一个,
这种方式有两个明显的问题:
-
第一,慢
-
第二,读太长的东西会健忘,前面的内容读到后面就记不住了(于是又出现了LSTM长短时记忆网络等技术)
这篇论文的核心创新,是提出了一个全新的架构,Transformer(想必如今大家已不陌生),彻底改变了AI处理语言的方式(逐字读),
让模型一眼看完所有字,再决定重点关注哪些字,这种机制就叫”注意力”(Attention)
这篇论文的影响力有多大呢?
今天几乎所有主流大模型,包括GPT系列、Claude、DeepSeek,底层都是Transformer架构,可以说,没有这篇论文,就没有今天的AI浪潮。
Transformer架构如下,篇幅限制,本文不详细讲了,


那什么是 KV Cache
注意力机制里有三个核心概念,Query(查询)、Key(键)、Value(值),就是我们常听到的QKV,KV Cache就是这个KV。
别被术语吓到,我们先讲一个查字典的故事,想象你手里有一本中文字典,你想查”猫”这个字的意思,
-
Query,就是你要查的那个词。在这个例子中,Query就是”猫”
-
Key,就是字典里的索引系统。拼音索引里”猫”在”M”下面,部首索引里”猫”在”犭”下面。这些索引就是Key
-
Value,就是你最终要找到的内容。翻开字典,“猫”的解释、例句、用法,这些就是Value
所以整个过程是这样的:你带着Query(“猫”),去匹配Key(拼音/部首索引),最后拿到Value(释义内容)
这不就是咱们小时候领到新华字典后,老师教咱们查字典的过程。
大模型每次回答你的问题,本质上就是在做这件事,把你的问题转成Query,然后去匹配它记忆里存好的Key,找到对应的Value,再组织成回答给你。

Transformer的注意力机制,比查一本字典更复杂,它更像是同时翻开好几本参考书,每本都给出一个答案,然后加权综合出一个最终答案。
当你问AI一个问题时,Query来自你的新问题,Key和Value来自之前所有的上下文,包括系统提示词、对话历史、你发的文档,全部都已经算好并存好了,
AI做的事情就是用你新问题的Query,去和之前所有上下文存好的Key做匹配,找出最相关的那些Value,然后综合起来生成回答。
这个过程就是一次”注意力计算”

回到本文的核心概念:KV Cache
前面说过,每次回答问题时,AI需要用你的Query去匹配之前所有上下文的Key和Value,如果每次都从头重新计算所有Key和Value,那计算量会非常巨大,尤其是在多轮对话中,上下文越来越长,计算成本指数级增长。
KV Cache的解决思路非常直观,把之前已经算好的Key和Value存起来,下次直接用,不用重新算。
还是用查字典的类比,KV Cache就是你查过的字典页,撕下来贴在了墙上,下次再遇到同一个字(Query),直接从墙上看,不用重新翻书。
那么,
-
缓存命中,就是墙上已经有这页了,直接看就行
-
缓存未命中,就是墙上没有这页,得重新翻开字典查一遍
哪个更省力已经很直观了。
另外,这里有一个细节值得注意,为什么叫KV Cache,不叫Q Cache?
因为Query每次都变(你的每个新问题都是不同的Query),但Key和Value可以复用(之前已经处理过的上下文,Key和Value已经算好了),所以只需要缓存Key和Value,不需要缓存Query。
02
为什么缓存命中的token更便宜
这是DeepSeek V4官方定价,缓存未命中的价格是缓存命中的120倍!

这是小米MIMo V2.5官方定价,同样地,缓存未命中的价格是缓存命中的120倍!


为什么?
大模型API的定价,本质上是对算力成本的标价,
而大模型最耗算力的环节,就是刚才我们讲的注意力计算过程(用Query去匹配Key再取出Value的那个过程),每次重新计算Key和Value,都需要大量的矩阵乘法。
缓存命中的情况下,模型只需要做两件事,
第一,把你的新问题转成Query
第二,用Query去和已经存好的Key做匹配(查表),取出对应的Value
这两个操作的计算量,比重新计算所有Key和Value小得多,所以原因就一句话,
重复利用已经算好的东西,比从头重新算要便宜得多

图解QKV注意力计算过程
这一部分给想深究的同学看,其它同学可以直接跳过,不影响后文理解。
我们再用稍微专业一点的角度简单讲讲,QKV的计算过程,搞懂这个过程,你对大模型会有深层次的理解。
下图是对第一个位置”Thinking”输入计算Self Attention 的全过程,

现在有两个输入,“Thinking”和”Machines”,我们的任务是去计算”Thinking”的下一个词是什么
第一步,Embedding。 每个词先被转成数字向量,就是图里的x₁(Thinking)和x₂(Machines)
第二步,生成Q、K、V。 每个词同时产出三个向量:Query(紫色q)代表”我想问什么”,Key(橙色k)代表”我有什么信息”,Value(蓝色v)代表”信息的内容是什么”
第三步,算注意力分数。 拿”Thinking”的Query(q₁)去分别和”Thinking”的Key(k₁)、“Machines”的Key(k₂)做点积,得到112和96,分数越高说明关联越强
第四步,缩放和Softmax。 把分数归一化,得到两个权重0.88和0.12,意思是”Thinking”这个词和自身关联度88%,和”Machines”只有12%
第五步,加权求和。 把两个Value按权重相加(v₁×0.88 + v₂×0.12),得到z₁,这就是”Thinking”经过注意力机制后的最终表示
整个过程中,Query每次都变,但Key和Value一旦算好就可以复用,这就是KV Cache能省钱的原理,Key和Value不用重复算。
已经看到这里啦,如果觉得不错,随手点个关注、点赞、转发吧~
如果想第一时间收到推送,可以给我个星标⭐哦~
你们的支持和鼓励,是我持续更新的最大动力 ❥(^_-)

03
影响缓存命中率的因素

命中率是怎么算的
缓存命中率=命中token数/总输入token数
举个例子,你给模型发了一次请求,总共1000个token,
其中800个是之前请求里已经出现过的内容(比如系统提示词、对话历史),这800个走缓存命中价,
剩下200个是你这次新问的内容,走缓存未命中价,
那么你的缓存命中率就是80%,
大部分API服务商都会在用量统计里显示这个数字,另外,大部分智能体都支持一个指令查看缓存命中情况。
在Claude Code中直接输入/usage即可查看,
我这里让CC读了个md文档,用量如下,缓存命中率非常高(29.7/30.6=97%)


什么情况下命中率高
影响缓存命中率的因素,主要有这么几个,
第一,系统提示词的稳定性
系统提示词是每次请求都会自动带上的一段”背景设定”。它告诉模型”你是谁”、“你能做什么”、“你要遵守什么规则”等等(如Claude Code的claude.md,Openclaw的agent.md)
在智能体框架里(如Claude Code、Codex、Openclaw、Hermes),系统提示词通常还包括工具列表、skill描述、工作区规则等大量内容,这部分内容几乎每次请求都一样,所以命中率接近100%,也就是说系统提示词越长、越固定,你的基础命中率就越高(但不是系统提示词越长越好)
第二,多轮对话中的前文重复度
你和AI的聊天记录,包括你的提问、它的回答、工具调用记录,全部都在上下文里。
后续追问时,前面的内容可以复用,这部分也会命中缓存,所以同一会话里聊得越久,累计可复用的上下文越多,命中率越容易拉高。
第三,长文档和RAG上下文的复用
如果你一次性把一份长文档发给模型,然后基于这份文档连续问多个问题,那么这份文档的token在第一次之后全部是缓存命中,反过来,如果你把同一份文档分多次发送,每次只发一部分,那么每次发送的新部分都是未命中。
第四,注意,图片内容没有缓存
这是很多人踩过的坑,图片没有KV缓存机制,每次你发一张图,模型都要重新对图片做编码计算,无法复用之前的计算结果。
高清图的分辨率高,视觉token消耗指数级增长,也就是说,一张高清长截图,可能比连续聊半小时还烧钱。
我之前就遇到过这种情况:用OpenClaw接千问3.5,让AI识别并总结一张手机截图的内容,一个任务花掉了40万token……


一个有意思的发现
智能体框架对命中率的影响
这里有一个很有意思的发现:同样的DeepSeek-V4模型,放在不同的工具里用,缓存命中率天差地别。
Claude Code里接DeepSeek-V4,缓存命中率能做到95%以上。而DeepSeek-TUI(一个轻量级的TUI客户端,现在改名叫CodeWhale了)里用同一个模型,命中率可能只有80%左右。
CC+DS V4的缓存命中 ↓
=439/453=96.9%

DeepSeek-TUI+DS V4的缓存命中 ↓
=291/354=82%

为什么会有这么大差距?
核心原因就是刚才提到的第一点,系统提示词
Claude Code每次请求都会注入大量系统内容:工具定义、skill描述、工作区规则、当前目录结构、shell状态等等,这些内容加起来可能有上万token,而且每次请求几乎一模一样,几乎100%命中,系统提示词这个”固定分母”足够大,把整体命中率拉得很高。
DeepSeek-TUI是一个相对简单的命令行客户端,系统提示词很短,可能只有几百token,大部分输入都是用户新打的内容,这些内容每次都不一样,自然很难命中缓存。
本质上说,智能体框架的”固定上下文占比”决定了命中率的基础水平,固定部分越多、越稳定,命中率越高,
这也意味着,如果你用的是功能丰富的智能体框架(Claude Code、OpenClaw、Codex),你的基础命中率天然就高,省钱空间更大。
04
如何提高缓存命中率,从而省钱

命中率越高越好吗?
一般来说是的,命中率越高,走低价token的比例越高,总花费自然越低。
但要注意一个误区,不要为了命中率而命中率
命中率高,本质上意味着你在重复发送相似的内容,如果你每次的任务都完全不同,比如每次都发给模型全新的文档、全新的代码库,那命中率低是正常的,这不是问题,是任务特性决定的。
正确的思路是,让”必须重复的部分”尽可能命中,同时减少”不该重复的部分”,
-
系统提示词、对话历史、长期参考文档,这些是应该命中的
-
无关的工具输出、重复发送的图片、临时性的中间数据,这些是不该重复占缓存的
优化的方向是增加前者,减少后者,而不是盲目追求一个数字

亲测有效的高缓存命中技巧
Claude Code里的缓存策略
Claude Code的系统提示词很长,工具定义、skill描述、workspace规则等内容每次请求都重复发送,它的基础命中率天然就高,在这个基础上,有几个实用的技巧可以进一步拉高命中率,
-
保持同一会话不频繁重启。 Claude Code的缓存是按会话维护的,如果你在同一个项目里连续工作,系统提示词和对话历史都保持在缓存里,后续请求大部分都能命中,频繁重启会话或切换项目,会把缓存清空,需要重新预热
-
在同一个workspace里集中处理相关任务。 不要把不相关的任务拆成多个独立的短会话,任务之间有上下文关联时,共用同一个会话,前文可以被后续请求复用
Codex里的缓存策略
Codex的逻辑和Claude Code类似,同样有大量的系统注入内容,工具定义、workspace规则、文件树状态等,每次请求都带,天然有高命中率的基础,
-
在同一个workspace里连续工作。 Codex的缓存是按workspace隔离的,在同一个workspace里连续修改文件、执行命令,系统提示词和项目上下文保持在缓存里,命中率高,频繁切换workspace会清空缓存
-
长文件修改时,一次性提供完整上下文。 如果你要让Codex修改一个长文件,尽量在一次请求里提供完整的修改需求和参考代码,不要分多次请求,每次新请求增加的内容都是未命中,一次性搞定能减少未命中的token数。
OpenClaw里的缓存策略
OpenClaw提供了更细粒度的缓存控制,适合做多智能体管理,
-
稳住系统提示词。 系统提示词每次请求都发,是最稳定的缓存来源,不要把system prompt改来改去,保持固定能让这部分长期命中,Skill列表也是会注入到系统提示词里的,没用的Skill删掉,留着的描述尽量写短
-
心跳保持缓存预热。 服务商的提示词缓存有过期时间(TTL),过了期就没用了,把心跳间隔设成比TTL略短(比如缓存TTL是1小时,心跳设成55分钟),快过期的时候自动发一个低成本请求”唤醒”缓存,保持缓存一直是热的,对长会话效果尤其明显
-
分智能体设缓存策略。 不同智能体干的活不一样,缓存策略也应该不一样
-
做深度研究的Research Agent,可以开长缓存,配心跳预热,保持长期命中。发通知的Alert Agent,每次请求都是独立的,直接关缓存就行,没必要浪费缓存写入的钱。
下面是我自己用的配置参考,编辑 ~/.openclaw/openclaw.json:
{
"agents": {
"defaults": {
"model": {
"primary": "volcengine-plan/doubao-seed-2.0-pro"
},
"models": {
"volcengine-plan/doubao-seed-2.0-pro": {
"params": {
"cacheRetention": "long"
}
}
},
"heartbeat": {
"every": "55m"
}
},
"list": [
{
"id": "research",
"default": true,
"heartbeat": {
"every": "55m"
}
},
{
"id": "alerts",
"params": {
"cacheRetention": "none"
}
}
]
}
}

最后再放几个容易踩的坑
-
频繁切换模型。 不同模型的缓存是不互通的,你今天用DeepSeek-V4聊了一半,明天切到GPT-5.5,再切回DeepSeek-V4,之前积累的缓存全废了,需要重新算。
-
工具调用返回大量无用数据。 你以为模型只是”调用一下工具”,实际上工具的输入和输出全部会塞回上下文,如果工具返回了一大段你用不上的内容,这些内容会占缓存窗口,可能把真正该命中的内容挤出去了,因此读文件时只取你需要的那部分,不要一上来就把整个项目的代码全读进来。
-
图片任务。 再次强调,图片没有KV缓存,每次发图都要重新编码,高清截图特别贵,分辨率越高,视觉token消耗指数级增长,发图之前想想,真的需要这么高的分辨率吗?
以上~
已经看到这里啦,如果觉得不错,随手点个关注、点赞、转发吧~
如果想第一时间收到推送,可以给我个星标⭐哦~
你们的支持和鼓励,是我持续更新的最大动力 ❥(^_-)

往期推荐
零经验 Vibe Coding 指南:编程小白也能做出自己的 AI 产品(万字长文拆解)
国内也能用!Claude Code高效部署+多模型切换教程来了
内容效果不满意?点此反馈