LLM 推理成本高、延迟长,缓存是必选项而非优化项。但 LLM 应用的缓存不是简单的 key-value 映射——用户换个问法、上下文略有差异,传统缓存就失效了。本文梳理五种缓存策略,按生效层次从底层到上层排列。
1. Prompt 缓存:减少重复 token 处理
原理:主流模型厂商(OpenAI、Anthropic、Google)都支持 Prompt Caching,即缓存请求中的固定前缀部分(system prompt、few-shot 示例、长文档上下文),后续请求只需处理变化的 suffix。
适用场景:
- 系统提示词固定且较长(超过 1024 token)
- 多轮对话中上下文反复出现
- RAG 场景中检索到的文档在短时间内被多次引用
实施要点:
- 将固定内容放在消息数组前部,变化内容放后部
- 注意缓存 TTL(通常 5-10 分钟),高频场景才划算
- 缓存命中与否对调用方透明,但会体现在账单的折扣 token 计费上
假设一个客服场景:系统提示词 + 知识库文档共 3000 token,用户问题 50 token。启用 Prompt 缓存后,第二次及之后的请求只需处理 50 token 的新增部分,延迟和成本都显著下降。
2. 语义缓存:相似问题复用答案
原理:将用户输入转为向量,在缓存中检索语义相似的历史请求。相似度超过阈值(如 0.95)时直接返回缓存结果,跳过 LLM 调用。
适用场景:
- FAQ 类应用,用户换表述问同一件事
- 客服、教育等领域知识相对稳定
- 对实时性要求不高的查询
实施要点:
- 用轻量 embedding 模型(几毫秒延迟)做相似度检索
- 相似度阈值需实验调优:过低误判,过高命中率低
- 缓存条目需关联时间戳,定期失效或主动清除过时内容
- 记录缓存命中日志,持续优化阈值与失效策略
开源方案如 GPTCache 提供了开箱即用的实现,但生产环境建议自建以便控制存储、失效策略和监控。
3. 结果缓存:确定性任务的精确匹配
原理:对输入做哈希,精确匹配时返回缓存。适合输入输出关系确定的场景。
适用场景:
- 代码生成、SQL 翻译等确定性任务
- 翻译、摘要等对同一输入期望稳定输出的场景
- API 调用参数完全相同的重复请求
实施要点:
- 哈希时需包含完整上下文(messages 数组、temperature 等参数)
- temperature > 0 的场景慎用,除非业务能接受非最新的随机采样结果
- 用 Redis/Memcached 存储,设置合理 TTL(如 1 小时到 1 天)
与语义缓存的区别:结果缓存是精确匹配,适合"同一问题必须同一答案"的场景;语义缓存是模糊匹配,适合"类似问题可以复用答案"的场景。
4. 向量缓存:RAG 检索加速
原理:在 RAG 流程中,文档切片的 embedding 计算成本不低。将文档 ID + chunk 内容哈希作为 key,缓存对应的向量。
适用场景:
- 知识库内容相对稳定
- 同一文档被多个用户或多次检索
- 文档更新频率低于查询频率
实施要点:
- 文档更新时主动失效相关缓存
- 向量数据库(如 Pinecone、Weaviate)通常自带缓存层,自建需评估收益
- 对于动态生成的文档(如用户上传),缓存收益取决于重复率
5. 会话缓存:多轮对话的上下文管理
原理:将会话历史存储在 Redis 等快速存储中,避免每次请求都从数据库加载完整对话记录。
适用场景:
- 多轮对话应用
- 需要跨请求保持状态的 Agent 系统
实施要点:
- 用会话 ID 作为 key,value 存储消息数组
- 设置滑动窗口(如保留最近 10 轮)或 token 数上限,避免上下文无限增长
- TTL 设置需平衡成本与体验:过短用户感知割裂,过长占用存储
组合使用与监控
实际应用中通常组合多种策略:会话缓存保证上下文连续性,Prompt 缓存降低固定部分成本,语义缓存拦截重复问题。关键是建立监控体系:
- 各层缓存命中率
- 缓存带来的延迟节省与成本节省
- 缓存导致的陈旧答案占比(需人工抽查或用户反馈)
缓存策略没有银弹,需根据业务特点实验调优。如果你的团队在 LLM 应用的成本优化或架构设计上需要支持,欢迎联系 Taylent Labs 探讨具体方案。