已发布资料基础官方资料 + 个人实践
·14 分钟0 次阅读
文章/AI 与智能体

LLM 缓存的四个层次:KV、Prefix、Prompt 与 Semantic Cache

从一次自回归推理出发,区分 KV Cache、Prefix Caching、托管 API 的 Prompt Caching 与应用层 Semantic Cache,说明它们分别缓存什么、何时命中、节省哪段计算,以及生产环境最容易踩中的失效与正确性风险。

#LLM#KV Cache#Prompt Caching#Prefix Caching#语义缓存
文章目录
  1. 一分钟概览
  2. 1. 先用一张表把四层分开
  3. 2. 从 Prefill 与 Decode 理解 KV Cache
  4. 2.1 它省的是计算,付的是内存
  5. 2.2 为什么 Decode 容易受带宽限制
  6. 3. Prefix Caching:把一次请求的 KV 留给下一次
  7. 3.1 为什么要链式哈希
  8. 3.2 Prefix Caching 不会加速所有请求
  9. 4. Prompt Caching:同一机制进入托管 API 后
  10. 4.1 OpenAI 当前的口径
  11. 4.2 Anthropic 当前的口径
  12. 4.3 Provider 不同,工程原则相同
  13. 4.4 用两次请求确认缓存真的命中
  14. 5. Semantic Cache:复用答案,而不是计算状态
  15. 5.1 哪些场景不该直接做模糊答案缓存
  16. 6. RAG 为什么容易破坏 Prefix Cache
  17. 7. 六种常见的缓存失效
  18. 8. 指标要按层观察
  19. 9. 应该从哪一层开始
  20. 10. 上线前检查清单
  21. KV / Prefix
  22. Prompt Caching
  23. Semantic Cache
  24. 结语
  25. 参考资料

我第一次同时看到 KV Cache、Prefix Cache、Prompt Cache 和 Semantic Cache 时,直觉上觉得它们只是同一个缓存技术的四种叫法。真正把链路拆开以后才发现:它们甚至不一定保存同一种东西,也不在同一个系统层工作。

有的缓存发生在一次生成内部,避免每生成一个 Token 都重算历史;有的让不同请求共享已经算过的前缀;有的只是云服务商把这种能力包装成 API、计费与可观测指标;还有一种直接返回旧答案,连模型都不再调用。

这篇文章从 Avi Chawla 的长文 KV, Prefix, Prompt and Semantic Caching in LLMs, clearly explained 出发,但不按原文顺序逐段复述。我更想解决一个实际问题:

当延迟或 Token 账单异常时,怎样判断到底是哪一层缓存没有工作;当缓存命中时,又怎样确认它没有把错误答案复用出去?

项目说明
内容类型LLM 推理基础与生产缓存设计笔记
适合读者使用过模型 API,但容易混淆四类缓存的开发者
阅读时间约 18-22 分钟
资料基础Avi Chawla 原文、OpenAI、Anthropic、Hugging Face、vLLM 与 GPTCache 官方资料
资料核对日期2026-09-04
可带走产物四层缓存对照表、缓存失效排查表、上线前检查清单
边界本文解释机制与工程判断,不给出跨模型通用的性能承诺

先说明来源处理方式

原文提供了很好的四层划分和可运行代码。本文保留其核心问题与实验启发,但重新组织了结构,并按当前官方文档修正 Provider 接口差异。原文中的英文 RAG 图没有直接搬运;文中图片均为中文重绘,用来解释本文对应段落。

一分钟概览

如果只想先记住结论,可以带走这八点:

  1. KV Cache 保存一次增量生成所需的 Key/Value 张量。 它减少 Decode 时的重复计算,却增加显存读写压力。
  2. Prefix Caching 把可复用的 KV Block 留到后续请求。 命中条件不是“文本意思相近”,而是渲染后的 Token 前缀精确一致。
  3. Prompt Caching 是托管服务提供的产品接口。 底层通常仍复用前缀 KV 状态,但断点、TTL、计费与指标由 Provider 定义。
  4. Semantic Cache 保存的是答案。 它通过 Embedding 找相似问题,命中后跳过 LLM,因此会引入错误答案复用风险。
  5. 前三层主要优化 Prefill,不会替你生成同一个答案。 Semantic Cache 才可能直接返回旧结果。
  6. 稳定内容放前面,动态内容放后面。 时间戳、用户 ID、工具顺序和重新摘要都可能让精确前缀提前分叉。
  7. 缓存命中率不是共同指标。 精确缓存看 Token 命中、TTFT 和成本;语义缓存还必须看错误命中率与答案新鲜度。
  8. 先测逐字节重复,再考虑语义缓存。 Exact Response Cache 没有模糊匹配的 False Positive,往往是更稳的第一步。

