Fermi
← 博客 · 2026 年 6 月 5 日

单 Agent 就够了

自 GPT-4 时代以来,模型的智力与泛化能力已经经历多次飞跃,提示词和工具设计带来的差距在前沿模型下也正被抹平。但是,模型上下文目前依然有限,且长上下文下模型会出现上下文腐烂(Context Rot),在面对长程任务时,上下文工程(Context Engineering)已经成为了当前 Agent 设计的重中之重。

关于上下文管理的具体含义,已经被很多文章透彻分析过,这里不再详细讲解,推荐 AWS 的 Agentic AI基础设施实践经验系列(九):Context Engineering 上下文工程. 我将直接开始对比目前主流 Coding Agent 的上下文管理策略,并说明,为什么我选择了单 Agent 作为"执行者"。

自动压缩 - 单执行者,保守、合理、简单

作为两个用户量断层领先的 Coding Agent, 无论是 Claude Code 还是 Codex, 默认状态下都一致地选择了保守而简单的做法:接近上下文的上限之后,进行一次性的自动压缩(Auto-Compaction),将整个会话总结成概要,并以概要作为新的上下文继续工作。这种方法的缺点似乎很明显:从一个已经长对话浓缩到一个很短的概要,一定会丢失信息……吗?

自动压缩的缺点并不那么简单,而是,模型目前缺乏良好的总结能力,或者说,有着长 Context 的 Agent 目前难以推断出,一个没有这些上下文的 Agent,究竟需要哪些信息。最容易在压缩过程中被错误丢掉或扭曲的,一方面是用户和 Agent 对话过程中做出决策的过程,另一方面是编写代码的过程中所做的一些隐性决策。而用户的意图,以及 Agent 行动过程中的隐性决策,在执行任务时非常重要,它们内化了隐性约束,这些约束实际上让 Agent 可以按用户预期完成任务,但在实际使用中,自动压缩难以保全这些隐性知识,这似乎是 Agent 的一种知识的诅咒

不过,真实的机制可能更复杂,如果你常用这个功能,就会发现有时自动压缩之后的对话质量意料之外地差,模型似乎以某种未知的方式不可逆地变"笨"了,这可能与概要中的思维/推理断层有关。

这种情况下,对于需自动压缩、甚至跨多个自动压缩的长程任务,Agent 的实现无法避免地逐渐走样,我们只能尽可能用系统提示词强化自动压缩的表现。Claude Code 做了特别设计,他们在 prompt 中要求:自动压缩时,要详细列出所有的用户消息。这种设计尽可能地保留用户的决策以及决策的意图不会被遗落,一定程度上缓解了该问题。

多 Agent 协作 - 多执行者,模仿人类

在过去几个月,尤其是 Claude Code 推出 Agent Team 功能之后,多 Agent 并行协作,成为了最热门的 Agent 设计理念之一,但这种模仿人类的工作方式的实现,并未取得明显成功。

首先,在多 Agent 协作流程中,一个事无巨细的计划,只是并行工作的起步标准。假设我们要求两个 Agent 按照计划分别开发同一个应用的两个页面,计划中规划了风格、每个页面的功能、字体… 但不可能约定每一个实现细节——否则写计划的 context 成本将比直接实现还高。结果,同样的列表加载,一个页面用骨架占位,另一个却用转圈动画;同样的输入框,一个用小圆角,另一个却用大圆角,且各自造了轮子。每个页面似乎都合理,但拼凑到一起之后,处处不同的交互逻辑和视觉效果摧毁了用户的体验。

Agent A 的页面
请输入用户名...
提交
Agent B 的页面
用户名
OK

Agent 之间的沟通系统是最困难的部分。人类没有硬性的上下文容量限制,思考、完成任务的速度也有限,沟通得以在工作间隙自然发生。但是,Agent 收到的每条消息都会永久写入上下文,并且,由于 Agent 的实现速度太快,中途发现问题时再沟通将变得异常困难,所以沟通几乎只能发生在计划阶段。几个 Agent 互相同步各自的决策,每条消息在每个 Agent 的上下文里各存一份,加上各自的回应和评估,上下文的消耗速度远超实际工作的产出。沟通越充分,每个 Agent 留给真正做事的空间就越少。最坏的情况是,某个 Agent 的上下文在协作途中被耗尽、触发了自动压缩,它将带着残缺的记忆继续参与共同的任务,不仅自身的工作质量下降,还可能把错误的理解传播给其他 Agent。不沟通,各做各的拼不到一起;沟通,又会迅速耗尽做事的空间。这是并行协作在 Agent 架构下的根本困境。

