Day 13 / 共 20 天 · 第 3 周 ADK 智能体开发
多智能体协作
一个 Agent 搞不定复杂任务时,让多个专精 Agent 协作。今天讲 Eino 的两种协作方式,以及官方为什么推荐 Agent-as-Tool 而不推荐 Transfer。
📍 你在整门课的位置 · 第 3 周 Agent 套件(共 4 周 · 20 天)
D11 ADK 抽象→
D12 ChatModelAgent→
D13 多智能体→
D14 中断恢复→
D15 ReAct 精读
L01
为什么要多智能体
把一个"全能 Agent"拆成多个"专精 Agent",各管一摊,好处:提示词更聚焦、工具集更小(模型不会在 50 个工具里选晕)、可独立测试和复用。
🤔 痛点:一个 Agent 塞满 50 个工具、提示词写成万言书,会怎样?
模型在几十个工具里频繁选错、提示词太长导致遵循度下降、一处改动牵连全部功能、也没法单独测某块能力。任务越复杂,"单 Agent 全能王"越不可靠。答案是拆分:多个专精 Agent 各管一摊。
💡 本质:官方推荐"子 Agent 当工具调"(Agent-as-Tool),父 Agent 始终握着控制权
Eino 让子 Agent 通过
adk.NewAgentTool(adk/agent_tool.go:93)包成一个普通 Tool,父 Agent 像调工具一样"调用—返回"它。与之相对的 transfer/handoff(把控制权整个交出去)在源码里被大量标注 NOT RECOMMENDED(adk/flow.go:72、adk/deterministic_transfer.go:40 等多处)。一句话:优先"调用返回",慎用"移交控制"。类比:就像生活中的一家公司
多智能体就像生活中的一家公司:让一个人既当客服、又当程序员、又当会计,他啥都会一点但都不精,还容易忙中出错。拆成"客服 Agent + 编程 Agent + 财务 Agent",各自提示词专业、工具精简,由一个"主管 Agent"根据问题分派。一句话复述:分工 = 每人只干一摊,整体反而更能干、更可靠。
L02
两种协作方式
Eino 提供两种让 Agent 之间协作的机制:
✅ Agent-as-Tool(推荐)
- 把子 Agent 包装成一个工具
- 主 Agent 像调普通工具一样"调"子 Agent
- 子 Agent 干完把结果返回给主 Agent,控制权回到主 Agent
⚠️ Transfer 转交(不推荐)
- 当前 Agent 通过 Action 把控制权整个转交给另一个 Agent
- 转交后不再回来,由新 Agent 接管
- 类似"踢皮球"式的接力
对应代码:Agent-as-Tool 用
adk.NewAgentTool(把 Agent 包成 Tool,adk/agent_tool.go:93);Transfer 用 AgentAction 里的 TransferToAgent(adk/flow.go 相关,多处标 NOT RECOMMENDED)。官方文档明确标注 Transfer 为 NOT RECOMMENDED——L05 讲原因。两种拓扑对比:左边是"星形调用—返回"(父始终是中心),右边是"链式单向移交"(控制权一路漂走)。Eino 推荐左边。
L03
Agent-as-Tool(推荐)
把子 Agent 包成工具,加进主 Agent 的工具集(adk/ 相关):
// 子 Agent(专精财务)
financeAgent, _ := adk.NewChatModelAgent(ctx, &financeConfig)
// 包装成工具
financeTool := adk.NewAgentTool(ctx, financeAgent)
// 主 Agent 把它当普通工具用
mainAgent, _ := adk.NewChatModelAgent(ctx, &ChatModelAgentConfig{
Tools: []tool.BaseTool{financeTool, weatherTool, ...}, // 子Agent 和普通工具混在一起
})
读法:子 Agent 被
NewAgentTool 变成一个 Tool,和普通工具平起平坐加进主 Agent。主 Agent 的模型在需要时"调用"这个工具(其实是运行子 Agent),拿到结果继续自己的推理。子 Agent 有自己独立的对话上下文和工具集。直觉:就像生活中的"项目经理外包"
Agent-as-Tool 就像生活中的项目经理把一块活外包出去:经理遇到财务问题,"打电话咨询财务专家"(调工具),专家给出意见后,经理继续主导整个项目,还亲自验收结果。控制权始终在经理手里——清晰、可控。而 transfer 则像"直接把客户整个转给别人",转出去经理就不管了。
📝 举例:客服主管接到"我要退款并开发票"
主 Agent(客服主管)先调
退款 Agent 这个工具拿到退款单号,再调 发票 Agent 工具拿到发票号,最后自己综合成一句"已退款(单号 R123),发票已开(票号 F456)"回给用户。两个子 Agent 各跑各的、互不知情,主管负责串起来——这就是 Agent-as-Tool 的"分包 + 验收 + 汇总"。⚠️ 小白常误以为:"把 Agent 包成工具"是什么高级新机制。其实:它就是 Day 12 那个普通 Tool 接口——子 Agent 被
NewAgentTool 塞进一个实现了 tool.BaseTool 的壳里,主 Agent 的模型根本分不清它调的是"查天气"还是"另一个 Agent"。没有新魔法,全是复用。L04
Transfer(不推荐)
Transfer 是子 Agent 通过发出 AgentAction{TransferToAgent: "另一个Agent"} 把控制权彻底交出去:
// 概念:Agent 运行中产出一个转交动作
event.Action = &AgentAction{TransferToAgent: &TransferToAgentAction{
DestAgentName: "specialistAgent",
}}
// Runner 收到后,切换到 specialistAgent 接管,原 Agent 退场
读法:转交后控制权归了新 Agent,原 Agent 不再参与。像接力赛交棒——棒交出去就不回来了。多个 Agent 之间可能一路 transfer 下去。
🧯 没有"调用—返回"、只用 transfer,会出什么事故?
设想报销场景:用户问"我这笔差旅能报吗",主 Agent transfer 给财务 Agent,财务又 transfer 给合规 Agent,合规发现缺发票又 transfer 回财务……链路绕了 5 手,最后用户收到的答复到底代表谁、上下文丢没丢,谁也说不清;想在中间加一步"经理审批"更是无处下手。这正是官方把 transfer 标 NOT RECOMMENDED 的现实代价——控制权一旦漂走就难收回。Agent-as-Tool 则天然没这问题:每次调用都会返回到主 Agent。
L05
为什么推荐 Agent-as-Tool 而非 Transfer
- 控制流清晰:as-Tool 是"调用-返回",控制权总回到主 Agent,行为可预测。Transfer 是"单向移交",链路一长就难追踪"现在到底是谁在负责"。
- 上下文可控:as-Tool 时主 Agent 决定给子 Agent 看什么、拿回什么。Transfer 时上下文怎么传递更含糊。
- 可组合:工具能任意嵌套组合,主 Agent 能"综合多个子 Agent 的结果"再决策;Transfer 更像状态机跳转,难综合。
- 可测试:子 Agent 作为工具能单独测;Transfer 的整链行为更难隔离测试。
💬 小白连环问
👶 小白:既然 transfer 也能让别的 Agent 干活,为啥不直接用它、更省事?
👨🏫 老师:省的是"当下这一步",赔的是"整条链的可控性"。transfer 交棒后你就失去了对结果的把关点。
👶 小白:那我用 Agent-as-Tool,子 Agent 会不会看到主 Agent 的全部对话历史?
👨🏫 老师:不会。子 Agent 有独立上下文,主 Agent 决定"喂它什么、拿回什么"——这正是它可控的原因。
👶 小白:那 transfer 是不是就完全没用?
👨🏫 老师:不是"没用",是"默认别用"。少数需要彻底移交所有权的场景才考虑,且要接受它难追踪的代价。
👨🏫 老师:省的是"当下这一步",赔的是"整条链的可控性"。transfer 交棒后你就失去了对结果的把关点。
👶 小白:那我用 Agent-as-Tool,子 Agent 会不会看到主 Agent 的全部对话历史?
👨🏫 老师:不会。子 Agent 有独立上下文,主 Agent 决定"喂它什么、拿回什么"——这正是它可控的原因。
👶 小白:那 transfer 是不是就完全没用?
👨🏫 老师:不是"没用",是"默认别用"。少数需要彻底移交所有权的场景才考虑,且要接受它难追踪的代价。
一句话:Agent-as-Tool 用"函数调用"的心智模型(调了会返回),符合程序员直觉、可控可组合;Transfer 用"控制权移交"心智模型,容易失控。所以 Eino 官方推荐前者。这也呼应 Day 01 的设计哲学——可控、可组合优先。
L06
Supervisor 模式
基于 Agent-as-Tool 最常见的结构就是 Supervisor(主管)模式——一个主管 Agent 统筹,多个专精子 Agent 作为它的工具:
Supervisor 主管 Agent(负责理解需求、分派、综合)
↓ 按需"调用"(Agent-as-Tool)↓
🔎 检索 Agent💰 财务 Agent💻 编程 Agent✍️ 写作 Agent
怎么搭
每个子 Agent 用
NewChatModelAgent 建好(各自的 Instruction 和工具),再全部 NewAgentTool 包成工具,塞进 Supervisor 的工具集。Supervisor 的 Instruction 写"你是主管,根据用户需求选择合适的下属工具来完成任务"。用 Day 12 学的单 Agent 机制拼出多 Agent 系统——没有新魔法。L07
子 Agent 的事件冒泡
子 Agent 运行时也会产出自己的 AgentEvent。这些事件会带着 AgentName(是哪个子 Agent 发的)冒泡到最外层的迭代器,所以你能在 UI 上显示"财务 Agent 正在查账……"这种嵌套进度。
因为每个 AgentEvent 都带
AgentName(Day 11),前端就能区分"这条是主管说的还是某个子 Agent 说的",画出层级化的执行过程。事件流的设计让多 Agent 的可观测性天然成立——你能看到整个团队每个成员在干嘛。L08
今日小结 + 动手
🧠 今天你应该能回答
- 为什么要多智能体?(分工、聚焦、可复用可测)
- 两种协作方式?各自的控制流特点?
- 为什么官方推荐 Agent-as-Tool 而不推荐 Transfer?
- Supervisor 模式怎么搭?
- 子 Agent 的事件怎么冒泡到外层?
✋ 动手
grep -rn 'NewAgentTool\|AgentTool' adk/ | head
grep -rn 'TransferToAgent\|Transfer' adk/ | head
grep -rn 'Supervisor\|supervisor' adk/ | head
明天预告 · Day 14:Agent 跑到一半需要人工审批怎么办?中断与恢复(Interrupt/Resume)——Agent 暂停、把现场存下来、等人类批准后从断点继续。看它怎么和图执行结合。