多智能体设计6种常见模式完整对比与选型指南
构建Agent系统时,最易混淆的并不是模型与工具的选择,而是“多智能体”这一概念在不同语境下代表的设计范式截然不同——它可能指向主控调度、角色切换、能力拆分、管道处理,甚至是自控执行图。
有时你需要一个中心调度器,有时需要动态切换对话角色,有时只是想把能力拆成独立的技能包。还有一些场景,本质上是一条数据处理管道,或者一张由业务逻辑驱动的执行图。
理清这些模式的差异,设计思路就会清晰许多。先从中使用的场景判断开始。
先判断何时真正需要多智能体
单智能体与多智能体的核心区别在于上下文管理。通常情况下,仅当遇到以下问题,才值得认真考虑多智能体架构:
- 一个Agent上绑定的工具过多,导致调度效率下降
- 某些任务明显需要独立的Prompt、独立的知识库以及独立的工具集
- 某些能力只应在特定阶段开放给用户
- 某些步骤需要并行执行,且不希望它们挤在同一个上下文窗口内
如果你的场景仅仅是功能数量多或工具丰富,先优化单智能体的结构(比如精简Prompt、重组工具链),往往比直接拆分成多智能体更省时省力。
一、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 加载对应的Prompt和工具集。
适用场景:多步骤对话流程,前一步的结果决定下一步路径,不同阶段需要不同角色直接与用户沟通。客服支持、售后分流、审批流程都属于此类。
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需要多种能力,能力之间没有严格的流程依赖,不同团队维护不同模块。它解决的问题是:主上下文不一次性塞入过多内容,能力可以按需装配,Prompt、规则、工具能够分开维护。
如果你要做的是“一个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:有时多智能体就是一条处理管道
有些场景根本不需要复杂的调度。如果问题天然是一条处理链,直接使用 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
把这几种模式分开理解之后,“多智能体”这个术语就不会再让人感到模糊。大多数时候,问题不在于“要不要用多智能体”,而在于:你是在拆分上下文、拆分流程、拆分能力,还是在拆分入口。先把这个问题想清楚,再选择模式,系统架构会稳健得多。
