Clipping 微信公众号

一文说清大模型缓存命中机制,同样的token,命中和未命中价格相差120倍!不懂KV Cache的人,每个月都在白烧钱

by 是sudden哦 原文 ↗
Created: 2026-07-03

公众号名称:sudden的AI日常

作者名称:是sudden哦

发布时间:2026-06-03 20:02

之前写了一篇LLM-Wiki逻辑优化的长文,提到了在LLM-Wiki实现过程中,使用DeepSeek-V4的token消耗,因为 KV Cache 缓存命中率高达90%而省下了不少费用,

收到了不少后台私信:

能不能讲讲 KV Cache 原理,以及提高缓存命中率的方法

OK!这篇文章就讲这些,开始啦~~❥(^_-)

TL;DR(本文摘要)

  1. 什么是 KV Cache 缓存命中?

  2. 为什么缓存命中的token更便宜?

  3. 影响缓存命中率的因素

  4. 如何提高缓存命中率,从而省钱

往期推荐

深度解析:Karpathy 的 LLM Wiki 隐藏陷阱,高效构建个人知识库(附最佳实践建议)

我用Andrej Karpathy的LLM wiki思路实现了“活”的个人知识库(附模板)

智能体搭建| 如何用OpenClaw搭建你的“一人公司”(附完整配置模板)

国内也能用!Claude Code高效部署+多模型切换教程来了

零经验 Vibe Coding 指南:编程小白也能做出自己的 AI 产品(万字长文拆解)

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高效部署+多模型切换教程来了

深度解析:Karpathy 的 LLM Wiki 隐藏陷阱,高效构建个人知识库(附最佳实践建议)

你一定用得上的智能体skills推荐,主流技能市场盘点

深度拆解Token消耗逻辑,OpenClaw/Hermes/Claude省钱攻略大公开!


内容效果不满意?点此反馈

输入关键词开始搜索