为什么要关心 LLMs 中的 Prompt Caching?
Source: Towards Data Science
在 RAG 与 AI 代理中的成本与延迟扩展
我们已经多次讨论了 RAG 是多么不可思议的工具,它能够在自定义数据上利用 AI 的强大能力。无论是处理普通的 LLM API 请求、RAG 应用,还是更复杂的 AI 代理,总有一个问题始终不变:
这些系统如何扩展?
具体来说,随着请求数量的增长,成本和延迟会发生什么?
对于高级 AI 代理——可能在处理单个用户查询时包含多次对 LLM 的调用——这些顾虑尤为重要。
为什么缓存很重要
在实际使用中,许多输入 token 会在多个请求之间重复:
- 用户经常会重复提问相同的具体问题。
- 系统提示和指令会出现在每一次查询中。
- 即使是单一的提示,也会触发递归的逐 token 生成,从而多次重复相同的上下文。
应用 缓存概念 可以显著降低成本和延迟。根据 OpenAI 关于 Prompt Caching 的文档:
- 延迟 可降低最高 80 %。
- 输入 token 成本 可下降最高 90 %。
要点
通过缓存重复的提示组件并利用 OpenAI 的 Prompt‑Caching 功能,您可以在 RAG 流程和 AI 代理扩展时实现更高的效率。这一优化对于在生产级 AI 应用中保持性能并控制费用至关重要。
什么是缓存?
一般来说,缓存(Cache (computing))并不是计算领域的新概念。其核心是临时存储数据,以便后续对同一数据的请求能够更快地得到响应。这会产生两种基本结果:
- Cache hit – 在缓存中找到了请求的数据,能够快速且低成本地检索。
- Cache miss – 缓存中没有该数据,应用必须访问原始来源,这更昂贵且耗时。
典型示例:网页浏览器
- 首次访问 – 浏览器检查其缓存中是否已有该 URL。
- 结果:cache miss → 浏览器必须向远程服务器请求页面。
- 页面加载完成后 – 浏览器将获取到的资源存入本地缓存。
- 随后访问(例如 5 分钟后) – 浏览器再次在缓存中查找该页面。
- 结果:cache hit → 页面瞬间加载,无需联系服务器。
这种机制让浏览更快,并且降低了网络流量。
为什么缓存如此高效
大多数系统并不是均匀访问数据,而是遵循一种偏斜分布:只有一小部分数据占据了大多数请求。许多实际应用遵循 帕累托原则:大约 80 % 的请求只针对 20 % 的数据。
如果请求是均匀分布的,缓存的容量就必须和主存一样大,成本将难以承受。通过利用这种偏斜性,较小的缓存就能满足大比例的访问,从而显著提升性能并降低成本。
Source: …
Prompt 缓存与一点关于 LLM 推理的介绍
缓存概念——将经常使用的数据存放在某处,并从那里检索,而不是再次从其原始来源获取——用于提升 LLM 调用的效率,显著降低成本和延迟。
缓存可以应用于 AI 应用的许多部分,其中最重要的是 prompt 缓存。它也可以用于其他方面,例如 RAG 检索或查询‑响应缓存,但本文仅关注 prompt 缓存。
LLM 推理是如何工作的
LLM 推理(使用已训练模型生成文本)分为两个独立阶段:
| 阶段 | 发生的事情 | 主要瓶颈 |
|---|---|---|
| 预填充(Pre‑fill) | 一次性处理整个提示,以生成第一个 token。 | 计算受限——大量矩阵乘法。 |
| 解码(Decoding) | 将上一次生成的 token 追加到序列中,并自回归生成下一个 token。 | 内存受限——每生成一个新 token 都必须从内存加载完整上下文。 |
示例
提示:
What should I cook for dinner?第一个 token(预填充后):
Here解码迭代:
Here
Here are
Here are 5
Here are 5 easy
Here are 5 easy dinner
Here are 5 easy dinner ideas在解码过程中,模型会反复重新处理相同的前置 token,效率极低。
KV(键‑值)缓存
KV 缓存 通过为提示和已生成的 token 存储中间 key 和 value 张量来解决上述低效问题。每一次解码步骤,模型:
- 检索已有上下文的缓存 KV 张量。
- 仅计算新 token 的 KV 张量。
- 将新的 KV 对追加到缓存中。
于是,模型只执行每个新 token 所需的 最小 计算。
然而,KV 缓存 仅适用于单个提示和单个响应。
Prompt 缓存
Prompt 缓存将 KV 缓存的作用范围扩展到 不同的提示、用户和会话。思路很简单:
- 确定提示的 重复前缀(例如系统提示、指令、检索到的上下文)。
- 对该前缀计算 KV 张量一次并存储。
- 当新请求包含相同前缀时,复用已存储的 KV 张量。
好处
- 降低成本——无需为相同的 token 再次计算。
- 降低延迟——模型跳过已经完成的工作。
- 对于 RAG 流水线或任何包含大量重复指令的应用尤为有价值。
Token 级别的操作
缓存工作在 token 级别。只要两个提示共享相同的 token 前缀,共享部分即可从缓存中提供,即使后缀不同。共享的 token 必须位于提示的开头;否则会出现缓存未命中。
示例 – 缓存命中
Prompt 1
What should I cook for dinner?
Prompt 2
What should I cook for lunch?共享前缀 “What should I cook” 产生缓存命中,省去 Prompt 2 的计算。
示例 – 缓存未命中
Prompt 1
Dinner time! What should I cook?
Prompt 2
Launch time! What should I cook?因为首个 token 不同(“Dinner” vs. “Launch”),即使语义相似,缓存也无法复用。
实用经验法则
- 静态信息(系统提示、指令、检索到的上下文) → 放在模型输入的开头。
- 动态信息(时间戳、用户 ID、用户特定查询) → 放在提示的末尾。
遵循此顺序可最大化缓存命中的概率,充分利用 prompt 缓存的优势。
用 OpenAI API 实战
大多数前沿基础模型——例如 GPT (OpenAI docs) 和 Claude (Claude cookbook)——在其 API 中直接提供 Prompt Caching。在这些 API 中,缓存是 在使用同一 API 密钥的同一组织的所有用户之间共享 的。
- 当发出请求时,模型会将提示前缀存入缓存。
- 包含相同前缀的后续请求会命中缓存,使模型能够复用预先计算的结果。
- 这会降低 token 消耗并加快响应生成——对企业级 AI 应用尤为重要,因为许多用户会反复发送相似的提示。
缓存保留选项
| 保留类型 | 常见时长 | 可用性 |
|---|---|---|
| 内存 提示缓存 | ~5 – 10 分钟(最长可达 1 小时) | 所有支持缓存的模型 |
| 扩展 提示缓存 | 最长 24 小时 | 仅在特定模型上可用(例如 GPT‑5.2) |
注意: 在大多数最新模型中,Prompt Caching 默认已启用,但仍可自行调整保留设置。
一个最小的 Python 示例
以下是一个演示 OpenAI API 提示缓存的简短脚本。示例使用非常大的共享前缀,以便缓存效果明显。
from openai import OpenAI
api_key = "your_api_key"
client = OpenAI(api_key=api_key)
# ----------------------------------------------------------------------
# A huge prompt prefix (repeated 80×) to push the token count above the
# 1 024‑token threshold required for caching.
# ----------------------------------------------------------------------
prefix = """
You are a helpful cooking assistant.
Your task is to suggest simple, practical dinner ideas for busy people.
Follow these guidelines carefully when generating suggestions:
General cooking rules:
- Meals should take less than 30 minutes to prepare.
- Ingredients should be easy to find in a regular supermarket.
- Recipes should avoid overly complex techniques.
- Prefer balanced meals including vegetables, protein, and carbohydrates.
Formatting rules:
- Always return a numbered list.
- Provide 5 suggestions.
- Each suggestion should include a short explanation.
Ingredient guidelines:
- Prefer seasonal vegetables.
- Avoid exotic ingredients.
- Assume the user has basic pantry staples such as olive oil, salt, pepper, garlic, onions, and pasta.
Cooking philosophy:
- Favor simple home cooking.
- Avoid restaurant‑level complexity.
- Focus on meals that people realistically cook on weeknights.
Example meal styles:
- pasta dishes
- rice bowls
- stir fry
- roasted vegetables with protein
- simple soups
- wraps and sandwiches
- sheet‑pan meals
Diet considerations:
- Default to healthy meals.
- Avoid deep frying.
- Prefer balanced macronutrients.
Additional instructions:
- Keep explanations concise.
- Avoid repeating the same ingredients in every suggestion.
- Provide variety across the meal suggestions.
""" * 80 # repeat to exceed the caching threshold
# --------------------------------------------------------------
# Prompt 1 – first request (populates the cache)
# --------------------------------------------------------------
prompt1 = prefix + "What should I cook for dinner?"
response1 = client.responses.create(
model="gpt-5.2",
input=prompt1
)
print("\nResponse 1:")
print(response1.output_text)
print("\nUsage stats:")
print(response1.usage)
# --------------------------------------------------------------
# Prompt 2 – second request (reuses the cached prefix)
# --------------------------------------------------------------
prompt2 = prefix + "What should I cook for lunch?"
response2 = client.responses.create(
model="gpt-5.2",
input=prompt2
)
print("\nResponse 2:")
print(response2.output_text)
print("\nUsage stats:")
print(response2.usage)背后发生了什么?
- Prompt 1 消耗完整的 token 数量(≈ 20 014 个 token)。
- Prompt 2 重用缓存的前缀,因此仅对非相同部分计费。
- 收费的 token 大约为 20 014 – 19 840 = 174 个 token(≈ 99 % 的节省)。
何时使用 Prompt 缓存能获得回报?
OpenAI 仅在达到 1 024‑token 最低阈值 后才会激活缓存,且缓存可保留 最长 24 小时(扩展模式)。因此,最大的成本和延迟优势出现在 大规模部署 中,其中:
- 许多用户每天都会使用同一应用。
- Prompt 前缀较长且经常重复。
在此类场景下,Prompt 缓存可以显著降低 token 使用量并提升 LLM 驱动应用的响应时间。
在我心中
Prompt 缓存是对大型语言模型(LLM)的一种强大优化手段,能够显著提升 AI 应用的效率——无论是成本还是时间。通过对相同的提示前缀复用先前的计算,模型可以跳过冗余的运算,避免反复处理相同的输入 token。这样可以获得更快的响应和更低的费用,尤其是在提示的大部分内容(例如系统指令或检索到的上下文)在多次请求中保持不变的场景下。
随着 AI 系统规模的扩大以及 LLM 调用次数的增加,这类优化变得愈发重要。
与我联系
除非另有说明,所有图片均为作者本人提供。