架构层:KV Cache 的注意事项
前缀匹配最高省 90%;动态切换工具为什么把缓存全打穿,滑动窗口 vs 章节缓存
本页解决的问题
先给结论「架构层:KV Cache 的注意事项」要解决的关键问题是什么?
前缀匹配最高省 90%;动态切换工具为什么把缓存全打穿,滑动窗口 vs 章节缓存
把成本看成形状,不是一个数字。 把一次请求拆成输入、输出、重试、工具和等待时间。使用量的形状,通常能告诉你是哪项设计选择最贵、哪里值得先改。
优化想象中的平均值之前,先测一次真实请求。
调用便宜了,却悄悄增加了重试、延迟或人工复核。
大模型的本质是「Token 推 Token」:它不关心你问的是什么问题,只关心前文是什么。这意味着——如果两次请求的前缀相同,模型其实在重复计算同样的内容。KV Cache 就是把算过的中间结果存下来,下次遇到相同前缀直接复用:用廉价的存储换昂贵的实时计算,「空间换时间」。
举个例子:你问「2 + 4 = ?」,它算出 6。再问「3 + 4 = ?」,前缀变了,只能从头算。但如果问的是「2 + 4 + 1 = ?」——前缀「2 + 4」没变,模型直接从 6 开始算出 7。只要前缀不变,缓存就能命中。DeepSeek、Qwen、智谱都支持这个能力(回看第 3 节报价表:缓存价只有标准价的 1/5),这是作者挑选大模型 API 时必看的一项。
上一次请求已经缓存了完整前缀。点下面三种「这一次的请求」,看命中(绿)和重算(红)的部分。
看起来省 Token,实际是大坑
有些产品为了极致省钱,根据用户意图动态挂载工具:问天气挂 WeatherTool,闲聊就不挂。问题出在大模型后端的模板逻辑——以 Qwen 3 为例,只要请求带了 tools 参数,服务器就会在 System Prompt 后面插入一段工具说明;如果你没写 System Prompt,模板还会自动帮你加一个再插。工具状态一变(从有到无、从 A 换成 B),Prompt 头部前缀就变了,之前缓存的几十万 Token 瞬间灰飞烟灭。
推荐操作:System Prompt 保持不变 + 不用 tools 字段;或者宁可浪费点 Token,把全量工具定义一直挂着,也要保住缓存命中。System Prompt 的稳定性,比省那点 Token 重要得多。
多轮对话和长文本场景,很多产品用「滑动窗口」处理超长历史——只保留最近 N 轮,旧的直接丢。这是偷懒,而且会出问题。滑动窗口的本质是 FIFO 队列:每滚动一次,前缀就变一次,缓存永远命不中。
作者的产品「伴写」(用前文生成后文)早期就是固定 800 字滚动窗口,又贵又容易「失忆」。后来改成章节缓存:AI 生成时识别到话题转换(场景切换、新章节)就插入分隔标记,系统据此判断哪些内容压缩成摘要、哪些完整保留——与其让 AI 自己有损压缩,不如让前缀尽量稳定,命中缓存。
| 指标 | 旧方案(滑动窗口) | 新方案(章节缓存) |
|---|---|---|
| KV Cache 命中率 | ~10%(前缀总在变) | ~80%(前缀稳定) |
| 逻辑连贯性 | 差(经常失忆) | 好(摘要 + 完整章节) |
| Token 成本 | 高(重复计算) | 低(缓存复用) |
| 问题 | 设计决策 |
|---|---|
| 哪些信息必须「恒久保留」? | 放入 Stable 区,作为缓存前缀 |
| 哪些信息可以「压缩存档」? | 用摘要替代原文,控制窗口大小 |
| 哪些信息需要「按需加载」? | 按章节 / 话题切分,动态挂载 |
| 如何识别「可压缩边界」? | 设计分隔符机制,让 AI 标记话题转换点 |
前缀不变,缓存命中,最高省 90%。选 API 时「支不支持上下文缓存」是必看项。
别动态切换 tools:工具状态一变,模板重写 System Prompt,缓存全打穿。宁可全量挂着。
滑动窗口是缓存杀手:用「Stable 前缀 + 摘要存档 + 章节挂载」代替,命中率 10% → 80%。
内容来源:整理自作者团队内部分享《AI Token 降本增效策略分享》实战篇「03|架构层」。DeepSeek 的硬盘缓存定价见官方公告;「Token 推 Token」的原理复习大模型原理 · Base 模型。
「什么是 KV Cache:前缀匹配」的完整成本怎么算
「大模型的本质是「Token 推 Token」:它不关心你问的是什么问题,只关心前文是什么。这意味着—— 如果两次请求的前缀相同,模型其实在重复计算同样的内容 。KV Cache 就是把算过的中间结果存下来,下次遇到相同前缀直接复用:用廉价的存储换昂贵的实时计算,「空间换时间」」提醒我们,AI 成本不是单价乘一次调用这么简单。输入、输出、重试、工具调用、等待时间和人工收尾,会共同决定一次任务到底贵不贵。
先找出账单里不断重复的部分
「举个例子:你问「2 + 4 = ?」,它算出 6。再问「3 + 4 = ?」,前缀变了,只能从头算。但如果问的是「2 + 4 + 1 = ?」——前缀「2 + 4」没变,模型直接从 6 开始算出 7。」对应的关键变量通常是上下文是否每轮重复发送、输出是否过长、失败是否触发重试,以及每次调用是否真的带来有用结果。减少无效 Token 往往同时降低费用、延迟和并发压力。
便宜的单次调用可能换来更贵的全流程
以「滑动窗口是缓存杀手: 用「Stable 前缀 + 摘要存档 + 章节挂载」代替,命中率 10% → 80%」为起点做一张小表:输入、输出、重试、工具和人工复核分别花了什么,再比较优化前后的质量,避免只看某一项价格。
从「什么是 KV Cache:前缀匹配」走到「交互演示 · 哪些 Token 命中了缓存」
「什么是 KV Cache:前缀匹配」先把问题落在「大模型的本质是「Token 推 Token」:它不关心你问的是什么问题,只关心前文是什么。这意味着—— 如果两次请求的前缀相同,模型其实在重复计算同样的内容 。KV Cache 就是把算过的中间结果存下来,下次遇到相同前缀直接复用:用廉价的存储换昂贵的实时计算,「空间换时间」」上;到了「交互演示 · 哪些 Token 命中了缓存」,讨论继续推进到「上一次请求已经缓存了完整前缀。点下面三种「这一次的请求」,看命中(绿)和重算(红)的部分」。两段连起来,重点就不只是记住一个结论,而是看清它成立所依赖的条件。
把这条判断带到下一个场景
分析成本时,先画出完整交互,再找每轮重复的输入、无效输出和失败重试;单次调用便宜,并不代表整个任务便宜。
- 「什么是 KV Cache:前缀匹配」:大模型的本质是「Token 推 Token」:它不关心你问的是什么问题,只关心前文是什么。这意味着—— 如果两次请求的前缀相同,模型其实在重复计算同样的内容 。KV Cache 就是把算过的中间结果存下来,下次遇到相同前缀直接复用:用廉价的存储换昂贵的实时计算,「空间换时间」
- 「交互演示 · 哪些 Token 命中了缓存」:上一次请求已经缓存了完整前缀。点下面三种「这一次的请求」,看命中(绿)和重算(红)的部分
- 「最后的要点」:作者的产品「伴写」(用前文生成后文)早期就是固定 800 字滚动窗口,又贵又容易「失忆」。后来改成 章节缓存 :AI 生成时识别到话题转换(场景切换、新章节)就插入分隔标记,系统据此判断哪些内容压缩成摘要、哪些完整保留——与其让 AI 自己有损压缩,不如让前缀尽量稳定,命中缓存
最后的「最后的要点」把讨论落到「作者的产品「伴写」(用前文生成后文)早期就是固定 800 字滚动窗口,又贵又容易「失忆」。后来改成 章节缓存 :AI 生成时识别到话题转换(场景切换、新章节)就插入分隔标记,系统据此判断哪些内容压缩成摘要、哪些完整保留——与其让 AI 自己有损压缩,不如让前缀尽量稳定,命中缓存」。回看这条线索时,最值得保留的是:当输入、规模或风险改变,哪些判断需要重新做一遍。
我把这篇文章里的一个判断改写成了今天可以验证的小实验。比记住结论更有用的是,知道下一步要观察什么。
读完以后我先回头找它成立的条件,而不是直接把方法搬进项目。这个顺序让后面的取舍清楚很多。
如果把这个判断放到真实工作里,最先需要补的约束是什么?我想知道从阅读到第一次实践之间,哪一步最值得先做。
还没有这篇文章的讨论。