图 1:LLM 请求从应用层语义缓存进入推理服务,再经过 Prompt/Prefix Cache 与单次请求 KV Cache图 1:LLM 请求从应用层语义缓存进入推理服务,再经过 Prompt/Prefix Cache 与单次请求 KV Cache

图 1:四层缓存不是四个同义词。越靠近模型内部,复用的越是计算状态;越靠近应用层,复用的越接近最终答案,正确性责任也越重。

1. 先用一张表把四层分开

判断一种“缓存”到底是什么,先问四个问题:

text
保存了什么?
键是什么?
命中后跳过哪段工作?
命中错误会不会改变答案?
层次保存对象典型键命中后省掉什么是否仍运行 LLM主要风险
KV Cache当前序列各层的 K/V 张量当前请求与 Token 位置Decode 时重算历史 K/V显存、带宽、生命周期管理
Prefix Caching跨请求保留的 KV Block父块哈希 + 当前 Token Block + 附加身份相同前缀的 Prefill前缀分叉、驱逐、租户隔离
Prompt CachingProvider 管理的前缀 KV 状态完整渲染前缀与 Provider 路由条件托管模型的部分 Prefill 与输入成本接口、TTL、断点和模型差异
Semantic Cache已生成响应及其元数据Prompt Embedding + 过滤条件整次模型调用和输出生成错误命中、过期、越权复用

这张表里最关键的一列是“是否仍运行 LLM”。前三种缓存命中后,模型仍会根据当前后缀生成新答案;Semantic Cache 命中后则直接把旧答案交给用户。

所以,前三种缓存未命中通常只让系统更慢、更贵;Semantic Cache 错误命中会让系统更快地给出错误答案

2. 从 Prefill 与 Decode 理解 KV Cache

一个 Decoder-only LLM 的生成过程可以先粗略拆成两段:

text
Prefill:一次处理输入 Prompt,建立每层注意力状态
Decode:每次生成一个新 Token,并继续追加状态

自注意力会为每个 Token 计算 Query、Key 与 Value。到了增量 Decode 阶段,最新 Token 的 Query 需要与此前所有 Token 的 Key 做匹配,再按权重聚合 Value。

此前 Token 的 Query 已经完成使命,不会被新 Token 再次使用;此前的 Key 和 Value 却要被后续每一步读取。因此,标准增量解码会保存 K/V,而不保存历史 Q。

图 2:Prefill 一次计算历史 Token 的 K/V,Decode 每步只追加一个新 Token 的 K/V图 2:Prefill 一次计算历史 Token 的 K/V,Decode 每步只追加一个新 Token 的 K/V

图 2:KV Cache 把“每一步重算全部历史”改成“读取历史 K/V,再为新 Token 追加一格”。计算减少了,缓存读取却随上下文增长。

2.1 它省的是计算,付的是内存

不使用 KV Cache 时,每生成一个 Token 都要再次计算历史 Token 的 K/V 投影。使用后,旧 K/V 可以直接读取,但缓存会随序列长度线性增长。

对常见全注意力结构,可以用下面的近似式理解一批请求的 KV Cache 总大小;计算单条序列时令 Batch Size = 1

text
KV bytes ≈
  层数
  × Token 数
  × KV Head 数
  × Head Dimension
  × 2(Key + Value)
  × 每元素字节数
  × Batch Size

假设一个模型有 80 层、8 个 KV Head、Head Dimension 为 128,使用 BF16 保存 128K Token,并且 Batch Size = 1

text
80 × 131072 × 8 × 128 × 2 × 2 bytes
≈ 40 GiB

这里刻意写出结构参数,而不是说“70B 模型一定占 40 GB”。KV Cache 大小由层数、KV Head、维度、精度和上下文共同决定,不能只看模型总参数量。

