长任务上下文压缩与摘要
系列入口:如何使用 Agent。前置:上下文窗口预算管理。
一、问题:关键决定在「自动压缩」里悄悄消失
许多 Agent 在上下文快满时会自动压缩(compaction),把前面的对话压成一段摘要再继续。这本来是救场机制,但有个隐患:自动摘要往往是模型自己决定保留什么,它可能把一段看似啰嗦、实则关键的决定(比如「这里故意不加缓存,因为一致性要求」)压没了,只留下泛泛的概述。等后续任务碰到这个点,它已经不记得当初的理由,就可能把决定推翻、重新踩坑。
所以在重要的长任务里,压缩不该完全交给工具自动做,而要由你主导保留什么。
二、什么时候该主动压缩
- 对话已经很长、你感觉它开始遗忘早期约定;
- 工具提示上下文将满、要触发自动压缩——在它自动压之前你先手动压,掌握保留内容的主动权;
- 一个清晰的阶段刚收尾(比如数据模型部分做完,要转去做接口),是天然的压缩点。
不必等到撑爆才做,在阶段边界主动小结比被动截断安全得多。
除了阶段边界,还有几个信号说明「现在是压缩的好时机」:你注意到它开始重复解释前面已定的事;一轮讨论刚收敛、结论清晰但过程很长;它即将进入一个与前面关联较弱的新部分;以及你打算把任务交给另一个会话或另一名执行者。这些时刻做压缩,既保住了刚形成的结论,又能让接下来轻装上阵。
反过来也有不适合压缩、或压缩要更谨慎的时刻:问题还没完全收敛、决定可能马上还要变,此时压缩可能很快过期,不如等稳定;以及正在处理高度依赖细节的调试,过早丢掉原始报错和尝试记录,可能让它后面失去线索。压缩时机的本质判断是——这部分信息是否已经从「需要细节」转入「只需结论」。是,就压;还在频繁使用细节,就先保留或只做很轻的小结。
三、摘要要分三类记,别写成流水账
让 Agent 做小结时,明确要求它把信息分门别类,而不是复述过程。一份好用的阶段状态通常包含:
- 已做的决定(Decisions):定了什么方案、关键取舍是什么。
- 硬约束(Constraints):哪些地方不能动、有什么必须满足的条件、埋了哪些「故意如此」的设计及原因。
- 未决项(Open Items):还没解决、下一步要处理的事。
可以直接给它模板:
「请把目前进展整理成三部分:① 已确定的方案和关键决定(含原因);② 必须遵守的约束和不能碰的地方;③ 待办和未决问题。尽量精简。」
这样压缩后,真正会影响后续判断的信息被显式保住,而过程性的试错可以丢弃。
给你一个好坏摘要的直接对照。假设前面经历了十几轮,最终确定:缓存方案被否决(因为一致性要求高)、改用数据库事务、金额以分为单位、还剩退款边界没处理。
一份偏弱的摘要可能写成:「我们讨论了性能问题,尝试了一些方案,目前进展顺利,下一步继续优化。」它读起来没毛病,却把所有真正关键的信息——为什么否决缓存、用了事务、金额单位、未决项——全丢了。带着这种摘要继续,它很可能重新提议缓存、或在金额单位上犯错。
一份合格的摘要应清楚列出:
- 决定:不引入缓存(原因:该场景一致性要求高,缓存失效复杂度不值);改用数据库事务保证一致性。
- 约束:金额一律以分为单位、不使用浮点;事务边界覆盖扣款与记录两步。
- 未决:退款超时的边界处理还没做;并发下的重试策略待定。
两相对照,你就明白判断摘要质量的标准:它能不能让一个「没看过前面过程」的角色,仅凭这份摘要就避免重复踩坑。 压缩后花一分钟核对,重点看那些「故意如此」的决定及其理由是否还在——这类信息最容易被当成啰嗦内容压掉,却恰恰是未来最需要的。
四、滚动记忆的做法
滚动记忆(rolling memory)就是让这份小结随阶段不断更新:做完阶段 1 产出小结 → 阶段 2 只带着小结继续 → 结束后把小结更新成覆盖到阶段 2 的新版本。原始对话越来越不重要,最新小结始终是权威状态。
两个落地方式:
- 把小结写进一个专门的状态文件(或 memory 文件),让 Agent 后续随时读取;
- 或者在开新会话接力时,把最新小结作为背景贴上,实现「跨会话不断线」。
滚动更新时有几个要点,避免小结越滚越乱。一是每次更新只保留当前仍然成立的状态,已经完成的未决项应移除或标记完成,而不是无限累加历史,否则小结会重新膨胀成另一篇长文。二是决定被推翻时要连同理由一起更新,明确写上「原决定 X 已废弃,改为 Y,因为……」,而不是悄悄覆盖——保留这个变更轨迹能防止它在后续又改回去。三是始终保持精简,小结的价值就在于高密度,它应该比原始对话短一个数量级;如果一次压缩后篇幅没明显下降,说明还不够狠或混入了过程叙述。
一个很实用的节奏是:把「阶段收尾 → 更新小结 → 以小结为准进入下一步」绑定成固定动作,并让最新小结始终是唯一权威版本,而不是同时散落好几份互相不一致的摘要。当这个机制跑顺后,你甚至可以中途换会话、换执行者,只要把最新小结交接过去,任务就能无缝继续,这正是滚动记忆名字里「接力」的含义。
五、和相关手段的配合
| 手段 | 解决什么 | 关系 |
|---|---|---|
| 预算管理 | 别让窗口被撑爆 | 压缩是预算的补救 |
| 子代理 | 隔离大量中间检索信息 | 减少需要压缩的垃圾 |
| 开新会话 | 甩掉无关历史 | 靠小结保证不丢关键背景 |
压缩不是删信息,而是把信息从「冗长原文」换成「高密度状态」。关键始终是:那些会影响未来判断的决定和约束,一个都不能在压缩中丢。
给你一个压缩后一分钟核对清单,照着过一遍就能确认摘要可用:
- 目标是否写清,且和最初需求一致?
- 每一个关键决定是否都在、且带了原因?尤其检查那些「故意不加 X、故意这样设计」的点。
- 硬约束有没有遗漏?金额单位、不能碰的目录、必须满足的条件等。
- 未决项是否能直接对应到下一步动作,而不是含糊的「继续优化」?
- 有没有把已经完成的事还当成待办、或把已废弃的旧决定当成现行方案?
这几条核对的共同点,是确认摘要既能防止「未来重复踩坑」,又没有混入过期信息。你不需要重看全部原文,只要对照自己心里清楚的几条关键决定核对即可。把这个核对养成和压缩绑定的固定动作,压缩就从「可能丢信息的风险操作」变成一道稳妥的工序。
六、可直接套用的压缩模板与字段说明
为了让你下次压缩时不必临场组织语言,这里给一份可直接使用、并可按需裁剪的模板,同时说明每个字段为什么存在。
请把当前任务状态压缩整理成下面五部分,务必精简、条目化,不要复述讨论过程:
- 目标:这个任务最终要达成什么、不做什么。
- 已确定的决定:每条决定后用一句话写明原因;被推翻的旧决定单独标注「已废弃」。
- 硬约束:不能违反的技术约定、不能碰的范围、以及「故意如此设计」的点和理由。
- 进度:已经完成并验证过的部分(注明用什么验证的)。
- 未决项:下一步要处理的事,按优先级排列;每条尽量给出明确的下一步动作。
各字段的作用:目标字段防止长任务里目标漂移,让它随时能回到原点对照;决定字段要求带原因,是为了防止它在未来无意中把结论推翻;硬约束字段专门承接那些不写理由就会被当成多余代码删掉的「故意设计」;进度字段要求注明验证方式,避免它把没验证的事当成已完成;未决项给出下一步动作,是为了让接力者拿到清单就能继续,而不必重新梳理。
使用模板时有两个小技巧。一是显式告诉它「过程性试错不用保留」,否则模型出于全面的惯性,容易把走过的弯路也写进摘要。二是要求压缩后自报长度或条目数,便于你确认它真的做了大幅精简。你还可以根据任务情况删字段——很短的任务有「决定 + 未决」就够,字段服务于需要,不必每次填满。关键始终是同一条:让这份状态足以支撑「不看原文也能正确继续」。
七、跨会话、跨执行者怎么交接不断线
滚动记忆一个特别有价值的应用场景,是任务需要跨会话、甚至跨不同执行者继续——比如今天做不完明天接着做,或要把任务从一个 Agent 交给另一个。交接质量决定了任务会不会「断线」,这里给一套可操作的做法。
交接前,先让当前执行者产出一份「交接快照」,内容比常规滚动小结更强调自包含:任务目标与背景(让没参与过的一方看得懂来龙去脉)、当前进展与已验证部分、关键决定及原因、硬约束、以及明确的下一步清单。关键是假设接手方完全看不到此前的对话,因此所有它需要的信息都要在快照里,而不是默认「它应该知道」。
交接时有两种落地方式。一是把快照写进项目里的状态文件并提交,接手方只要读这一个文件就能进入状态,这种方式最可靠,信息不依赖某次对话。二是在新会话里直接贴上快照作为开场背景,适合不想落文件的临时情况。无论哪种,都建议在接手方开始前先让它复述目标和下一步,确认它真的接住了,而不是似懂非懂就开干——这一步能在最小成本下发现交接遗漏。
还有一个常被忽略的细节:交接时要说明「哪些尝试已经做过、为什么失败」,哪怕只写一两句。否则接手方很可能把已经走过的弯路再走一遍,这在跨执行者、信息不互通时尤其常见。把失败前提也交代清楚,交接才真正完整。
当这套机制熟练后,「长任务必须在同一个对话里一口气做完」的限制就被打破了——你可以自然地中断、分段、换人,而任务的关键信息始终通过快照延续。这不仅是记忆技巧,也是把 Agent 用成可长期协作的工作方式的重要一环。
八、一个关键心法:宁可主动小压,不要被动大压
把压缩策略浓缩成一句心法:在阶段边界主动、多次、小幅地压缩,远好过等窗口爆满后被动地一次性大压缩。 主动小压时你清楚每个阶段在做什么、能精确指定保留什么;被动大压时面对的是大量混杂历史,模型只能笼统概括,丢关键信息的概率高得多。而且压缩越晚,需要一次性处理的内容越多,出错面越大。
这也和前面的任务拆解呼应:当任务被切成边界清晰的小阶段,每个阶段自然就是一个低代价的压缩点。你不需要专门记住「何时压缩」,只要在每个阶段收尾时顺手小结即可。结构良好的拆解,让及时压缩成为自然而然的动作。
九、常见问题
Q:自动压缩既然存在,我完全不管不行吗? 对简单、短的任务可以。但重要长任务里,自动压缩可能丢掉关键的「故意如此」决定,且你事后很难察觉。涉及核心方案、不可逆决策的任务,建议在自动压缩前主动主导,把保留内容定下来。
Q:摘要里要不要保留具体代码片段? 一般保留接口契约、关键约束即可,大量实现细节不必进摘要——它们可以留在文件里,需要时再读。摘要承载的是「决定和约束」,不是代码备份,否则会重新变臃肿。
Q:压缩后我发现关键信息还是丢了,怎么补救? 如果原始对话还在,尽快从原文里把那条决定补回状态文件;更稳妥的预防办法,是把关键约束在确定当时就写进规则或记忆文件这类持久载体,而不是只放在会被压缩的对话里。
Q:滚动小结和记忆文件是什么关系? 滚动小结是「当前任务的实时状态」,随任务频繁更新;记忆文件偏向跨任务的长期背景。当前任务的滚动小结在任务结束后,其中有长期价值的部分可以沉淀为记忆或规则,两者可以衔接。
总结
重要长任务别依赖自动压缩:在每个阶段边界让 Agent 把「决定、硬约束、未决项」整理成精简状态,随阶段滚动更新——原始过程可以丢,关键决定必须留,它才不会聊着聊着就把自己早先的结论推翻。