一、前言:单个 Agent 越强,反而越菜?

兄弟们,先抛个扎心问题:

你是不是也遇到过这种情况——

  • Agent 工具塞了十几个,模型挑工具挑到“精神分裂”;
  • Prompt 越写越长,Token 烧得飞起,回答却越来越像“废话生成器”;
  • 同一个 Agent 又要写代码、又要写诗、还要算命,最后活成了“四不像”。

别急着换模型,大概率是 架构问题,不是模型问题。

Spring AI Alibaba 的多智能体(Multi-agent)框架,就是来治这种“全能 Agent 病”的。把一个超级 Agent 拆成多个专业 Agent,再用合适的协作模式串起来,效果往往立竿见影。

这篇文章,我会结合自己 demo 仓库里的 MultiAgent 模块,把 6 种主流多智能体协作模式掰开揉碎讲清楚:

序号 模式 一句话理解
1 顺序执行(Sequential) A 干完给 B,B 干完给 C,一条流水线
2 并行执行(Parallel) 三个小弟同时干活,老大最后汇总
3 路由(LlmRouting) 让 LLM 当“前台”,自动分诊到对应专家
4 监督者(Supervisor) 派一个“项目经理”,动态调度多个小弟
5 自定义条件(Customized Conditional) 不靠 LLM,靠规则关键词精准路由
6 混合模式(Compound) 监督者里套路由,复杂业务直接起飞

这坑我替你踩过了,下面直接上硬菜。


二、环境速览

先把家底亮一下,方便后面所有代码直接跑:

项目 内容
JDK 17
Spring Boot 3.x
Spring AI Alibaba 1.0.x
ChatModel DashScope(通义千问)/ Ollama 均可
关键依赖 spring-ai-alibaba-agent-framework

核心 Maven 依赖:

<dependency>
<groupId>com.alibaba.cloud.ai</groupId>
<artifactId>spring-ai-alibaba-agent-framework</artifactId>
<version>1.0.0</version>
</dependency>

别急着 Ctrl+C / Ctrl+V,先把场景看完。


三、什么是多智能体(Multi-agent)?

写正文之前,先把“多智能体”这个概念压实。
不然你后面看到 SequentialAgentLlmRoutingAgent 一定会一脸懵。

3.1 一句话理解

Multi-agent 就是把一个“什么都干”的大 Agent,拆成多个“专精一门”的小 Agent,再按业务场景拼成一个协作工作流。

简单说:从“一个人干所有事”变成“一个团队协作”

3.2 官方定义

Multi-agent 将复杂的应用程序分解为多个协同工作的专业化 Agent。与依赖单个 Agent 处理所有步骤不同,Multi-agent 架构允许你将更小、更专注的 Agent 组合成协调的工作流。

用人话翻译一下:

单 Agent 架构 Multi-agent 架构
一个 Agent 身兼数职 每个 Agent 只干一件事
工具塞一坨,模型挑花眼 各 Agent 工具互不干扰
Prompt 越写越长 每个 Agent 提示词短而精准
一个 Agent 挂了全挂 单点失败不影响全局

3.3 什么时候必须上 Multi-agent?

别为了“架构高级”强行上 Multi-agent,单 Agent 能解决的就别拆

以下三种情况出现,基本就是 Multi-agent 出场的信号

  • 单个 Agent 拥有太多工具,难以做出正确的工具选择决策
  • 工具超过 10 个,模型就开始“工具选择困难症”了;
  • 拆成多个 Agent,每个 Agent 只挂 2~3 个工具,模型瞬间清醒。
  • 上下文或记忆增长过大,单个 Agent 难以有效跟踪
  • 对话超过 20 轮,Token 烧得飞起;
  • 拆成多个 Agent,每个 Agent 只关心自己这一段上下文,省 Token 又高效。
  • 任务需要专业化(例如:规划器、研究员、数学专家)
  • 业务天然有分工(写代码的、写文档的、测试的);
  • 一个 Agent 没法同时是“全栈工程师 + 资深文案 + 顶级测试”,那就各司其职。

经验之谈:当你的单 Agent Prompt 超过 500 字还没把任务说清楚时,就该考虑拆了

3.4 两大协作模式:Tool Calling vs Handoffs

Spring AI Alibaba 的 Multi-agent 框架底层支持两种核心协作模式,搞懂这个,后面 6 种具体实现就是"排列组合"

模式 工作原理 控制流 使用场景
Tool Calling Supervisor Agent 将其他 Agent 作为工具调用。"工具"Agent 不直接与用户对话——只执行任务并返回结果 集中式:所有路由都通过调用 Agent 任务编排、结构化工作流
Handoffs 当前 Agent 决定将控制权转移给另一个 Agent。活动 Agent 随之变更,用户可以继续与新的 Agent 直接交互 去中心化:Agent 可以改变当前由谁来担当活跃 Agent 跨领域对话、专家接管
怎么选?
问题 Tool Calling Handoffs
需要集中控制工作流程? ✅ 是 ❌ 否
希望 Agent 直接与用户交互? ❌ 否 ✅ 是
专家之间复杂的、类人对话? ❌ 有限 ✅ 强