Hugging Face 的缓存策略文档 目前把常用选择分为 DynamicCacheStaticCache、Offloaded Cache 与 QuantizedCache:它们分别在动态内存、编译友好、CPU/GPU 传输和低精度存储之间取舍。量化缓存可以省内存,却可能因量化/反量化开销在短上下文上更慢。

2.2 为什么 Decode 容易受带宽限制

每生成一个 Token,模型都要读取此前的大量 K/V。上下文越长,单步读取量越大。计算 Kernel 可能很快完成,GPU 却还在等待 HBM 把缓存搬进来,于是瓶颈从纯计算转向内存带宽。

这也解释了为什么“减少 KV Cache 精度”“减少 KV Head”“限制注意力窗口”和“把缓存分层存储”会成为推理系统的重要方向:它们不只是为了塞进更长上下文,也是在改变每一步需要搬运的数据量。

3. Prefix Caching:把一次请求的 KV 留给下一次

KV Cache 默认属于当前运行。请求结束后,如果服务端仍保留其中可复用的完整块,并允许后续请求查找,就进入 Prefix Caching。

这里最容易出现的误解是:

两个 Prompt 有一大段相同文本,所以一定能复用。

真正比较的是 Token 序列和相关渲染状态。系统消息、Chat Template、工具定义顺序、特殊 Token、换行、图像哈希、LoRA 身份都可能成为键的一部分。

3.1 为什么要链式哈希

vLLM 的 Automatic Prefix Caching 设计 会把 Prompt 切成完整 KV Block,并让每个块的哈希包含:

text
父块哈希
+ 当前块的 Token ID
+ LoRA / 多模态输入 / cache_salt 等附加值

因此,第 3 块的键不只代表第 3 块,还代表“前两块完全匹配之后的第 3 块”。调度器从左向右查找,在第一个 Miss 处停止;后面即使出现相同文本,也不再是同一个前缀位置。

图 3:Prefix Cache 使用链式块哈希复用最长公共前缀,并在第一个 Miss 处停止图 3:Prefix Cache 使用链式块哈希复用最长公共前缀,并在第一个 Miss 处停止

图 3:请求 B 复用请求 A 的前两个完整块;第三块不同后,剩余后缀全部重新 Prefill。只有完整块进入索引,块大小会影响查找开销与尾部浪费。

当前 vLLM 文档还强调两点:

  • v0.11 起默认使用 sha256,并提供可复现序列化与更快非加密哈希的不同选项;非加密哈希需要评估碰撞和多租户风险。
  • 可以传入 cache_salt,让只有持有相同 Salt 的请求共享缓存,从而缓解共享 Prefix Cache 暴露的时序侧信道。多租户部署应使用不可预测的用户级或租户级秘密值,不要直接把公开的 tenant_id 当作 Salt。详见 vLLM 安全文档

3.2 Prefix Caching 不会加速所有请求

vLLM 功能文档 对边界写得很直接:APC 只减少 Query 的 Prefill,不减少新 Token 的 Decode。

因此它更适合:

  • 同一份长文档后接不同问题;
  • 多轮对话持续追加历史;
  • 大量请求共享稳定系统指令与工具 Schema。

它不太适合:

  • 每个 Prompt 从开头就不同;
  • 输出很长,绝大多数时间花在 Decode;
  • 缓存占用挤压了并发 Batch,驱逐又让命中率不稳定。

不能只看“开启 APC 后单个请求快了多少”,还要同时看 TTFT、并发吞吐、GPU Cache 使用率和驱逐后的冷启动比例。

4. Prompt Caching:同一机制进入托管 API 后

托管 API 不会把 Provider 的 Block Table、调度器和驱逐队列交给调用者。它暴露的是另一组东西:是否自动启用、最小可缓存长度、断点、TTL、缓存键、Usage 指标以及计费方式。

底层仍可能是 Prefix KV 状态复用,但 Prompt Caching 是产品契约,不是一个跨 Provider 完全统一的协议。

图 4:稳定前缀写入 Prompt Cache,动态问题放在断点之后;下一次请求复用最长匹配前缀图 4:稳定前缀写入 Prompt Cache,动态问题放在断点之后;下一次请求复用最长匹配前缀

图 4:稳定工具定义、系统规则与参考资料放前面;时间戳、用户变量和当前问题放在断点之后。缓存键帮助路由,但不等于强制命中。

4.1 OpenAI 当前的口径

