上下文 5 層壓縮策略
上下文 5 層壓縮策略
概述
長對話場景下,上下文 token 數會逐漸逼近模型的上下文視窗限制。系統採用三層架構、五個壓縮策略的級聯方案,在保證對話品質的前提下智慧管理上下文長度。
策略總覽

| 編號 | 層級 | 策略名稱 | 觸發條件 | 處理方式 |
|---|---|---|---|---|
| ① | 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 節摘要格式:
- 使用者意圖與目標
- 關鍵概念與術語
- 涉及的檔案與路徑
- 遇到的錯誤與解決方案
- 問題解決思路
- 使用者關鍵訊息
- 待完成任務
- 當前工作進展
- 下一步計劃
分塊策略:當訊息超過 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)能保持更多上下文
- 開新對話:如果對話已經非常長且混亂,開一個新對話可能比繼續更高效
相關文件
- Agent 循環引擎 — 上下文管理在循環中的位置
- 模型配置 — 各模型的上下文視窗大小
- 支援的模型列表 — 模型能力矩陣
