前言
也算是有一段时间没写博客了。
自从AI Coding愈发成熟之后,许多直接的编码工作已经可以完全被AI取代,许多问题也可以稍微问一问AI就能得到答案。翻看以前的博客,无外乎就是遇到问题经过一番调研找到的解决方案,或者进行了某项编码和开发工作获得的经验。前者现在已经大部分能在几分钟内用AI解决,而后者在如今Claude Code、Codex等Agent的帮助下也变得很容易,甚至Agent可以直接在服务器上Debug和做迁移之类的工作。
AI生成的文章也在泛滥…甚至已经到了觉得打两个错别字,写点病句,用几个大小写不规范的名词,才有活人感,这样的地步。
因此也很长一段时间没有写博客,主要感觉没什么好分享的。
不过想来,真的没什么好分享吗。其实使用AI的过程中,就算是模型和harness工具都一样,不同人的sense差别,也可能造就差异巨大的成果。
所以思来想去,还是觉得可以写写AI利用在实践中的经验。或者干脆,单纯的水一些观点也没问题。文科生的时代要到来了(笑)。
需要管理的Agent上下文
回到正题,最近在项目实践中也接触到了不少Sub Agent。我所接触的使用Sub Agent的理由无非是两种:
- 并行某些可并行的任务节省时间
- 不同角色不同分工,合理规划上下文
其中第二点,也就是Context Engineering,属于一个经久不衰的课题,也算是各大harness工具的开发者和使用者都会面对的问题。
规划上下文的理由也很简单,也就是模型的上下文有限。而且更重要的,注意力在在每个token上都一样强大,而是呈现稀疏的形态。据说,当上下文短一点的时候,注意力集中在头尾两侧;而上下文长一点的时候,基本上头部的优势也丧失了,往往是越靠近结尾注意力越强。
积极使用Sub Agent的两个思路
如果因为上下文过长,模型注意力缺失,就会导致幻觉明显,比如忘记之前做过的设计决策,实现时漏掉之前讨论过的细节等,这类问题叫做context rot。
或者,当上下文长度触发强制compact,得到的只是一个非常简略的summary,丢失了很多重要信息和细节。
积极使用Sub Agent是解决这样问题的一个手段,所谓Sub Agent,就是通过Main Agent去主动通过自己生成的prompt拉起的Agent,它们有自己的上下文,完成任务后,会输出一份完成报告返回给Main Agent。
如这个项目的设计,希望通过给不同Sub Agent分派不同的角色,完成编码工作生命周期的所有内容,而Main Agent仅仅负责协调,传递上下文,管理记忆文件等等。
例如Main Agent可以生成:Researcher Agent, Planner Agent, Plan Checker Agent, Execution Agent (backend-dev, frontend-dev, database-manager), Review Agent等等。
不同功能的Agent各司其职,拥有全新的上下文,只获取必要的信息;Main Agent永远不会接触具体的代码文件,因此可以「上下文窗口缓慢且可预测地增长」。
确实这样的话,如果规划得当,或者任务本身拆解适中,就不会出现Main Agent被compact的情况,能够保留所有上下文记忆。
看起来不错,不过也有文章提出了反面的意见,或者说进行了一些修正。
例如这篇文章指出,应该只能让Sub Agent进行调研工作,而不是编码任务。分成backend-dev, frontend-dev, database-manager这种模式是「彻底的灾难」。
每个子代理都是孤立执行的。完全没有关于其他人做了什么的上下文。当出现错误时,没有人知道其他人构建了什么。token 使用量?高得离谱——没有任何成果,正常的三倍。实际上发生的是:
- 父代理分配任务 → 子代理盲目工作 → 返回摘要
- 父代理无法了解实际变更
- 子代理 #2 重新开始,重复工作
- 你现在正在调试没人能懂的代码。
所以文章认为只应该让Sub Agent进行调研,而具体的编码实现工作永远让Main Agent亲自完成。
至于会不会被compact,文中的观点认为,只要不是在写实现之前读取代码调查当前架构,这种高度消耗token的任务,剩下纯写的任务让Main Agent完成,应该是够的。
不过个人感觉,还是得看任务的复杂度。如果任务涉及到的文件比较多或者系统架构本身就很复杂,上下文还是不够用。尤其是当所用的Agent上下文长度只有200K的时候。
而且,现在的Agent harness工具是要求改一个文件就必须先读一遍。如果涉及到的文件很多的话,读得多了,上下文不还是会被占满吗。
当然,就算是第一篇文章提到的那种方案,例如把编码工作也委派给Sub Agent,分成backend-dev, frontend-dev, database-manager,也同样会在大的codebase遇被compact的问题。
除了从200K升级到1M上下文似乎就没有别的办法了。
1M上下文真的就管用吗
就算是1M上下文,还是会发生context rot。事实上就算是1M的模型,也未必就有完美1M的注意力。
200K的模型,可能注意力也仅仅在最后100K。而就算是1M的模型,在某些复杂任务里,1M标称窗口的可靠有效上下文可能远低于1M;有些模型在128K、256K甚至更短就明显退化。
这里还有论文的结论:Yi-34B 标称 200K,有效长度只有 32K;LWM 标称 1M,有效长度小于 4K
不用Sub Agent反而更好?
这些文章,以及各种管理上下文的项目都「宣称这种问题会发生,并且造成很大的影响」。不过事实上,可能确实发生了,但也可能随着技术的进步,同样的问题渐渐不会发生了。
另一种想法是认为不用Sub Agent,不搞这些花里胡哨的上下文管理反而更好。
将同样的内容工作保持在同一个上下文中,如果是同一项任务的话,就一直一直地复用会话。
自然,模型会犯错,但可以靠人类指正。经验表明,一旦人类指正模型犯的错误,在同一个session接下来的会话中,犯同一个错误的概率会超级降低。
但作为人类大脑,还是会漏掉东西的,反而会导致人和AI都按照错误地路径走下去。AI不记得,人也不记得,人只是模模糊糊记得自己和AI讨论过这个问题,就从大脑中划掉了。人和AI都觉得已经讨论过确定下来了,但其实AI那边发生了context rot,导致最后实施的时候和之前讨论的内容完全不对应。
还生成一个文档吧
作为解决方案,或许每次讨论完成准备实施,就让AI将会话总结为一个md文档,由人工再审查一遍,再开一个全新的上下文窗口,对着这个文档去实施比较好。
我能理解的是,在讨论阶段其实会产生很多无效信息,比如设计的更改之类的。生成一个文档确定下来,把讨论过程的噪音剥离掉,应该是用不用Sub Agent的人都同意的。
而且,就算后面被compact,AI也能读取这个文档,至少对当前实现在做什么,约束是什么有个清晰的了解。之后再去调研代码库,看当前实现到哪里,继续实现下去也不迟。
调研也不用Sub Agent??
本来想着无论怎样,总该用Sub Agent吧。就算不让Sub Agent去实现具体功能,调研也该用Sub Agent进行。要不然上下文也太容易爆炸了。
但「就算是调研也让Main Agent自己来!」也是有这样的想法存在。
觉得即使调研,Sub Agent也不一定很好,大概有以下原因:
- Sub Agent是概括的,损失细节,如果模型有1M上下文的话,还不如让它把所有细节都读进自己的上下文里
- 甚至有时候Main Agent在接收Sub Agent的总结输出后,会不放心,又自己去看了几个文件确认一下,十分滑稽
- 大概是由于就算是Main Agent给Sub Agent下发的prompt,Sub Agent由于缺乏对任务的全面了解,还是不太清楚应该调研到何种程度,要输出给Main Agent的内容中包含到什么地步的细节
- Sub Agent调研需要再输出一份长长的总结报告给Main Agent,中间信息互换的过程又浪费了时间和金钱
- Sub Agent 的成本未必低,因为它会重复其他 Sub Agent 做过的事情,比如了解项目的基础,读 README,然后它还要输出很长的概括,输出 token 比输入 token 贵得多
另外如果模型要做决策,它开始调研,调研的 token 都是在最近的 tokens 里面,因为它调研完就要做决策,所以靠的很近。
如果看一些模型的 thinking trace,会发现它们会定期总结自己调研的结果,然后决定下一步。就是说调研的结果反复出现在 context window 里,以 thinking 的形式,因此有一种强调的作用,不会轻易忘了之前的重要细节。
这么说context rot确实存在,但也没严重到那种地步?
模型的所有thinking trace现在确实在Agent架构中都会保留,并占据上下文。毕竟如果不这样就没法命中缓存了。
不过虽然这样反复出现,后面好像还是可能有偏离的情况。
比如某次总结因为当前轮次对话没用到A事实,A就没出现在thinking里,后面就也没提到A,导致之前确定的A就遗失在漫长的对话里了。最终实施的时候变成了完全没考虑到A的情况。
Opus 4.8倒是进化出来一招,就是它会隐约记得这些,然后再去读一遍相关的行;它不会因为读过一个文件就再也不去看了,如果记忆淡化它就会再读一遍。
但毕竟不是所有模型都是Opus。
而且如果遇到compact就更糟糕了,很多情况下compact之后模型就和失忆了一样,这不仅仅是context rot的问题了,甚至就是大失忆术。
所以如果没有1M上下文,只有200K,还是要好好规划以下。用Sub Agent做调研也不失为一种解决方法。
不知道之后会不会所有模型都变成1M呢。
结论
这篇文章没有结论,单纯是使用中的一些感受。
根据实际情况选择要不要用Sub Agent吧。