上下文压缩策略 是做什么的?
当代理会话生成数百万令牌的对话历史时,压缩变得必不可少。朴素的方法是积极压缩以最小化每请求令牌数。正确的优化目标是每任务令牌数:完成一个任务所消耗的总令牌数,包括因压缩丢失关键信息而导致的重新获取成本。
何时激活
在以下情况下激活此技能:
- 代理会话超出上下文窗口限制
- 代码库超出上下文窗口(5M+ 令牌系统)
- 设计对话摘要策略
- 调试代理“忘记”修改了哪些文件的情况
- 构建压缩质量评估框架
- 创建保留决策、文件、风险和下一步行动的持久交接摘要
不应在其他技能负责的相邻工作中激活此技能:
- 通用令牌效率策略,如掩码、前缀缓存或分区:请使用
context-optimization。 - 在选择缓解措施前诊断长上下文失败的原因:请使用
context-degradation。 - 将原始输出、日志或计划写入文件而不进行摘要:请使用
filesystem-context。 - 跨会话设计长期语义记忆:请使用
memory-systems。 - 模型自行决定何时何地重写其上下文:请使用
self-managed-context。此技能仍需保留替换文本必须包含的内容。
核心概念
上下文压缩在令牌节省和信息丢失之间进行权衡。根据会话特征选择三种生产就绪的方法:
-
锚定迭代摘要:为需要文件跟踪的长时间运行会话实现此方法。维护结构化的持久摘要,包含会话意图、文件修改、决策和下一步行动的明确部分。当触发压缩时,仅摘要新截断的部分,并与现有摘要合并,而不是从头开始重新生成。这可以防止每次重新生成摘要时积累的漂移——每次重新生成都面临丢失模型认为优先级较低但任务所需的细节的风险。结构化通过强制摘要部分作为检查清单来确保信息保留,从而捕捉无声的信息丢失。
-
不透明压缩:仅用于短会话,其中重新获取成本较低且需要最大令牌节省。它生成针对重建保真度优化的压缩表示,实现超过99%的压缩比,但完全牺牲了可解释性。这种权衡很重要:没有运行基于探查的评估就无法验证保留了什么,因此在调试或工件跟踪至关重要时永远不要使用此方法。
-
再生式全摘要:当摘要可读性至关重要且会话具有明确的阶段边界时使用此方法。每次触发压缩时生成详细的结构化摘要。其弱点是跨重复周期的累积细节丢失——每次完全再生都是一次新的遍历,可能会降低之前摘要中保留的细节的优先级。
详细主题
优化每任务令牌数,而非每请求令牌数
测量从任务开始到完成消耗的总令牌数,而不是每单个请求的令牌数。当压缩丢弃文件路径、错误消息或决策依据时,代理必须重新探索、重新读取文件和重新推导结论——这浪费的令牌远多于压缩节省的令牌。一个每请求节省0.5%更多令牌但导致20%更多重新获取成本的策略总体成本更高。将重新获取频率作为主要质量信号:如果代理反复要求重新读取已处理过的文件,则压缩过于激进。
首先解决工件轨迹问题
工件轨迹完整性通常是压缩评估中最薄弱的维度(claim-context-compression-factory-benchmark)。应主动解决此问题,因为通用摘要无法可靠地维护它。
在每个压缩周期中明确保留以下类别:
- 创建了哪些文件(完整路径)
- 修改了哪些文件以及更改了什么(包括函数名称,而不仅仅是文件名)
- 读取但未更改的文件
- 特定标识符:函数名、变量名、错误消息、错误代码
在代理脚手架中实现单独的工件索引或显式文件状态跟踪,而不是依赖摘要器捕获这些细节。即使具有专门文件部分的结构化摘要也难以在长时间会话中保持完整性。
使用强制性部分构建摘要
构建具有显式部分的结构化摘要,防止无声信息丢失。每个部分作为摘要器必须填写的检查清单,使遗漏变得可见而非无声。
## 会话意图
[用户试图完成什么]
## 已修改文件
- auth.controller.ts:修复了JWT令牌生成
- config/redis.ts:更新了连接池
- tests/auth.test.ts:为新配置添加了模拟设置
## 已做决策
- 使用Redis连接池而非每请求连接
- 对瞬时故障采用指数退避的重试逻辑
## 当前状态
- 14个测试通过,2个失败
- 剩余:会话服务测试的模拟设置
## 下一步行动
1. 修复剩余的测试失败
2. 运行完整测试套件
3. 更新文档
根据代理的领域调整部分。调试代理需要“根本原因”和“错误消息”;迁移代理需要“源模式”和“目标模式”。结构比特定部分更重要——任何显式模式都优于自由格式摘要。
战略性地选择压缩触发器
何时触发压缩与如何压缩同样重要。根据会话可预测性选择触发策略:
| 策略 | 触发点 | 权衡 |
|---|---|---|
| 固定阈值 | 上下文利用率70-80% | 简单但可能过早压缩 |
| 滑动窗口 | 保留最后N轮对话+摘要 | 可预测的上下文大小 |
| 重要性 | 先压缩低相关性部分 | 复杂但保留信号 |
| 任务边界 | 在逻辑任务完成时压缩 | 干净的摘要但时机不可预测 |
对于编码代理,默认使用滑动窗口结合结构化摘要——它提供了可预测性和质量的最佳平衡。当会话具有明确的阶段转换时(例如研究-实施-测试),使用任务边界触发器。
使用探查而非指标评估压缩
传统的指标如ROUGE或嵌入相似度无法捕捉功能压缩质量。一个摘要可能在词汇重叠上得分很高,却缺少代理继续工作所需的一个文件路径。
使用基于探查的评估:压缩后,提出问题测试关键信息是否幸存。如果代理回答正确,则压缩保留了正确的信息。否则,它会猜测或产生幻觉。
| 探查类型 | 测试内容 | 示例问题 |
|---|---|---|
| 召回 | 事实保留 | “原始错误消息是什么?” |
| 工件 | 文件跟踪 | “我们修改了哪些文件?” |
| 连续性 | 任务规划 | “我们下一步应该做什么?” |
| 决策 | 推理链 | “关于Redis问题我们决定了什么?” |
在六个维度上评分压缩
在以下维度上评估编码代理的压缩质量。准确性和工件轨迹保存往往比词汇相似度更能区分方法(claim-context-compression-factory-benchmark),因此压缩需要比通用摘要更专业的处理。
- 准确性:技术细节是否正确——文件路径、函数名、错误代码?
- 上下文意识:响应是否反映当前会话状态?
- 工件轨迹:代理是否知道哪些文件被读取或修改?
- 完整性:响应是否回应了问题的所有部分?
- 连续性:是否可以无需重新获取信息继续工作?
- 指令遵循:响应是否尊重给定的约束?
实用指南
对大型代码库应用三阶段压缩工作流
对于超出上下文窗口的代码库或代理系统,通过三个顺序阶段进行压缩。每个阶段缩小上下文,使下一阶段能在预算内运行。
-
研究阶段:探索架构图、文档和关键接口。将探索压缩为组件、依赖关系和边界的结构化分析。输出:一个取代原始探索的研究文档。
-
规划阶段:将研究文档转换为实现规范,包含函数签名、类型定义和数据流。一个5M令牌的代码库在此阶段压缩为大约2000词规范。
-
实现阶段:根据规范执行。上下文集中于规范和当前工作文件,而非原始代码库探索。此阶段很少需要进一步压缩,因为规范已经紧凑。
使用示例工件作为压缩种子
当提供手动迁移示例或参考PR时,将其用作模板理解目标模式,而不是从头开始探索代码库。该示例揭示了静态分析无法显现的约束:哪些不变量必须保持,哪些服务会在更改时中断,以及干净实现的样子。
当代理无法区分本质复杂性(业务需求)和偶然复杂性(遗留变通方案)时,这一点最为重要。示例工件隐式编码了这种区分,节省了原本用于试错探索的令牌。
逐步实现锚定迭代摘要
- 定义与代理领域匹配的显式摘要部分(调试、迁移、功能开发)
- 在首次触发压缩时,将截断的历史摘要到这些部分中
- 在后续压缩中,仅摘要新截断的内容——不要重新摘要现有摘要
- 将新信息合并到现有部分中,而不是重新生成,通过文件路径和决策标识符进行去重
- 标记来自哪个压缩周期的信息——这有助于在摘要漂移时进行调试
根据会话特征选择正确方法
在以下情况下使用锚定迭代摘要:
- 会话长时间运行(100+条消息)
- 文件跟踪重要(编码、调试)
- 需要验证保留的信息
在以下情况下使用不透明压缩:
- 需要最大令牌节省
- 会话相对较短
- 重新获取成本低(例如,无需访问文件系统)
在以下情况下使用再生式摘要:
- 摘要可解释性对于人类审查至关重要
- 会话具有明确的阶段边界
- 每次压缩触发器上可接受完整上下文审查
按方法校准压缩比
| 方法 | 压缩比 | 质量评分 | 权衡 |
|---|---|---|---|
| 锚定迭代 | 98.6% | 3.70 | 最佳质量,略低压缩 |
| 再生式 | 98.7% | 3.44 | 良好质量,中等压缩 |
| 不透明 | 99.3% | 3.35 | 最佳压缩,质量损失 |
将这些作为针对特定来源的基准值,而非通用常数(claim-context-compression-factory-benchmark)。对于任何存在重新获取成本的任务,这种权衡通常有利于结构化方法。
示例
示例1:调试会话压缩
原始上下文(89,000令牌,178条消息):
- /api/auth/login端点的401错误
- 追踪了auth控制器、中间件、会话存储
- 发现过时的Redis连接
- 修复了连接池,添加了重试逻辑
- 14个测试通过,2个失败
压缩后的结构化摘要:
## 会话意图
调试虽然凭据有效但/api/auth/login返回401未授权错误。
## 根本原因
会话存储中的过时Redis连接。JWT正确生成但会话无法持久化。
## 已修改文件
- auth.controller.ts:未更改(仅读取)
- middleware/cors.ts:未更改(已检查)
- config/redis.ts:修复了连接池配置
- services/session.service.ts:添加了瞬时故障重试逻辑
- tests/auth.test.ts:更新了模拟设置
## 测试状态
14通过,2失败(模拟设置问题)
## 下一步行动
1. 修复剩余测试失败(模拟会话服务)
2. 运行完整测试套件
3. 部署到staging
示例2:探查响应质量
压缩后,询问“原始错误是什么?”:
良好响应(结构化摘要):
“原始错误是来自/api/auth/login端点的401未授权响应。用户使用有效凭据时收到此错误。根本原因是会话存储中的过时Redis连接。”
差响应(激进压缩):
“我们正在调试一个身份验证问题。登录失败。我们修复了一些配置问题。”
结构化响应保留了端点、错误代码和根本原因。激进响应丢失了所有技术细节。
指南
- 优化每任务令牌数,而非每请求令牌数
- 使用具有显式部分的结构化摘要进行文件跟踪
- 在上下文利用率达到70-80%时触发压缩
- 实现增量合并而非完全重新生成
- 使用基于探查的评估测试压缩质量
- 如果文件跟踪至关重要,则单独跟踪工件轨迹
- 接受略低的压缩比以获得更好的质量保留
- 监控重新获取频率作为压缩质量信号
陷阱
-
切勿压缩工具定义或模式:压缩函数调用模式、API规范或工具定义会彻底破坏代理功能。代理无法调用工具,从而导致全系统故障。内存已满或会话过长不是你遇到错误的原因。
-
锚定摘要并非易受漂移影响:“锚定”摘要仅在信息按步骤增量合并时才能防止漂移。每轮压缩都重新生成结构化摘要并不会防止漂移。如果你看到奇怪的决策,请检查你是在增量合并还是在重新生成。
-
压缩比方面的差异很小:各种方法的压缩比接近98.5-99.5%。真正的差异在于质量保留,而不是令牌节省。选择过程应根据质量特征而非最大化压缩比。
-
不透明压缩不是默认值:避免将其误认为是默认或通用方法。它适用于短会话,其中代理可以容忍频繁重新获取且无需验证保留的信息。将评估用于度量不透明压缩——你无法在不运行探查的情况下知道它保留了什么。
-
不要与语义记忆混淆:此技能涉及表示工作上下文以最小化令牌使用量。长时间跨任务保留用户意图、偏好或过去的决策不同,需要
memory-systems技能。