处理一个完整的故障排查流程,AI的上下文(Context)能膨胀到什么地步?
- 收集100条日志 → 5000 tokens
- 分析每个错误 → 10000 tokens
- 搜索解决方案 → 15000 tokens
- 10轮对话下来 → 上下文长度直接爆掉
我尝试过Claude的200K长窗口,也测试过Gemini的1M超长上下文。但窗口越大,注意力稀释问题就越严重——信息确实能装下,但AI反而找不到重点了。
真正的解决方案并非一味追求更大的上下文窗口,而是需要更智能的上下文压缩技术。
一、观察掩码:用完就扔的临时信息
在AI Agent的工作流中,工具调用的原始输出往往占据了上下文80%以上的体积。然而,真正有价值的是当前步骤的分析结论,而非冗长的原始数据。
举个例子:Agent调用了一个日志查询工具,返回了5000行原始日志。分析后得出结论“发现OutOfMemoryError”,那么这5000行日志就完成了使命,可以丢弃,仅需保留“发现OutOfMemoryError”这个结论。
这种策略被称为观察掩码(Observation Masking)——将工具输出视为临时信息,用完即弃,不占用长期上下文。
在我的实践中,所有工具调用输出都会附带一个retention_policy标记来管理其生命周期:
transient:用完即弃,不进入对话历史。
summary:保留摘要,丢弃原始详情。
persistent:完整保留(仅适用于极少数关键信息,如最终结论或核心配置)。
二、内容摘要:让AI自己给自己做笔记
随着对话轮数增加,历史记录本身就会成为负担。
我的做法是:设定每5轮对话触发一次自动摘要。由Agent自己将前5轮对话中的核心结论、重要决策、待办事项提炼成一段约200字的摘要,然后用这段摘要替换掉原始冗长的对话记录。
摘要的本质不是简单的文本压缩,而是信息抽取。一份合格的摘要必须包含:
- 用户的核心诉求
- 已完成的子任务
- 待确认的决策点
- 明确的下一步行动计划
如此一来,10轮对话后,上下文的构成不再是5000个token的原始聊天记录,而是400字的精炼摘要加上当前轮次的输入。这也是构建高效Agent和进行规范驱动开发的核心思路之一。
三、关键信息提取:只保留“必须知道”的内容
最激进的压缩方式是:只保留那些“没有它AI就无法做出判断”的关键信息。
在日志分析这个具体场景中,我设计了一个关键信息过滤器流水线:
输入:原始日志(10000 tokens)
↓
过滤:只保留 ERROR/WARN 级别的日志条目(2000 tokens)
↓
聚合:按错误类型分组,每组仅保留最早和最晚出现的一条(500 tokens)
↓
提取:抽取出时间戳、错误类型、影响范围、堆栈摘要(200 tokens)
↓
进入Context
压缩率高达98%,但所有关键信息无一丢失。
四、三阶段压缩工作流
对于复杂的运维或开发场景,我目前采用的标准流程是一个清晰的三阶段压缩工作流:
Phase 1:研究阶段
- 输入:系统架构图、相关文档、关键API接口说明。
- 输出:一份结构化的分析文档(约2000 tokens)。这份文档是原始信息的消化与提炼。
Phase 2:规划阶段
- 输入:上一阶段产出的研究文档。
- 输出:一份清晰的实现规范,包括函数签名、类型定义、数据流图等。
Phase 3:执行阶段
- 输入:上一阶段产出的实现规范。
- 输出:最终的代码实现。
这个流程的关键在于,每个阶段只携带上一阶段精炼后的输出结果作为输入,而不会背负所有原始的、未经处理的信息。这正是在像LangChain这样的框架中构建高效Agent工作流时需要实践的理念。
五、压缩的代价:在效率与完整性间寻找平衡
压缩并非越狠越好,它需要权衡。
一些研究数据揭示了不同压缩策略的效果:
- 结构化摘要:压缩率98.6%,信息质量得分3.70
- 再生式摘要:压缩率98.7%,信息质量得分3.44
- 不透明压缩:压缩率99.3%,信息质量得分3.35
0.35的质量得分差距看似不大,但如果在压缩过程中丢失了关键文件路径或特定错误码这类元数据,Agent可能不得不额外花费20%的token预算去重新探索和确认,最终得不偿失。
因此,我遵循的核心原则是:关键元数据必须保留,过程性数据可以压缩。要明确区分哪些是决策必需的“信息”,哪些只是用于生成信息的“数据”。
写在最后
上下文压缩远不止是“让Context变短”这么简单。它本质上是在信息的完整性与注意力的使用效率之间寻找一个最佳平衡点。
每一次关于是否压缩、如何压缩的决策,都在回答一个根本性问题:这条信息,AI在下一步推理中真的需要“记住”吗?通过有策略地管理AI的“记忆”,我们才能让它在复杂的任务中持续保持高效和精准。这正是优化RAG应用与智能体效能的深层实践。