实战建议:可以混合使用两种模式——用 Handoffs 进行 Agent 切换,并让每个 Agent 将子 Agent 作为工具调用来执行专门任务。

本文的 Sequential / Parallel / LlmRouting / Supervisor / Customized / Compound,本质上都是这两种模式的具体实现。

3.5 本文的 6 种协作模式预告

下面要讲的 6 种模式,就是 Spring AI Alibaba 给我们提供的 “多人协作剧本”

模式 协作方式 一句话类比
Sequential 流水线 工厂的传送带
Parallel 一起干 小组会议同时发言
LlmRouting 智能分诊 公司前台
Supervisor 动态调度 项目经理派活
Customized Conditional 规则路由 按地区转客服
Compound 混合编排 大型项目多团队协作

记住这张表,后面看到名字就知道在干啥


四、模式一:顺序执行(Sequential Agent)

4.1 场景故事

让 AI 写一篇散文,然后让 AI 当评委修改润色。

这就是典型的 流水线:写 → 审 → 输出。

4.2 核心原理

顺序模式下,每个 Agent 按 subAgents 列表顺序执行,前一个 Agent 的 outputKey 输出,会作为状态写入 OverAllState,下一个 Agent 通过 instruction 占位符 {outputKey} 引用。

流程图

一图胜千言:Input → 第一个 subAgent → 第二个 subAgent → … → Output,一条道走到黑,谁也别想插队。

4.3 关键代码