按 2026-09-04 的 OpenAI Prompt Caching 文档

  • 支持的模型默认启用 Prompt Caching,复用的是 KV 张量,不是原始 Prompt 文本。
  • 完整渲染前缀必须匹配,包含 OpenAI 提供的指令、Developer Message、Tool Definition 和对话历史。
  • GPT-5.6 及后续模型支持隐式与显式断点,最小可缓存前缀为 1,024 个可见输入 Token。
  • 对这组较新模型,缓存写入按普通输入费率的 1.25× 计费,读取为 0.1×prompt_cache_options.ttl 当前支持 30m
  • 更早模型的最小长度、断点能力、写入计费和保留参数不同,不能把新模型规则反推到全部模型。
  • prompt_cache_key 影响相关请求的路由分组,不会把请求钉死在某台机器上,也不保证 Hit。

原文把 1.25× 写入与 0.1× 读取概括成 OpenAI 当前模型的统一规则。这个解释对较新模型很直观,但写生产代码时必须先检查目标模型的差异表。

4.2 Anthropic 当前的口径

按当前 Anthropic Prompt Caching 文档

  • 可以在请求顶层加入 cache_control 使用自动缓存,也可以在具体内容块设置显式断点。
  • 缓存前缀按 tools → system → messages 的顺序形成层级,前方变化会让后续部分失效。
  • 默认 5 分钟写入通常为基础输入价的 1.25×,1 小时写入为 ;读取通常为 0.1×,但新模型可能采用不同读取倍率,因此应以实时价格页为准。
  • 显式断点 Miss 后会向前寻找较早写入项,当前回看窗口最多为 20 个内容块。
  • Usage 中的 cache_creation_input_tokenscache_read_input_tokens 才是是否真正写入、命中的证据。

Anthropic 目前还提供 Beta 状态的 Cache diagnostics,可比较连续请求在模型、系统指令、工具或消息历史中的分叉位置。按本文核对日期,调用时需要使用文档指定的 Beta Header,因此不能把响应中的诊断字段当作长期稳定接口。它说明了一个朴素事实:日志里“看起来没变”,不代表最终发送给模型的字节前缀没变。

4.3 Provider 不同,工程原则相同

尽管接口不同,常见策略是一致的:

text
稳定且高复用:工具 Schema、系统规则、共享参考资料
变化较慢:项目配置、会话历史
每次变化:时间戳、用户变量、当前问题、实时工具结果

把稳定层放前面,动态层放后面;只有在知道前缀会再次使用时,才主动承担缓存写入成本。

4.4 用两次请求确认缓存真的命中

不要仅凭第二次响应更快就判断缓存生效。对支持显式断点的模型,可以准备一段从未使用过、且超过目标模型最小缓存长度的稳定测试前缀,在稳定部分之后设置断点,然后连续发送两次请求:

text
请求 1:相同模型 + 稳定长前缀 + 问题 A
请求 2:相同模型 + 同一稳定前缀 + 问题 B

两次请求的动态问题可以不同,但断点之前的最终渲染内容必须一致。预期证据如下:

Provider第一次请求第二次请求可以得出的结论
OpenAI GPT-5.6+cache_write_tokens > 0cached_tokens = 0cached_tokens > 0前缀先写入,再被后续请求读取
Anthropiccache_creation_input_tokens > 0cache_read_input_tokens = 0cache_read_input_tokens > 0缓存项已创建,并在后续请求中命中

如果第二次仍然没有读取 Token,按下面的顺序排查:

  1. 两次请求是否使用相同模型、缓存模式和 TTL。
  2. 断点之前的系统指令、工具顺序、消息与空白字符是否一致。
  3. 稳定前缀是否达到目标模型当前要求的最小长度。
  4. 第二次请求是否在缓存生命周期内开始。

这个实验验证的是“Provider 报告的缓存命中”,不是笼统的延迟下降。网络、排队与 Decode 长度都可能让端到端耗时产生噪声。

5. Semantic Cache:复用答案,而不是计算状态

Semantic Cache 位于应用层。一次请求大致经历:

text
Prompt
  → Embedding
  → 向量检索
  → 过滤与相似度阈值
  → Hit:返回旧答案
  → Miss:调用 LLM,再保存 Prompt、答案与元数据

它与前三层有三个本质区别:

  1. 保存的是响应,而不是注意力张量。
  2. 键是近似语义,而不是精确 Token 前缀。
  3. 命中后完全不运行 LLM,因此会直接继承旧答案的错误和时效。