Agent A
Agent B
Agent C
Agent D

所以,人类的协作过程中,哪一部分可以拿来借鉴?人类沟通、分工、各自完成自己的工作,关于"沟通"的部分,我将在子 Agent 不写代码这一节中详细分析,前面已经分析过的是——并行完成工作在 Agent 系统里非常困难,那么分工,然后串行完成呢?

Droid 做了这样的尝试。

依次执行(根据计划) - 多执行者,各自为政?

Droid 的 Mission 功能采用了先计划、后串行实现的编排路线,Orchestrator(架构师)负责与用户进行对话并商讨出详细的计划、验收契约,计划好之后,让独立的 Runner 根据计划,派出 Worker 执行每个子任务节点,并在每个里程碑达成后派 Validator 对这一阶段进行 Review.

这类架构的首要问题仍是隐性知识的丢失。决策时的意图和意图中包含的隐性约束,能否被计划完美地传达到 Worker? 下一个 Worker 能否真正理解上一个 Worker 行动中所做的隐性决策?计划不可能覆盖所有细节,Worker 在实现中必然会做出一些计划之外的判断,比如选择某种数据结构,或者在两种等价方案中选了其中一种,这些决策的原因不会被下一个 Worker 显式获悉,却会影响后续 Worker 的工作。在缺少这些隐性知识的情况下,每个 Worker 只能"各自为政",写出能运行的代码,但更难在前一个 Worker 的基础上做好优化,甚至可能做出相互矛盾的设计选择。

偏离一旦发生,纠正代价很高。Worker 被要求完成特定的子任务,即使它意识到前面的实现有可以优化的地方,也不会主动转向去修正,因为那并非它的工作。更坏的情况是,前面某个 Worker 的实现已经部分偏离了计划,后续 Worker 看到已有代码,容易把它当作权威的实现继续向下开发,导致偏离被放大。而 Orchestrator 只在里程碑处通过 Validator 获得反馈,等它发现问题时,可能已经有好几个 Worker 在错误的方向上堆叠了大量代码,此时重写契约、回滚重做的成本将很高。并且,Validator 也只能根据计划审查代码,如果 Worker / Validator 自己对计划的解读和 Orchestrator 的实际意图有冲突,当 Orchestrator 发现时,很可能为时已晚,此时再重写一整套契约来修?或者接受这个没那么完美的结果?

另一个潜在的问题是 over-engineering. Droid 为了控制较为复杂、容易失控的多 agent 架构,在中间的过程中制定了大量的规范,把几乎所有能固定的流程都进行了固定,通过大量的硬性约束来规范整套流程。比如当 Worker 无论是正常做完还是认为有问题需要反馈,都不会通过输出的方式向上级反映,而是通过 EndFeatureRun 工具的字段 returnToOrchestrator 来控制自己的 handoff 是否由系统直接转交给 Orchestrator. 较重的系统设计显著提升了系统运行的稳定性,保证了系统能长时间稳定运行,但重流程同样有代价:它增加模型认知负担(特别是对于不同智力、做事风格的模型,引入同一套系统带来的结果很可能相差较大),也限制了系统的灵活性,想要做什么都要写好计划、写好契约… 但这只能保证 Agent 执行稳定,不能保证实现方式更好。

但是,Droid 的 Mission 功能仍是当前最合理的多执行者设计,串行执行的路线避免了最严重的并行协作的混乱,重流程也确实能让系统持续运行数小时而不崩溃。

Claude Code 在我撰写这篇文章的过程中,推出了 Dynamic Workflows / Ultracode, 这是一种较为落后的实践方式,类似一个轻量化、定制版、动态化的 LangGraph, 过去已经有非常多相关实践。它完全没有解决上述问题,包括隐性知识的丢失与中途纠偏能力的缺失(灵活性问题)。尤其是一次性编排+派发后只等待返回(同步等待)的机制,让它大幅丧失了普通多 Agent 系统的灵活性,虽然可以写一些条件分支/while, 或是由子 Agent 返回的清单在运行中决定 Agent 派发的数量, 但编排路线本身必须在每次运行前写定,子 Agent 一经派出,与主 Agent 之间就只剩一次性的返回值,没有任何运行中的沟通与协商。换句话说,为了避免"沟通混乱"带来的上下文占用,它直接禁止了主 Agent 在运行过程中干预流程。这使它作为一个"多执行者"体系处境尴尬:论流程约束,远不如 Mission 系统齐全;论灵活性,又比不上 Agent Team 系统。

