提示词也能缓存:固定前缀为什么能省钱提速?

TL;DR

解释 Prompt caching、Prefix caching 与语义缓存的区别,说明前缀顺序、TTL、命中率和多租户隔离如何影响 AI 应用性能。

Prompt caching 缓存的不是旧答案,而是模型处理重复提示词前缀时产生的中间状态。本文解释它与语义缓存的区别、为什么顺序会影响命中、如何整理 Agent 上下文,以及多租户场景中的隔离风险。

提示词也能缓存:固定前缀为什么能省钱提速?

很多 AI 应用会反复发送同一批内容:系统指令、工具定义、产品文档、代码仓库摘要、对话历史。虽然每次请求的最后一句问题不同,但前面可能有几万 token 完全一样。

如果模型每次都从头计算这些重复前缀,延迟和成本都会被重复放大。Prompt caching 的思路是:已经计算过的前缀可以暂存,下一个请求命中时直接复用中间状态。

先给结论:Prompt caching 缓存的是计算,不是答案

它和常见的语义缓存不是一回事。

  • 语义缓存:两个问题意思相近,就尝试复用旧答案。
  • Prompt caching:两个请求前缀完全相同,就复用模型处理输入时产生的中间计算结果。

因此,Prompt caching 不会让模型把旧答案直接发给用户。它仍然会读取新问题并生成新答案,只是跳过一部分已经完成的输入计算。

在开源推理框架 vLLM 中,这种机制通常叫 prefix caching:系统把共享前缀对应的 KV Cache 分块保存,并在后续请求中复用。vLLM Automatic Prefix Caching

为什么“顺序”比“内容”更重要

模型看到的输入不是一个无序资料库,而是一串 token。缓存通常匹配的是从开头开始的连续前缀:前面有一个字符、工具定义或消息顺序不同,后面的缓存就可能无法继续复用。

可以把 Prompt 想成:

[稳定系统指令]
+ [稳定工具定义]
+ [稳定项目资料]
+ [变化的对话历史]
+ [变化的用户问题]

如果把用户问题插到最前面,整个后续前缀都会失去复用机会;如果把稳定内容集中放在前面,变化内容放在后面,命中概率就更高。

这也是为什么 Agent 的工具列表、系统指令和文件摘要不应该每轮随机排序。即使模型逻辑上认为两个列表等价,缓存系统看到的 token 序列也可能完全不同。

一次请求怎样命中缓存

简化后的过程是:

缓存并不是把原文简单放到 Redis 里。推理引擎保存的是模型针对前缀计算出的中间状态,因此它和具体模型、tokenizer、推理实现及缓存布局有关。更换模型、改变关键参数或改变前缀内容,都可能让旧缓存失效。

最有效的工程整理方式

把稳定内容前置

系统说明、工具 schema、固定示例和项目级规则应尽量放在前面。用户问题、当前时间、随机追踪 ID 等动态内容放后面。

保持序列化稳定

工具定义、JSON 字段和枚举值要稳定排序。不要因为一次请求的业务数据不同,就重新生成一份字段顺序随机的 schema。

把高频变化拆出上下文

如果每次只需要少量状态,不要把完整数据库快照都拼进前缀。可以先检索、再把当前真正需要的片段放在变化区域。

观察命中率而不是猜

至少记录:输入 token 数、缓存命中 token 数、前处理延迟、总延迟和缓存写入次数。账单下降但缓存命中率很低,可能只是请求量下降;延迟变快但输出变差,则可能是上下文整理时误删了重要信息。

TTL 会改变收益模型

缓存不是永久存在。不同服务可能采用不同的缓存生命周期、最小前缀长度、显式断点和定价规则。OpenAI 的早期 Prompt Caching 说明采用了自动匹配公共前缀的方式,并在响应中返回命中的 token 数;Anthropic 的 API 文档则同时提供自动缓存和显式断点等选择。OpenAI Prompt CachingAnthropic Prompt Caching

工程上不要把某个平台的具体 TTL 或折扣写死成架构假设。真正应该稳定的是“公共前缀尽量稳定、缓存命中可以观测、未命中也能正常工作”。

多租户场景要注意缓存隔离

如果不同用户共享一个推理服务,缓存命中机制可能引入侧信道:攻击者可以通过响应时间或命中行为推测某些前缀是否曾经出现。vLLM 的安全文档就专门讨论了多租户 Prefix Cache 的隔离问题,并提供了通过 cache salt 进行隔离的方式。vLLM 安全说明

缓存设计至少需要回答三个问题:

  1. 哪些前缀可以跨用户共享?
  2. 哪些内容必须按租户或用户隔离?
  3. 缓存失效和清理是否有明确策略?

不要因为“缓存里没有原文答案”就忽略隐私。中间状态仍然可能承载输入信息,缓存键和命中信号也可能暴露业务行为。

什么时候值得做

Prompt caching 最适合长上下文、重复工具定义、代码 Agent、长对话和批量文档处理。如果每个请求都很短、前缀高度随机,缓存命中带来的收益就有限。

一句话总结:Prompt caching 的第一优化目标不是“让模型记住答案”,而是让请求保持一段足够长、足够稳定的共同前缀。

来源

KEEP READING