编程基础篇 · AI 背后的数据结构

缓存:AI 账单的隐形折扣

KV Cache 和语义缓存都是同一招:算过的别再算。拖动命中率滑块实时看账单变化——Harness 核心篇成本优化的底层原理

本页解决的问题

先给结论

「缓存:AI 账单的隐形折扣」要解决的关键问题是什么?

KV Cache 和语义缓存都是同一招:算过的别再算。拖动命中率滑块实时看账单变化——Harness 核心篇成本优化的底层原理

判断标准

让这个结论先证明自己值得留下。 把这一页当成决策工具,而不是需要背下来的定义。把概念连到一个真实任务、一个可观察结果,以及一个能改变你判断的失败上。

下一步

写下一个问题:试完这个方法后,你能用什么证据回答它?

常见误区

结论听起来很完整,却没有检查最关键的假设。

先想一个日常场景

你算过一次「37 × 89 = 3293」,第二天有人又问你 37 × 89 等于几——你会重新列竖式吗?不会,你直接报答案。缓存就是电脑的这种「直接报答案」:把算过的结果按 key 存进上一课的哈希表,下次遇到同样的 key,一步直达取结果。哈希表管「存哪、怎么找」,缓存管「什么值得存」。两课合起来才是完整的「空间换时间」。

交互 1 · KV Cache:同一段开头别算两遍

大模型每生成一个字,都要「回头看」前面所有 token,给每个 token 算一份注意力的中间结果。关键在于:只要前缀一模一样,这些中间结果就一模一样——那第二轮对话还重算它干嘛?下面每个小方块是一个 token,先点「播放第一轮」,再点「播放第二轮」。留意第二轮里绿色方块出现的速度:它们没有被计算,是直接从缓存取的。

正在计算(烧算力) 本轮算过 缓存命中,免算 还没轮到
第一轮对话
系统提示词 + 问题①,每个 token 都要从零计算
第二轮对话
前缀(系统提示词 + 第一轮全部内容)一字没变
先播第一轮,看每个 token 逐个点亮计算
第二轮的计算量对比(方块数 = 要算的 token 数)
没有 KV Cache
0 个 token
有 KV Cache
0 个 token
KV Cache 缓存的是「算过的注意力中间结果」(每个 token 的 Key 和 Value,名字就是这么来的),不是缓存答案本身。对话每多一轮,前缀就更长、省得就更多——真实场景里系统提示词动辄几千 token,轮轮重算等于轮轮全价买单。模型厂商价格表上「缓存命中的输入 token 打一折」,指的正是这些绿色方块。
一个立刻能用的验收直觉:KV Cache 只认「前缀一模一样」。如果你的应用每轮都把系统提示词改一个字(比如把当前时间拼在最前面),缓存就轮轮失效,账单直接翻几倍。把会变的内容放到提示词末尾、固定内容放开头——这是花一分钟就能省一大笔的架构习惯。
交互 2 · 语义缓存的账单

KV Cache 省的是「同一段开头」,还有一种更狠的:同样的问题,答案整个都别再算。客服机器人每天被问 1 万次「怎么退货」,问法五花八门但意思相同——把「意思」当 key(用向量相似度判断,第十课细讲),命中就直接返回存好的答案,一次模型调用都不用发。拖动命中率滑块,留意月账单的变化。

场景:客服机器人每天 10,000 次提问,每次调用大模型约 0.02 元,一个月 30 天。命中缓存的提问直接返回存好的答案,不产生调用费
0%
这个月要付
¥6,000
每天 10,000 次全部真实调用
缓存帮你省下
¥0
这就是Harness 核心篇讲过的语义缓存策略在省钱

⚠️ 但是——退货政策改了怎么办?

缓存里还躺着按旧政策生成的标准答案,机器人会一本正经地拿它继续回答十天半个月,比不缓存错得更稳定、更理直气壮。所以工程师常说:缓存最难的不是存,是知道什么时候作废(术语叫「缓存失效」,计算机科学两大难题之一)。常见做法:给缓存设个保质期(比如 24 小时过期)、或者政策一更新就主动清掉相关条目。设计任何缓存前先想好这一步,否则省下的钱会用客诉还回来。

它在 AI 世界的真身

「算过的别再算」这一招无处不在,下面四个你天天在享受的东西,本质上是同一个结构。

🧠

KV Cache

大模型推理的标配:前缀 token 的注意力中间结果只算一次。没有它,长对话根本跑不动

💬

语义缓存

把「问题的意思」当 key,相似提问直接复用答案。高频客服场景能砍掉一大半调用费。

🌐

浏览器缓存

图片、样式文件下载一次就存本地,第二次打开网页秒开——你刷网页快,一半功劳是它的。

🗺

CDN

把内容提前存到离你最近的机房,全国用户都像访问本地服务器。缓存 + 地理位置,还是那一招。

「先想一个日常场景」为什么要看操作

「你算过一次「37 × 89 = 3293」,第二天有人又问你 37 × 89 等于几——你会重新列竖式吗?不会,你直接报答案。」把结构落到了一个具体动作。这里真正要比较的不是名词谁更高级,而是数据如何被放置,以及最常发生的操作需要走多远。

读懂结构,要同时看访问方式和变化方式