图 5:同义改写可以命中语义缓存,但否定词和业务字段变化也可能被误判为相似图 5:同义改写可以命中语义缓存,但否定词和业务字段变化也可能被误判为相似

图 5:相似度高不等于答案可复用。“如何重置密码”是合理同义改写;“是否限流”与“是否不限流”需要相反答案;年度与月度套餐则可能受不同政策约束。

原文用一个小实验展示了这个问题。同义改写与只多一个否定词的句子,余弦相似度可能非常接近。提高阈值会牺牲大量有效 Hit,降低阈值又会放大 False Positive。

这不是“找到一个万能阈值”就能解决的问题。Embedding 表示的是统计语义相近,不自动编码:

  • 答案是否仍然有效;
  • 两个用户是否有相同权限;
  • 年度与月度套餐是否使用同一政策;
  • 一个 not 是否翻转了业务结论;
  • 原答案是否经过审核。

GPTCache 的结构也体现了这些决策:Embedding、向量存储、相似度评估、阈值、驱逐策略和后处理都需要配置。其 ACL 论文 说明了用缓存先拦截请求、Miss 后再调用 LLM 的基本架构,但生产安全性仍取决于具体流量和验证策略。

5.1 哪些场景不该直接做模糊答案缓存

以下请求默认不适合只凭相似度返回旧答案:

  • 金融价格、仓位、交易与投资建议;
  • 医疗、法律和安全处置;
  • 权限判断与用户私有数据;
  • 订单、退款、库存等快速变化状态;
  • 带版本号、日期、地域、套餐或金额的政策问题;
  • Agent 的工具调用计划和外部副作用结果。

更稳妥的 Semantic Cache 至少要把这些字段纳入精确过滤条件:

text
tenant_id / user_scope
policy_version / data_version
locale / region
model_and_prompt_version
tool_or_data_freshness
answer_validation_status
expires_at

向量相似度只负责找候选,结构化约束负责判断它是否有资格成为 Hit。

6. RAG 为什么容易破坏 Prefix Cache

原文保存下来的配图展示的是标准 RAG:文档进入向量库,查询检索相关片段,片段与问题一起发给 LLM。对 Prefix Cache 而言,麻烦发生在“检索片段拼进 Prompt”这一步。

图 6:RAG 检索到相同文档但排序变化时,链式前缀在第一个不同块处失效图 6:RAG 检索到相同文档但排序变化时,链式前缀在第一个不同块处失效

图 6:两次查询都拿到 A、B、C 三个片段,但第二次顺序变成 B、A、C。链式哈希要求此前块也匹配,因此普通 Prefix Cache 不能把三个片段任意重排后继续复用。

把每个文档片段单独 Prefill,再把 KV 张量简单拼起来也不可靠:位置编码不同,片段之间没有发生完整交叉注意力,直接拼接会改变模型真正看到的状态。

CacheBlend 原始论文提出了一种非前缀 KV 复用方法,随后进入 LMCache 的工程实现:它在移动片段位置时复用部分缓存,并选择性重算一部分 Token 来恢复跨片段关系。这里最值得带走的不是某个固定加速倍数,而是一个边界:Prefix Cache 天然适合稳定顺序,非前缀复用需要额外算法维持注意力正确性。

7. 六种常见的缓存失效

现象根因排查方式修复方向
每次 cached_tokens 都接近 0时间戳、Request ID 或用户名出现在前缀开头比较最终 Token ID 分叉点稳定内容前置,动态字段后移
改了一个工具后全部冷启动Tool Schema、顺序或 Tool Choice 改写了前缀记录排序后的完整 Tool 定义保持定义和顺序稳定,用允许列表控制可调用项
长对话摘要后突然 MissCompaction 重写了历史对比摘要前后的渲染上下文接受一次冷启动,再从新前缀继续追加
切换模型后缓存消失KV 状态与模型/配置绑定按模型拆分指标不期待跨模型复用
RAG 明明命中同一批文档却没缓存检索片段顺序或边界变化记录 Chunk ID 和排序稳定排序,或采用专门的非前缀方案
Semantic Hit 很高但投诉增加相似问题并不共享答案审核命中样本,统计错误命中加结构化过滤、版本、TTL 与验证器

