logo
开发者文档
搜索
上下文 5 层压缩策略

上下文 5 层压缩策略

概述

长对话场景下,上下文 token 数会逐渐逼近模型的上下文窗口限制。系统采用三层架构、五个压缩策略的级联方案,在保证对话质量的前提下智能管理上下文长度。


策略总览

上下文压缩策略-CN

编号 层级 策略名称 触发条件 处理方式
Layer 1 单工具结果截断 单个工具结果超过上下文的 50% 截断到预算,在换行边界断点
Layer 1 旧工具结果压实 总输入超过上下文的 75% 白名单工具结果替换为占位符
Layer 2 消息历史剪枝 LLM 返回上下文溢出错误 保留关键消息,剪除中间历史
Layer 3 LLM 全量摘要 Layer 2 不足以缓解 分块摘要 + 合并,9 节结构化格式
Layer 3 部分摘要降级 LLM 摘要失败 排除超大消息后重试,最终降级为纯文本通知

Layer 1:预防性工具结果截断

触发时机:每次 LLM 调用前自动执行(预防性,不等溢出发生)。

策略 ① — 单工具结果截断

当单个工具结果超过上下文窗口的 50% 时,截断到预算:

原始工具输出(超长) │ ├── 保留前 N 个字符(在换行边界断点) └── 追加标记: [truncated: output exceeded context limit]
                      
                      原始工具输出(超长)
│
├── 保留前 N 个字符(在换行边界断点)
└── 追加标记: [truncated: output exceeded context limit]

                    
此代码块在浮窗中显示

关键常量

  • SINGLE_TOOL_RESULT_CONTEXT_SHARE = 0.5(单工具上限占比)

策略 ② — 旧工具结果压实

当总输入超过上下文窗口的 75% 时,从最早的工具结果开始压实:

工具调用历史(时间序列) │ ├── 最新的工具结果 → 保留完整内容 ├── 较新的工具结果 → 保留完整内容 ├── 较旧的工具结果 → [compacted: tool output removed to free context] └── 最旧的工具结果 → [compacted: tool output removed to free context]
                      
                      工具调用历史(时间序列)
│
├── 最新的工具结果 → 保留完整内容
├── 较新的工具结果 → 保留完整内容
├── 较旧的工具结果 → [compacted: tool output removed to free context]
└── 最旧的工具结果 → [compacted: tool output removed to free context]

                    
此代码块在浮窗中显示

白名单机制:只对以下高输出工具执行压实:

  • Read File、Bash、Grep、Glob、Search Files、Web Fetch、Edit

Write/Create 类工具的输出永远保留,因为其输出是后续操作的依据。

关键常量

  • CONTEXT_INPUT_HEADROOM_RATIO = 0.75(总输入上限占比)

Layer 2:溢出检测与消息历史剪枝

触发时机:LLM 返回上下文溢出错误时被动触发。

策略 ③ — 消息历史剪枝

剪除中间历史消息,保留关键消息:

消息历史 │ ├── System Prompt ← 始终保留 ├── 第一条用户消息 ← 始终保留 ├── _pin: true 的消息 ← 始终保留 ├── ........ 中间历史 ........ ← 剪除(替换为通知) ├── [context compacted: X earlier messages removed] ├── 最近 N 条消息 ← 保留(N = min(6, ⌊总数/3⌋)) └── 当前消息 ← 保留
                      
                      消息历史
│
├── System Prompt                    ← 始终保留
├── 第一条用户消息                    ← 始终保留
├── _pin: true 的消息                ← 始终保留
├── ........ 中间历史 ........       ← 剪除(替换为通知)
├── [context compacted: X earlier messages removed]
├── 最近 N 条消息                    ← 保留(N = min(6, ⌊总数/3⌋))
└── 当前消息                         ← 保留

                    
此代码块在浮窗中显示

剪枝后自动修复孤立的工具对(tool_use 无对应 tool_result,或反之),确保消息格式合法。


Layer 3:LLM 智能摘要

触发时机:Layer 2 剪枝后仍不足以缓解上下文压力时触发。

策略 ④ — 全量摘要

使用独立的 LLM 调用对历史消息进行结构化摘要:

9 节摘要格式

  1. 用户意图与目标
  2. 关键概念与术语
  3. 涉及的文件与路径
  4. 遇到的错误与解决方案
  5. 问题解决思路
  6. 用户关键消息
  7. 待完成任务
  8. 当前工作进展
  9. 下一步计划

