跳到主要内容

LLM 应用的语义缓存:基准测试没告诉你的真相

· 阅读需 10 分钟
Tian Pan
Software Engineer

每个销售 LLM 网关的供应商都会向你展示一张标有“95% 缓存命中率”的幻灯片。那张幻灯片不会告诉你的是小字说明:这个数字是指在找到匹配项时的匹配准确度,而不是找到匹配项的频率。实际的生产系统命中率为 20–45% —— 营销与现实之间的差距正是大多数团队踩坑的地方。

语义缓存(Semantic caching)是一项非常有用的技术。但在不了解其失效模式的情况下部署它,会导致你以极高的置信度向用户返回错误答案,并让你纳闷为什么支持工单翻了一倍。

语义缓存究竟在做什么

传统缓存是确定性的:对请求进行哈希处理,查找哈希值,返回存储的响应。当相同的字节重复出现时,这种方法非常有效。但 LLM 查询很少是字节完全一致的。“我该如何重置密码?”和“重置密码的步骤”是不同的字符串,但在查询意图上是完全一致的。精确缓存(Exact caching)在第一次之后会错过这两个查询。

语义缓存通过将每个查询转换为嵌入向量(embedding vector),并使用余弦相似度(cosine similarity)将新查询与存储的向量进行比较来解决这个问题。当相似度分数超过阈值时,系统会直接返回缓存的响应,而无需调用 LLM。

架构如下:

  1. 第一层(精确缓存):对完整查询字符串进行哈希处理。如果命中,立即返回。在大多数生产系统中,这可以捕获 15–30% 的流量 —— 自动化流水线和用户重试产生的精确重复比你预期的要多。
  2. 第二层(语义缓存):对查询进行向量化,搜索向量索引,评估余弦相似度。如果分数超过你的阈值,返回缓存的响应。
  3. 未命中路径:转发给 LLM,缓存该“查询-响应”对供将来查找。

运行第二层的嵌入模型通常比生成模型更轻、更快 —— 比如 sentence-transformer 或小型双编码器(bi-encoder)。缓存查找路径的延迟预算需要控制在 ~50ms 以下,否则你会抵消掉因避免调用 LLM 而节省的延迟优势。

命中率的现实情况

研究论文通常报告 60–70% 的缓存命中率。但生产流量要复杂得多。真实部署中的实际范围大致按应用类型细分如下:

  • FAQ 和支持机器人:40–60% —— 这是语义缓存大放异彩的地方。用户会反复询问那几个固定的问题。
  • 分类任务:50–70% —— 输入空间离散,查询多样性有限。
  • 基于 RAG 的问答:15–25% —— 用户在广泛的事实领域提问;真正的重复很少见。
  • 开放式对话:10–20% —— 几乎每一轮对话都是唯一的。语义缓存在这里基本无效。
  • Agent 工具调用:5–15% —— 查询取决于先前的上下文和当前状态;表面上相同的问题可能需要完全不同的响应。

FAQ 性能与 Agent 性能之间的差距至关重要,因为团队通常会在最简单的用例上评估语义缓存,然后进行全局部署。如果你的系统处理多种查询类型,25% 的综合命中率比 60% 更现实。

如果每月 LLM 支出为 5,000 美元,25% 的命中率在扣除基础设施成本前大约能节省 1,000 美元/月。这是一笔真金白银,但值得与正确调整和维护缓存所需的工程时间进行对比 —— 这就涉及到了最困难的部分。

阈值是旋钮,而非固定设置

余弦相似度阈值决定了你的缓存是有用还是危险。它也是语义缓存部署中最常被错误配置的组件。

阈值过低(低于 0.80):你会针对表面相似的查询返回缓存响应。一家金融服务机构就直接遇到了这个问题 —— 一位客户说“我不想再要这个商业账户了”,系统以 88.7% 的余弦相似度置信度将其路由到了自动取消付款程序,而该查询实际上需要触发账户关闭审核。这两个查询虽然相关,但所需的响应完全不同。

阈值过高(高于 0.95):你的行为会接近精确缓存。你承担了基础设施的复杂性,却没有获得语义匹配的好处。

通常推荐的最佳平衡点是 0.92 —— 但这只是一个全局默认值,而全局默认值对于异构工作负载来说是错误的。在稠密代码嵌入空间中,单一阈值会将 "sort_ascending" 和 "sort_descending" 视为相同的(它们的向量非常相似),同时在稀疏的对话空间中错过有效的改写。

更好的方法:

加载中…
References:Let's stay in touch and Follow me for more thoughts and updates