上下文工程:Agent 长程任务的缓存、压缩与回放


上下文工程:Agent 长程任务的缓存、压缩与回放

上下文工程:Agent 长程任务的缓存、压缩与回放封面图

Agent 与大模型之间没有另一条隐藏的通信通道。模型能看到什么、记住什么、调用什么工具、如何理解上一步结果,最终都要通过上下文传递。因此,上下文不是简单地“把更多内容塞给模型”,而是在有限窗口中动态组织一组最相关、最稳定、最可回放的信息。

本文以一场关于 Agent 上下文管理的技术分享为基础,重点整理四个问题:为什么 KV Cache 命中率重要,长上下文应该怎样压缩,如何避免长程任务发生偏移,以及如何用事件日志和回放机制支撑一个可维护的 Harness。

一、上下文工程不等于 Prompt Engineering

Prompt Engineering 更关注单次输入输出:如何写一条系统指令、加入哪些 Few-shot 示例,让模型在一次请求中完成目标。

Context Engineering 则关注 Agent 的每一轮推理循环:在有限的上下文窗口里,动态装配系统规则、工具定义、技能说明、历史结果、任务状态和当前变量。它承载了:

  • 记忆管理;
  • 工具加载;
  • Skill 发现;
  • 任务状态维护;
  • 中断与重连;
  • 压缩与回放;
  • 长程任务的偏移控制。
flowchart LR
    A[用户任务] --> B[Agent状态]
    B --> C[上下文装配]
    C --> D[模型推理]
    D --> E[工具与环境执行]
    E --> F[结果与事件]
    F --> B

不同模型的上下文窗口、训练分布和最佳装配方式可能不同。同一个 Agent 任务中频繁切换模型,不只是切换推理能力,也可能改变上下文理解方式,从而增加任务漂移风险。

二、第一优先级:让 KV Cache 尽可能命中

前缀缓存的基本逻辑是:如果后续请求的前缀与之前已经处理过的内容逐字一致,模型就可以复用已经计算过的 Key 和 Value,避免重复处理相同 Token。

因此,上下文设计的第一个原则不是“让模型看到最多信息”,而是:不变的内容保持不变,需要变化的内容尽量放到后面。

一个适合缓存的装配顺序可以是:

  1. 稳定的 System Prompt;
  2. 工具定义;
  3. Skill 内容;
  4. 按稳定顺序组织的历史工具结果;
  5. 动态变量和当前请求状态。
flowchart TD
    A[稳定System Prompt] --> B[工具定义]
    B --> C[Skill内容]
    C --> D[历史工具结果]
    D --> E[动态变量]
    E --> F[当前请求]

如果用户 ID、时间、环境变量等动态内容被嵌入 Skill 或系统提示词中,那么一次变量变化就可能让后面的缓存全部失效。把变量移动到上下文末尾,能够保留更长的稳定前缀。

实际命中率取决于模型提供商、缓存时长、请求组织方式和具体实现,不能把某个经验数字当成所有平台的保证。但在 Agent 成本和延迟都敏感的场景中,前缀稳定性应当成为一等设计目标。

三、上下文压缩的四种思路

上下文达到窗口上限之前,系统必须决定删什么、保留什么、是否可恢复,以及压缩后怎样继续完成任务。

1. 直接删除

最简单的方式是从历史中删除较早的工具结果、临时输出或已经完成的中间步骤。工具结果有时会占据上下文的大部分空间,删除已经消费完的信息可以快速降低 Token 数。

缺点是不可恢复。如果后续步骤依赖早期结果,Agent 只能重新调用工具;而工具结果可能已经变化,导致原本可以完成的循环被破坏。

2. 摘要与索引

把长段工具结果、推理过程或历史对话压缩成摘要,并建立摘要到原始内容的映射。模型先读取摘要,必要时再通过索引回放原文。

这种方法比直接删除更稳健,但会增加额外模型调用、检索和映射逻辑。摘要如果遗漏了因果关系、约束或异常信息,后续模型可能在错误的压缩状态上继续执行。

3. 基于重要度的有损压缩

可以使用小模型或规则判断哪些 Token、字段或结果与当前任务关系较弱,再删除这些内容。它适合处理异常膨胀的工具返回值,例如工具返回了远超任务需要的大量用户历史数据。

这类方法不可逆,因此必须明确哪些字段属于不可删除的任务事实、约束、权限和安全信息。

4. 可解码的软压缩

软压缩试图在减少长度的同时保留恢复能力,让后续系统可以重新展开或解释压缩内容。它的工程实现更复杂,目前不能简单理解成普通文本压缩或 Base64 编码;模型是否能稳定理解压缩表示,需要单独验证。

四、压缩策略也要服务于缓存

如果压缩时直接重写整个上下文,前缀缓存很可能全部失效。更稳妥的策略是从后往前压缩:先处理最新的工具结果和可变内容,再处理较早的 Skill 或历史信息,尽量保留前面的稳定前缀。

