AutoCompact:学会何时压缩,以及压缩后怎么继续
上下文没有溢出,保留全部历史也未必最好。让代码 Agent 把阶段性探索整理成可执行的工作状态,并真正学会从这个状态继续。
AutoCompact 把上下文压缩拆成三个相互依赖的能力:选对时机、写对工作状态、按状态继续行动。先用 Judge 在执行过程中纠正这三类行为,收集真实续跑的轨迹做 SFT,再用任务成败奖励联合训练代码操作与压缩。
Base → AutoCompact,+9.2 个百分点
Base → AutoCompact,+5.0 个百分点
来自 379 个 SWE-rebench 任务
以上是论文同一基础模型与 scaffold 下的结果;成功率为三次运行的平均。训练、上下文阈值与推理预算不同的对照,后文分别解释。
01上下文管理不只是防溢出
代码 Agent 会反复搜索仓库、读取文件、修改代码、执行测试。这些交互让上下文持续增长,但历史信息的价值并不均匀:前期的候选假设、已经排除的方向、冗长的工具输出,未必对后续修改仍然有用。
一种常见策略是等到剩余上下文不足时才生成摘要。这解决了容量限制,却把“何时整理信息”绑定到 token 数量上。一个已经定位根因的 Agent 可能仍带着大量过时搜索结果前进;相反,一个还在对照关键证据的 Agent,也可能因窗口接近上限而被迫压缩。
AutoCompact 的问题设定是:能否根据任务进度,而不仅是窗口占用,决定何时把历史整理成下一阶段需要的状态?例如根因已经确定、实现尚未开始,就是一个可能的整理时机。但这不是“每次定位后都必须压缩”的固定规则,模型仍需判断证据是否足够。
在 256K 评测中,没有轨迹触发强制压缩,主动压缩训练仍带来收益。这支持“长上下文能够容纳全部历史”与“全部历史最适合当前决策”是两件事。但其中也包含模型训练带来的改进,还需要同一 checkpoint 的消融进一步归因。
02compact() 到底改变什么
系统在原本读文件、编辑、运行测试的工具体系里,增加了模型可以主动调用的 compact()。模型决定需要整理时,就生成一个以 # Auto Context Summary 开头的工作状态摘要,替换较早的交互历史;原始任务保持不变,再从新的上下文继续执行。原文也提到保留最近交互,但没有给出统一的保留条数。
这个图是对论文机制的概念整理,不是完整的消息拼接规范。重要的是,压缩改变了模型下一步看到的证据,而代码仓库中的修改并不会因为历史被替换而自动消失。因此,摘要必须正确反映真实工作区。
“工作状态”比“对话摘要”更具体
一般摘要可能只讲“之前做了什么”;可执行的工作状态还需要讲清“现在已经知道什么、文件现在是什么状态、下一步应该做什么”。以下是解读者构造的教学例子,不是论文中的实际轨迹:
已经确认:空输入失败来自解析入口,缓存路径已排除。
工作区:parser.py 尚未修改;已新增一个复现空输入问题的测试,该测试当前失败。
待完成:在解析入口补充边界处理,运行复现测试和已有解析测试;全部通过前不提交。
这里既保留结论,也保留证据与执行状态。“新测试已添加”和“新测试已通过”是不同事实,混淆它们会让后续策略走向不同的分支。压缩不是单纯删字,而是在有限文本里保留足以支撑下一步行动的状态。
压缩也不是越频繁越好。过早压缩可能丢失仍需核对的证据,反复压缩又会消耗生成预算;本方法让模型通过训练学习取舍,没有额外设置“压缩一次就奖励一次”的目标。
03在线纠错如何构造训练数据
作者首先尝试在提示中加入压缩规则,但基础模型很少在接近窗口限制之前主动调用 compact()。对模型来说,“当前轨迹还能继续,却主动打断并重写上下文”是一个不常见行为,单靠提示不容易稳定诱发。
因此,作者让基础策略在训练任务上运行,并使用 Judge 审查每一步候选输出。Judge 只接收当前时刻已经存在的执行历史,按照预定义标注规范决定是否纠正。它并非事后看到最终成败,再回头给过去的动作写理由。
| 纠正类型 | 检查什么 | 对应失误 |
|---|---|---|
| 触发时机 | 阶段是否已充分解决,原始证据是否仍需保留 | 根因已定位却继续重复搜索,或证据不足就急于压缩 |
| 工作状态 | 结论、相关代码、工作区状态与剩余动作是否准确 | 漏掉目标文件,误记已完成修改,未保留必要约束 |
| 压缩后续行动 | 最初几步是否遵循新状态 | 摘要已经记录结论,策略却重新搜索,或忽略计划中的编辑 |
为什么不在完成的轨迹里插一段摘要就好
离线插入压缩操作,可以给模型示范工具调用的形式,但插入点之后的动作仍然来自原始完整历史。它们未必是模型只看压缩状态时会生成的动作,也未必证明摘要足够支撑后续执行。
在线纠错改变了后面的实际状态分布:如果搜索被替换成压缩,下一个动作就从新上下文生成;如果摘要被补上“修改尚未验证”,后续策略也能据此转去测试。因而训练数据包含了纠正后的选择及其实际续跑,而不只是一个经过文字编辑的展示版本。
原文称其为 on-policy 数据采集,应理解为围绕当前策略运行时产生的提议做在线干预。实际执行轨迹混合了策略输出与 Judge 替换输出,并不是未经干预的纯策略采样。这个区别在讨论数据分布时很重要。
依据:原文 §2.2;最后一段是对采样过程的解释。
04SFT 与 RL 分别学什么
SFT:先让模型会做这些动作
基础模型为 Qwen3-Coder-30B-A3B-Instruct,使用终端式 REPL scaffold。数据采集中的 Judge 为 GPT-5.5-Codex。作者在 379 个 SWE-rebench 任务上收集并过滤,得到 1,052 条纠正后的轨迹,排除了格式错误的请求、摘要循环和偏离任务的续跑。
论文给出的监督类型占比为:触发时机 24%,工作状态构造 53%,压缩后续行动 23%。这反映采集数据的监督构成,不能当成基础模型三种错误的发生概率。SFT 使用标准 next-token 目标,同时学习普通代码操作和压缩相关行为。
RL:再让这些行为对任务完成真正有用
从 AutoCompact-SFT 初始化,在 SWE-Gym 上进行多轮 GRPO 训练,并采用全异步 RL 系统。每题采样 8 条轨迹,最终补丁通过任务测试得到 1,否则为 0。组内相对优势成为该轨迹所有模型生成 token 的共享学习信号。
原文没有给压缩专门设计奖励,也没有用摘要长度、压缩次数或 Judge 分数作为额外 RL 奖励;训练不加入 KL 惩罚或熵奖励,损失按 token 平均。Judge 的作用主要在前面的示范数据阶段,而非每轮 RL 的在线评分。
| 训练阶段 | 数据与配置 | 直接优化对象 |
|---|---|---|
| SFT | 379 题、1,052 条纠错轨迹;2 epochs;学习率 5 × 10⁻⁷;batch 8 | 模仿被执行的纠正后轨迹 |
| RL | SWE-Gym;每题 8 rollout;学习率 1 × 10⁻⁶;batch 64;rollout 上限 50 环境步、32K token | 最终任务测试是否通过 |
这两阶段的互补关系是:SFT 为不常出现的主动压缩行为提供起点;RL 通过最终结果继续筛选哪些压缩与续跑方式有用。但奖励是整条轨迹共享的,因此不能把某条成功轨迹中的每一句摘要,都看成被单独验证正确。
05压缩之后,训练序列怎样切
普通多轮交互中,下一轮输入往往是在已有上下文后继续追加内容。但 compact() 会重写前缀:此前完整历史消失,换成摘要。若训练时把整条轨迹直接拼成一个长序列,压缩后的动作就可能看见推理时已经被删掉的信息,造成训练条件不一致。
论文的处理是:在上下文前缀被重写的位置切分轨迹,让每段内部保持前缀只增长;同一轨迹的各段仍共享同一个 outcome advantage。模型生成的压缩决定、摘要和后续动作,即使分属不同段,也都获得最终任务成败的训练信号。
以上是帮助理解切分边界的示意,不规定具体 tokenizer 或消息模板。核心要求是每个被训练的 token,应当以它在实际执行时能够看到的上下文为条件。
压缩前的行为为什么还能被训练
从后续推理输入中删除历史,不代表训练日志也丢失了那段历史。采集系统保留各段当时的输入与模型输出,最终奖励可以回传为各段共享的优势。压缩删掉的是运行时可见上下文,训练仍然能够用真实历史条件计算此前动作的损失。
实现时需要额外核对的地方
- 摘要的角色变化。摘要生成时是模型输出;被带入下一段时又成为条件前缀。实现应明确 loss mask,避免无意重复监督同一份复制内容。
- 工具观察与模型动作的区别。测试日志参与下一步条件,但不应自动变成模型生成目标。
- 多次压缩的段映射。每段要保留同一轨迹身份,不能在打包时误分配到其他 rollout 的奖励。
上述三点是解读者的工程检查建议,论文没有逐项给出实现代码。这里也没有引入跨段 GAE:本文描述的是 GRPO 的共享轨迹优势,不应直接照搬另一篇论文的 critic 或时间折扣推导。
依据:原文 §2.3。
06实验设置与完整结果
所有方法使用同一个 Qwen3-Coder-30B-A3B-Instruct 基础模型与终端 scaffold,评测 SWE-bench Verified 和 SWE-PolyBench Verified。主表报告不设推理成本上限的完整运行成功率,所有定量结果为三次运行的平均。
这里的“同一基础模型”不代表每一行都用了相同训练过程:有的只用提示,有的做 SFT,有的做 RL;长度触发方法还有 16K 强制压缩阈值。先保留这些差异,再解释分数。
| 方法 | 触发 / 训练 | 上下文设置 | SWE-bench | PolyBench |
|---|---|---|---|---|
| 完整历史基线 | ||||
| Base | 无 / 无 | 256K | 30.4% | 19.5% |
| 长度触发压缩 | ||||
| Fixed Compaction | 长度 / 无 | 16K† | 28.8% | 18.6% |
| CompactionRL | 长度 / RL | 16K† | 32.7% | 19.8% |
| 主动压缩 | ||||
| SelfCompact | 规则提示 / 无 | 256K | 31.7% | 20.6% |
| SWE-Compressor | 学习 / SFT | 256K | 31.0% | 20.1% |
| AutoCompact-SFT | 学习 / SFT | 256K | 32.2% | 21.7% |
| AutoCompact | 学习 / SFT → RL | 256K | 39.6% | 24.5% |
据原文表 1 整理。SWE-bench 与 PolyBench 均指 Verified 版本;† 表示 16K 强制压缩阈值,不能把它误读成模型架构的原生最大窗口。这里的 CompactionRL 分数来自 AutoCompact 论文的对照设置,不是 CompactionRL 原论文主实验成绩。
把增益分成可核对的几步
- Base → AutoCompact-SFT:两个基准分别增加 1.8 和 2.2 个百分点,说明纠错示范初始化带来收益。
- AutoCompact-SFT → AutoCompact:再增加 7.4 和 2.8 个百分点,说明 outcome RL 是完整结果中的重要增量。
- Base → 完整方法:总计增加 9.2 和 5.0 个百分点;这是绝对百分点差,不是相对增长百分比。
- SWE-Compressor → AutoCompact-SFT:分别增加 1.2 和 1.6 个百分点。作者使用可比任务集合与相近轨迹数量,但并非逐条相同的数据,因此不能完全排除轨迹质量等其他差异。
Fixed Compaction 比 Base 更低,并不能单独证明“压缩通常有害”,因为它同时处在更紧的 16K 阈值条件下。同理,完整方法超过 CompactionRL 的差距,也不能全部归因于主动触发这一个改动。训练初始化、数据与运行条件需要共同考虑。
07预算实验与同模型消融
长轨迹任务只比较完整运行的成功率还不够:实际系统可能在预算耗尽时就停止。作者在 SWE-bench Verified 上设置每任务 $0.10、$0.20、$0.40、$0.80、$1.20、$4.00 六档推理预算,累计成本达到上限时终止 rollout。
成本由输入、输出和缓存 token 用量估算,采用论文所引用的阿里云模型价格,并把缓存 token 计为标准输入价格的 20%。这是该实验的计费模型,不是本文对当前 API 价格的报价;也不等同于训练成本或端到端墙钟时间。
| 子图 | 控制了什么 | 能够支持的结论 |
|---|---|---|
| (a) SFT vs Base | 256K;都未触发强制压缩 | 监督训练后的主动上下文管理,在不溢出的条件下也有收益 |
| (b) RL vs SFT | 同为 256K,比较 RL 前后 | RL 在各预算下进一步提高成功率,低预算增量更明显 |
| (c) AutoCompact vs Base | 共同使用 16K 强制压缩回退 | 主动压缩可以与长度兜底共存,在共同阈值下仍有收益 |
| (d) 同一 checkpoint | 模型参数不变,只改变是否执行 compact() | 部分收益确实依赖推理时的压缩操作,而不只是训练后的参数变化 |
最值得细读的是 Summary-ignored
这个变体不是“生成摘要但不给模型看”,而是直接跳过 compact() 调用:不生成摘要,保留已有历史继续运行。完整方法与它使用同一个已训练 checkpoint,因此保留了训练学到的代码能力。
正常执行压缩在所有预算上都更好。正文报告,$0.10 时成功率优势为 19.9 个百分点,$4.00 时仍为 1.9 个百分点;图中的高预算终点分别是 39.6% 和 37.7%。随着预算放宽差距缩小,说明压缩对尽快把预算用在有效行动上尤其有帮助。
这个消融的解释也有边界:跳过压缩同时改变上下文内容、输入成本和续跑条件,因此它检验的是整个压缩动作的效果,不能单独分解“摘要语义质量”和“减少重复输入费用”各贡献多少。Summary-ignored 也会让策略处在与正常压缩运行不同的状态分布中。
压缩需要额外生成摘要,重写前缀也可能改变缓存复用;收益来自后续多轮输入与决策的变化。仅报告摘要更短,不能推出总推理费用一定更低。本文直接比较固定费用上限下的成功率,更接近受预算约束的使用场景。
08摘要完整,为什么仍会失败
RL 后,压缩更常用,遗漏也更少
作者在全部 500 个 SWE-bench Verified 任务的轨迹上,统计主动压缩使用情况,并通过关键词筛查结合随机人工抽查,检查摘要是否遗漏相关状态或具体下一步。
| 指标 | AutoCompact-SFT | AutoCompact(RL 后) |
|---|---|---|
| 主动压缩的任务比例 | 44.3% | 58.5% |
| 摘要遗漏关键状态 | 3.1% | 0.2% |
| 摘要遗漏具体下一步 | 8.2% | 2.2% |
这些结果表明,任务成败奖励可以伴随压缩行为的改善,而不需要单独给摘要完整度打 RL 分。但关键词能够发现“是否提及某项信息”,未必能够全面判断该信息是否真实、是否与当前代码一致、是否足以支撑下一步。
自洽性:下一步必须与记录的状态相容
原文以 django-13809 为定性案例,展示经过转述的摘要。SFT 模型的摘要记下“仍有一个未解决的语法错误”,却把下一步写成“结束,不再操作”;RL 模型则记录参数与条件逻辑修改已完成,下一步是验证并提交。
两个摘要都可以同时包含“状态”和“下一步”,但只有后者的计划与所记录状态相容。由此可以把摘要评估分成三个问题:关键内容有没有留下;留下的事实对不对;下一步是否受这些事实约束。
论文用这一例子说明“自洽性”超出信息覆盖率。它是有启发性的案例,不是大规模自洽性评估,也不能从单例推出 RL 总能消除矛盾。SFT 学习示范文本、RL 通过后续任务结果筛选行为,是作者提出的解释,仍需更系统的实验验证。
09与 CompactionRL 的区别
站内已有 CompactionRL 解读。两篇都把摘要生成纳入可训练策略,但侧重点不同:CompactionRL 强调让压缩参与长轨迹 RL;AutoCompact 进一步把触发时机与压缩后的续跑行为纳入学习。
| 维度 | CompactionRL | AutoCompact |
|---|---|---|
| 何时压缩 | 剩余上下文预算低于固定阈值 | 模型可按任务阶段主动调用,也可与长度触发兜底共存 |
| 摘要如何学习 | 摘要生成参与任务奖励下的 RL | 在线 Judge 纠错轨迹做 SFT,再通过任务奖励做 RL |
| 压缩后的行为 | 压缩后的续跑参与任务执行与 RL | 采集阶段还直接纠正最初的续跑动作,并实际执行修正结果 |
| 本篇关注的问题 | 固定触发条件下,压缩能否成为有效的训练组件 | 是否该主动压缩、该保留什么、压缩状态如何驱动后续决策 |
| 证据重点 | 详见站内原论文解读,不混用不同模型成绩 | 大窗口不溢出实验、共同 16K 回退、同 checkpoint 跳过压缩 |
还应区分与 SWE-Compressor 的差别。后者同样学习主动压缩,因此“可主动调用工具”本身不是 AutoCompact 唯一的新意。本文更有辨识度的部分,是在线修正后继续真实执行,以及对后续动作的显式纠正,最后再以任务成功做联合优化。
和本站的 GAGAR 相比,两者也使用“Judge”,但位置不同。GAGAR 在线比较同题成功解并调整 RL 优势;AutoCompact 的 Judge 用于构造 SFT 轨迹,本文 RL 阶段的奖励仍只有最终任务成败。把两种 Judge 都称为 reward model,容易遮蔽它们实际承担的职责。
对照依据:AutoCompact §1、§4及本站两篇相关笔记;此表为解读者整理。
10证据边界与复现缺口
以下区分论文明确承认的限制与本笔记的补充分析。收益已经在当前实验中显示出来,但要把它迁移到其他模型或 harness,还需要更多信息。
32K 训练,不等于完成了 256K 长轨迹训练验证
作者明确说明,由于资源限制,RL 使用 32K token 序列,短于评测的 256K 上下文窗口。这支持短一些的训练也能学到有用主动压缩行为,却不能自动保证多次压缩、极长依赖或更长任务上的稳定性。评测窗口大小也不能直接解释为每条评测轨迹都用了 256K token。
单一模型、单一 scaffold 的外推有限
所有变体共用一个基础模型与终端 REPL,这让内部比较更清楚,但本文未验证迁移到更大模型、多 Agent、不同工具协议或其他工作区管理机制后的收益。作者把 model–harness 协同设计作为方向,并将更广泛系统中的应用留给后续工作。
“何时、保留什么、怎么继续”尚未分别消融
全文提供了 SFT/RL 阶段对比和跳过压缩的实验,但没有逐一移除三种 Judge 纠正类型的完整消融。因此不能断言续跑纠正单独贡献了多少,也不能把完整方法的 +9.2 个百分点全部归给触发时机学习。
Judge 规范与压缩模板仍是重要复现变量
论文给出了训练量、学习率和基本流程,但正文没有完整展开标注协议、Judge 提示、近期历史保留规则、SFT token mask、摘要长度限制,以及异步训练中的陈旧样本处理细节。复现者若自行补齐,应把它们作为实现选择记录下来,不能声称与作者完全一致。
质量统计与任务指标之间,仍缺少更细的连接
关键词筛查加抽查能给出行为信号,却不等同于逐条事实核验。若要了解失败机制,需要把遗漏、事实错误、状态与下一步矛盾、压缩后重复探索分开统计,再与任务成败关联。三次运行取平均也不等于已经报告了每项差异的置信区间或显著性。
效率结果没有覆盖训练与标注总成本
预算曲线关注推理阶段,未把 Judge 逐步审阅、轨迹纠错和 SFT/RL 的费用一起摊入。对于服务大量重复请求的模型,训练投入可能值得;对于只处理少量任务的系统,收益与成本的关系可能不同,需要按实际使用量评估。
作者承认的限制见 原文 §5;其余是基于本文实验与披露内容提出的补充问题,不是已验证的负面结论。
11工程启发与阅读索引
如果要将思路用于自己的代码 Agent,最值得先验证的是“压缩状态能否驱动下一步”,而不仅是输出是否足够短。可以用同一批任务比较完整历史、固定阈值压缩、主动压缩三种路径,再观察重复搜索、测试遗漏、预算耗尽和任务通过率。
- 触发:主动/强制压缩次数、触发时的上下文占用与任务阶段。
- 状态:必要文件、已做修改、测试状态、未解决问题是否正确保留。
- 续跑:压缩后最初几步是否执行计划,是否重复已经完成的探索。
- 成本:摘要生成、缓存与非缓存输入、输出 token、总费用与成功率。
这是解读者建议的检查清单,不代表论文公开了全部对应日志。工程试验仍应保留长度触发兜底,并记录它与主动压缩分别发生的频率。
本篇最值得带走的是一个可检验的思路:把压缩视为会改变后续决策的动作。训练数据要包含动作实际执行后的续跑,优化目标要落到任务结果,评测则要使用相同模型禁用压缩等对照,区分参数改进与运行时机制的贡献。


