← 返回首页
AI 工程作者 · Vic Agent

Agent 上下文压缩:从策略设计到效果评估

为什么 Agent 需要压缩上下文?如何选择滑动窗口、摘要、检索与结构化状态?又该怎样用任务表现、信息忠实度和真实成本评价方案?

随着大语言模型从单轮问答走向复杂任务执行,Agent 需要维护的上下文也越来越庞大:系统规则、用户目标、多轮对话、工具结果、执行状态、检索资料,都会在一次长任务中不断累积。

更大的上下文窗口缓解了容量焦虑,却没有消除问题。长上下文仍然意味着更高的输入成本和延迟,也可能让过期信息、重复日志与关键约束竞争模型的注意力。上下文压缩因此不只是“把文本变短”,而是一个有预算约束的信息选择问题:在有限 Token 内,保留最能支持下一步正确决策的信息。

本文围绕三个问题展开:为什么 Agent 需要上下文压缩,常见策略各自解决什么问题,以及如何科学地评价一种压缩方案。

一、为什么 Agent 需要上下文压缩

一个典型的 Agent 上下文可以抽象为:

Agent Context
├── System Instructions     系统指令与安全约束
├── Task Definition         当前目标与验收条件
├── Conversation History    历史对话
├── Tool Results            工具调用结果
├── Working State           计划、进度与当前问题
└── Retrieved Knowledge     外部检索资料

任务每推进一步,这个集合都可能继续增长。最终会暴露出三个核心问题。

1. 上下文窗口始终有限

Coding Agent 可能反复读取代码、执行测试、分析日志并修改文件。即使单次工具调用只返回几千 Token,多次迭代后也会积累出庞大的轨迹。一旦逼近模型的窗口上限,系统只能删除、转移或压缩部分信息,否则任务无法继续。

窗口更大,只是推迟了这个时刻。只要任务能够持续运行,历史增长速度最终仍可能超过可用容量。

2. 容量不等于利用率

把信息放进上下文,不代表模型一定能正确使用它。Lost in the Middle 的实验表明,相关信息位于长输入的不同位置时,模型表现可能明显不同;至少对论文测试的模型与任务而言,位于输入中部的信息往往更难被利用。

在 Agent 场景中,这类问题会表现为:

  • 忘记用户早期提出的约束;
  • 重复已经完成的步骤;
  • 忽略工具返回的关键结果;
  • 根据已经过时的状态继续决策。

因此,上下文管理既要解决容量问题,也要提高有效信息的密度、位置与可访问性。

3. 累计成本会随历史增长

假设第 n 轮请求的上下文长度为:

Lₙ = L₀ + ∑ᵢ₌₁ⁿ⁻¹ ΔLᵢ

其中,L₀ 是初始上下文长度,ΔLᵢ 是第 i 轮新增的上下文。若每轮都携带完整历史,累计输入量为:

Tₙ = ∑ₙ₌₁ᴺ Lₙ

即使最终一轮尚未触及窗口上限,整个任务也可能已经为同一段历史重复付费多次。提示缓存可以降低部分成本,但实际收益取决于缓存命中、消息前缀是否稳定、服务商计费方式和部署架构,不能替代上下文治理。

二、五类常见压缩策略

不存在适用于所有任务的最优策略。不同方法对“什么值得保留”的回答并不相同。

1. 滑动窗口:相信最近的信息

滑动窗口只保留最近 N 轮或最近 B 个 Token,丢弃更早的内容。

压缩前:[M1][M2][M3][M4][M5][M6][M7][M8]
窗口 = 4
压缩后:                [M5][M6][M7][M8]

它不需要额外模型,速度快、成本低,也很容易实现。但时间接近不等于任务相关。用户第一轮提出的“必须兼容 Python 3.12”,可能在几十轮后仍是硬约束。

因此,滑动窗口适合做兜底裁剪或保留近期工作区,不适合独自承担长期任务记忆。

2. 摘要压缩:相信语义提炼