「大模型每生成一个字,都要「回头看」前面所有 token,给每个 token 算一份注意力的中间结果。关键在于: 只要前缀一模一样,这些中间结果就一模一样 ——那第二轮对话还重算它干嘛?下面每个小方块是一个 token,先点「播放第一轮」,再点「播放第二轮」。」揭示了一个容易被忽略的取舍:按位置读取、按键查找、从两端进出、插入新元素和遍历关系,适合的组织方式并不相同。一个结构在某个操作上很快,不代表它在所有操作上都快。

  • 缓存 = 算过的别再算 :结果按 key 存进哈希表,下次直达取——上一课的结构在这一课开始赚钱
  • KV Cache 认前缀 :固定内容放提示词开头、会变的放末尾,缓存命中率直接决定账单
  • 语义缓存更狠 :意思相同的提问连模型都不调,高频场景省钱效果按命中率线性放大

把规模和更新频率一起算进去

实践时可以把「把内容提前存到离你最近的机房,全国用户都像访问本地服务器。」当作边界提醒:先写下数据量、最常用的操作和允许的延迟,再看 AI 给出的结构是否真的匹配。

从「先想一个日常场景」走到「交互 1 · KV Cache:同一段开头别算两遍」

「先想一个日常场景」先把问题落在「你算过一次「37 × 89 = 3293」,第二天有人又问你 37 × 89 等于几——你会重新列竖式吗?不会,你直接报答案。 缓存就是电脑的这种「直接报答案」 :把算过的结果按 key 存进上一课的哈希表,下次遇到同样的 key,一步直达取结果。哈希表管「存哪、怎么找」,缓存管「什么值得存」。两课合起来才是完整的「空间换时间」」上;到了「交互 1 · KV Cache:同一段开头别算两遍」,讨论继续推进到「大模型每生成一个字,都要「回头看」前面所有 token,给每个 token 算一份注意力的中间结果。关键在于: 只要前缀一模一样,这些中间结果就一模一样 ——那第二轮对话还重算它干嘛?下面每个小方块是一个 token,先点「播放第一轮」,再点「播放第二轮」。 留意 第二轮里绿色方块出现的速度:它们没有被计算,是直接从缓存取的」。两段连起来,重点就不只是记住一个结论,而是看清它成立所依赖的条件。

把这条判断带到下一个场景

遇到一个新的数据结构时,不要从定义开始背。先写出最频繁的操作,再估计数据量和更新方式,最后检查结构是否让这三个条件同时成立。

  • 「先想一个日常场景」:你算过一次「37 × 89 = 3293」,第二天有人又问你 37 × 89 等于几——你会重新列竖式吗?不会,你直接报答案。 缓存就是电脑的这种「直接报答案」 :把算过的结果按 key 存进上一课的哈希表,下次遇到同样的 key,一步直达取结果。哈希表管「存哪、怎么找」,缓存管「什么值得存」。两课合起来才是完整的「空间换时间」
  • 「交互 1 · KV Cache:同一段开头别算两遍」:大模型每生成一个字,都要「回头看」前面所有 token,给每个 token 算一份注意力的中间结果。关键在于: 只要前缀一模一样,这些中间结果就一模一样 ——那第二轮对话还重算它干嘛?下面每个小方块是一个 token,先点「播放第一轮」,再点「播放第二轮」。 留意 第二轮里绿色方块出现的速度:它们没有被计算,是直接从缓存取的
  • 「最后的要点」:验收视角 :看到「每次请求都重新调用模型 / 重新计算」的设计,就该问一句「这里为什么不缓存?」

最后的「最后的要点」把讨论落到「验收视角 :看到「每次请求都重新调用模型 / 重新计算」的设计,就该问一句「这里为什么不缓存?」」。回看这条线索时,最值得保留的是:当输入、规模或风险改变,哪些判断需要重新做一遍。

✅ 这一课想和你分享的

  • 缓存 = 算过的别再算:结果按 key 存进哈希表,下次直达取——上一课的结构在这一课开始赚钱
  • KV Cache 认前缀:固定内容放提示词开头、会变的放末尾,缓存命中率直接决定账单
  • 语义缓存更狠:意思相同的提问连模型都不调,高频场景省钱效果按命中率线性放大
  • 缓存三问:存什么(值得复用的结果)、存哪(内存 / 磁盘 / 离用户近的地方)、何时作废(最难的一问)
  • 验收视角:看到「每次请求都重新调用模型 / 重新计算」的设计,就该问一句「这里为什么不缓存?」
标记为已学完 阅读进度会自动记录
← 上一篇下一篇 →

继续阅读

同一条线上的下一篇。

文章讨论

读到这里,留下一个判断。

把刚想明白的地方、还没想通的问题,留给下一位一起学习的人。

正在讨论 缓存:AI 账单的隐形折扣 AI 背后的数据结构
3条讨论文章讨论 · 与共学社区同步
在共学社区查看
AM
Asha Morgan内容编辑
观点实践记录

我把这篇文章里的一个判断改写成了今天可以验证的小实验。比记住结论更有用的是,知道下一步要观察什么。

文章讨论7 有帮助
LH
Lin Harper独立开发者
观点观点

读完以后我先回头找它成立的条件,而不是直接把方法搬进项目。这个顺序让后面的取舍清楚很多。

文章讨论5 有帮助
KM
Kiki Moore产品运营
问题问题

如果把这个判断放到真实工作里,最先需要补的约束是什么?我想知道从阅读到第一次实践之间,哪一步最值得先做。

文章讨论4 有帮助