🧠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,不考虑版本和失效
  • 摘要过度压缩导致信息丢失
  • 缓存策略不考虑时效性

记忆技巧

记住上下文管理三要素:

  1. 裁剪 = “保留什么,丢弃什么”
  2. 摘要 = “长话短说,抓重点”
  3. 缓存 = “重复查询,直接返回”

典型应用场景:

  • 对话系统:历史消息管理
  • 文档分析:长文档摘要
  • 问答系统:查询结果缓存
  • 实时系统:时效性敏感缓存