可以把上下文划分为三层:

flowchart TB
    A[稳定层:系统规则、工具定义、Skill] --> B[任务层:检查点、历史结果、摘要索引]
    B --> C[变化层:当前变量、最新工具结果、临时状态]
    C --> D[模型请求]

当上下文接近阈值时,可以设定目标区间,例如从较高占用压缩到一个更低水位。但具体阈值必须结合模型窗口、任务类型、压缩成本和回放能力来确定,不应机械套用某个百分比。

还要考虑缓存的时间窗口。如果用户离开一段时间后再回来,原来的缓存可能已经失效。此时与其带着超长历史直接发起请求,不如先执行一次更充分的离线压缩,再开始新的推理循环。

五、长程任务为什么容易偏移

短任务通常只需要几轮 Agent Loop,不容易碰到窗口上限。Coding、网站搭建、复杂办公和多轮研究则可能持续几十轮,任务中还会出现跨步骤依赖。

长程任务的主要风险包括:

  • 压缩删除了后续步骤仍需使用的工具结果;
  • 上下文过长导致中间信息被模型忽略;
  • 缓存命中率低,模型每轮都要重新理解任务;
  • 检查点没有结构化保存,导致 Agent 重复执行;
  • 当前状态与原始目标逐渐分离;
  • 某一步错误没有被发现,后续步骤继续建立在错误结果上。

长上下文模型也可能出现“中间信息关注不足”的现象。重要规则不能只出现一次,可以在结构上放到高可见位置,并通过检查点和验证器持续确认,而不是单纯重复 Prompt。

六、从事件日志到可回放的 Harness

一个可维护的 Agent Harness,不应只保存最终答案。更完整的设计是把原始会话作为事件日志,再从日志投影出模型当前可见的上下文表面:

flowchart LR
    A[Raw Session Event Log] --> B[事件追加与审计]
    B --> C[上下文投影 Surface]
    C --> D[模型请求]
    D --> E[工具调用与新事件]
    E --> A
    A --> F[崩溃恢复与历史回放]

事件日志可以记录用户输入、模型请求、工具参数、工具结果、插件版本、上下文版本、错误、重试、检查点和资源消耗。Surface 则只保留当前模型需要看到的内容。

这种分层有三个价值:

  1. 可观测:能回答模型当时看到了什么;
  2. 可恢复:Agent 崩溃后可以重放历史事件;
  3. 可演化:可以改变投影策略,而不破坏原始记录。

压缩也应当视为一个事务:确定触发条件、锁定会话、生成新检查点、更新上下文投影、验证结果,再释放锁。如果多个子 Agent 同时操作同一会话,还需要明确并发控制和失败恢复。

七、不同 Agent 应采用不同上下文策略

Coding Agent 更关注长程任务完整性、成本和可回放性;实时业务 Agent 更关注延迟、缓存命中和上下文长度;研究型 Agent 更关注证据保留、检索和来源关联。不存在脱离业务目标的“最佳上下文管理方案”。

可以按目标选择策略:

  • 低延迟场景:优先稳定前缀、缓存命中和短上下文;
  • 长任务场景:优先检查点、摘要映射和故障恢复;
  • 高风险场景:优先不可变日志、权限隔离和人工确认;
  • 高成本场景:优先压缩时机、Token 预算和模型分层;
  • 知识密集场景:优先可索引摘要、原文回放和证据完整性。

因此,记忆、Skill、工具和上下文压缩不应只是通用组件的堆叠,而应围绕业务的失败模式设计。

八、上下文工程的实践路线

个人或团队可以从一个可回放的最小 Harness 开始:

  1. 记录完整的事件日志,而不是只保存最终答案;
  2. 将稳定指令、工具定义、Skill 和动态变量分层;
  3. 为工具结果设置大小、字段和权限边界;
  4. 实现一种简单的从后往前压缩策略;
  5. 为摘要建立到原始事件的索引;
  6. 保存任务检查点和未完成步骤;
  7. 对压缩前后的任务成功率、延迟和成本做回归;
  8. 模拟中断、重连、工具失败和上下文溢出;
  9. 对高风险变更保留回滚点和人工确认。

评估时不要只看最终成功率,还应观察 P95 延迟、输入与输出 Token、缓存命中率、工具错误率、重复调用次数、人工接管率和回放一致性。

结语

上下文工程的目标不是把所有历史都保存下来,而是让模型在每一轮都看到正确、稳定、足够且可恢复的信息

可以用一句话概括这套方法:

稳定内容保持稳定,变化内容放在后面;压缩从后往前,原始事件可回放;每一次删减都要有验证,每一种自动优化都要有边界。

当 Agent 从短对话走向长程任务,真正决定系统质量的往往不是再加一条 Prompt,而是上下文装配、缓存、压缩、事件日志和回放机制能否形成一个完整工程系统。


文章作者: Onefly
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Onefly !
评论
  目录