长任务里的上下文问题不只是"token 不够"。一次文件读取可能产生几万 token,模型已经提炼过的原文仍留在后续每轮请求里;用户追问、模型判断和工具轨迹也会不断累积;换一个 session 后,上轮结论又全部消失。
tool_use/ 中的 context engineering notebooks 分别用 tool-result clearing、compaction 和 memory 处理这三种情况。它们都能让模型少读一些内容,但删除的对象、保留的信息和有效期不同。选错机制,省下来的往往正是后面需要的证据。
一个长任务里同时存在三类信息
context_engineering_tools.ipynb 让研究 Agent 比较八份文档。每份约 27K token,八次读取加上消息和工具记录,使 baseline 的上下文峰值达到 335,279 token。它在 1M 窗口下能完成;把窗口限制为 200K 后,第三轮之后的请求被拒绝,任务停在中途。
这个案例的上下文并非一种东西:
- 文档原文很大,但可以重新读取。
- 模型在当前任务中形成的发现、取舍和待办需要延续。
- 某些结论要留给下一次会话使用。
clearing、compaction 和 memory 正好对应这三层。把它们都叫"压缩上下文",会掩盖最重要的差别。
Clearing 删除旧工具结果
Tool-result clearing 只处理旧的 tool_result。工具调用本身及其参数仍在消息历史里,结果内容被替换成短占位。它不调用另一个模型做摘要,因此没有额外推理成本,也不会改写用户消息和模型回复。
实验把旧文件读取清掉后,峰值从 baseline 的 335,279 token 降到 173,137。到任务结束时,八份文档中七份已经不在上下文,只剩最近一份仍可见。模型若要核对原文,只能再次调用 read_file。
所以 clearing 是否安全取决于两件事:工具结果能否重现,以及模型是否已经把需要的内容写成可靠笔记。读取本地文件、查询稳定数据库通常可以重做;临时上传、会变化的网页、一次性流式结果和昂贵 API 未必可以。即使能够重读,过早清理也会让跨文档逐句比较变成反复 I/O。
clearing 的"无损"是有条件的。它没有修改原始数据,但数据已经离开当前上下文;只要来源仍在、权限没变、返回值没变,系统才有机会恢复。若模型在清理前只记下粗略结论,最终综合就会依据粗略结论,而不是原文。
Compaction 重写已经发生过的任务
Compaction 的处理范围更大。触发后,旧用户消息、模型回复、工具调用、工具结果和已有压缩块被整理成一份摘要,后续对话从这份摘要继续。它适合压缩"到目前为止发生了什么",而不只是一批过大的工具返回。
同一实验中,compaction 在第四轮把此前历史压成约 2,783 token 的摘要,最终上下文只有 5,829 token,峰值为 169,164。notebook 随后检查摘要保留了什么:三个主线事实全部留下,三个附录里的具体数值全部丢失。
这说明 compaction 并非把原对话换一种编码保存,而是在当时做了一次信息取舍。摘要 prompt 决定哪些目标、事实、决策和未决事项进入新上下文。被略去的内容以后不会因为突然变重要而自动回来,除非来源仍可读取并且 Agent 知道要重新查。
摘要还会把当时的理解固化成后续前提。模型若误读了一段材料,compaction 可能保存误读后的结论并删除原始证据。之后的模型看到的是一份整齐、自洽的任务状态,很难发现它来自一次错误概括。因而高风险任务不能只保存结论,至少要保留来源位置、关键数字和仍未核实的判断,让后续步骤有机会回查。
短会话没有必要做 compaction。原文仍放得下时,主动把它改写成摘要,只是用信息保真度换取暂时用不到的空间。
Memory 把信息带到下一次会话
clearing 与 compaction 都作用于当前会话。新 session 开始时,它们保不住任何内容。Memory 让模型把选中的笔记写到上下文之外,并在后续会话按需读取。
notebook 先让 Session 1 保存四种模式生物的比较笔记。Session 2 没有这份 memory 时,重新读取八份原始文档,峰值为 333,977 token;有 memory 时,它先读取约 2,707 token 的笔记,只重读另外四份文档,峰值降到 172,623。Memory 在这里省掉四次文件读取。
这项收益来自 Session 1 写得足够完整,不来自 memory 自动理解了过去。memory 原样保存被写入的内容,却无法保证模型选择了正确内容。漏记的事实不会凭空出现,写错的结论还会跨会话继续生效。
长期保存使错误比 compaction 更难消失。旧偏好可能已经改变,项目结论可能已经过期,模型自己的解释也可能被误当成事实。有效的 memory 需要记录来源和更新时间,允许覆盖、删除和审计,并按用户与项目隔离。memory_cookbook.ipynb 还指出一个安全问题:memory 文件会被重新读入模型上下文,因此可能携带 prompt injection;路径校验、内容检查和作用域隔离不能交给模型自觉完成。
Memory 也不解决当前 session 的膨胀。Session 1 即使持续写笔记,原始工具结果仍在上下文里,除非同时使用 clearing 或 compaction。
三者的组合不是越多越好
notebook 还把三种机制同时打开。Agent 读取第一批文档后写入 memory,第二批文档把上下文推高时,clearing 删除旧工具结果,compaction 把剩余历史压成摘要。最终峰值为 169,938 token,结束时为 13,749 token。
这条时间线能看出分工:
- clearing 回收可重新取得的原始材料;
- compaction 保存当前任务的压缩状态;
- memory 保存未来会话仍要使用的笔记。
组合也增加了相互作用。clearing 若先删掉证据,compaction 只能总结剩余内容;compaction 若把错误写进摘要,memory 可能再把错误存得更久;memory 的工具结果若被 clearing 当作普通结果删除,模型可能刚读完笔记又失去它。因此示例在 clearing 配置中排除了 memory 工具。
触发阈值同样不是通用常数。keep 太小,Agent 会重复读取刚被清掉的文件;compaction 太早,细节会在任务尚未定型时丢失;memory 写得太频繁,则会积累大量未经整理的中间判断。合理配置取决于材料能否重取、后续是否需要逐字证据、任务是否跨会话,以及错误结论会造成多大影响。
应该先设计信息的寿命
长任务不可能保留所有内容。系统需要明确每类信息活多久:原始搜索结果可能只服务当前几轮,经过核对的任务状态需要撑到本轮结束,稳定偏好或跨期结论才值得进入 memory。
这种分类比统一的 token 阈值更可靠。若只看窗口大小,系统会在达到阈值后机械遗忘;若先标出哪些结果可重取、哪些数字必须逐字保留、哪些结论允许跨会话,clearing、compaction 和 memory 才能各自处理合适的对象。
三种机制的难点都不在删除动作,而在删除之前的判断。clearing 要判断证据是否可重现,compaction 要判断哪些细节以后仍会有用,memory 要判断哪些信息值得长期影响模型。窗口变大只能推迟这些判断,不能替系统做出判断。