提示词缓存基础设施:降低LLM成本与延迟
更新于2025年12月11日
2025年12月更新: Anthropic前缀缓存实现长提示词90%成本降低和85%延迟降低。OpenAI自动缓存默认启用(节省50%成本)。31%的LLM查询呈现语义相似性——缺乏缓存的部署将造成巨大效率损失。² 缓存读取仅需$0.30/百万token,而新请求需$3.00/百万token(Anthropic)。多层缓存架构(语义→前缀→推理)最大化节省。
Anthropic的提示词缓存可将长提示词的成本降低高达90%,延迟降低高达85%。¹ OpenAI通过默认启用的自动缓存实现50%成本降低。研究表明,31%的LLM查询与之前的请求存在语义相似性,这意味着缺乏缓存基础设施的部署存在巨大的效率损失。² 运行生产级AI应用的企业如果没有适当的缓存策略,将白白损失大量资金。
提示词缓存在多个层级运作——从重用KV缓存计算的服务商侧前缀缓存,到为相似查询返回先前响应的应用层语义缓存。理解每个层级及其适用场景,有助于企业根据自身的工作负载模式优化成本和延迟。
缓存基础知识
LLM推理成本来源于两部分:处理输入token和生成输出token。缓存策略针对这两方面:
输入token缓存(前缀缓存)
每个LLM请求都会通过模型的注意力机制处理输入token,生成存储在KV缓存中的键值对。当多个请求共享相同的前缀——系统提示词、少样本示例或文档上下文时——KV缓存的计算会不必要地重复。
前缀缓存解决方案: 存储常见前缀的已计算KV值。后续具有匹配前缀的请求可跳过重新计算,直接从缓存状态开始。
成本影响: - Anthropic:缓存读取仅需$0.30/百万token,而新处理需$3.00/百万token(节省90%) - OpenAI:缓存token享受50%折扣 - Google:基于上下文窗口的可变定价
延迟影响: 跳过前缀计算可将首token时间降低50-85%,具体取决于前缀长度。
输出缓存(语义缓存)
某些请求应获得相同的响应——重复问题、确定性查询或无需重新生成的查找。
语义缓存解决方案: 以语义相似的输入为键存储响应输出。对于匹配的查询,直接返回缓存响应,无需调用LLM。
成本影响: 缓存响应完全消除API调用——缓存命中时节省100%。
延迟影响: 响应在毫秒内返回,而非LLM推理所需的数秒。
缓存层级
生产系统通常实现多层缓存:
请求 → 语义缓存(节省100%) → 前缀缓存(节省50-90%) → 完整推理
↓ ↓ ↓
缓存响应 缓存KV状态 新鲜计算
每一层根据请求的相似性模式捕获不同的优化机会。
服务商级提示词缓存
Anthropic Claude
Anthropic提供最可配置的提示词缓存:³
定价: - 缓存写入:比基础输入价格高25% - 缓存读取:90%折扣(基础价格的10%) - 收支平衡点:每个缓存前缀2次以上缓存命中
要求: - 每个缓存检查点最少1,024个token - 每个请求最多4个缓存检查点 - 缓存有效期:最后访问后5分钟(定期命中可延长至1小时) - 最多可缓存5轮对话
实现:
import anthropic
client = anthropic.Anthropic()
# 使用cache_control标记需要缓存的内容
response = client.messages.create(
model="claude-3-5-sonnet-20241022",
max_tokens=1024,
system=[
{
"type": "text",
"text": "You are an expert assistant for our enterprise software...",
"cache_control": {"type": "ephemeral"} # 标记为缓存
}
],
messages=[{"role": "user", "content": "How do I configure user permissions?"}]
)
最佳实践: - 将静态内容(系统提示词、文档)放在提示词开头 - 将动态内容(用户输入、对话)放在末尾 - 在自然边界处使用缓存检查点 - 监控缓存命中率以验证优化效果
OpenAI
OpenAI实现了无需代码更改的自动缓存:⁴
定价: - 缓存token:基础输入价格的50% - 无缓存写入溢价
要求: - 最少1,024个token才能启用缓存 - 缓存命中以128个token为单位递增 - 缓存有效期:不活跃5-10分钟
自动行为: - 超过1,024个token的提示词自动缓存 - 系统自动检测跨请求的匹配前缀 - 无需修改API
监控:
response = client.chat.completions.create(
model="gpt-4-turbo",
messages=[...],
)
# 检查使用情况中的缓存命中
print(f"缓存token数: {response.usage.prompt_tokens_details.cached_tokens}")
print(f"总输入token数: {response.usage.prompt_tokens}")
Google Gemini
Google为Gemini模型提供上下文缓存:⁵
定价: - 基于缓存上下文大小和持续时间的可变定价 - 缓存内容存储费用
功能: - 显式缓存创建和管理 - 可配置的生存时间 - 跨请求缓存共享
实现:
from google.generativeai import caching
# 创建缓存内容
cache = caching.CachedContent.create(
model='models/gemini-1.5-pro-001',
display_name='product-documentation',
system_instruction="You are a product expert...",
contents=[product_docs],
ttl=datetime.timedelta(hours=1)
)
# 在请求中使用缓存内容
model = genai.GenerativeModel.from_cached_content(cached_content=cache)
response = model.generate_content("How do I configure feature X?")
Amazon Bedrock
AWS为支持的模型提供预览版提示词缓存:⁶
要求: - Claude 3.5 Sonnet每个检查点最少需要1,024个token - 第二个检查点需要2,048个token
实现模式遵循Bedrock API结构中Anthropic的cache_control方法。
vLLM前缀缓存
使用vLLM自托管推理包含自动前缀缓存:⁷
架构
vLLM的自动前缀缓存(APC)将KV块存储在哈希表中,无需树结构即可实现缓存重用:
关键设计: - 所有KV块在初始化时存储在块池中 - 基于哈希的前缀匹配查找 - O(1)的块管理操作 - 保持PagedAttention的内存效率
配置
from vllm import LLM
llm = LLM(
model="meta-llama/Llama-3.1-8B-Instruct",
enable_prefix_caching=True, # 启用APC
gpu_memory_utilization=0.90,
)
性能影响
使用PagedAttention的vLLM比朴素实现展示出14-24倍的更高吞吐量。⁸ 前缀缓存额外带来:
- 缓存和非缓存token之间10倍的成本差异
- 匹配前缀的延迟降低一个数量级
- 通过共享KV块提高内存效率
安全考虑
vLLM支持共享环境中的缓存隔离:
# 每请求缓存盐值防止跨租户缓存访问
response = llm.generate(
prompt="...",
sampling_params=SamplingParams(...),
cache_salt="tenant-123" # 按租户隔离缓存
)
缓存盐值注入块哈希可防止定时攻击,即攻击者通过延迟观察推断缓存内容。
LMCache扩展
LMCache通过高级缓存功能扩展vLLM:⁹
功能: - 跨引擎实例的KV缓存重用 - 多层存储(GPU → CPU内存 → 磁盘) - 非前缀内容缓存 - 基准测试中3-10倍延迟降低
架构:
vLLM引擎 → LMCache → GPU显存(热)
→ CPU内存(温)
→ 本地磁盘(冷)
语义缓存
语义缓存为语义相似(而非仅仅相同)的查询返回先前的响应:
GPTCache
GPTCache为LLM应用提供开源语义缓存:¹⁰
架构:
查询 → 嵌入 → 向量搜索 → 相似度检查 → 响应/API调用
↓ ↓ ↓
BERT/OpenAI Milvus/FAISS 阈值(0.8)
组件: - LLM适配器: 与各种LLM服务商的集成 - 嵌入生成器: 查询向量化 - 向量存储: 相似性搜索(Milvus、FAISS、Zilliz) - 缓存管理器: 存储和检索 - 相似度评估器: 基于阈值的匹配
实现:
from gptcache import cache
from gptcache.adapter import openai
# 初始化语义缓存
cache.init(
pre_embedding_func=get_text_embedding,
data_manager=manager,
)
# 使用缓存的OpenAI调用
response = openai.ChatCompletion.create(
model='gpt-4',
messages=[{"role": "user", "content": "What is machine learning?"}]
)
# 语义相似的查询("Explain ML"、"Define machine learning")
# 返回缓存响应
性能
GPTCache实现显著的效率提升:¹¹
- API调用减少: 各查询类别高达68.8%
- 缓存命中率: 61.6%至68.8%
- 准确率: 97%以上的正向命中率
- 延迟降低: 缓存命中时40-50%,完全命中时高达100倍
高级技术
VectorQ自适应阈值:¹²
静态相似度阈值(如0.8)在多样化查询中表现不佳。VectorQ学习特定于嵌入的阈值区域,可适应查询复杂度:
- 简单事实查询:较高阈值(更严格匹配)
- 开放式查询:较低阈值(更多重用)
- 模糊查询:动态调整
SCALM模式检测:
SCALM通过模式检测和频率分析改进GPTCache: - 缓存命中率提升63% - token使用减少77% - 识别高频缓存条目模式
何时使用语义缓存
适合的场景: - 答案空间有限的FAQ式查询 - 查找类查询(产品信息、文档) - 确定性响应(计算、格式化) - 具有查询重复的高流量应用
不适合的场景: - 需要独特性的创意生成 - 个性化响应(用户特定上下文) - 时效性信息 - 低重复率的查询模式
实现模式
聊天应用
聊天系统同时受益于前缀缓存和语义缓存:
系统提示词缓存:
# 静态系统提示词在请求开始时缓存
system_prompt = """
You are a customer support agent for Acme Corp...
[2000+个token的指南和知识]
"""
# 动态对话附加在缓存前缀之后
messages = [
{"role": "system", "content": system_prompt, "cache_control": {...}},
{"role": "user", "content": user_message}
]
对话历史缓存: Anthropic支持缓存最多5轮对话,降低多轮对话的成本。
RAG应用
检索增强生成缓存检索到的上下文:
# RAG的缓存结构
cached_context = {
"system": system_prompt, # 始终缓存
"documents": retrieved_chunks, # 按查询集群缓存
"examples": few_shot_examples # 跨请求稳定
}
# 仅用户查询变化
dynamic_content = {
"query": user_question
}
文档块缓存: 当多个查询检索相同文档时,前缀缓存消除了共享上下文的冗余处理。
Agent工作流
带有工具调用的Agent系统受益于前缀缓存:
``` 系统提示词 → 工具定义 → 对话历史 → 当前查询 (已缓存) (已缓存) (部分缓存)
[内容因翻译而截断]