如果使用本地 Tokenizer,可以用下面的最小逻辑定位两个输入的公共前缀:

python
def shared_prefix_length(a: list[int], b: list[int]) -> int:
    shared = 0
    for left, right in zip(a, b):
        if left != right:
            break
        shared += 1
    return shared

不要只 Diff 自己编写的 Prompt 字符串。真正输入还可能经过 Chat Template、工具序列化、特殊 Token 和 Provider 系统内容处理。

8. 指标要按层观察

四类缓存不能共用一个“Hit Rate 看板”。

层次至少记录什么不足以说明什么
KV Cache每请求 KV bytes、活跃 Token、读带宽、驱逐/Offload单独请求的答案是否正确
Prefix Cache可复用 Token、完整块命中、TTFT、驱逐率、Salt 作用域Decode 是否更快
Prompt CacheCache Read/Write Token、普通输入 Token、TTFT、实际费用、模型与 TTL请求一定落到缓存机器
Semantic Cache候选相似度、结构化过滤结果、命中来源、答案年龄、错误命中率高 Hit Rate 等于高质量

语义缓存尤其应该把 false_hit_rate 放在 hit_rate 前面。一个 60% 命中、几乎不返回错误答案的系统,往往比 90% 命中、偶尔跨权限或跨政策版本复用答案的系统更可靠。

9. 应该从哪一层开始

可以按下面的顺序做决策:

text
单次生成显存或 Decode 成本高?
  → 先看 KV Cache 策略、GQA/MLA、量化与 Offload

大量请求共享精确长前缀?
  → 看 Prefix Caching,并验证最长公共 Token 前缀

使用托管 API,希望降低重复输入成本和 TTFT?
  → 按目标 Provider 配置 Prompt Caching,并读 Usage

大量问题逐字节完全相同?
  → 先做 Exact Response Cache

只有语义相近、业务也允许复用旧答案?
  → 最后才评估 Semantic Cache,并建立错误命中测试集

这几层也可以同时存在:应用先查语义或精确答案缓存;Miss 后请求 Provider;Provider 查 Prompt Cache;推理进程内部再使用 KV Cache。此时 Trace 必须标出最终在哪一层 Hit,否则“请求很快”并不能说明是哪项优化生效。

10. 上线前检查清单

KV / Prefix

  • 计算过真实模型结构下的 KV Cache 大小,而不是按参数量猜测。
  • 明确缓存是每请求、跨轮次还是跨请求保存。
  • 记录 Prefill 与 Decode 延迟,不把整段加速都归给 Prefix Cache。
  • 验证完整块大小、驱逐策略和并发 Batch 的内存竞争。
  • 多租户场景评估 Salt、命名空间和时序侧信道。

Prompt Caching

  • 以目标模型的当前官方文档核对最小长度、断点、TTL 与价格。
  • 工具定义、系统规则与共享资料保持稳定顺序。
  • 时间戳、用户变量和当前问题放在稳定前缀之后。
  • 读取 Provider 返回的 Cache Read/Write Token,而不是凭延迟猜命中。
  • 模型切换、Compaction 和工具变更后允许一次可解释的冷启动。

Semantic Cache

  • 先测量 Exact Response Cache 能覆盖多少流量。
  • 为租户、权限、地区、政策和数据版本设置精确过滤。
  • 缓存项保存来源、生成时间、模型/Prompt 版本、验证状态和 TTL。
  • 用同义句、否定句、数字、日期和业务字段变化构造 False Hit 测试集。
  • 高风险请求默认绕过模糊缓存。
  • 对命中样本持续抽检,而不是上线后只看 Hit Rate。

结语

“缓存”这个词掩盖了四个完全不同的问题:

text
KV Cache:当前生成怎样避免重算历史?
Prefix Cache:后续请求怎样复用精确前缀?
Prompt Cache:Provider 怎样把前缀复用变成产品契约?
Semantic Cache:应用是否敢直接复用旧答案?

前三层越做越好,通常意味着相同任务使用更少的 Prefill 计算;第四层越激进,则越需要为正确性、新鲜度和权限负责。

下次再看到“缓存命中率提升”时,我会先追问:命中的究竟是 Token 状态,还是用户最终看到的答案? 这两个结果在监控图上可能都叫 Hit,在工程风险上却相差很远。

参考资料

继续阅读

这篇笔记最后更新于 2026年9月4日