开发者质疑AI子代理架构:摘要丢失关键信息,上下文隔离代价高
来源标题:Subagents Conwidered Harmful
开发者指出子代理存在与上下文压缩相同的摘要丢失问题:主代理写几段任务描述后,子代理便从摘要开始工作,看不到产生该摘要的对话。作者曾认为这种设计有利于并行化,如今认为通常是糟糕的交易。其一次让子代理调研工具是否与Anthropic、OpenAI产品重复时,摘要竟完全没提到Anthropic。
以下正文由 AI 翻译自 Hacker News 最新(原文版权归原站所有),可能存在偏差,重要内容请以原文为准。
如果你见过 agent 在压缩完上下文之后转眼就忘掉重要信息,你就知道摘要有多容易丢失信息。比较少被提到的一点是,subagent 其实也有同样的问题!主 agent 写几段话描述它认为任务是什么,subagent 从这个摘要出发,却永远看不到产生这个摘要的那段对话。作为交换,主 agent 的上下文保持得又小又聚焦。我以前觉得这是笔划算的买卖,因为它能让你并行处理任务。但现在我觉得这通常是个糟糕的交易。
事实证明,向 subagent 委派任务有几种不同的方式,而它们失败的方式各不相同。这篇文章会讲它们分别是什么、为什么让 agent 学会在它们之间做选择才是最难的部分,以及我正在测试的一种可能两全其美的新方法。我先从最常见的那种方式是怎么失败的讲起。
我曾让一个 agent 去查一下我写的一个工具是否重复实现了 Anthropic 和 OpenAI 已经推出的功能,并让它派一个 subagent 去调研。它写的那份摘要让 subagent 去调查我的工具,却莫名其妙地从头到尾都没提到 Anthropic 或 OpenAI。subagent 尽职尽责地带回了一份详尽的报告,把我自己代码的所有细节都讲了一遍,却只字未提 OpenAI 或 Anthropic 的功能 🤦♂️。那个 agent 明明面前摆着我完整的请求,却还是把最关键的那一半弄丢了。更糟的是,subagent 根本无从得知这一点,因为就它所能判断的而言,它收到的摘要就是完整的,于是它勤勤恳恳地做了一堆无用功。
Alexander Yue 最近发了一个帖子,正是因为这个问题,把 subagent 称为「AI 失败的最大原因」,还附上了数据。在一个 137k token 的会话中,使用 Opus 5.5,让主 agent 自己完成一项任务耗时 67 秒,花费 $0.38。把同样的任务通过摘要交给 subagent,耗时 123 秒,花费 $0.57。所以,惯常的 subagent 生成方式同时做到了更慢、更贵、信息还更少。
这个问题的常见解决方案是使用 forked subagent。subagent 拿到的不是摘要,而是整段对话的副本,外加一条说明,告诉它哪部分工作是它的职责。Codex 和 Claude Code 现在都支持 forked subagent,而且在这两个 harness 中,都是由模型自己决定是启动一个全新的 subagent 还是一个 fork。这是一个实实在在的权衡:带紧凑摘要的全新 subagent 更便宜、更专注(因为它不必每一轮都在冗长且往往无关的历史里跋涉),但它更可能缺失关键上下文、做出糟糕的判断。fork 消耗更多 token,但它确切知道被要求了什么、哪些地方被纠正过、哪些方案已经被否决。
不过 fork 也有自己的怪毛病。我第一次尝试时,新 agent 读到了它继承的历史里的最后一条消息——那是一条启动 fork 的请求——把它误当成了对自己的指令,于是在第一个 fork 里又启动了一个子 fork。它还看到了父级的待办清单,就开始照着做。所以现在我的 fork 实现会插入一条说明,告诉每个子 agent 它就是这个 fork、创建它的请求已经被处理过了、以及哪部分工作是它的职责。在我自己的环境里这很容易修,但如果你依赖别人的实现或者自己动手做,这或许值得了解一下。
让 forking 跑起来是简单的部分。难的部分是让 agent 以和我一样的方式做出「fork 还是摘要」的决定,而不需要每次都让我参与其中。
权衡本身很简单:如果执行者需要做出依赖对话内容的判断,就 fork 它。如果它只是在执行已经做好的决定,那就用摘要。很简单,对吧?然而当我把这条写进 agent 的指令里时,它几乎从不 fork。
当我催它更频繁地 fork 时,它竟然做出了一个最糟的选择:把整个项目交给一个全新的 subagent,然后让那个 subagent 去委派 fork。协调者的全部职责就是把握大局,而大局存在于对话之中,这个新协调者对此一无所知。而且既然协调者本身不做任何实际工作,在专注度和并行度上也没有任何收益。这个 agent 基本上是把工作交给了一个信息更少的自己,然后让它当老板。
真正让我恍然大悟的时刻,是我看到一个 agent 把三个规划任务派给全新的 subagent,并把它们描述为「小范围代码检查」。没错,每个任务只涉及几个文件。但这些任务是规划新工作,而规划主要就是做决定:我们讨论过的方案里选哪个、哪些我已经排除了、这个功能到底是为了什么。这些都不在代码里。一个拿着摘要的 subagent 可以整天检查文件,却仍然对真正重要的事情一无所知。那个 agent 看着这些任务,看到「几个文件」,就把它们归为机械性工作。它在不知不觉中把「判断性决策需要 fork」变成了「小任务用摘要」,因为任务大小一目了然,而判断力不是。
于是我尝试让它自己爬山爬出这个烂摊子,而 agent 做了 agent 会做的事:它针对眼前的情况打补丁,直到我们积累了一堆令人困惑且过拟合的边界情况指令。多 fork。不要什么都 fork。规划算作判断。
(原文较长,此处译出前 6000 字,完整内容请点「打开原文」。)
正文由 探How 从来源站点 RSS 同步,内容未经改写;遇到排版缺失或需要图片、视频时请以原文为准。