参考文件:[SequentialAgentChat.java](file:///d:/project/learn/spring_ai_alibaba_demo/src/main/java/com/spring/ai/alibaba/agent/springaialibabaagent/MultiAgent/impl/SequentialAgentChat.java)

// 写作 Agent
ReactAgent writingAgent = ReactAgent.builder()
.name("writingAgent")
.model(reactAgentChatModel)
.description("你是一个专业的写作Agent")
.instruction("你是一个知名的作家,擅长创作高质量的文学作品。请根据用户的提问进行回答:{input}。")
.outputKey("article")  // 关键:输出键名
.build();
// 审核 Agent
ReactAgent reviewAgent = ReactAgent.builder()
.name("reviewAgent")
.model(reactAgentChatModel)
.description("你是一个专业的审核Agent")
.instruction("你是一个专业的写作审核Agent,擅长审核和修正文学作品。" +
"请对文章进行评审修正:\n{article}," +  // 占位符引用上一个 Agent 的输出
"最终返回评审修正后的文章内容;不要返回:'评审意见'等文字")
.outputKey("reviewedArticle")
.build();
// 顺序编排
SequentialAgent sequentialAgent = SequentialAgent.builder()
.name("sequentialAgent")
.description("根据用户给的内容写一个文章,然后审核文章,最后返回审核修正后的文章内容")
.subAgents(List.of(writingAgent, reviewAgent))
.build();
// 执行
Optional<OverAllState> result = sequentialAgent.invoke("帮我写一个100字左右的散文");
OverAllState state = result.get();
state.value("article").ifPresent(article ->
log.warn("写作Agent输出: {}", ((AssistantMessage) article).getText()));
state.value("reviewedArticle").ifPresent(reviewedArticle ->
log.warn("评审后文章: {}", ((AssistantMessage) reviewedArticle).getText()));

4.4 关键特性

顺序执行模式有 4 个核心特性,每个都值得背下来

  • 按顺序执行:Agent 按照 subAgents 列表中定义的顺序执行
  • 写在前面的先跑,写在后面的后跑,别想插队
  • 状态传递:每个 Agent 的输出通过 outputKey 存储在状态中,可被后续 Agent 访问
  • 这是顺序模式能"传话"的根本原因。
  • 消息历史:默认情况下,所有 Agent 共享消息历史
  • 简单说就是:后面的 Agent 能看到前面 Agent 的对话记录
  • 推理内容控制:使用 returnReasoningContents 控制是否在消息历史中包含中间推理
  • 想省 Token 就关掉,想看完整链路就打开,自己权衡

这 4 个特性决定了顺序模式的边界:能传话、能共享,但没法并行、没法动态跳转

4.5 占位符机制(核心中的核心)

Spring AI Alibaba 的 instruction 支持三种占位符:

占位符 说明 使用场景
{input} 用户输入的原始内容 第一个 Agent
{outputKey} 引用其他 Agent 的输出 顺序执行中引用前序输出
{stateKey} 引用状态中的任意键值 访问任意状态数据

看似简单,实则是多 Agent 数据传递的命脉。

4.6 自定义 Agent 上下文(高级玩法)

Multi-agent 设计的核心是上下文工程——决定每个 Agent 看到什么信息。Spring AI Alibaba 提供了细粒度的控制:

参数 作用 实战建议
instruction 在当前 Agent 节点处插入新的问题说明,支持占位符 每个 Agent 的 instruction 要短而精准
returnReasoningContent 控制子 Agent 的上下文是否返回父流程。设为 false,其他 Agent 看不到这个子 Agent 的推理过程,只能看到 outputKey 输出 想省 Token 就关掉 ,想看完整链路就打开
includeContents 控制当前子 Agent 执行时,是只基于自己的 instruction 工作,还是带上所有父流程的上下文 设为 false 可以让子 Agent 专注于自己的任务,不受父流程复杂上下文的影响
outputKey 指定输出内容的键名,可被后续 Agent 通过占位符引用 使用有意义的命名,如 articlereviewedArticle
systemPrompt / instruction LlmRoutingAgent 和 SupervisorAgent 支持定制,用于覆盖默认实现,控制路由决策行为 路由准确性全靠这俩 ,后面章节专门讲

核心原则:系统的质量在很大程度上取决于上下文工程。目标是确保每个 Agent 都能访问执行任务所需的正确数据,不多不少。

4.7 适用场景

  • 内容创作流水线(写 → 审 → 翻译)
  • 数据处理管道(清洗 → 校验 → 入库)
  • 多步骤业务编排(需求 → 设计 → 实现)

五、模式二:并行执行(Parallel Agent)

5.1 场景故事

“我是天蝎座,帮我分析一下我的星座、配对和星盘。”

一个用户问三个问题,为啥要排队回答?

并行模式:三个专家 Agent 同时上,结果最后汇总。

5.2 核心原理

所有子 Agent 同时接收同一份输入,各自执行完后再走 MergeStrategy 合并策略。

流程图

一张图看清 并行模式的本质一个 Input 扇出到 N 个 subAgent,每个 subAgent 独立产出自己的 Output_1/Output_2/Output_3,最后由 MergeStrategy 汇总。

三种默认合并策略
策略 行为
DefaultMergeStrategy 拼接成键值 Map
ConcatenationMergeStrategy 拼接成单一字符串
ListMergeStrategy 合并为 List

5.3 关键代码

参考文件:[ParallelAgentChat.java](file:///d:/project/learn/spring_ai_alibaba_demo/src/main/java/com/spring/ai/alibaba/agent/springaialibabaagent/MultiAgent/impl/ParallelAgentChat.java)

ReactAgent constellationAgent = ReactAgent.builder()
.name("constellationAgent")
.model(reactAgentChatModel)
.instruction("你是一个星座分析大师。用户给的内容是:{input},请根据用户的内容分析星座。")
.outputKey("constellation")
.build();
ReactAgent pairAgent = ReactAgent.builder()
.name("pairAgent")
.model(reactAgentChatModel)
.instruction("你是星座配对大师。用户给的内容是:{input},请根据用户的内容配对星座。")
.outputKey("pair")
.build();
ReactAgent starDiskAgent = ReactAgent.builder()
.name("starDiskAgent")
.model(reactAgentChatModel)
.instruction("你是星盘大师。用户给的内容是:{input},请根据用户的内容分析星盘。")
.outputKey("starDisk")
.build();
ParallelAgent parallelAgent = ParallelAgent.builder()
.name("parallelAgent")
.subAgents(List.of(constellationAgent, pairAgent, starDiskAgent))
.description("并行执行多个创作任务")
.mergeOutputKey("parallel")
.mergeStrategy(deduplicationSummaryMergeStrategy)  // 用自定义策略
.build();

5.4 进阶:自定义合并策略(重点!)

默认策略只能“傻拼”,但实际项目里,多个 Agent 输出经常有内容重复。怎么办?

自己写一个 MergeStrategy 接 LLM 做二次摘要去重。

参考文件:[DeduplicationSummaryMergeStrategy.java](file:///d:/project/learn/spring_ai_alibaba_demo/src/main/java/com/spring/ai/alibaba/agent/springaialibabaagent/MultiAgent/tool/DeduplicationSummaryMergeStrategy.java)

@Component
public class DeduplicationSummaryMergeStrategy implements ParallelAgent.MergeStrategy {
private final ChatModel reactAgentChatModel;
@Override
public Object merge(Map<String, Object> subAgentResults, OverAllState overallState) {
// 1. 聚合多 Agent 结果
String aggregated = aggregateSubAgentResults(subAgentResults);
// 2. 调一个总结 Agent 做二次去重
ReactAgent summaryAgent = ReactAgent.builder()
.name("deduplicationSummaryAgent")
.model(reactAgentChatModel)
.instruction("你是内容整合专家,擅长去重与摘要。输入:\n{input}\n" +
"请去除重复信息,整合输出一份结构清晰的综合报告。")
.outputKey("summaryReport")
.build();
try {
return summaryAgent.invoke(aggregated)
.map(state -> state.value("summaryReport").orElse(""))
.map(this::extractText)
.orElse("");
} catch (GraphRunnerException e) {
// 兜底:返回原始聚合
return aggregated;
}
}
// ... aggregateSubAgentResults / formatAgentOutput / extractText 略
}

这就是“看似能跑,其实已经埋雷”和“程序跑起来了,头发少了”的真实写照——不做二次去重,三个 Agent 输出的星座描述 80% 重复。

5.5 适用场景

  • 多视角分析(星座/八字/紫微同时算)
  • 多模态内容生成(标题/正文/标签并行产出)
  • A/B 内容对比

六、模式三:路由(LlmRoutingAgent)

6.1 场景故事

“我梦见自己在大雾里开车……”(解梦)
“帮我分析下我的星座……”(星座)
“我是 1990-01-01 出生,帮我算下生命数字……”(数字密码)

每种问题对应一个专家 Agent,让 LLM 充当“前台分诊台”,自动判断该派给谁。

6.2 核心原理

LlmRoutingAgent 接收用户输入,调用 LLM 分析子 Agent 的 description,选择一个最匹配的子 Agent 执行

流程图

一张图看清 路由模式的精髓In → LLM Call Router(一次 LLM 调用决策走哪条线)→ 只选一个 LLM Call N → Out
不是全选,是单选,虚线代表没被选中的路径。

注意:每次只选一个,不是全选。

6.3 关键代码

参考文件:[LlmRoutingAgentChat.java](file:///d:/project/learn/spring_ai_alibaba_demo/src/main/java/com/spring/ai/alibaba/agent/springaialibabaagent/MultiAgent/impl/LlmRoutingAgentChat.java)

ReactAgent constellationAgent = ReactAgent.builder()
.name("constellationAgent")
.model(reactAgentChatModel)
.description("你是一个专业的星座分析大师,擅长分析星座。")  // 重要:路由靠这个判断
.instruction("你是一个星座分析大师,擅长分析星座")
.outputKey("constellation")
.build();
ReactAgent birthAgent = ReactAgent.builder()
.name("birthAgent")
.model(reactAgentChatModel)
.description("你是一个专业的生命数字密码分析大师,擅长分析生命数字密码。")
.instruction("你是一个生命数字密码分析大师")
.outputKey("birth")
.build();
ReactAgent zhugongAgent = ReactAgent.builder()
.name("zhugongAgent")
.model(reactAgentChatModel)
.description("你是一个专业的周公解梦大师,擅长解梦。")
.instruction("你是一个周公解梦大师")
.outputKey("zhugong")
.build();
LlmRoutingAgent llmRoutingAgent = LlmRoutingAgent.builder()
.name("llmRoutingAgent")
.model(reactAgentChatModel)
.description("根据用户需求智能路由到合适的专家Agent")
.subAgents(List.of(constellationAgent, birthAgent, zhugongAgent))
.build();
Optional<OverAllState> result = llmRoutingAgent.invoke("我梦见自己在一片大雾里开车,怎么也找不到回家的路");

6.4 关键特性

路由模式有 4 个核心特性,每个都值得背下来

  • 智能路由:LLM 根据输入内容和子 Agent 的描述自动选择最合适的 Agent
  • 不用写 if-else,模型自己"看人下菜碟"。
  • 灵活扩展:可以轻松添加新的专家 Agent,LLM 会自动识别并路由
  • 加 Agent 不用改路由逻辑

    ,改 subAgents 列表就行。

  • 描述驱动:子 Agent 的 description 非常重要,它告诉 LLM 何时应该选择该 Agent
  • description 写不好,路由就废一半

    ,下一节专门讲怎么写。

  • 单次执行:每次请求只路由到一个 Agent 执行
  • 不是"广播"是"派单"

    ,别指望 LLM 同时调多个。

这 4 个特性决定了路由模式的边界:能智能分诊,但没有状态记忆、不能多步串联

6.5 路由准确性优化(避坑重点)

坑:为什么我的路由 Agent 经常选错?

罪魁祸首:description 写得太模糊!

反面教材:

description = "你是星座分析大师"  // ❌ 太短,LLM 看不出区别

正确写法:

description = "专门处理星座分析问题,擅长分析星座运势、性格、配对。" +
"适用于用户问'我的星座怎么样'、'天蝎座配什么'等场景。"  // ✅ 场景化

6.6 进阶:自定义 systemPrompt / instruction

除了靠 description 自动路由,LlmRoutingAgent 还支持通过 systemPromptinstruction手动控制路由决策,这是官方文档里的高级玩法:

systemPrompt:设置路由决策的系统提示

替换默认系统提示,提供详细的决策规则和上下文:

final String ROUTING_SYSTEM_PROMPT = """
你是一个智能的内容路由Agent,负责根据用户需求将任务路由到最合适的专家Agent。
## 可用的子Agent及其职责
### constellationAgent
- 功能: 擅长星座分析
- 适用场景: 用户问星座运势、性格、配对
### birthAgent
- 功能: 擅长生命数字密码分析
- 适用场景: 用户问生命数字、数字密码
### zhugongAgent
- 功能: 擅长周公解梦
- 适用场景: 用户说"梦见"、"解梦"
## 决策规则
只返回Agent名称,不要包含其他解释。
""";
LlmRoutingAgent routingAgent = LlmRoutingAgent.builder()
.name("content_routing_agent")
.model(chatModel)
.systemPrompt(ROUTING_SYSTEM_PROMPT)  // 关键:自定义系统提示
.subAgents(List.of(constellationAgent, birthAgent, zhugongAgent))
.build();
instruction:设置路由决策的用户指令

作为 UserMessage 添加到消息列表中,提供额外的上下文信息或特定的路由指导:

final String ROUTING_INSTRUCTION = """
请根据用户的需求,选择最合适的Agent来处理任务。
特别注意:
- 如果用户提到"星座"、"运势",选择 constellationAgent
- 如果用户提到"生命数字"、"数字密码",选择 birthAgent
- 如果用户提到"梦见"、"解梦",选择 zhugongAgent
""";
LlmRoutingAgent routingAgent = LlmRoutingAgent.builder()
.name("content_routing_agent")
.model(chatModel)
.instruction(ROUTING_INSTRUCTION)  // 关键:自定义路由指令
.subAgents(List.of(constellationAgent, birthAgent, zhugongAgent))
.build();

实战建议systemPrompt 定义路由决策的整体框架,instruction 提供具体的路由指导。两个可以同时用,效果叠加。

6.7 适用场景

  • 多领域客服(售前/售后/投诉自动分流)
  • 多技能助手(编程/写作/翻译一键切换)
  • 智能问诊(按症状自动派科室)

七、模式四:监督者(Supervisor Agent)

7.1 场景故事

“卜卦占星师,帮我分析一下今年我的运势,我的伴侣是什么星座?”

这问题至少需要两步:

  1. 运势分析
  2. 伴侣匹配

两次执行,先后顺序还不一定。路由模式搞不定(只能选一个),并行模式也不合适(步骤有依赖)。

这时候就要 监督者(Supervisor) 上场——一个“项目经理” Agent,动态决定先调谁、再调谁、最后调谁

7.2 核心流程

流程图

一张图看懂 监督者的"项目管理循环"
主 Agent(content_supervisor)→ check state(状态评估)→ 选一个子 Agent(reviewer_agent / translator_agent)→ 回到主 Agent → 再次 check state → … → stop(FINISH)
核心是"循环调度",不是"一次性派单"

流程详解

监督者模式下,整个调度过程是一个循环,由 mainAgent(监督者)反复决策驱动:

  1. 监督者 Agent 接收用户输入或前序 Agent 的输出
  • 第一轮接收用户原始需求,后续轮接收子 Agent 的执行结果。
  1. LLM 分析当前状态并决定最合适的子 Agent
  • 这步由 mainAgent 完成,它是个纯路由器,输出严格的 JSON 数组。
  1. 选中的子 Agent 处理任务
  • 每次只调一个子 Agent(一次调用原则)。
  1. 子 Agent 执行完成后返回监督者
  • 结果写入 OverAllState,作为下一轮决策的输入。
  1. 监督者根据结果决定下一步
  • 继续路由到另一个子 Agent

    (多步骤任务未完成)

  • 返回 FINISH 完成任务

    (所有需求已满足)

这个循环会一直跑下去,直到 mainAgent 输出 ["FINISH"] 才会退出。
千万别让 mainAgent 干业务,否则 JSON 解析必挂。

7.3 核心原理

SupervisorAgent 由两部分组成:

角色 作用
mainAgent 纯路由器 ,只输出 JSON 数组,告诉框架下一步调谁
subAgents 业务执行者 ,真正干活的 Agent

关键约束:mainAgent 绝对不能是业务执行型 Agent! 否则它的业务输出(Markdown 文章等)会破坏 JSON 解析。

7.4 提示词模板(核心资产)

参考文件:[PromptConstant.java](file:///d:/project/learn/spring_ai_alibaba_demo/src/main/java/com/spring/ai/alibaba/agent/springaialibabaagent/MultiAgent/tool/PromptConstant.java)

public static final String SUPERVISOR_PROMPT_TEMPLATE =
"你是一个严格的【任务路由器】,不执行业务,只负责决定下一步调用哪一个子 Agent。\n" +
"\n" +
"## 可用子 Agent(必须使用下方 name 字段,不要自创名称)\n" +
"\n" +
"{agent_list}\n" +
"\n" +
"## 路由原则(极其重要)\n" +
"1. 【一次调用原则】每次只调用 1 个最匹配的子 Agent。\n" +
"2. 【无擅自追加】子 Agent 完成后,检查用户原始需求是否已满足。若已满足,直接返回 [\"FINISH\"]。\n" +
"3. 【严格收敛】当且仅当用户需求全部满足时,返回 [\"FINISH\"];中间过程禁止 FINISH。\n" +
"\n" +
"## 输出格式(极其重要,必须严格遵守)\n" +
"1. 你的回复必须且只能是一个 JSON 数组。\n" +
"2. 调用单个 Agent:[\"agentName\"]\n" +
"3. 任务完成:[\"FINISH\"]\n" +
"4. 禁止输出任何 JSON 以外的内容。\n";

{agent_list} 会在运行时动态替换为子 Agent 列表,增删子 Agent 无需改模板——这才是企业级写法。

7.5 关键代码

参考文件:[SupervisorAgentChat.java](file:///d:/project/learn/spring_ai_alibaba_demo/src/main/java/com/spring/ai/alibaba/agent/springaialibabaagent/MultiAgent/impl/SupervisorAgentChat.java)

// 三个业务 Agent
ReactAgent constellationAgent = ReactAgent.builder()
.name("constellationAgent")
.model(reactAgentChatModel)
.description("你是一个专业的星座分析大师,擅长分析星座。")
.outputKey("constellation")
.build();
ReactAgent partnerMatchingAgent = ReactAgent.builder()
.name("partnerMatchingAgent")
.model(reactAgentChatModel)
.description("你是一个专业的伴侣匹配专家,擅长根据用户需求匹配伴侣。")
.outputKey("partnerMatching")
.build();
ReactAgent constellationContentEditorAgent = ReactAgent.builder()
.name("constellationContentEditorAgent")
.model(reactAgentChatModel)
.description("资深的卜卦占星师,擅长根据卜卦分析星座运势")
.outputKey("constellationContentEditor")
.build();
List<Agent> subAgents = List.of(constellationAgent, partnerMatchingAgent, constellationContentEditorAgent);
// 动态拼接子 Agent 列表到提示词
String agentListSection = subAgents.stream()
.map(agent -> "- " + agent.name() + ":" + agent.description())
.collect(Collectors.joining("\n"));
// mainAgent(纯路由器)
ReactAgent mainAgent = ReactAgent.builder()
.name("supervisorRouter")
.model(reactAgentChatModel)
.instruction(PromptConstant.SUPERVISOR_PROMPT_TEMPLATE
.replace("{agent_list}", agentListSection))
.build();
// 监督者
SupervisorAgent supervisorAgent = SupervisorAgent.builder()
.name("supervisorAgent")
.model(reactAgentChatModel)
.description("监督者代理服务")
.mainAgent(mainAgent)
.subAgents(subAgents)
.build();

7.6 关键特性

监督者模式有 4 个核心特性,和路由模式对比着记

  • 循环调度:不是一次性派单,而是"调完一个回来再决定下一个"
  • 路由模式是单次执行,监督者是多轮循环
  • 动态决策:mainAgent 根据当前状态(包括前序 Agent 的输出)决定下一步
  • 这就是"项目经理"和"前台"的区别——前台只管分诊,项目经理管全程
  • 严格 JSON 输出:mainAgent 必须输出 ["agentName"]["FINISH"]
  • 千万别让 mainAgent 干业务

    ,否则 JSON 解析必挂。

  • 状态累积:每轮调用的结果都写入 OverAllState,后续轮次可以访问
  • 第二轮 Agent 能看到第一轮 Agent 的输出,信息不丢

这 4 个特性决定了监督者模式的边界:能多步串联、能动态调度,但mainAgent 必须是纯路由器,不能干业务。

7.7 适用场景

  • 任务多步骤且依赖关系不固定
  • 需要根据中间结果动态调整下一步
  • 业务复杂到单 Agent 根本 hold 不住

八、模式五:自定义条件代理(Customized Conditional Agent)

8.1 为什么需要自定义?

业务方要求:“星座关键词走星座 Agent,生肖关键词走生肖 Agent,不准用 LLM 路由,关键词必须严格匹配。”

官方没现成的“关键词路由” Agent。怎么办?

自己造一个 ConditionalAgent

8.2 核心思路

继承 FlowAgent,手动用 StateGraph API 构建条件路由图:

START → 根透明节点 → 条件评估节点 → [AgentA | AgentB | ...] → END

8.3 关键代码

参考文件:[ConditionalAgent.java](file:///d:/project/learn/spring_ai_alibaba_demo/src/main/java/com/spring/ai/alibaba/agent/springaialibabaagent/MultiAgent/tool/ConditionalAgent.java)

public class ConditionalAgent extends FlowAgent {
private final Map<String, List<String>> conditionKeywords;
private final Map<String, Agent> conditionalAgents;
@Override
protected StateGraph buildSpecificGraph(FlowGraphBuilder.FlowGraphConfig config)
throws GraphStateException {
StateGraph graph = new StateGraph(config.getName(), config.getKeyStrategyFactory());
// 1. 根 Agent 透明节点
graph.addNode(name(), node_async(new TransparentNode()));
// 2. 条件评估节点
String conditionNodeName = name() + "_condition";
graph.addNode(conditionNodeName, node_async(state -> {
String input = Optional.ofNullable(state.value("input", ""))
.map(Object::toString).orElse("").toLowerCase();
String conditionResult = evaluateCondition(input);
return Map.of("_condition_result", conditionResult);
}));
// 3. 边:根 → 条件评估
graph.addEdge(name(), conditionNodeName);
// 4. 子 Agent 节点 + 条件边
Map<String, String> routingMap = new LinkedHashMap<>();
for (Map.Entry<String, Agent> entry : conditionalAgents.entrySet()) {
Agent subAgent = entry.getValue();
FlowGraphBuildingStrategy.addSubAgentNode(subAgent, graph);
routingMap.put(entry.getKey(), subAgent.name());
graph.addEdge(subAgent.name(), END);
}
routingMap.put("default", END);
graph.addConditionalEdges(conditionNodeName, new ConditionEvaluatorAction(), routingMap);
graph.addEdge(START, name());
return graph;
}
/**
* 最佳匹配策略:匹配数最多的关键词组胜出
*/
private String evaluateCondition(String input) {
return conditionKeywords.entrySet().stream()
.map(entry -> Map.entry(entry.getKey(),
entry.getValue().stream().filter(input::contains).count()))
.filter(entry -> entry.getValue() > 0)
.max(Map.Entry.comparingByValue())
.map(Map.Entry::getKey)
.orElse("default");
}
}

8.4 使用示例

参考文件:[CustomizedAgentChat.java](file:///d:/project/learn/spring_ai_alibaba_demo/src/main/java/com/spring/ai/alibaba/agent/springaialibabaagent/MultiAgent/impl/CustomizedAgentChat.java)

private static final List<String> CONSTELLATION_KEYWORDS = List.of(
"星座", "星盘", "占星", "卜卦", "天蝎", "白羊", "金牛", "双子", "巨蟹");
private static final List<String> ZODIAC_KEYWORDS = List.of(
"生肖", "属相", "本命年", "属鼠", "属牛", "属虎", "属龙", "属蛇");
ReactAgent constellationAgent = ReactAgent.builder()
.name("constellationAgent")
.model(reactAgentChatModel)
.instruction("你是一个星座分析大师。请根据用户的内容分析星座:{input}")
.outputKey("constellation")
.build();
ReactAgent zodiacAgent = ReactAgent.builder()
.name("zodiacAgent")
.model(reactAgentChatModel)
.instruction("你是一个生肖分析大师。请根据用户的内容分析生肖:{input}")
.outputKey("zodiac")
.build();
ConditionalAgent conditionalAgent = ConditionalAgent.builder()
.name("conditionalAgent")
.description("根据关键词条件路由到星座或生肖 Agent")
.conditionalAgent("constellation", constellationAgent, CONSTELLATION_KEYWORDS)
.conditionalAgent("zodiac", zodiacAgent, ZODIAC_KEYWORDS)
.subAgents(List.of(constellationAgent, zodiacAgent))
.build();
Optional<OverAllState> result = conditionalAgent.invoke("我是属蛇的,帮我分析一下我的生肖运势和属相");

8.5 避坑要点

千万别只用“第一个匹配的关键词”!
通用词如“运势”、“配对”会让精确条件被错覆盖。

正确做法:使用“最佳匹配”策略,匹配关键词数量最多的条件胜出。


九、模式六:混合模式(Compound Agent)

9.1 场景故事

“帮我查询一下长沙的天气,然后分析下适合干啥,再生成一份 HTML 报告和 MD 表格报告。”

这个需求包含:

  1. 顺序步骤

    :查天气 → 分析天气

  2. 路由选择

    :HTML 报告 vs MD 表格报告

  3. 多轮调度

    :项目经理来决定先后顺序

这就是混合模式:监督者(Supervisor)里嵌套路由(Routing)。

9.2 架构图

SupervisorAgent
├── mainAgent (路由器)
├── WeatherAgent        (查天气)
├── WeatherAnalyzerAgent (分析天气)
└── report_router (LlmRoutingAgent)
├── HTMLGeneratorAgent
└── MDTableGeneratorAgent

9.3 关键代码

参考文件:[CompoundAgentChat.java](file:///d:/project/learn/spring_ai_alibaba_demo/src/main/java/com/spring/ai/alibaba/agent/springaialibabaagent/MultiAgent/impl/CompoundAgentChat.java)

// 查天气
ReactAgent weatherAgent = ReactAgent.builder()
.name("WeatherAgent")
.model(reactAgentChatModel)
.outputKey("weather")
.instruction("这是一个查询天气的Agent,输入城市名称,返回天气信息")
.methodTools(compoundAgentTool)  // 挂载天气查询工具
.build();
// 分析天气
ReactAgent weatherAnalyzerAgent = ReactAgent.builder()
.name("WeatherAnalyzerAgent")
.model(reactAgentChatModel)
.outputKey("weatherAnalyzer")
.instruction("这是一个分析天气的Agent,输入天气信息,返回天气分析结果")
.build();
// 报告生成(HTML vs Markdown 路由)
LlmRoutingAgent reportAgent = LlmRoutingAgent.builder()
.name("report_router")
.description("根据需求选择报告格式")
.model(reactAgentChatModel)
.subAgents(List.of(htmlGeneratorAgent, mdTableGeneratorAgent))
.build();
// mainAgent:项目经理
ReactAgent mainAgent = ReactAgent.builder()
.name("MainDispatchAgent")
.model(reactAgentChatModel)
.outputKey("supervisor_next")
.instruction("你是主调度Agent,根据用户输入决定下一步执行哪个子Agent。" +
"可用子Agent:WeatherAgent(查询天气)、WeatherAnalyzerAgent(分析天气)、" +
"report_router(生成报告)。你必须且只能以JSON数组格式输出。")
.build();
// 监督者编排
SupervisorAgent supervisorAgent = SupervisorAgent.builder()
.name("supervisor")
.mainAgent(mainAgent)
.subAgents(List.of(weatherAgent, weatherAnalyzerAgent, reportAgent))
.build();
Optional<OverAllState> result = supervisorAgent.invoke("帮我查询一下长沙的天气");

9.4 工具集成小贴士

.methodTools(compoundAgentTool)  // 给 Agent 挂载 @Tool 标注的工具

工具类示例([CompoundAgentTool.java](file:///d:/project/learn/spring_ai_alibaba_demo/src/main/java/com/spring/ai/alibaba/agent/springaialibabaagent/MultiAgent/tool/CompoundAgentTool.java)):

@Tool(name = "weather", description = "查询指定城市未来 15 天的天气信息")
public String weather(String city) {
// ... 查天气逻辑
}

这是 Spring AI 原生 @Tool 注解,与 Agent 无缝集成。

9.5 适用场景

  • 复杂业务编排(多步骤 + 多分支)
  • 报告生成系统(查询 → 分析 → 多格式输出)
  • 工作流引擎核心

十、六大模式对比与选型

模式 并行性 依赖性 路由方式 适合场景
Sequential ❌ 串行 ✅ 强依赖 固定顺序 流水线
Parallel ✅ 并行 ❌ 无依赖 多视角分析
LlmRouting ❌ 单次 ❌ 无 LLM 智能选择 多专家分诊
Supervisor ❌ 串行 ✅ 动态依赖 LLM 路由器 复杂多步任务
Customized Conditional ❌ 单次 ❌ 无 关键词匹配 规则化路由
Compound ✅ 可并行 ✅ 强依赖 多层组合 复杂业务编排

选型口诀

流水线 → Sequential
一起干 → Parallel
智能派单 → LlmRouting
动态调度 → Supervisor
规则路由 → Customized
复杂业务 → Compound


十一、避坑指南(我踩过的坑)

1. mainAgent 不能是业务执行型

❌ 让 mainAgent 既负责路由又负责写文章 → JSON 解析必挂
✅ mainAgent 严格只输出 ["agentName"] 或 ["FINISH"]

2. 占位符名要和 outputKey 严格一致

❌ outputKey = "article",instruction 写 {Article} → 替换失败
✅ 完全小写匹配

3. 并行模式必须做二次去重

❌ 三个 Agent 直接拼接 → 70% 内容重复
✅ 自定义 MergeStrategy 调 LLM 摘要

4. description 写不清楚 = 路由必错

❌ "你是聊天助手"
✅ "专门处理用户闲聊、寒暄、打招呼,不处理具体业务问题"

5. 关键词路由不能用“首个匹配”

❌ 输入"我是属蛇的,帮我看星座" → 误匹配"蛇"
✅ 最佳匹配策略:哪个条件关键词命中最多选哪个

6. Agent name 必须全局唯一

❌ 两个 Agent 都叫 "agent" → 状态覆盖、路由错乱
✅ 命名规范:业务前缀_功能 (例:weather_query_agent)

学AI大模型的正确顺序,千万不要搞错了

🤔2026年AI风口已来!各行各业的AI渗透肉眼可见,超多公司要么转型做AI相关产品,要么高薪挖AI技术人才,机遇直接摆在眼前!

有往AI方向发展,或者本身有后端编程基础的朋友,直接冲AI大模型应用开发转岗超合适!

就算暂时不打算转岗,了解大模型、RAG、Prompt、Agent这些热门概念,能上手做简单项目,也绝对是求职加分王🔋

在这里插入图片描述

📝给大家整理了超全最新的AI大模型应用开发学习清单和资料,手把手帮你快速入门!👇👇

学习路线:

✅大模型基础认知—大模型核心原理、发展历程、主流模型(GPT、文心一言等)特点解析
✅核心技术模块—RAG检索增强生成、Prompt工程实战、Agent智能体开发逻辑
✅开发基础能力—Python进阶、API接口调用、大模型开发框架(LangChain等)实操
✅应用场景开发—智能问答系统、企业知识库、AIGC内容生成工具、行业定制化大模型应用
✅项目落地流程—需求拆解、技术选型、模型调优、测试上线、运维迭代
✅面试求职冲刺—岗位JD解析、简历AI项目包装、高频面试题汇总、模拟面经

以上6大模块,看似清晰好上手,实则每个部分都有扎实的核心内容需要吃透!

我把大模型的学习全流程已经整理📚好了!抓住AI时代风口,轻松解锁职业新可能,希望大家都能把握机遇,实现薪资/职业跃迁~

这份完整版的大模型 AI 学习资料已经上传CSDN,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费

在这里插入图片描述

Logo

这里是“一人公司”的成长家园。我们提供从产品曝光、技术变现到法律财税的全栈内容,并连接云服务、办公空间等稀缺资源,助你专注创造,无忧运营。

更多推荐