Skip to content

07 · 长跑的上下文 ​

单轮对话里上下文窗口是个"聊久了会忘"的问题。在 Agent 里它变成一个结构性问题:每转一圈,工具返回的东西就往桌上堆一层。跑到二十圈,你的目标已经被埋在最底下了。

一圈往桌上放多少东西 ​

数一遍:

text
每一圈进上下文的:
  · 它的思考("我打算搜索……")
  · 它发出的工具调用(工具名 + 参数)
  · 工具返回的结果            ← 大头,可能几千字

十圈就是十份工具返回。如果每份两千字,光工具返回就是两万字——而你的目标只有三百字,还在最上面。

于是就有了 Agent 最典型的三种"跑着跑着变傻":

现象原因
忘了目标,开始做别的目标被挤到边上或挤出去了
重复做已经做过的事早期的工具返回被挤掉,它不记得查过了
早期的约束失效(开始碰不该碰的)约束和目标写在一起,一起被挤掉了

四个办法 ​

一、把目标和约束放进"每轮都在"的位置 ​

最便宜的一招。

关键约束不要只写在第一条消息里——写进系统提示,那是每一轮都会重新发的。

text
系统提示(每轮都在):
- 当前任务目标:【一句话】
- 完成标准:【清单】
- 硬约束:不要写 ./data/;对外动作必须先请求确认;
  连续三次同样的尝试无果就换路

这一招几乎零成本,但能解决大半问题。

二、让工具返回瘦下来 ​

03 章那条"返回要精简",在长跑里是硬需求:

text
❌ 读网页 → 返回整页 HTML(一万字)
✅ 读网页 → 返回:标题 + 正文纯文本,截断到 2000 字 + URL

再进一步:让工具返回"摘要 + 存到文件":

text
返回:已保存到 ./output/page-03.txt(全文 12000 字)
     摘要:这是 A 家的定价页,包含 5 个套餐,
           起步价 $29/月,按席位计费。

全文落到文件里,上下文里只留一句摘要。 需要细节时它可以再去读那个文件——这就是渐进式披露在 Agent 里的用法。

三、外置的"工作笔记" ​

给 Agent 一个专门的文件当草稿本,要求它每完成一项就写进去:

text
每查完一家,把结果追加写入 ./output/notes.md,格式:
## A 家
- 套餐:…
- 价格:…
- 未获得:计费单位(官网未公开,已查 pricing 和 docs 两页)

写完之后,你的上下文里不需要保留这家的原始网页内容。

好处有三个:上下文压力降下来;你随时能打开这个文件看进度;跑挂了重来时,已完成的部分还在。

这一招是长跑 Agent 最有效的单项改动。

把"记住"这件事,从上下文搬到文件里。 上下文是易失的、会被挤掉的;文件是持久的、你能看见的、它自己也能重新读的。

顺带你还白得了一份执行留痕。

四、压缩:能用就用,但知道它的代价 ​

有些工具会在上下文快满时自动做一次摘要,把前面的历史压成一段。这能续命,但要清楚代价:

压缩必然丢细节

被压掉的是"当时的原文",留下的是"它对当时的总结"。如果某个细节在压缩时被判断为不重要,它就永远消失了——而它的重要性可能要到第 25 圈才显现。

所以:重要的东西别指望留在上下文里,落到文件里去。(上面第三招)

拆子任务:更彻底的办法 ​

当一个任务实在太长,最干净的做法不是压缩,是拆成几个独立的运行:

text
❌ 一个 Agent 跑 40 圈把三家都查完

✅ 主流程(这是一条 Workflow):
   for 每一家:
       起一个新的 Agent 运行,目标只有"查清这一家"
       它跑完,产出写进 notes.md
   最后:汇总 notes.md

好处很实在:

  • 每个子运行的上下文都是干净的,从头开始;
  • 一家查砸了不影响另外两家;
  • 三家可以并行(注意并发上限);
  • 每个子运行的验收都更简单。

注意这里发生了什么

外层是一条 Workflow,内层每一步是一个 Agent。

这就是上一篇那句"Agent 是流水线里的一个节点"的实际长相。 你会发现真正好用的 Agent 系统,多半长这样——而不是一个跑八十圈的巨型 Agent。

一个判断信号 ​

跑完之后,看它用了多少圈。

  • 5 圈以内:很好,可能这活本来就该是 Workflow。
  • 5~15 圈:正常范围。
  • 20 圈以上:警惕。多半是目标太大、或者工具返回太胖、或者它在绕圈。
  • 接近你设的上限:几乎肯定有问题,去看轨迹。

圈数是最便宜的健康指标,每次都值得瞄一眼。

下一步 ​

08 · 看得见:轨迹与复盘

一份讲通用概念的入门手册 · 不绑定任何一家模型或工具 · 例子可直接照抄