分块策略:当消息超过 50,000 字符时,分为最多 4 块分别摘要,再合并为最终摘要。

策略 ⑤ — 部分摘要降级

当全量摘要失败时,执行三级降级:

降级级别 处理方式
Level 1 排除超大消息(>50,000 字符),对剩余消息重试摘要
Level 2 添加注释 [Note: X oversized message(s) were excluded]
Level 3 返回纯文本通知 [Summary unavailable — X messages could not be summarized]

关键常量汇总

常量 说明
CONTEXT_INPUT_HEADROOM_RATIO 0.75 Layer 1 总输入上限占比
SINGLE_TOOL_RESULT_CONTEXT_SHARE 0.5 Layer 1 单工具上限占比
MAX_OVERFLOW_COMPACTION_ATTEMPTS 5 最大压缩重试次数
COMPACT_MAX_OUTPUT_TOKENS 20,000 摘要 LLM 调用的输出上限
COMPACT_BUFFER_TOKENS 13,000 压实阈值的缓冲区
CHARS_PER_TOKEN 4 普通文本每 token 字符数
TOOL_RESULT_CHARS_PER_TOKEN 2 工具结果(更密集)每 token 字符数

EMA Token 校准

系统使用指数移动平均动态校准 chars-per-token 估算:

阶段 校准方式
初始 3.0 chars/token(保守,适配中文+代码)
前 3 次 LLM 调用 均值收敛
后续 EMA α=0.15 平滑追踪
异常过滤 0.5 < observed < 8 范围外忽略

压缩流程图

每次 LLM 调用前 │ ├── Layer 1: enforceToolResultBudget() │ ├── 单工具截断(>50% 上下文) │ └── 旧工具压实(总输入 >75% 上下文) │ ├── shouldPreemptiveCompact() ? │ └── 是 → compact()(Layer 2 剪枝) │ └── LLM 调用 │ ├── 成功 → 继续 └── 溢出错误 → getRetryStrategy() │ ├── compact()(Layer 2) │ │ │ └── 仍不足 → compactWithSummary()(Layer 3) │ ├── summarizeMessagesFull()(策略 ④) │ ├── 失败 → summarizeMessagesPartial()(策略 ⑤ Level 1-2) │ └── 全失败 → bare notice(策略 ⑤ Level 3) │ └── 重试 LLM 调用(最多 5 次)
                      
                      每次 LLM 调用前
    │
    ├── Layer 1: enforceToolResultBudget()
    │   ├── 单工具截断(>50% 上下文)
    │   └── 旧工具压实(总输入 >75% 上下文)
    │
    ├── shouldPreemptiveCompact() ?
    │   └── 是 → compact()(Layer 2 剪枝)
    │
    └── LLM 调用
        │
        ├── 成功 → 继续
        └── 溢出错误 → getRetryStrategy()
            │
            ├── compact()(Layer 2)
            │   │
            │   └── 仍不足 → compactWithSummary()(Layer 3)
            │       ├── summarizeMessagesFull()(策略 ④)
            │       ├── 失败 → summarizeMessagesPartial()(策略 ⑤ Level 1-2)
            │       └── 全失败 → bare notice(策略 ⑤ Level 3)
            │
            └── 重试 LLM 调用(最多 5 次)

                    
此代码块在浮窗中显示


对用户意味着什么

上下文压缩是你在长对话中可能感受到的"Agent 忘记了之前的内容"现象的原因。 它不是 bug,而是系统在有限的上下文窗口内智能管理信息的机制。

你可能观察到的现象

  • 长对话中,Agent 突然"不记得"你在开头提到的需求 → 这是 Layer 2/3 压缩了早期消息
  • Agent 说"根据之前的讨论..."但细节可能不完全准确 → 压缩后只保留了摘要
  • 工具调用的历史结果变成了 [compacted] → 这是 Layer 1 压实了旧的工具输出

你可以这样应对

  • 关键信息说"请记住":触发记忆系统存储,不受上下文压缩影响
  • 重述关键需求:在长对话中,定期重述你的核心需求
  • 选择大上下文模型:GPT-4.1(1M)或 Claude(200K)比 DeepSeek(64K)能保持更多上下文
  • 开新对话:如果对话已经非常长且混乱,开一个新对话可能比继续更高效

相关文档