语义缓存:LLM 应用的降本增效利器

AI 应用的成本大头是 LLM 调用,而现实是:用户会反复问相似的问题。“简历怎么写亮点"和"怎么写简历更出彩”——语义上是一个问题,但每次都要重新调用大模型,token 烧两遍。

语义缓存:把"相似的问题"映射到"同一个答案",命中即复用。是 LLM 应用降本增效性价比最高的手段之一。

一、为什么需要语义缓存

A B k e e m y b e d d i n g 9 0 % m i s s

核心:把"精确匹配"换成"语义匹配"——用 embedding 距离判断两个问题是不是一回事。

二、架构

1 2 . . e m b > e d L d L i M n g 0 + L L M
1
2
3
4
5
6
7
8
def answer_with_cache(question):
    q_vec = embed(question)
    hit = cache.search(q_vec, threshold=0.92)   # 语义相似度阈值
    if hit:
        return hit.answer, "cache"
    answer = llm.chat(question)
    cache.store(q_vec, question, answer)         # 入库
    return answer, "llm"

三、关键参数:相似度阈值

阈值决定缓存的质量

阈值 效果 风险
0.98(严格) 几乎只有同义句命中 命中率低
0.92(推荐) 语义相同基本命中 偶发答非所问
0.85(宽松) 命中率高 相关但不相同的问题拿到旧答案

调优方法:用评测集测——100 组"相似问题对",找"该命中都命中、不该命中都不命中"的阈值。

兜底设计:低相似度命中时,在答案里注明"这是基于类似问题的回答",或直接 miss 走 LLM。

四、缓存什么

适合缓存的

F A Q

不适合缓存的

" " " " " "

判断标准答案是否会随时间/用户变化。会变的不缓存,不会变的缓存。

五、缓存更新与失效

1 2 3 . . . " "

关键:语义缓存的失效比精确缓存难——“相似的问题"没法精确定位删除。实践:知识更新后,按主题/标签批量过期(不是逐个删)。

六、效果数据

指标 无缓存 语义缓存
缓存命中率 - 30-40%(FAQ 场景)
LLM 调用成本 100% 省 30-40%
P50 延迟 1.5s 200ms(命中时)
日 LLM 调用量 10k 6-7k

延迟收益比成本收益更明显:命中时不需要 LLM,P50 从秒级降到百毫秒级——缓存不只是省钱,是体验优化

七、实现选型

方案 适用
Redis + 向量模块(RediSearch) 已有 Redis,规模中等
SQLite-vec / LanceDB 本地/轻量
专用向量库(Qdrant/Milvus) 大规模、高 QPS
云向量服务 不想运维

我们的实践:Redis(已有)存向量 + 答案,成熟、零新增组件

八、踩坑记录

  1. 阈值太松:0.80 命中,用户得到"答非所问"的缓存 → 负反馈率上升 → 阈值 0.92 + 低分标注
  2. 缓存了时效答案:把"本周活动"缓存了 → 下周还在推上周的活动 → 时效性场景强制过期(TTL 短)
  3. 个性化污染:A 用户的答案缓存后,B 用户命中 → B 得到 A 的个性化内容 → 个性化问题不缓存(或 key 带用户维度)
  4. embedding 成本:每个问题都要 embedding 调用 → embedding 模型本地部署(便宜 100 倍)或缓存 embedding

总结

语义缓存的核心认知:

  1. 把精确匹配换成语义匹配:相似问题复用同一答案
  2. 阈值是灵魂:0.92 起步,用评测集调
  3. 缓存"不变"的答案:时效/个性化场景不缓存
  4. 降本 + 降延迟双收益:命中时体验反而更好

AI 应用降本第一刀,砍向重复劳动。 语义缓存砍掉的正是"同一个问题反复烧 token”——理解它,你的 AI 应用成本结构会健康很多。