摘要压缩让模型把较早的对话、工具结果和执行记录整理为更短的表示,再用摘要替换原文。高质量摘要通常会显式区分:

  • 当前目标与验收条件;
  • 用户硬约束;
  • 已确认的事实与架构决策;
  • 已完成、待完成和失败的步骤;
  • 仍需保留的文件、错误与原始证据引用。

摘要比截断更能保留跨轮次关系,但它是有损变换。事实可能被遗漏,建议可能被写成决定,尚未验证的状态可能被写成完成。摘要再次被摘要时,误差还会累积。

工程上应避免把摘要当成新的绝对事实源。更稳妥的做法是保留摘要对应的原始区间或引用,使系统在需要时能够回溯。

3. 重要性筛选:相信价值评分

重要性筛选为上下文片段打分,在预算内优先保留高价值信息。一个启发式评分可以写成:

Sᵢ = αRᵢ + βIᵢ + γDᵢ + δFᵢ

其中:

  • Rᵢ:与当前任务的相关性;
  • Iᵢ:信息本身的重要性;
  • Dᵢ:后续步骤对它的依赖程度;
  • Fᵢ:新鲜度或时效性;
  • α、β、γ、δ:各维度权重。

这不是行业统一公式,而是一种可实现的思考框架。真实系统可以结合确定性规则、关键词、Embedding、依赖图和 LLM Judge。

它的优势是预算分配更精细,难点则在于评分错误具有隐蔽性:被删掉的信息不会主动提醒系统“我其实很重要”。对安全规则、用户硬约束等内容,更适合使用不可淘汰的固定优先级,而不是完全交给相关性模型。

4. 检索式压缩:相信按需召回

检索式方案不要求所有历史始终出现在模型输入中,而是把历史对话、工具结果和任务产物存入外部系统,需要时再召回。

原始历史 → 分块与索引 → 长期存储
                         ↓
当前任务 → 生成查询 → 检索与重排 → 注入本轮上下文

它把“系统是否保存信息”和“本轮模型是否看到信息”分开,适合长周期任务与跨会话记忆。但它把风险从压缩器转移给了检索器:索引粒度、查询表达、权限过滤、Top-K 和重排质量都会影响最终召回。

向量相似度也不等于任务依赖。一次技术决策的理由可能分散在多轮对话中,单次相似度检索未必能恢复完整因果链。

5. 结构化状态:相信显式字段

对状态流转明确的任务,可以把历史转化为结构化状态:

{
  "goal": "实现用户认证模块",
  "constraints": ["使用 FastAPI", "使用 JWT"],
  "completed": ["数据库模型", "登录接口"],
  "pending": ["Token 刷新", "单元测试"],
  "current_issue": "Token 过期处理尚未完成"
}

这种表示紧凑、可校验,也方便程序消费,尤其适合 Coding Agent、工作流与自动化运维。代价是必须提前设计 Schema、更新规则和冲突语义。若实际操作已经失败,而状态仍写着“完成”,结构化只会让错误看起来更确定。

策略比较

策略压缩能力主要优势主要风险典型场景
滑动窗口中简单、快速、确定丢失早期关键约束短对话、近期工作区
LLM 摘要高保留跨轮语义遗漏、失真、误差累积多轮对话、任务交接
重要性筛选中至高预算分配灵活评分错误难察觉任务型 Agent
检索式压缩高存储与即时上下文解耦漏检、错检、依赖恢复困难长期记忆、跨会话任务
结构化状态高紧凑、可校验、可编程Schema 与状态同步成本Coding、Workflow

成熟系统通常会混合使用:固定保留系统规则与当前目标,用结构化状态维护任务进度,用滑动窗口保留近期交互,把旧轨迹压成摘要,同时让原始记录可以被检索和追溯。

三、压缩的终点是分层上下文管理

把上下文压缩理解为“缩短一段文本”仍然过于狭窄。更合理的架构是分层管理:

L0  System Instructions   不可丢失的系统规则与安全边界
L1  Current Task          当前目标、约束、计划与状态
L2  Working Memory        近期对话、关键工具结果与决策
L3  Long-term Memory      用户偏好、历史任务、知识与经验
L4  Raw History           完整对话、原始日志与任务产物

