🧠AI Prompt 与上下文
上下文管理与缓存
面试回答
常见问法
为什么 AI 系统要做上下文裁剪、摘要和缓存?
回答
因为上下文窗口有限,而且上下文越长,成本和延迟通常越高。实际系统必须决定哪些信息保留、哪些裁剪、哪些压缩成摘要,同时通过缓存减少重复请求带来的浪费。
# 上下文裁剪策略示例
def manage_context(history, max_tokens=4000):
"""
智能上下文管理:根据重要性保留关键信息
策略:
1. 最新对话优先
2. 摘要压缩长对话
3. 关键决策点保留
"""
# 按时间排序,最新对话优先
sorted_history = sorted(history, key=lambda x: x['timestamp'], reverse=True)
current_tokens = 0
selected_messages = []
for msg in sorted_history:
msg_tokens = estimate_tokens(msg['content'])
# 系统消息和最新用户消息必须保留
if msg['role'] == 'system' or msg.get('is_latest_user', False):
selected_messages.append(msg)
current_tokens += msg_tokens
else:
# 长消息用摘要替代
if msg_tokens > 200:
summary = summarize_message(msg['content'])
summary_tokens = estimate_tokens(summary)
if current_tokens + summary_tokens <= max_tokens:
selected_messages.append({
'role': msg['role'],
'content': f"[摘要] {summary}",
'original_id': msg['id']
})
current_tokens += summary_tokens
else:
# 普通消息直接保留
if current_tokens + msg_tokens <= max_tokens:
selected_messages.append(msg)
current_tokens += msg_tokens
# 确保不超过token限制
while current_tokens > max_tokens and len(selected_messages) > 2:
removed = selected_messages.pop(0)
current_tokens -= estimate_tokens(removed['content'])
return selected_messages
# 缓存策略示例
class LLMResponseCache:
def __init__(self, max_size=1000, ttl=3600):
self.cache = {}
self.max_size = max_size
self.ttl = ttl
def get_cache_key(self, prompt, model_params):
"""生成缓存键"""
key_data = f"{prompt}:{json.dumps(model_params, sort_keys=True)}"
return hashlib.md5(key_data.encode()).hexdigest()
def get(self, prompt, model_params):
"""获取缓存响应"""
key = self.get_cache_key(prompt, model_params)
if key in self.cache:
response, timestamp = self.cache[key]
if time.time() - timestamp < self.ttl:
return response
return None
def set(self, prompt, model_params, response):
"""设置缓存"""
key = self.get_cache_key(prompt, model_params)
# LRU淘汰
if len(self.cache) >= self.max_size:
oldest_key = min(self.cache.keys(), key=lambda k: self.cache[k][1])
del self.cache[oldest_key]
self.cache[key] = (response, time.time())
return key
追问
- 什么信息适合保留原文,什么适合摘要?(关键决策vs细节)
- 为什么缓存不仅省钱,还可能提升稳定性?(避免重复生成)
- 对话历史过长时,直接截断会有什么风险?(上下文丢失)
原理展开
上下文管理的本质是信息预算分配。模型并不会自动知道”哪些历史最重要”,所以系统层必须控制输入结构。常见策略包括固定窗口、摘要压缩、按任务重组上下文和检索式补充历史。
缓存则更多是工程优化手段,适合放在系统提示词、重复查询结果或中间步骤上。做得好可以降低延迟和成本,做不好则可能把过期或不适用的信息重复喂给模型。
# 高级上下文管理:基于语义的摘要
def semantic_context_compression(history, importance_threshold=0.7):
"""
基于语义重要性的上下文压缩
1. 对每个消息进行重要性评分
2. 保留高重要性消息
3. 压缩低重要性消息
"""
from sentence_transformers import SentenceTransformer
import numpy as np
model = SentenceTransformer('all-MiniLM-L6-v2')
# 评分每个消息的重要性
message_scores = []
for i, msg in enumerate(history):
score = calculate_importance(msg, history, model)
message_scores.append((i, score))
# 按重要性排序
message_scores.sort(key=lambda x: x[1], reverse=True)
# 保留高重要性消息,压缩低重要性消息
compressed_context = []
for i, score in message_scores:
msg = history[i]
if score >= importance_threshold:
# 高重要性:保留原文
compressed_context.append(msg)
else:
# 低重要性:生成摘要
summary = summarize_message(msg['content'])
compressed_context.append({
'role': msg['role'],
'content': f"[压缩] {summary}",
'importance_score': score
})
return compressed_context
# 智能缓存:考虑时效性
class TimeAwareCache:
def __init__(self):
self.cache = {}
self.access_log = {}
def should_cache(self, prompt, response):
"""
智能判断是否应该缓存
1. 高频查询优先缓存
2. 时效性强的内容谨慎缓存
3. 复杂计算结果优先缓存
"""
# 检查查询频率
query_count = self.access_log.get(prompt, 0)
# 检查响应复杂度(token数量)
response_complexity = len(response.split())
# 判断是否适合缓存
if query_count > 3 and response_complexity > 50:
return True
elif query_count > 10:
return True
else:
return False
易错点
- 只关注窗口长度,不关注上下文质量
- 把缓存当作简单 key-value,不考虑版本和失效
- 摘要过度压缩导致信息丢失
- 缓存策略不考虑时效性
记忆技巧
记住上下文管理三要素:
- 裁剪 = “保留什么,丢弃什么”
- 摘要 = “长话短说,抓重点”
- 缓存 = “重复查询,直接返回”
典型应用场景:
- 对话系统:历史消息管理
- 文档分析:长文档摘要
- 问答系统:查询结果缓存
- 实时系统:时效性敏感缓存