Agent的上下文处理

约 914 字 约 4 分钟阅读

2026-03-23 Agent的上下文处理


引言

Agent 是基于 LLM 完成任务的系统,而上下文管理直接决定它能不能正确理解和执行任务。

上下文处理不是把所有历史记录一股脑塞给 LLM,而是要根据任务性质和上下文类型选择处理方式。对话轮次一多,上下文会持续膨胀,全量传递会带来几个直接问题:

  • Token 消耗过大:成本急剧上升
  • 响应延迟增加:模型处理时间变长
  • 信息噪音干扰:关键信息被淹没
  • 上下文窗口溢出:超出模型限制

所以,上下文策略是 Agent 工程里绕不开的一环。


上下文处理的常见方式

1. 上下文缓存

缓存是最基础也最有效的手段:把频繁使用的上下文预先算好存起来,避免重复处理。

实现方式:

class ContextCache:
    def __init__(self, max_size=100):
        self.cache = {}
        self.max_size = max_size
    
    def get(self, key):
        return self.cache.get(key)
    
    def set(self, key, value):
        if len(self.cache) >= self.max_size:
            # LRU 淘汰策略
            oldest_key = next(iter(self.cache))
            del self.cache[oldest_key]
        self.cache[key] = value

应用场景:

  • 系统提示词(System Prompt)缓存
  • 常用工具描述缓存
  • 用户偏好设置缓存
  • RAG 检索结果的缓存

注意事项:

  • 需要合理的缓存失效策略
  • 注意缓存一致性问题
  • 对于动态变化的内容要谨慎使用

2. 上下文压缩

压缩的目标,是在不丢关键信息的前提下减少上下文的 Token 数量。

常用压缩技术:

技术 原理 适用场景
语义压缩 提取核心语义,去除冗余表达 长对话历史
结构化压缩 将非结构化文本转为结构化格式 工具调用结果
截断压缩 保留最近 N 轮对话 简单对话场景
蒸馏压缩 用小模型生成压缩版本 大规模文档

示例:语义压缩

原始上下文(150 tokens):
"用户在 3 月 15 日询问了关于 Python 异步编程的问题,我详细解释了 async/await 
的用法,并提供了三个示例代码。用户表示理解了,然后问了一个关于 asyncio 库的
问题,我解释了事件循环的概念..."

压缩后(30 tokens):
"对话主题:Python 异步编程;已解答:async/await、asyncio;用户状态:理解"

实现要点:

  • 压缩比与信息保留需要权衡
  • 关键决策点信息不能丢失
  • 可使用 LLM 辅助压缩(但需考虑成本)

3. 上下文摘要

摘要和压缩类似,但它不只是提取关键点,更强调生成一段连贯的总结性描述。

摘要层级结构:

层级 名称 描述
第一层 全局摘要 整个会话的核心目标与进展
第二层 阶段摘要 最近 N 轮对话的总结
第三层 原始对话 最近 3-5 轮的完整上下文

摘要触发策略:

  • 轮次触发:每 N 轮对话生成一次摘要
  • 长度触发:上下文超过阈值时触发
  • 阶段触发:完成一个子任务后触发

代码示例:

def should_summarize(messages, threshold=4000):
    total_tokens = sum(estimate_tokens(m) for m in messages)
    return total_tokens > threshold

def summarize_context(messages, llm):
    summary_prompt = f"""
    请总结以下对话的核心内容:
    
    对话历史:
    {format_messages(messages)}
    
    请用简洁的语言总结:
    1. 用户的核心需求
    2. 已完成的工作
    3. 待解决的问题
    """
    return llm.generate(summary_prompt)

4. 上下文筛选

筛选指的是根据当前任务的相关性,动态决定哪些上下文值得放进窗口。

筛选维度:

  1. 时间相关性:优先保留最近的对话
  2. 主题相关性:保留与当前任务相关的历史
  3. 重要性权重:保留关键决策和结果
  4. 用户关注度:保留用户明确提及的内容

基于向量检索的筛选:

from sentence_transformers import SentenceTransformer
import numpy as np

class ContextSelector:
    def __init__(self, model_name='all-MiniLM-L6-v2'):
        self.model = SentenceTransformer(model_name)
    
    def select_relevant(self, query, history, top_k=5):
        # 编码查询
        query_embedding = self.model.encode(query)
        
        # 编码历史上下文
        history_embeddings = self.model.encode(history)
        
        # 计算相似度
        similarities = np.dot(history_embeddings, query_embedding)
        
        # 选择最相关的 top_k
        top_indices = np.argsort(similarities)[-top_k:][::-1]
        return [history[i] for i in top_indices]

筛选策略组合:

最终上下文 = 最近3轮对话 + 相关历史(检索) + 关键决策(标记) + 系统提示

最佳实践

分层上下文管理

Level 1: 系统级(始终保留)
    └── 系统提示、工具定义、安全规则

Level 2: 会话级(摘要保留)
    └── 会话目标、关键决策、重要结果

Level 3: 阶段级(压缩保留)
    └── 当前任务相关历史

Level 4: 即时级(完整保留)
    └── 最近 2-3 轮对话

动态调整策略

class AdaptiveContextManager:
    def __init__(self):
        self.strategies = {
            'simple': SimpleTruncation(),
            'moderate': CompressionStrategy(),
            'complex': SummaryStrategy(),
        }
    
    def select_strategy(self, task_complexity, context_length):
        if context_length < 2000:
            return self.strategies['simple']
        elif task_complexity == 'high':
            return self.strategies['complex']
        else:
            return self.strategies['moderate']

总结

上下文处理是 Agent 架构的核心挑战之一。做得好的收益很直接:

  1. 降低成本:少花冤枉 Token
  2. 提升性能:响应更快
  3. 提高质量:模型的注意力集中在关键信息上
  4. 扩展能力:支撑更长的对话和更复杂的任务

实际应用里通常是多种策略组合使用、按场景动态切换。另外一个趋势是:随着上下文窗口越来越大,处理的重点已经从"怎么塞进去"变成"怎么组织得更有效"。

aiagent上下文llm

评论讨论