L0 和 L1 应优先保证完整性;L2 可以组合窗口、筛选与摘要;L3 通过结构化存储或检索动态召回;L4 用于恢复、审计和重新压缩,不必常驻模型输入。

这里最重要的区分是:压缩不应等同于永久删除。 系统可以保存完整证据,只在本轮推理时构造一个更小、更可信、更相关的工作集。

四、如何评价一种压缩方案

假设框架 A 把 20,000 Token 压到 5,000,框架 B 压到 8,000。A 是否更好?不能只看长度,因为把全部历史压成“用户要完成一个开发任务”也有极高压缩率,却几乎没有任务价值。

科学评估至少要同时覆盖压缩效率、信息质量、下游任务和系统开销。

1. 压缩率与 Token 减少率

定义压缩后长度占原始长度的比例:

CR = 压缩后 Token 数 ÷ 原始 Token 数

对应的 Token 减少率为:

TR = 1 − CR

若 20,000 Token 压到 5,000 Token,则 CR = 0.25,TR = 0.75。需要明确口径:有些资料会把原始长度除以压缩后长度,称为“4 倍压缩”,不能与这里的 CR 直接混用。

2. 关键信息召回率

先为原始上下文标注关键事实集合:

K = {k₁, k₂, …, kₙ}

再检查压缩结果保留了多少:

Rₖ = 保留下来的关键事实数 ÷ 关键事实总数

如果五条关键事实保留了四条,则 Rₖ = 0.8。检测时应接受语义等价表达,并同时检查事实之间的关系、条件和状态,而不是只做字符串匹配。

更重要的是给关键事实分级。一条安全限制或用户硬约束的丢失,可能无法被几十条普通事实的正确保留所抵消。

3. 忠实度与事实精度

压缩不仅会遗漏,也可能引入原文没有的信息,或者改变事实的确定性。例如:

原文:团队正在评估 Redis,尚未确定。
摘要:项目使用 Redis。

这里保留了关键词,却把候选方案改写成了最终决策。忠实度评估至少要检查:

  • 是否出现原文不存在的事实;
  • 是否改变条件、时间、否定或确定性;
  • 是否混淆用户要求、Agent 建议和已经执行的结果;
  • 是否错误合并了新旧冲突信息。

可以使用人工标注、规则和 LLM Judge 组合评估,但 Judge 本身也需要抽样复核与一致性测试。

4. 下游任务表现

这是最有业务意义的指标。压缩的目标不是生成一段漂亮摘要,而是让 Agent 在更少上下文中继续正确工作。

一组公平的对照实验应当固定任务、原始历史、底层模型、System Prompt、工具 Schema、采样参数和运行环境,只替换上下文方案:

                       同一任务与历史
                              │
              ┌───────────────┼───────────────┐
              │               │               │
          原始上下文       压缩方案 A      压缩方案 B
              │               │               │
              └───────────────┼───────────────┘
                              │
                          相同底层模型
                              │
                    比较任务结果与执行轨迹

Coding Agent 可以关注单元测试通过率、任务完成率、约束遵循率、修复成功率和额外工具调用次数;问答 Agent 可以关注答案准确率、历史事实恢复率、多轮指令遵循率和幻觉率。

5. 端到端成本与延迟

LLM 摘要、Embedding、检索、重排和存储都不是免费的。完整任务成本应写成:

总成本 = 压缩成本 + 推理成本 + 检索成本 + 存储成本

若各阶段串行,端到端延迟可以近似表示为:

总延迟 = 压缩延迟 + 检索延迟 + 推理延迟 + 其他延迟

实际存在并行或缓存时,应记录真实墙钟时间及 P50、P95 等分位数,而不是机械相加。一个方案即使减少 80% 输入 Token,如果额外压缩调用抵消了节省,也不具备工程优势。

五、如何设计一组可靠的对照实验

1. 使用接近真实的长任务

