第5课:多 Agent 系统

⭐⭐⭐⭐ 高频↔ Hermes 源码

← 上一章:第4课下一章 → 第6课

一、为什么需要多个 Agent?

单个 Agent 有明确的局限:

多 Agent 系统的核心思路:把复杂任务拆成子任务,分配给专门的子 Agent,每个子 Agent 专注一件事。

二、两大模式:编排器 vs 蜂群

┌─── 模式 A:编排器(Orchestrator) ───────────┐ │ │ │ ┌──────────────────┐ │ │ │ Orchestrator │ │ │ │ (主管Agent) │ │ │ └────────┬─────────┘ │ │ ┌───────────┼───────────┐ │ │ ▼ ▼ ▼ │ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │ │ Worker │ │ Worker │ │ Worker │ │ │ │ Agent A │ │ Agent B │ │ Agent C │ │ │ │ (代码) │ │ (搜索) │ │ (测试) │ │ │ └─────────┘ └─────────┘ └─────────┘ │ │ │ │ 特点:集中控制、任务分发、结果汇总 │ │ 代表:Hermes delegate_task │ └──────────────────────────────────────────────┘ ┌─── 模式 B:蜂群(Swarm) ─────────────────┐ │ │ │ Agent A ─── Agent B │ │ │ │ │ │ │ │ │ │ Agent C ─── Agent D │ │ │ │ 特点:去中心化、Agent 相互发现、自由协作 │ │ 代表:CrewAI、AutoGen、A2A 协议 │ └──────────────────────────────────────────────┘

三、模式 A:编排器(Orchestrator)

3.1 核心流程

用户:"帮我研究一下 Agent 框架的对比,然后写成文章" 编排器 Agent 的思考: Step 1: 我需要拆成 3 个子任务 ├── 研究任务:搜索 LangChain, CrewAI, AutoGen 的优缺点 ├── 整理任务:把搜索结果整理成结构化对比表 └── 写作任务:基于对比表写成文章 Step 2: 并行派发前两个任务 delegate_task(goal="搜索 LangChain 优缺点", ...) delegate_task(goal="搜索 CrewAI 优缺点", ...) Step 3: 等结果回来,综合分析 "根据两个子任务的结果,LangChain 生态好但臃肿, CrewAI 简洁但生态小..." Step 4: 派发写作任务 delegate_task(goal="基于对比分析写文章", ...) Step 5: 输出最终结果给用户

3.2 Hermes 的 delegate_task 实现

你在使用 Hermes 时调用的 delegate_task 工具,就是编排器模式的标准实现。它的架构:

// Hermes delegate_task 架构 delegate_task( goal="子任务目标", context="背景信息", // 父 Agent 提供上下文 toolsets=["web","terminal"], // 限制子 Agent 可用的工具 role="leaf" // leaf=不能进一步委托 ) -> 返回子任务结果 // 子 Agent 的生命周期(从 agent_init.py 源码) class AIAgent: def __init__(self, ...): self.max_iterations = 90 // 父 Agent 预算 self.iteration_budget = IterationBudget( max_total=max_iterations ) // 子 Agent 的预算独立(来自 delegation.max_iterations=50) // 父子 Agent 的 iteration budget 互相独立 // 这意味着父 Agent 可以花 50 轮委托,子 Agent 再花 50 轮 // 代理合计可以超过父 Agent 的 90 轮上限 // —— async_delegation.py(386行) // 后台委托:子 Agent 在独立线程运行 // 完成后通过 completion_queue 通知父 Agent // 结果包含完整的 task-source block: // original goal + context + toolsets + model + // dispatch_time + status + full result summary
和 Hermes 的对照:
你刚才调用了 3 次 delegate_task 来并行调研 EDA 公司招聘——
这就是编排器模式!

每次 delegate_task 都产生了 1 个子 Agent:
- 子 Agent 1:调研国际三巨头(花了很多步尝试各种方法)
- 子 Agent 2:调研 A 股上市 EDA 公司
- 子 Agent 3:调研独角兽 EDA 公司

3 个子 Agent 并行运行,总共花了 ~500 秒但实际等效串行要 1500+ 秒。
然后我(编排器)汇总了所有结果。

3.3 编排器模式的设计考量

面试重点:设计编排器时需要考虑什么?

考量点说明
委托粒度任务拆太大 → 子Agent又要委托(嵌套);拆太小 → 通信开销 > 收益
上下文传递父 Agent 给子 Agent 传 context,子 Agent 返回 summary。传多了浪费 token,传少了子 Agent 不知道背景
并发控制同时跑多少个子 Agent?Hermes 默认 3(delegation.max_concurrent_children)
嵌套深度子 Agent 能不能再委托?Hermes 支持 max_spawn_depth 控制
超时与预算子 Agent 跑太久怎么办?独立 iteration budget + timeout
结果验证子 Agent 可能产生幻觉。父 Agent 应验证再采用(我在 EDA 调研中检查了子 Agent 输出)
错误隔离一个子 Agent 失败不影响其他。父 Agent 可以决定重试或跳过