唯一的好处似乎是:能够避免多 Agent 编排的中间过程占用上下文。因此,该系统只对少数场景有价值,如自动化生产高质量的 review(派出多个 Reviewer 审查代码的不同部分,随后给每个 Reviewer 配一个 Adversarial Agent 来做交叉审查),但是,居高不下的成本,让这个功能的性价比变得很低。

Fermi 的自我压缩 - 单执行者,更灵活,但尚需实践验证

无论是单 Agent 的 auto-compaction, 还是多 Agent 协作的编排,其面临的问题都是隐性知识能否传递,但目前的模型似乎还并不擅长做这种任务,常常过于强调细节,而忽略背后的决策逻辑,这也是为什么 Worker / Executor 需要一个持久、尽可能完整的大脑来处理任务。

因此,在 Fermi 中,我引入了自我压缩的工具来帮助单执行者应对长程任务,为了防止全量自我压缩带来的对用户意图的破坏,以及对决策、计划过程中的思路的破坏,我采用了更细粒的压缩,让 Fermi 能够做到单工具级别的压缩,从而在不压缩关键思路和对话的情况下,对部分没那么重要的地方进行大幅压缩,例如:

通过这种方式,Fermi 避免了压缩和用户的讨论过程,尽可能保留了决策过程,避免隐性约束的丢失。目前,Fermi 的自我压缩分为两种:

  1. 用户手动使用 /summarize 进行压缩,通过这种方式,用户可以选择压缩连续的 turns(一条用户消息和对应的 Agent 的行动和输出),并可以给出自定义压缩指令;
  2. Fermi 自己进行压缩,但此过程被限制在单个 turn 内部,也即:用户消息是不可被压缩的,Fermi 无法跨用户消息进行压缩。

但自我压缩目前还存在不少未确定的问题:

子 Agent 不写代码

目前为止,最行之有效的子 Agent 的工作方式仍是不直接修改代码,仅承担其余工作,如下:

事实上,正如 Cognition 的 Walden Yan 在博客 Multi-Agents: What's Actually Working 中所提到的,子 Agent 作为 Reviewer 的效果出乎意料地好,尤其是在和执行者完全不共享上下文的情况下。他给出的解释是:Reviewer 被迫从实现反推而非根据 spec/用户指令推进,以及长上下文的 Context Rot 两个因素共同作用。但还可能存在的原因是:LLM 受到的训练更多是逻辑严密的推理(reasoning),训练中可能不会要求它自己找出自己的错误(因为训练者想要训出第一次就输出最优质代码的模型,而不是输出之后自己纠错的模型),这导致:它在自己的代码中找 Bug 相比让 Reviewer 来找 Bug 更困难,也就是代码是 role="assistant" 还是 role="user" 所引起的 LLM 行为的不同。

建议给 Sub-Agent 设置多种不同的模型,Fermi 提供了三种 Tier 可配置,当碰到困难问题时,主 Agent 将自动选择 Tier-High 的模型作为 Sub-Agent. 我自己常用的配置:主 Agent - DeepSeek V4 Pro max, High - Codex/GPT 5.5 xhigh, Medium - DeepSeek V4 Pro max, Low - Codex/GPT 5.4 mini.

在这种方式下,主 Agent 不断一路 fork 自己直接执行各项子任务,或许也是一种选择?由于无需压缩与传递,这种方式不会有隐性知识的问题。目前 Codex 设置了这种方案,Fermi 将在不久的将来支持该功能。

写在最后

"执行者必须只有一个"……吗?其实,多执行者体系并非天生有错,只是:当前模型的瓶颈在于隐性知识无法可靠传递——无论是自动压缩时传给"未来的自己",还是协作时传给别的 Agent。单执行者 + 干净上下文的辅助 Agent(探索、审查、咨询),是该瓶颈下最可靠的设计。但是,如果模型真摆脱了"知识的诅咒",本文大部分结论便都可以重写了——但在那之前,还请先保住执行者的大脑。