测试集不应只是随机拼接长文本,至少应覆盖:

  • 早期事实记忆:从很早的对话中恢复关键事实;
  • 长期约束遵循:任务运行很久后仍遵守初始限制;
  • 多步骤执行:后续操作依赖前面多个工具结果;
  • 任务切换与恢复:从任务 A 切到 B,再回到 A;
  • 信息更新与冲突:旧决定被新决定明确替换;
  • 失败与回滚:区分“尝试过”“失败了”和“已经完成”。

LongBench 可以提供长文本理解任务,但完整 Agent 框架还需要补充工具调用、状态恢复和多轮执行等测试。

2. 在多个预算点比较

只测一个压缩比例无法展示方案的退化曲线。可以设置 75%、50%、25% 和 10% 等保留预算,观察事实召回与任务成功率如何变化。

比较时应同时回答两个问题:

  1. 同预算比效果:保留相同 Token 时,谁的任务表现更好?
  2. 同效果比成本:达到相同成功率时,谁需要的 Token、延迟和费用更少?

第二个问题往往更接近生产决策。

3. 多次运行并报告分布

模型输出具有随机性。应对每个条件重复运行,报告均值、方差或置信区间,而不是用一次成功样例下结论。还应记录失败类型:遗漏约束、召回错误、摘要幻觉、状态过期和工具使用错误,可能需要完全不同的修复手段。

4. 使用硬门槛,而不只看综合分

可以构造归一化综合分数:

Score = w₁E + w₂Q + w₃P + w₄C,其中 w₁ + w₂ + w₃ + w₄ = 1

其中 E 是压缩效率,Q 是信息质量,P 是下游任务表现,C 是工程效率。但单一分数容易让极高压缩率掩盖严重信息损失。

更稳妥的方式是先设置硬门槛,例如关键约束召回率和任务成功率必须达标;再在合格方案中比较成本、延迟与压缩率。高风险任务还应对关键约束采用“任何一次丢失都不合格”的规则。

下面是一组仅用于说明分析方法的假设数据:

指标不压缩LLM 摘要筛选 + 检索
上下文 Token20,0005,0005,000
关键事实召回率100%84%94%
任务成功率90%76%87%
平均总成本$0.20$0.09$0.11
平均端到端延迟8.0s6.5s7.0s

这组演示结果中,摘要方案最便宜,但任务损失最大;混合方案成本略高,却更接近基线。哪一个更好,最终取决于准确性要求、预算和错误代价,而不是某个孤立指标。

六、研究与工程实践

LLMLingua 系列 表明,Prompt Compression 不必局限于让大模型写摘要:LLMLingua 使用由粗到细的 Token 级压缩,LongLLMLingua进一步考虑长上下文中的问题相关性,LLMLingua-2 则将压缩建模为 Token 分类任务。

这类方法主要处理给定 Prompt 的压缩,而 Agent 上下文管理还要面对持续更新、工具结果、跨任务恢复和状态冲突。两者目标相近,但系统边界不同。

Microsoft Agent Framework 的 Compaction 文档 也展示了工程侧的不同策略:截断、摘要工具调用组,或在不破坏原始存储历史的情况下只压缩本次请求上下文。这个区分很重要——模型看到的工作上下文可以被压缩,原始会话仍可以完整保留。

七、结语:把压缩看成信息选择策略

上下文压缩真正要优化的不是摘要长度,而是 Agent 在预算约束下的决策质量。给定候选信息集合:

X = {x₁, x₂, …, xₙ}

每个片段 xᵢ 具有 Token 成本 cᵢ。系统要在预算 B 内选择信息子集 S,最大化它对当前任务 q 的效用:

在 S ⊆ X 的范围内,最大化 U(S, q)

满足:

同时满足:S 中所有信息片段的 Token 成本之和 ≤ B

现实中的效用并不容易直接计算,还存在信息依赖、冲突、新鲜度、权限和不可压缩约束。但这个视角能够提醒我们:更短不一定更好,保留更多也不一定更好。

一套成熟的上下文系统,应当做到信息分层、动态压缩、按需检索、状态维护、原始证据可追溯,并持续用真实任务验证。最终评价标准很朴素:在相同预算下,Agent 是否更可靠;在相同可靠性要求下,系统是否更省成本、更低延迟。

这才是上下文压缩从技巧走向工程的分界线。