Skip to content

Prompt Caching

Prompt Caching 是 LLM 服务提供的一种缓存优化机制,旨在减少重复前缀内容的重复计算。当多次请求共享相同的前缀(如系统提示、工具定义、历史对话中的早期轮次)时,模型服务端可以复用之前的 KV Cache 计算结果,跳过对缓存前缀的重新编码,从而大幅降低首 token 延迟和处理成本。

工作原理

LLM 推理过程中,每个 token 的生成都需要基于之前所有 token 的 Key-Value 注意力状态。在没有缓存的情况下,每次请求都需要对完整的输入序列重新计算这些 KV 状态,即便系统提示和工具定义在多轮对话中完全不变。当系统提示长达数千 token 时,每次请求都重新编码这些重复内容是对计算资源的严重浪费。

Prompt Caching 的基本思路是:将输入序列中稳定的前缀部分(如系统提示、固定的 few-shot 示例、工具定义 Schema)缓存为 KV 张量,后续请求直接从缓存中读取这些预先计算好的注意力状态,只需对新增加的 token(如最新的用户消息和检索结果)进行增量编码。这本质上是一种计算换存储的策略——用显存或内存存储预计算的 KV 状态,避免重复的矩阵乘法运算。

目前主流 LLM 服务提供商均已支持 Prompt Caching。Anthropic 的原生 Prompt Caching 要求缓存内容至少 1024 token(缓存边界必须在 token 边界对齐),缓存命中后的处理成本按缓存读取费率计费(通常为基本费率的 10%),远低于完整处理成本。OpenAI 的 Automatic Caching 更为透明——API 自动检测请求中的重复前缀,在服务端无感缓存,按缓存命中折扣计费,无需用户显式管理缓存边界。

缓存策略

Prompt Caching 的效果取决于缓存命中率,而命中率又取决于上下文内容的组织方式。最佳实践是将不变的静态内容集中在上下文窗口的前缀位置,形成一个连续的缓存区域。

系统提示应按稳定性分层组织:第一层是"绝对不会变"的基础行为指令(角色定义、回答格式要求、安全约束),第二层是"偶尔会变"的场景切换指令(当前对话的领域上下文),第三层是"每次都会变"的当前查询。通过将静态内容置于最前面,可以最大化缓存命中率。few-shot 示例如果跨请求复用,也应该放在系统提示之后、当前查询之前。

工具定义的 Schema 在多轮对话中通常不变,将其集中放在前缀中是另一种高价值缓存场景。对于 Agent 系统来说,工具定义可能长达数千 token,缓存这些内容能显著降低每次工具调用的延迟。

对话历史的管理也需要考虑缓存友好性。在多轮对话中,早期的历史轮次在每轮中都是相同的,可以被缓存。随着对话的推进,只有最新的几轮是变化的。合理的策略是维护一个"缓存前缀窗口":将最近 N 轮的消息视为动态部分,将 N 轮之前的对话摘要化为一个固定的上下文段落放在缓存前缀中——既保留了对话的长期记忆,又不破坏缓存结构。

与其他缓存的区别

Prompt Caching 与语义缓存(Semantic Cache)解决的是不同层面的问题。Prompt Caching 发生在 LLM 推理的注意力计算层面,缓存的是 KV 状态张量,本质上是"避免对同样前缀的重复矩阵运算"。语义缓存发生在应用层,缓存的是"相似问题的答案",通过 Embedding 相似度匹配来命中,本质上是"避免重复调用 LLM"。

两者的适用场景互补。Prompt Caching 适合高频重复前缀但每次查询不同(如 Agent 多轮工具调用中,系统提示和工具定义不变但每次调用的参数不同)。语义缓存适合查询高度重复的场景(如客服系统中大量相同问题),可以直接返回缓存答案而不调用 LLM。

从成本优化角度看,Prompt Caching 和语义缓存可以级联使用:请求首先经过语义缓存检查,如果命中相似问题(相似度 > 0.95),直接返回缓存答案;如果未命中,再调用 LLM API,此时 Prompt Caching 确保系统提示等静态部分不被重复计费。这种两级缓存策略在高 QPS 的生产环境中可以同时降低 API 调用次数和单次调用的 token 成本。