先问一个问题
AgentTeams 被移除了,这算失败吗?
我的回答是:不算。
一个功能被移除,有两种截然不同的原因:
第一种:设计有缺陷,做错了。 比如引入了一个 bug,或者选择了一条走不通的技术路线。
第二种:超出了当前系统边界,应该在另一个地方。 功能本身没问题,但它属于一个更复杂的问题域,强行塞进现在的系统会破坏整体结构。
AgentTeams 是第二种。
理解这个区别,才能理解 MyCodeAgent 团队为什么要花精力实现它、又为什么要花精力把它移除,以及这个过程对项目本身的意义。
回顾 AgentTeams 的设计与实现
这一篇要把前三篇的内容综合起来,所以先快速回顾一下:
- 第 16 篇:设计动机------单 agent 上下文有限、不能并行,AgentTeams 提供团队模型解决这个问题
- 第 17 篇:消息协议------SendMessage + ACK 三态(pending/delivered/processed),保证消息可靠传递
- 第 18 篇:TeamFanout/Collect------非阻塞分发、上下文隔离、冲突检测不自动合并
从设计角度看,这三个机制都是有价值的。那为什么要移除?
结论先说
AgentTeams 被移除的核心原因不是一个,而是三个层面的问题叠加:
| 层面 | 问题 |
|---|---|
| 复杂度 | 多 agent 系统引入的复杂度远超它解决的问题 |
| 边界 | 它不属于"agent harness core",而属于"应用层"问题 |
| 成本 | 维护一个实验性系统会持续消耗核心系统的精力 |
移除的本质,是一次边界重划:把一个从"试试看"开始的功能,从主产品边界里剥离出去,让它保留在 Git 历史里,而不是保留在代码库里。
一、复杂度雪球:每增加一个 agent,复杂度不是加法
先来看最直接的原因:复杂度。
单 agent 系统的复杂度,主要来自 LLM 调用的不确定性、工具执行的副作用和上下文管理。这些我们在 Part 4 里已经深入讲过,是可以被系统性管理的。
但多 agent 系统引入了一类全新的复杂度,而且是以乘法而非加法的方式增长的。
举一个具体的例子。单 agent 遇到工具调用失败,处理逻辑是:
markdown
工具调用失败
│
▼
分类:是否可恢复?
│
├── 可恢复 → 重试(有限次数)
└── 不可恢复 → 走终止路径
这个逻辑相对清晰,第 14 篇详细讲过。
但如果是 AgentTeams 里的一个成员 agent 工具调用失败了,情况变成:
arduino
成员 agent 3 的工具调用失败
│
▼
这个失败影响了什么?
├── 成员 3 的任务只是"坏了",其他成员不受影响?
├── 成员 3 在修改的文件,成员 4 也在修改?(有依赖关系)
├── 成员 3 本来要把结果传给成员 5?(有消息依赖)
└── 协调者需要知道这个失败,还是静默重试?
如果协调者正在等待 TeamCollect,超时了怎么办?
每一个"?"都是一个需要被回答的设计问题。而且这些问题之间是相互依赖的------你没法独立回答其中一个,因为答案会影响其他的。
更麻烦的是,有些问题在单 agent 里根本不存在,是多 agent 特有的:
- 成员 agent 之间的隐式依赖:两个成员在修改同一个文件,谁先修改谁后修改,结果可能完全不同
- 协调者的状态爆炸:协调者需要追踪所有成员的状态,成员越多,协调者的状态机越复杂
- 调试困难度:单 agent 出了问题,看 trace 就能定位。多 agent 出了问题,需要同时看多个 trace,还要找它们之间的时序关系
二、边界错位:它在解决哪一层的问题?
MyCodeAgent 的目标,在 HARNESS_ROADMAP 文档里有明确的五条:
- 能把模型调用组织成可解释、可恢复的 Agent Loop
- 能安全、确定地调度工具
- 能把完整历史、长期存储和模型当前视图区分开
- 能判断任务是否真正完成,并在失败后有限恢复
- 能通过受限子 Agent 展示上下文隔离、能力裁剪和独立验证
注意第 5 条:受限子 Agent。不是"通用多 agent 协作平台",而是"受限的、用于展示特定能力的子 Agent"。
AgentTeams 解决的是什么问题?它解决的是"如何高效地把大任务并行分发给多个通用 agent"------这是一个应用层问题,属于"用 agent 来完成具体业务任务"的范畴。
而 MyCodeAgent 的定位是基础设施层------agent harness 的骨架,而不是基于 agent 构建的应用。
两个层次的错位,导致了一个根本性的张力:AgentTeams 越完善,项目的定位就越模糊。
这就是为什么在 HARNESS_ROADMAP 里,Coordinator、Teams、Ultraplan 被归入"只做原理研究"而不是"必须深入实现":
这些内容可以在面试中讨论设计和取舍,但不应消耗当前项目的主要开发时间。
三、维护成本:一个实验系统的隐形代价
实验性功能有一个特点:它不在主路线上,但它会持续消耗主路线的注意力。
AgentTeams 在主代码库里存在期间,带来了以下隐形成本:
1. 测试表面扩大
每次修改 runtime 的核心逻辑,都要检查是否破坏了 AgentTeams 的行为。即使 AgentTeams 默认关闭,它也在测试矩阵里占据一席之地。
2. 代码边界模糊
AgentTeams 需要访问 RuntimeRunner 的内部,这意味着 RuntimeRunner 的接口不能随意变动。实验性功能和核心功能之间的依赖,让两边的演化都受到约束。
3. 认知负担
任何新加入项目的人,都需要先搞清楚"这个 AgentTeams 是干什么的?我现在要改的这个地方会不会影响它?"------即使 99% 的情况下答案是"不会"。
FINAL_REPORT 里有一个数据可以说明这个问题的严重程度:在精简运行时之前,稳定生产代码是 19,320 行 ;移除 AgentTeams 等实验性功能之后,降到了 14,094 行 。减少了 27%。
将近三分之一的代码,是实验性功能带来的负担。
四、移除的方式:尊重而不是删除
AgentTeams 被移除,但没有被"删除"。
这里有一个值得注意的工程细节:代码不是被 git rm 掉的,而是通过一次有记录的 commit 移出,然后在 docs/research-archive.md 里保存了精确的 commit 引用:
csharp
# docs/research-archive.md
The removed Agent Teams research runtime is preserved only in Git history.
Its exact pre-removal commit is f497b172c9bce8279d9a26eb69273e25db7392cf.
Inspect it with:
git show f497b172c9bce8279d9a26eb69273e25db7392cf:experimental/teams/manager.py
这个做法传递了一个明确的信号:我们认为这个设计有价值,只是它不属于这里。
Git 历史是代码库的长期记忆。任何想研究这个设计的人,可以精确地还原到那一刻,看到完整的实现。而当前版本的代码库,保持干净。
这和"因为做坏了所以删掉"有本质区别。前者是设计决策,后者是失败处理。
五、AgentTeams 被移除后,多 agent 能力去哪里了?
这里有一个很自然的问题:AgentTeams 移除之后,MyCodeAgent 还有多 agent 能力吗?
有,但形式变了。
Phase 7 的最终方案是:不再维护第二套 ReAct Loop,而是用受限子 Agent 复用主 RuntimeRunner。
vbnet
原来的 AgentTeams 方案:
主 loop ← 独立维护
成员 agent ← 维护第二套 loop (实验性 TurnExecutor)
两套 loop,两套状态机,两套故障处理
Phase 7 最终方案:
RuntimeRunner ← 唯一的 loop 实现
Explore Agent ← RuntimeRunner 的受限实例(只读工具,独立上下文)
Verification Agent ← RuntimeRunner 的受限实例(独立上下文,结构化 verdict)
区别在于:子 agent 不再是独立的第二套系统,而是用"配置"来驱动同一套系统产生不同的行为。
yaml
子 agent 的"受限"体现在配置上:
- tool allowlist: [Read, Glob, Grep] # 只能读,不能写
- step_budget: 10 # 最多跑10步
- context source: 父 agent 传入的摘要 # 独立上下文
- completion policy: return_structured_verdict # 结构化结果
这个方案的好处:只需要测试和维护一套 loop,子 agent 的行为完全可以通过测试 RuntimeRunner 的配置来验证。
六、这个故事的普遍意义
AgentTeams 的生命周期是一个在软件工程中非常普遍的模式:
- 识别真实需求:单 agent 有局限,需要多 agent(真实的工程动机)
- 快速原型验证:做一个 MVP,看看行不行(实验性功能)
- 评估边界和成本:这个功能属于哪一层?维护成本是多少?(架构审视)
- 做出边界决策:继续深入 OR 移出边界、保留设计知识(有意识的取舍)
- 干净地结束:有记录地移除,不是静默删除(工程纪律)
每一步都是有意识的选择,而不是随机发生的事情。
对任何做过一段时间工程的人来说,这个模式都不陌生:有一些功能,做了是对的,因为不做你不知道它值不值得做;移除也是对的,因为留着它会拖累整个系统。
AgentTeams 就是这样一个功能。
设计亮点
1. 移除也是设计决策
"增加功能"和"移除功能"都需要经过设计审视。一个能有意识地说"这个东西不应该在这里"的工程团队,比一个只会堆功能的团队更成熟。
2. Git 历史是设计的档案馆
通过 commit 引用保存移除前的实现,比注释掉代码或者留下空文件更干净,也更可信。任何人都可以精确地还原到那一刻,没有"残留"。
3. 受限配置比第二套系统便宜
AgentTeams 用第二套 loop 来支持多 agent;Phase 7 的替代方案用配置来约束同一套 loop。后者的设计更精简,但覆盖了前者最有价值的能力:上下文隔离和能力裁剪。
4. 边界文档比边界代码更重要
HARNESS_ROADMAP 里的"只做原理研究"和"必须深入实现"分级,是写给未来维护者看的边界说明。这些文字的价值不亚于代码本身------它们说明了"为什么不做",而不只是"做了什么"。
小结
| 为什么被移除? | 详细原因 |
|---|---|
| 复杂度 | 多 agent 的复杂度以乘法增长,超出当前项目的承载能力 |
| 边界错位 | 解决的是应用层问题,项目定位是基础设施层 |
| 维护成本 | 实验性功能带来 27% 的额外代码量,持续消耗核心精力 |
| 替代方案存在 | 受限子 Agent 复用 RuntimeRunner,覆盖最有价值的能力 |
| 怎么被移除的? | 有记录地移出,Git 历史保存精确引用,文档说明设计价值 |
至此,Part 5 AgentTeams 全部完成。回顾这四篇:
- 16:设计动机------单 agent 局限,多 agent 需要解决上下文、并行、协调三个问题
- 17:消息协议------SendMessage + ACK 三态,保证分布式消息可靠传递
- 18:并行机制------TeamFanout 非阻塞分发,TeamCollect 容错汇总
- 19:移除决策------复杂度边界、定位错位、维护成本,以及"受限配置"这个更轻量的替代
四篇合在一起,讲的是同一件事:多 agent 系统不是"启动多个模型",而是一整套涉及消息、状态、故障和边界的工程问题。AgentTeams 是一次认真的尝试,它的生命周期完整地展示了这个问题的深度。
关于本系列的源码
本系列所有分析均基于开源项目 MyCodeAgent。
相关文档:
docs/research-archive.md:AgentTeams 的 Git 存档引用docs/archives/legacy-harness/HARNESS_ROADMAP.md:Phase 7 设计目标与取舍docs/plans/2026-07-12-lean-runtime/tasks/M2-03-remove-agent-teams.md:移除计划
bash
git clone https://github.com/chendongqi/MyCodeAgent
cd MyCodeAgent
cp .env.example .env
uv sync
uv run python main.py
欢迎访问 PrimeSkills ------ 一个精心策划的 AI Agent 与技能市场,所有内容均经过真实企业级工作流验证。没有噱头,只有真正有效的东西。
更多实用知识和有趣产品,欢迎访问我的个人主页