1. 上下文压缩
因为agent会做的事情更多了,上下文会越来越快膨胀:
- 读一个大文件,会塞进很多文本
- 跑一条长命令,会得到大段输出
- 多轮任务推进后,旧结果会越来越多
如果没有压缩机制,很快就会出现这些问题:
- 模型注意力被旧结果淹没
- API 请求越来越重,越来越贵
- 最终直接撞上上下文上限,任务中断
所以这一章真正要解决的是:
怎样在不丢掉主线连续性的前提下,把活跃上下文重新腾出空间。
1.1 最小心智模型
建议你先记三层,不要一上来记八层十层:
第 1 层:大结果不直接塞进上下文
-> 写到磁盘,只留预览
第 2 层:旧结果不一直原样保留
-> 替换成简短占位
第 3 层:整体历史太长时
-> 生成一份连续性摘要
手动触发 /compact 或 compact 工具,本质上也是走第 3 层。
1.2 关键数据结构
(1)Persisted Output Marker
当工具输出太大时,不要把全文强塞进当前对话。
最小标记可以长这样:
<persisted-output>
Full output saved to: .task_outputs/tool-results/abc123.txt
Preview:
...
</persisted-output>
这个结构表达的是:
- 全文没有丢
- 只是搬去了磁盘
- 当前上下文里只保留一个足够让模型继续判断的预览
(2)CompactState
最小教学版建议你显式维护一份压缩状态:
{
"has_compacted": False,
"last_summary": "",
"recent_files": [],
}
这里的字段分别表示:
has_compacted:这一轮之前是否已经做过完整压缩last_summary:最近一次压缩得到的摘要recent_files:最近碰过哪些文件,压缩后方便继续追踪
(3)Micro-Compact Boundary
可以先设一条简单规则:
只保留最近 3 个工具结果的完整内容
更旧的改成占位提示
这就已经足够让初学者理解:
不是所有历史都要原封不动地一直带着跑。
所以一份合格的压缩结果,至少要保住下面这些东西:
- 当前任务目标
- 已完成的关键动作
- 已修改或重点查看过的文件
- 关键决定与约束
- 下一步应该做什么
如果这些没有保住,那压缩虽然腾出了空间,却打断了工作连续性。