我第一次在自己的 Agent 里用“子 Agent”,动机很朴素:主任务的上下文太长了。主 Agent 在帮我做一次跨模块的重构,前面已经读了一堆文件、讨论了好几轮方案,这时候它需要搞清楚“仓库里有哪些地方调用了某个旧接口”。这种搜索很费上下文:要翻很多文件,大部分都是无关的。
于是我想,把这个搜索派给一个子 Agent 去做,让它搜完只汇报结果,主 Agent 的上下文就干净了。
想法没问题,但我前后改了三版才算勉强满意。这篇就聊聊这个过程里我对“上下文隔离”的理解:为什么要隔离、派活时给什么、收回来要什么,以及哪些情况其实不该隔离。
第一版:把整个对话都传过去
最开始我图省事,直接把主 Agent 的完整对话历史复制给子 Agent,再加一句“请找出所有调用旧接口的地方”。
结果很有意思:子 Agent 读到了前面关于重构方案的讨论,然后开始“热心”地帮忙——找到调用点之后,它顺手开始改代码了。它还在汇报里大段复述我们之前讨论过的方案。更糟的是,传过去的上下文本来就很长,子 Agent 一开始就背着一个沉重的包袱,搜了没多少文件就开始接近上下文上限。
这一版让我明白了:把所有信息都给子 Agent,等于没有隔离。 它不仅继承了上下文的长度,还继承了主线的“意图”,于是会去做不属于它的事。
第二版:只给一句话
吸取教训,第二版我只给子 Agent 一句话的任务描述,什么背景都不给。
这次它倒是很专注,但问题出在另一头:它不知道哪些目录是生成代码可以跳过,不知道那个旧接口有一个别名,也不知道测试代码里的调用要不要算。最后它交回来的结果,漏掉了通过别名调用的地方,又把一堆生成代码里的引用算了进去。
而且子 Agent 通常没法回头问用户,也不方便问主 Agent。信息不够的时候,它只能猜。
第三版:任务卡加回执
折腾两版之后,我发现关键不在于“给多少”,而在于给什么。我最后把派活和交活都做成了固定的格式,我自己管它们叫“任务卡”和“回执”。
任务卡里,我现在会写这几样东西:
目标:一句话说清楚要做什么。
完成标准:怎样才算做完,比如“列出所有调用点,每一处给出文件路径和行号”。
相关背景:只给和这个任务有关的事实,比如“这个接口还有一个别名”“生成代码目录可以跳过”。不要给主线的讨论过程。
约束:明确不能做什么,比如“只读,不要修改任何文件”。
可用工具和权限:这次子任务只给搜索和读文件的工具,写文件的工具干脆不给。
预算:最多多少步、多长时间,到了就停,交回已有的结果。
回执格式:要求它按什么结构汇报。

图:任务卡与回执:派给子 Agent 什么、收回来什么(原创示意图)
这里我想特别说一下“工具和权限”这一条。我原来是在任务描述里写“请不要修改文件”,后来改成了直接不给写工具。靠提示词约束行为,模型大多数时候会听,但不是每次都听;而一个不存在的工具,它是不可能调用的。隔离不只是上下文的隔离,也应该是权限的隔离。
回执:收回来的东西比派出去的更重要
派活想清楚之后,我发现另一个容易被忽视的问题:子 Agent 交回来什么。
如果让它自由发挥,它会把整个搜索过程都写进汇报里:“我首先搜索了某某目录,然后发现……接着我又……”这些过程性的信息,对主 Agent 几乎没用,却会重新把主 Agent 的上下文撑大,等于白隔离了。
所以我要求回执只包含这几样:
结论:直接回答任务的问题;
证据:每个结论对应的文件路径、行号或链接,让主 Agent 可以抽查;
置信度和未完成项:哪些地方没搜完、哪些结论不太确定;
建议的下一步:如果有的话。
其中“证据”这一条特别重要。主 Agent 不应该无条件相信子 Agent 的结论,它应该能随时根据证据去核对一两个点。我在主 Agent 的提示里也加了一句:重要的结论,至少抽查一处证据再采用。
我还给回执设了一个长度上限。超过上限,就要求子 Agent 自己再压缩一遍。这听起来有点死板,但它保证了一件事:无论子任务内部有多复杂,回到主线的只有一页纸。
隔离还有一个好处:把风险关在小房间里
后来我给 Agent 加了读网页的能力,又发现子 Agent 的另一个用处。
网页内容是不可信的,里面可能夹带着试图操纵模型的指令。如果主 Agent 直接读网页,这些内容就进入了主线上下文,而主线上下文里有写文件、执行命令这些高权限工具。
我的做法是:读外部内容的活,交给一个只有只读工具的子 Agent 去做,要求它只按固定格式回传提取出来的信息。这样就算它在网页里读到了奇怪的指令,它手上也没有能造成破坏的工具;回到主线的,是一段结构化的摘要,而不是原始网页。
我得说清楚,这不是一个完整的防护方案,结构化的摘要里依然可能夹带有问题的内容,所以主 Agent 对回执里的内容,也应该当作数据而不是指令来对待。但相比于让主 Agent 直接读原始网页,它确实把风险的范围缩小了很多。

图:把读外部网页的风险关在只读子 Agent 里(原创示意图)
并行子 Agent:最怕抢同一块地
有了子 Agent,自然就会想并行:同时派几个出去,各查一块。查询类的任务并行起来很顺利,但我有一次让两个子 Agent 并行做修改,它们改到了同一个文件,后完成的那个覆盖了前一个的改动。
我现在的原则是:并行的子 Agent 默认只读,它们交回来的是“建议怎么改”,真正动手改的只有主 Agent 一个。如果实在要并行写,就提前按文件或者模块切好地盘,保证互不重叠。
什么时候不该隔离
最后说说反面。子 Agent 不是越多越好,我也走过“什么都派出去”的弯路。以下几种情况,我现在倾向于不用子 Agent:
任务强依赖主线的细节。 要把这些细节讲清楚,任务卡会写得和主线上下文一样长,那还不如自己做。
需要频繁来回确认的任务。 子 Agent 不方便中途提问,来回的成本很高。
很小的任务。 派活、交活本身都有开销,一个两三步就能完成的事,派出去反而更慢、更贵。
我的经验法则是:当一个子任务需要读大量信息、但只需要交回少量结论时,最适合隔离。 搜索、调研、读长文档、读外部网页,都属于这一类。

图:要不要派给子 Agent 的二乘二判断图(原创示意图)
最后
回头看这三版,我觉得上下文隔离的本质,其实和我们平时给同事派活很像。你不会把整个项目群的聊天记录都转给他,也不会只丢给他一句话就走开;你会告诉他要做什么、做到什么程度、哪些地方要注意、什么时候交,然后期待他交回来一个清楚的结论,而不是一份流水账。
给子 Agent 派活,也是这个道理:给任务卡,收回执。 中间的过程关在它自己的上下文里,主线只留下结论和证据。这样主 Agent 才能一直保持清醒,专注在真正需要它判断的事情上。


2026-10-14鱼鱼