四、模式 B:蜂群(Swarm)

4.1 什么场景适合蜂群?

4.2 编排器 vs 蜂群:选型决策

选型决策树: 任务需要并行处理子任务吗? ├── 是 → 子任务依赖关系明确吗? │ ├── 是 → 编排器(主管分配任务) │ └── 否 → 蜂群(自由协作) │ ├── 否 → 需要一个"主管"角色吗? │ ├── 是 → 编排器 │ └── 否 → 单 Agent 就够了 │ 需要跨组织协作吗? ├── 是 → A2A 协议 + 蜂群模式 └── 否 → 内部单系统,编排器就够了

4.3 蜂群的工程挑战

五、A2A 协议与多 Agent 系统

第 3 课我们讲过 A2A(Agent-to-Agent Protocol)。和多 Agent 系统的关系:

六、综合案例:多 Agent 系统的设计

┌── 企业级智能客服系统 ──────────────────────┐ │ │ │ 用户问题 │ │ │ │ │ ▼ │ │ ┌──────────────┐ │ │ │ Router Agent │ ← 分析用户意图 │ │ │ (分类器) │ │ │ └──────┬───────┘ │ │ │ │ │ ┌───┼───┬───────┬───────┐ │ │ ▼ ▼ ▼ ▼ │ │ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ │ │ │ 售前│ │ 售后│ │ 技术│ │ 投诉│ │ │ │Agent│ │Agent│ │Agent│ │Agent│ │ │ └─────┘ └─────┘ └─────┘ └─────┘ │ │ │ │ │ │ │ │ └───────┴───┬───┴───────┘ │ │ ▼ │ │ ┌──────────┐ │ │ │ Escalation│ ← 复杂问题升级 │ │ │ Manager │ │ │ └──────────┘ │ │ │ └──────────────────────────────────────────────┘ Router Agent: 分析用户意图 → 路由到正确的子 Agent 子 Agent: 各自有专门的 tools/knowledge/context Escalation Manager: 超出能力范围时升级到人工

七、面试问答

🎯 Q1:"设计一个多 Agent 系统,你会选择编排器还是蜂群?为什么?"

回答框架:
1. 先分析任务特征:子任务依赖关系是否明确?是否需要集中控制?
2. 选编排器如果:任务可拆分成独立子任务,需要主管角色汇总结果,需要精确控制执行顺序
3. 选蜂群如果:任务需要自由探索和迭代,没有固定流程,多个 Agent 需要互相协作才能完成
4. 实际折衷:多数生产系统用编排器 + 有限的子 Agent 自主权(混合模式)

补充:我实际使用 Hermes 的 delegate_task 时,发现编排器更适合我——因为任务拆分明细、结果需要集中汇总。蜂群模式更适合开放式研究场景。
🎯 Q2:"子 Agent 跑超时了或者失败了怎么办?"

5 层容错:
1. 独立超时:每个子 Agent 有独立的 iteration budget + 时间上限
2. 错误隔离:一个子 Agent 失败不影响其他子 Agent 和父 Agent
3. 选择性重试:父 Agent 根据失败原因决定是否重试(网络错误重试,逻辑错误不重试)
4. 降级输出:子 Agent 挂了 → 父 Agent 用自己的能力补位(虽然慢但能出结果)
5. 部分结果:如果 5 个子任务 4 个成功,先输出 4 个的结果并标注"第 5 个失败"
🎯 Q3:"多 Agent 系统的 token 成本怎么控制?"

框架:
1. Token 预算分层:父 Agent 和子 Agent 各有独立预算(Hermes 父 90 轮,子 50 轮)
2. 上下文隔离:子 Agent 的上下文互不相通,各自独立 → 不会 N 倍膨胀
3. 精简 context 传递:父 Agent 给子 Agent 传 context 时要精炼,不要整个对话历史
4. 子 Agent 结果摘要:子 Agent 返回完整结果,但父 Agent 可以要求"只给我摘要"
5. 避免循环调用:设定最大嵌套深度(Hermes 默认 1 层,即子 Agent 不能进一步委托)

八、课后行动

  1. ✅ 区分编排器和蜂群两种模式,理解各自的适用场景
  2. ✅ 回忆今天的 EDA 调研 —— 3 个并行子任务就是编排器模式
  3. ✅ 准备 Q1(多 Agent 选型)和 Q3(Token 成本控制)的面试回答
  4. ⏭ 下节课:Go 框架架构设计——完整的框架接口定义

📁 0005-multi-agent.html
📁 源码参考:/usr/local/lib/hermes-agent/tools/async_delegation.py (386行)
📁 源码参考:/usr/local/lib/hermes-agent/agent/agent_init.py (delegate_task 派发)
📁 相关概念:第3课 A2A 协议 | 你在本 session 中的 3 次 delegate_task 调用
📝 有问题随时问。

← 上一章:第4课下一章 → 第6课