LLM应用落地必读(四):上下文管理与Claude Code的分级压缩
回顾上一篇文章中的智能体天气助手:经过三轮推理-行动,LLM的输入从最初的三条消息,膨胀到了七条——用户问题、系统提示词、工具定义、前两轮的LLM输出以及工具执行结果,而这已经占用了上下文窗口中的数千Token。
试想一个更复杂的智能体:需要调用十几个工具、经历七八轮循环,上下文长度将轻松突破数万甚至数十万Token。上下文太少,LLM无法推理;太多,又会导致成本上升,推理性能崩塌。更麻烦的是,循环次数是LLM动态决定的,根本无法提前预判最终的上下文会有多长。这涉及到了智能体开发中的核心问题——上下文管理。
智能体的上下文中到底有什么?为什么需要管理它?具体又该如何管理?——这三个问题,正是本文要回答的。
一、为什么需要管理上下文
一个常见的挫败场景:你开发了一个智能体,前几轮对话它表现完美。但聊了几分钟后,它开始“变笨”——它忘记你之前说过的话、忽略关键信息、回答也变得混乱。
这不是模型变差了,而是上下文窗口满了。这个问题的根源,要从Transformer架构的底层机制说起。
当前主流的LLM都采用Transformer架构,该架构中的自注意力机制(Self-Attention)计算上下文中每个Token之间的注意力分数,对于n个Token而言,自注意力机制会进行n的平方次交互计算,因此计算量和内存需求与上下文长度的平方成正比。上下文窗口是一种稀缺资源,它是有瓶颈的。
Kelly Hong等人在2025年评估了18种前沿模型,包括GPT-4.1、Claude 4、Gemini 2.5和Qwen3,证明了大语言模型在不同输入长度下无法保持一致的性能,即使在上下文窗口限度之内,随着输入长度的增加,LLM性能也呈现出越来越明显的不均衡性,他们将之称为上下文衰减(Context Rot),这和我们在挫败场景中的感知一致。
综合来看,上下文管理的核心目标是精简上下文长度,不要把无效、失效信息输入LLM,避免它忽略重要内容。同时要防止上下文窗口的溢出,确保关键信息不会因超限而被截断。
有效的上下文管理对于智能体的可靠性至关重要。
二、上下文里有什么
上下文是LLM的输入,在智能体中,它包括了如下几部分内容:系统提示词(System Prompt)、工具定义(Tool Definition)、对话历史(Conversation History)、当前轨迹的工具执行结果(Tool Call Results from Current Trajectory)以及检索到的文档(Retrieved Doc)。下面将逐一介绍这几大内容。
2.1 系统提示词
这是上下文中“最稳定”的部分,通常固定不变,但在每一轮推理-行动中都会被重复输入。
2.2 工具定义
LLM能够在推理中做出调用工具的决定的前提是它知道所有工具的定义。每个工具的定义(采用JSON Schema格式)都会在每一轮的推理-行动中注入上下文。如果一个智能体有10个工具,每个工具定义平均300个Token,这就是3000 Token的固定开销。对于一个进行7轮推理-行动循环的任务而言,单就工具定义一项就花费了21000 Token。
部分模型支持Prompt Caching机制(如Anthropic Claude),工具定义可以被缓存,后续轮次不会重复计费。但缓存在上下文结构发生变化时会失效,实际节省效果取决于具体实现。
2.3 对话历史
对话历史是在推理-行动循环中累计产生的,它包括:
1. 用户的原始问题和中间的澄清回应
2. LLM的中间回复和工具调用指令
3. LLM的中间推理内容
不同LLM的策略不同——例如OpenAI的reasoning_content字段默认不回传,而DeepSeek的同一字段会被纳入上下文。
4. 历史的工具执行结果
智能体常处于多轮推理-行动循环中,如果每一轮推理-行动产生的对话作为对话历史被带入下一轮,这将导致上下文快速膨胀。
2.4 当前轨迹的工具执行结果
工具执行结果属于历史的还是当前轨迹的,取决于它对应的任务是否已完成。
历史的工具执行结果:已完成任务中产生的工具执行结果。例如用户先询问“上海天气”,再询问“北京天气”,上海天气的查询结果就属于历史的工具执行结果。
当前轨迹的工具执行结果:正在执行的任务中产生的工具执行结果。例如在“查询北京天气,如果北京下雨就查天津的天气”这个任务中,北京天气的查询结果就属于当前轨迹的工具执行结果,它直接影响下一步决策。
区分历史的和当前轨迹的工具执行结果的意义在于:历史的可以压缩,而当前轨迹的必须完整保留。
2.5 检索到的文档
这类内容主要出现在检索增强生成(Retrieval-Augmented Generation,简称RAG)的场景中,这是为了解决LLM自身知识不足的问题,因为LLM无法获知私有知识(如公司内部文档)和最新知识(如LLM训练数据截止日期之后的信息)。
检索到的文档对上下文管理带来了独特的挑战:
1. 相关性带来的噪音:检索算法可能将相关性低文的档注入上下文。
2. 时效性导致的误导:LLM无法判断检索到的文档是否过时。
相关性和时效性都不仅会浪费宝贵的上下文资源,也会干扰LLM的推理。应对这些挑战的常见策略包括:检索时使用更高阈值的相似度过滤、对检索结果进行重排序(Rerank)、以及对过时文档进行时效性标注。
了解了上下文中具体包含哪些内容之后,下一个问题是:如何高效地管理它们?下一章,我们将以Claude Code为例,深入分析其5级分级压缩机制。
三、Claude Code的上下文管理
Claude Code的上下文管理采用5个层级的分级压缩机制,压缩程度逐级递增,只有当破坏性更小,更经济的压缩机制无法胜任的时候才会升级到下一层压缩机制。
这5级压缩机制依次为:
1. 工具执行结果预算控制(Tool Result Budget):这是第1级压缩机制,该压缩机制始终激活,对每个工具执行结果的大小进行限制。
2. 历史消息裁剪(History Snip):这是第2级压缩机制,由功能标识HISTORY_SNIP控制。该压缩机制对较早的历史消息进行裁剪。
3. 微压缩(Microcompact):这是第3级压缩机制,由功能标识CACHED_MICROCOMPACT控制。该压缩机制对特定工具的历史执行结果进行“精准瘦身”。
4. 上下文折叠(Context Collapse):这是第4级压缩机制,由功能标识CONTEXT_COLLAPSE控制。在不修改 REPL 存储历史的前提下,通过对完整对话历史进行只读投影,为LLM生成一个经过压缩与摘要处理的视图。
5. 自动压缩(Auto Compact):这是第5级压缩机制,默认启用,可禁用。该压缩机制又分为会话内存压缩(Session Memory Compaction)和传统压缩(Legacy Compaction)。会话内存压缩直接利用已有的记忆作为摘要,无需额外调用LLM。而传统压缩则要调用LLM将对话历史生成自然语言摘要。
3.1 工具执行结果预算控制
Claude Code 用两层限制机制对工具执行结果做了替换处理:
1. 第一层(单工具限制):如果单个工具执行结果的大小超过该工具声明的 maxResultSizeChars(每个工具可独立声明字符上限,但不能超过系统级上限,即默认 50K 字符),结果将被完整保存到磁盘。原始内容不会出现在 LLM 的输入中,取而代之的是一段简短的替代文本,其中包含保存路径和原始大小等元信息。
2. 第二层(单消息聚合限制):针对一次性并行调用多个工具的情况,如果单个工具的执行结果均未超过单工具限制,但合计超过 200K 字符,则从最大的工具执行结果开始依次保存到磁盘,直到总大小回到200K字符的限制内为止。输入LLM的同样是被替换为包含文件路径的文本。
替换后的文本作为工具执行结果会在后续推理-行动轮次中持续复用,从而降低上下文大小。如果 LLM 需要获取完整的工具执行结果,可以通过文本读取工具根据替代文本中的文件路径读取。
3.2 对话历史裁剪
较早的对话历史会被裁剪从而控制上下文大小,裁剪后会返回如下内容:
1. messages:裁剪后的新消息列表,旧的历史片段被移除。
2. tokensFreed:显式传递裁剪节省的 Token 数。由于LLM回复的最近一条 assistant 消息的usage字段记录的是裁剪前的 Token 数,主计数器无法自动感知节省的Token数,因此需要该值来修正后续自动压缩阶段的阈值判断。
3. boundaryMessage:作为边界标记,表明此处省略了较早的对话历史。这是为了保持语义完整,避免 LLM 对缺失的历史产生困惑。
对话历史裁剪示例:
裁剪前:[消息1, 消息2, 消息3, 消息4, 消息5]
裁剪后:[boundaryMessage, 消息4, 消息5]
由于 Claude Code 未公开此部分代码,故无法获知更多的实现细节。
3.3 微压缩
一个工具被执行,如果返回结果超过限制,会先被工具结果预算控制机制处理(输入LLM前的预处理)。对于那些已经在上下文中的历史工具执行结果,Claude Code 采用微压缩机制进行精准控制。
这里需要指出的是:微压缩机制不是针对所有工具,而是针对如下的特定工具。
/ Only compact these tools
const COMPACTABLE_TOOLS = new Set<string>([
FILE_READ_TOOL_NAME,
...SHELL_TOOL_NAMES,
GREP_TOOL_NAME,
GLOB_TOOL_NAME,
WEB_SEARCH_TOOL_NAME,
WEB_FETCH_TOOL_NAME,
FILE_EDIT_TOOL_NAME,
FILE_WRITE_TOOL_NAME,
])
这些工具有着共同特点:执行结果体积大(如文件读取),但一旦执行完成,后续推理只需要知道“这个工具被调用过”,而不需要记住具体内容。
针对这些特定工具的历史执行结果,微压缩机制确保 LLM 在后续推理中看到的是 [Old tool result content cleared] 占位符,而非原始内容。这样 LLM 只知道"曾调用过这个工具",而无需记住具体内容。
微压缩机制根据缓存(Prompt Cache)状态自动选择如下两种实现方式:
缓存有效时(Warm Cache):通过Anthropic API发送完整的历史工具执行结果,保持 Prompt Cache 命中,但同时附带cache_edits字段(包含[Old tool result content cleared]内容),如此告知LLM在推理时忽略该工具完整的历史执行结果。
缓存失效时(Cold Cache):此时Prompt Cache已经不再值得强行维护,直接将历史工具执行结果改为[Old tool result content cleared] 占位符
这样做的最终效果是:节省上下文空间,降低 Token 成本,同时最大程度保留缓存价值。
Prompt Cache 是一种 LLM 复用 Token 的优化机制。它的核心原理是将输入到 LLM 的上下文的 KV 缓存保存下来。当新的输入与已缓存的上下文共享相同的前缀时(即两次输入有共同的前段部分),可以直接复用这共同部分的 KV 缓存,只需计算差异部分即可,无需重新计算整个前缀。
3.4 上下文折叠
上下文折叠是一种运行时投影(Projection)机制,它在不修改 REPL 存储历史的前提下,通过对完整对话历史进行只读投影,为LLM生成一个经过压缩与摘要处理的视图。摘要消息保存在独立的折叠存储(Collapse Store)中,而非原始 REPL 数组中,这使得折叠后的上下文能够在多轮对话中持续生效。该机制在自动压缩之前执行,旨在通过折叠降低上下文长度,从而避免触发更激进的自动压缩,保留更细粒度的历史信息。每次进入对话时,系统会重放折叠日志来重建视图;而在同一轮对话内,视图会随状态向前推进,已归档的消息不会重复处理。这种设计让LLM能够看到精简后的内容,同时完整历史依然可用于回溯与重建。
通俗理解:上下文折叠不是真的删掉历史,而是给LLM一个“精简版”的视图。就像你看一本书的目录和摘要,不需要逐页阅读也能把握全局。完整历史仍然保留,必要时可以回溯。
由于 Claude Code 未公开此部分代码,故无法获知更多的实现细节。
3.5 自动压缩
在前面4种机制运行后,上下文仍超限,自动压缩将会被触发。在自动压缩机制中又有两级压缩方案
1. 第一优先级:会话内存压缩
Claude Code 在推理-行动循环中会持续维护会话内存(Session Memory),这是一个结构化的会话记忆。会话内存压缩时,直接利用这个已有的记忆作为摘要,无需额外 调用LLM。
2. 第二优先级:传统压缩
传统压缩调用LLM将对话历史生成自然语言摘要,只有当会话内存压缩不可用时才会启用。这也是最后一层防止上下文溢出的防线。
两种压缩方案的本质区别在于:会话内存压缩是“复用已有结构”(无需额外LLM调用),传统压缩是“即时生成摘要”(需要一次LLM调用)。前者更快更便宜,但依赖会话内存机制始终有效。
四、小结
本文从智能体上下文膨胀的问题出发,拆解了上下文的五大组成部分:系统提示词、工具定义、对话历史、当前轨迹的工具执行结果、检索到的文档。每一部分都有其独特的消耗特征和管理策略。
Claude Code的5级分级压缩机制为我们提供了一个优秀的设计范本和值得借鉴的设计原则:
1. 分级递进:从破坏性最小的压缩机制开始逐级升级
2. 按类型区分:不同工具、不同阶段的内容采用不同策略
3. 保留回溯能力:压缩不等于永久删除,重要信息仍可恢复
上下文管理需要根据应用场景在“信息完整性”和“窗口效率”之间做出权衡。
五、参考文献
1. Kelly Hong, Anton Troynikov, and Je! Huber. Context rot: How increasing input tokens impacts llm performance, 2025.
2. Jiacheng Liu, Xiaohan Zhao, Xinyi Shang. Dive into Claude Code: The Design Space of Today’s and Future AI Agent Systems. 2026
3. Junjie Li, Xi Xiao, Yunbei Zhang, et al. Agent Harness Engineering: A Survey. 2026
作者:徐宏勤
版权声明:本文为原创内容。如需转载,请务必在文章开头标注作者和来源,并保持文章完整,否则视为侵权。
更多推荐

所有评论(0)