在构建 Agent 系统时,最容易引发混淆的概念并非模型与工具,而是“多智能体”这个术语本身——在不同的应用场景下,它实际上对应着截然不同的设计模式。

有些场景需要主控调度,有些场景需要角色切换,还有一些场景仅需将能力拆分成独立的技能模块。另外,某些本质上是处理管道或自定义执行图的结构。
将这些模式逐一厘清,设计思路就会清晰许多。先从需求端切入分析。
先明确何时真正需要 multi-agent
单智能体与多智能体的核心差异在于上下文管理。通常,只有遇到以下问题时,才值得认真考虑向多智能体方向发展:
- 单个 agent 挂载的工具过多,导致调度困难
- 某些任务明显需要独立的提示词、独立的知识库以及独立的工具集
- 某些能力只应在特定阶段开放使用
- 某些步骤需要并行执行,不希望全部挤在一个上下文窗口内
如果只是功能增多、工具增多,先优化单智能体结构往往比直接拆分成多智能体更高效。
一、Supervisor:主智能体统一调度,子智能体充当工具
Supervisor 是最直观的多智能体模式。
结构简单:主智能体直接面向用户,子智能体不直接与用户交互,而是被包装成工具,由主智能体决定何时调用。代码骨架大致如下:
@Tool
String callSubagent(String agentName, String query) {
ReActAgent subagent = subagentRegistry.get(agentName);
return subagent.reply(query);
}
再向上封装一层,将子智能体注册到 Toolkit 中:
Toolkit toolkit = Toolkit.builder()
.subAgent("researcher", () -> buildResearchAgent())
.subAgent("coder", () -> buildCodingAgent())
.tool(this::callSubagent)
.build();
这种模式适用场景:请求天然跨越多个领域,需要统一控制工作流,某些步骤适合并行执行,且不希望每个子智能体分别与用户独立对话。
其中有一个关键约束:子智能体最好保持无状态。主智能体负责全局上下文,子智能体只执行局部任务,完成后返回结果。这样主控层只需管理调度,无需背负子智能体的长期状态。
实际落地时,难点通常集中在以下几个方面:是否应将额外上下文传递给子智能体?子智能体的返回值如何标准化?并行分支何时汇总?用户中途打断时,由哪一层负责停止?
二、Handoffs:并非调用工具,而是切换当前接待你的 Agent
Handoffs 与 Supervisor 本质不同。Supervisor 是主控调用他人,Handoffs 则是系统内部直接切换“当前由谁负责”。
这种模式通常会显式维护两个状态:current_step 和 active_agent。代码结构类似:
class SupportState {
String currentStep;
String activeAgent;
Boolean underWarranty;
}
工具的作用不仅执行动作,还会推进状态:
@Tool
String recordWarrantyStatus(boolean covered) {
state.underWarranty = covered;
state.currentStep = "specialist";
state.activeAgent = covered ? "support_agent" : "sales_agent";
return "状态已更新";
}
然后在 Hook 或调度层,根据 activeAgent 决定加载哪一套提示词和工具集。
适用场景:多步骤对话流程,前一步结果决定下一步路径,不同阶段需要不同角色直接与用户交流。客服支持、售后分流、审批流程等都属于此类。
Handoffs 的难点不在“切换角色”本身,而在状态管理:状态放在哪里?多个 agent 如何共享状态?传递完整消息历史还是摘要?中途回退一步时,current_step 如何恢复?如果系统本质上是流程型产品,Handoffs 往往比 Supervisor 更贴切。
三、Skills:将能力拆解为按需加载的技能包
Skills 更像是能力装配,而非多角色接力。
一个 skill 通常包含:描述、业务规则、schema、示例查询或示例用法。可以如此组织:
AgentSkill dataSkill = AgentSkill.builder()
.name("data_analyst")
.description("根据 schema 和业务规则回答数据问题")
.content("""
schema: orders, users, payments
rule: GMV excludes refunded orders
example: select ...
""")
.build();
然后将其与真实工具一起装入 SkillBox:
SkillBox skillBox = SkillBox.builder()
.skill(dataSkill)
.build();
Toolkit toolkit = Toolkit.builder()
.skillBox(skillBox)
.tool(queryDatabaseTool)
.build();
这种模式适用:单个 agent 需要多种能力,能力之间没有严格的流程依赖,不同团队维护不同模块。它解决的问题是:主上下文不必一次性塞入过多内容,能力可以按需装配,提示词、规则、工具可以分开维护。
如果目标是“一个 agent,多种技能”,Skills 往往比 Supervisor 和 Handoffs 更自然。
四、Routing:先分流,再决定交给谁
Routing 常常与 Supervisor 混为一谈,但重点完全不同。Supervisor 是在会话中动态决定调用谁,Routing 则是系统先进行分类,再将请求送到不同入口。
最简单的 router 就是一段条件判断:
String route(String query) {
if (isBilling(query)) return "billing_agent";
if (isSupport(query)) return "support_agent";
if (isSales(query)) return "sales_agent";
return "general_agent";
}
然后根据路由结果调用对应的 agent。
适用场景:不同请求具有明确的垂直领域,入口处就能完成大部分分类,某些请求需要并行发给多个领域再汇总。常见做法有两种:单智能体里做隐式路由,或者多智能体并行处理后再合并结果。
最常见的 router 是无状态的:一次请求做一次分类,路由结束就结束,下一次请求重新判断。如果 router 也需要记录状态,通常需要在外层再包裹一层 agent 或 workflow,复杂度立刻上升。因此 Routing 的关键问题不是“agent 有几个”,而是入口如何分流。
五、Pipeline:有些 multi-agent 就是一条处理管道
有些场景根本不需要复杂调度。如果问题天然是一条处理链,直接用 Pipeline 即可。
最常见的是两类:顺序管线和扇出管线。
new SequentialPipeline(agent1, agent2, agent3);
new FanoutPipeline(agentA, agentB, agentC);
前者是顺序处理:输入 → Agent1 → Agent2 → Agent3 → 输出。后者是扇出处理:一个输入同时发给多个 Agent,各自产生结果再汇总。
适用场景:检索 → 提取 → 归纳,生成 → 评审 → 改写,数据清洗 → 分析 → 汇总。这类模式的重点不在角色切换,也不在复杂状态,而在数据流本身。如果问题本来就是线性的,或者天然适合扇出再汇总,Pipeline 往往比 Handoffs 和 Supervisor 更直接。
六、Custom Workflow:前面几种都不够,就自己写执行图
如果前面几种模式都无法满足需求,最实际的做法就是自行编写 workflow。代码结构大致如下:
if (needRetrieval) { runRetriever(); }
if (needParallelAnalysis) { fanout(analyzerA, analyzerB, analyzerC); }
if (!verified(result)) { runReviewer(); }
也就是将顺序、条件、循环、并行、agent 调用全部纳入自己的执行图中。
这类模式通常出现在:业务逻辑本身就复杂,需要严格控制步骤,要混合 RAG、路由、推理、验证,前面几类模式只是其中某几个节点。此时,不如将 Supervisor、Handoffs、Pipeline、Routing 视为积木,按业务需求重新拼装。
最后如何选择
如果需要先有一个可落地的判断,直接参照以下方式:
- 需要一个主控统一调度专家 →
Supervisor - 会话在不同阶段切换角色 →
Handoffs - 给一个主智能体不断添加能力 →
Skills - 入口先分类分流 →
Routing - 一条线性或扇出处理链 →
Pipeline - 前面都装不下 →
Custom Workflow
将这几种模式区分清楚后,“多智能体”这个说法就不再含糊。很多时候,问题不在于“要不要 multi-agent”,而在于:你是在拆解上下文、拆解流程、拆解能力,还是在拆解入口。先把这个问题想明白,再选择模式,系统构建会更加稳健。
