Agent 上下文工程
前置:写过一个会调工具的 Agent,见过它跑十几轮以上。不需要懂模型内部。
本专题回答:为什么 Agent 跑久了会变笨,以及每一轮该往上下文里放什么、删什么、挪到哪去。
一个跑了四十轮的 Agent,上下文从 3K 涨到 180K。窗口还没满,但它开始重复调已经调过的工具、忘记第五轮定下的约束、对着一份自己十轮前读过的文件再读一遍。
这不是模型退化,是上下文里能用的东西被不能用的东西挤掉了。上下文工程要解决的就是这件事:在每一轮里决定往那个有限的窗口里放什么、不放什么、放在哪个位置。
先约定几个词,本专题全程使用 :
| 词 | 意思 |
|---|---|
| 上下文工程 | 在推理时策划并维护那组进入模型的 token。区别于提示工程 —— 后者只管怎么把一次指令写好,前者管的是每一轮该带什么进来 |
| 注意力预算 | 一个类比:模型对上下文的有效利用能力是有限的,越长越摊薄。它不是硬上限,而是一条持续下滑的曲线 |
| 上下文腐烂(context rot) | 输入变长导致模型表现变差的现象,即使任务本身没变难。02 篇给实测形态 |
| 压缩(compaction) | 把旧内容总结成一段摘要,替换掉原文。有损,但保留语义 |
| 裁剪(context editing) | 直接删掉特定内容(比如老的工具结果),不做总结。更省,但删掉就是删掉了 |
| 卸载(offload) | 把内容挪到上下文之外(文件、子 Agent、外部存储),需要时再取回一小部分 |
| 前缀缓存 | 模型服务对请求前缀的缓存。前缀有一个字节变化,后面全部要重算 |
| 延迟加载(defer_loading) | 工具定义先不进上下文,等模型搜索到再加载。05 篇的主要手段 |
一、三组问题
二、七篇正文
| # | 标题 | 读完能回答的问题 |
|---|---|---|
| 01 | 窗口里装了什么 | 我这 180K token 到底是被谁吃掉的?哪一块涨得最快?「窗口没满」和「模型还用得动」是不是一回事 |
| 02 | 上下文腐烂 | 同一道题,只是把输入拉长,模型就答错了 —— 这是我的错觉还是真的?18 个模型的实测长什么样 |
| 03 | 压缩与裁剪 | 内容太多了,该总结成摘要还是直接删掉?两者分别会在什么地方悄悄失效、悄悄多花钱 |
| 04 | 卸载到外部 | 能不能把东西挪到窗口外面去,用的时候再取?写文件、开子 Agent、临时检索,这三条路各自把麻烦推给了谁 |
| 05 | 工具与检索结果的占用 | 我还一句话没说,光工具定义就占了两万 token 怎么办?工具超过多少个模型就开始选错 |
| 06 | 前缀缓存与排布 | 为什么我删掉了一些内容,账单反而更贵了?什么改动会让缓存整段作废,怎么验证有没有命中 |
| 07 | 观测与落地 | 上面这些手段该按什么顺序上?该盯哪几个数字才知道有没有起作用 |
只读两篇的话:05 篇(工具与检索结果)和 06 篇(前缀缓存)。前者是省得最多的一处,后者决定你省下来的 token 会不会被缓存失效吃回去。