Spring AI Alibaba 发布于 2025 年 6 月,是国内 Java 领域首个企业级 AI Agent 框架。它内置了 Supervisor、ReAct Agent 等标准模式,支持通过声明式配置实现多 Agent 任务分解与状态同步。Graph是 Spring AI Alibaba 的核心组件,负责流程编排、状态流转、并行执行、条件路由等底层能力。在上一篇文章的工具调用基础上,多 Agent 协作可以看作工具调用的“升级版”——把工具换成了 Agent。
3.2 项目搭建
<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.3.10</version></parent><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>com.alibaba.spring</groupId><artifactId>spring-ai-alibaba-starter</artifactId><version>1.1.2.0</version></dependency><!-- Jackson 序列化 --><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId></dependency></dependencies>
<dependencies> <dependency> &: dashscope: api-key: sk-xxx # 替换为你的阿里云 DashScope key
build(); } }
几点注意:
用 @Bean 分别注册三个 Worker Agent,各自有独立的 instruction 和 outputKey 三个 Agent 定义在不同配置类中或用不同 Bean 名称区分 outputKey 是占位符引用机制的关键——每个 Agent 的输出会存入 OverAllState 的对应键中
3.4 实现 Supervisor Agent 并配置 Workflow 在 Spring AI Alibaba 中,Graph 是多 Agent 协作的核心引擎。
用 Spring AI Alibaba 打造你的智能体“天团”
一、为什么一个 Agent 不够用了
在之前的文章中,我们聊过大模型工具调用——让模型自己判断该调用哪个 API,比如查天气、查订单。这在很多场景下已经够用了,比如用户问“北京今天天气怎么样”,调一个天气 API 就解决了。
但现实中的业务问题,往往没有这么简单。
拿一个电商客服的场景来说,用户问:“帮我查一下订单 10086 的物流状态,然后如果已经超过预计送达时间,给我发一封催件邮件。”
如果只用一个 Agent 来处理,它需要同时具备三种能力:查订单、判断是否超时、调用邮件服务。听起来好像也不难?但问题在于,大模型的上下文是有容量限制的,当工具数量增加到十几个甚至几十个时,单个 Agent 在众多工具中做出正确选择就变得非常困难。
更麻烦的是,如果用户连续问了三个彼此独立的事情:“查订单 10086 的物流、查北京明天天气、帮我查一下 2025 年 Java 岗位平均薪资”。普通对话里,这三个问题没有任何关联,但如果你只用一个 Agent,它的上下文里会塞满这三次调用的历史记录,Token 消耗翻倍、模型更容易“幻觉”。
这就是为什么我们需要多 Agent 协作。
把一个复杂的系统拆成多个更小、更专注的 Agent,每个 Agent 负责自己擅长的那一摊活,然后由“总指挥”来协调它们的工作。一个 Agent 做不好所有事,但多个 Agent 可以。
二、三种主流的协作模式
在 2026 年的企业级 AI 实践中,有三种常见的多 Agent 协作模式被广泛使用:Supervisor/Worker(监督者-工人模式)、Peer-to-Peer(对等模式)和 Hierarchical(层级模式)。选择哪种模式取决于任务复杂度和容错要求,而不是看哪个框架支持得好。
Supervisor/Worker(监督者-工人模式)
这是最常用、也最容易理解的一种模式。一个中心化的 Supervisor Agent 接收用户的复杂任务,把它拆解成多个子任务,分发给不同的 Worker Agent 执行,最后汇总它们的结果。
什么时候用:任务的各个环节之间有明确的依赖关系,需要统一的调度和监控。
Peer-to-Peer(对等模式)
在这种模式下,Agent 之间可以直接通信,不需要一个中心节点来协调。每个 Agent 都可以主动发起对话或请求。A2A(Agent-to-Agent)协议正是为此设计的。
什么时候用:Agent 之间需要持续协作、能力互补,比如一个写代码的 Agent 和另一个做代码审查的 Agent。
Hierarchical(层级模式)
这是 Supervisor/Worker 的扩展版,可以在多个层级上嵌套。父 Agent 可以向下级 Agent 委派任务,逐级细化。
什么时候用:任务本身就有清晰的多层结构,比如“公司战略规划→部门执行→个人任务”这种天然的上下级关系。
在 Spring AI Alibaba 中,Supervisor 模式具体对应“Agent Tool”模式——Supervisor Agent 将其他 Agent 作为工具来调用,实现集中式任务编排。
三、用 Java 实现 Supervisor-Worker 多 Agent 协作
下面用一个“旅游规划助手”的完整例子,演示 Supervisor-Worker 模式的实现。用户输入“我想五一去杭州玩 3 天,预算 5000 元”,Supervisor Agent 拆解任务,三个 Worker Agent 并行执行并聚合结果。
3.1 为什么选 Spring AI Alibaba
Spring AI Alibaba 发布于 2025 年 6 月,是国内 Java 领域首个企业级 AI Agent 框架。它内置了 Supervisor、ReAct Agent 等标准模式,支持通过声明式配置实现多 Agent 任务分解与状态同步。Graph是 Spring AI Alibaba 的核心组件,负责流程编排、状态流转、并行执行、条件路由等底层能力。在上一篇文章的工具调用基础上,多 Agent 协作可以看作工具调用的“升级版”——把工具换成了 Agent。
3.2 项目搭建
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>3.3.10</version> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>com.alibaba.spring</groupId> <artifactId>spring-ai-alibaba-starter</artifactId> <version>1.1.2.0</version> </dependency> <!-- Jackson 序列化 --> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> </dependency> </dependencies># application.yml spring: ai: dashscope: api-key: sk-xxx # 替换为你的阿里云 DashScope key3.3 定义子 Agent(Worker Agents)
// 住宿规划 Agent @Configuration public class AccommodationAgent { @Bean(name = "accommodationAgent") public ReactAgent accommodationAgent(@Qualifier("dashscopeChatModel") ChatModel chatModel) { return ReactAgent.builder() .name("accommodation_agent") .model(chatModel) .description("住宿规划专家,负责根据目的地、预算和天数推荐酒店或民宿") .instruction(""" 你是一个专业的住宿规划专家。 任务:根据用户提供的目的地、预算和旅游天数,推荐合适的住宿方案。 输入格式示例:{input} 输出要求: 1. 推荐的酒店/民宿名称和区域位置 2. 预估每晚价格及总预算占比 3. 推荐理由(如交通便利性、周边景点) 4. 实际预订建议 请以结构化的中文文本返回结果。 """) .outputKey("accommodation") .build(); } }// 行程规划 Agent @Configuration public class ItineraryAgent { @Bean(name = "itineraryAgent") public ReactAgent itineraryAgent(@Qualifier("dashscopeChatModel") ChatModel chatModel) { return ReactAgent.builder() .name("itinerary_agent") .model(chatModel) .description("行程规划专家,负责设计每日的景点游览路线和活动安排") .instruction(""" 你是一个专业的旅游行程规划专家。 任务:根据用户提供的目的地、预算和旅游天数,设计合理的每日行程。 输入格式示例:{input} 输出要求: 1. 按天划分的行程安排,每天包含 3-4 个主要景点 2. 每个景点的建议游览时长 3. 景点之间的交通建议和大致耗时 4. 每日餐饮建议(推荐特色餐厅) 5. 每日预算明细(门票、交通、餐饮) 请以结构化的中文文本返回结果。 """) .outputKey("itinerary") .build(); } }// 预算规划 Agent @Configuration public class BudgetAgent { @Bean(name = "budgetAgent") public ReactAgent budgetAgent(@Qualifier("dashscopeChatModel") ChatModel chatModel) { return ReactAgent.builder() .name("budget_agent") .model(chatModel) .description("预算规划专家,负责根据总预算进行分项预算分配和费用预估") .instruction(""" 你是一个专业的旅游预算规划专家。 任务:根据用户提供的总预算和旅游天数,制定详细的费用分配方案。 输入格式示例:{input} 输出要求: 1. 预算拆分:交通(往返)、住宿、餐饮、门票、购物及其他 2. 各项预估费用和占比 3. 预算控制建议(如省钱技巧、替代方案) 4. 应急备用金建议 请以结构化的中文文本返回结果。 """) .outputKey("budget") .build(); } }几点注意:
@Bean分别注册三个 Worker Agent,各自有独立的instruction和outputKeyoutputKey是占位符引用机制的关键——每个 Agent 的输出会存入 OverAllState 的对应键中3.4 实现 Supervisor Agent 并配置 Workflow
在 Spring AI Alibaba 中,Graph 是多 Agent 协作的核心引擎。我们需要定义一个工作流,让 Supervisor Agent 按顺序或并行调用 Worker Agent。
@Configuration public class SupervisorWorkflowConfig { @Autowired @Qualifier("accommodationAgent") private ReactAgent accommodationAgent; @Autowired @Qualifier("itineraryAgent") private ReactAgent itineraryAgent; @Autowired @Qualifier("budgetAgent") private ReactAgent budgetAgent; @Bean public StateGraph travelPlannerGraph() { // StateGraph 是 Spring AI Alibaba 的工作流编排引擎 // 用于定义 Agent 之间的执行顺序和数据流转 StateGraph graph = new StateGraph() // 添加住宿规划节点 .addAgentNode("accommodation_planner", accommodationAgent, agentNodeSpec -> agentNodeSpec .instruction("请为以下行程规划住宿方案:{user_input}")) // 添加行程规划节点 .addAgentNode("itinerary_planner", itineraryAgent, agentNodeSpec -> agentNodeSpec .instruction("请为以下行程规划每日安排:{user_input}")) // 添加预算规划节点 .addAgentNode("budget_planner", budgetAgent, agentNodeSpec -> agentNodeSpec .instruction("请为以下行程规划预算分配:{user_input}")) // 添加汇总节点(普通节点,非 Agent) .addNode("aggregator", this::aggregateResults) // 定义执行顺序:三个子 Agent 并行执行 .addEdge("accommodation_planner", "aggregator") .addEdge("itinerary_planner", "aggregator") .addEdge("budget_planner", "aggregator") // 设置入口和出口 .setEntryPoint("accommodation_planner") .setEntryPoint("itinerary_planner") .setEntryPoint("budget_planner") .setFinishPoint("aggregator"); return graph; } // 汇总节点逻辑 private Map<String, Object> aggregateResults(Map<String, Object> state) { Map<String, Object> result = new HashMap<>(); result.put("accommodation", state.get("accommodation")); result.put("itinerary", state.get("itinerary")); result.put("budget", state.get("budget")); result.put("status", "completed"); // 打印完整的规划结果 log.info("住宿方案: {}", state.get("accommodation")); log.info("行程规划: {}", state.get("itinerary")); log.info("预算分析: {}", state.get("budget")); return result; } }@Service public class TravelPlannerService { @Autowired private StateGraph travelPlannerGraph; public String planTrip(String userInput) { // 初始化状态,将用户输入存入 state Map<String, Object> initialState = new HashMap<>(); initialState.put("user_input", userInput); // 执行工作流 Map<String, Object> finalState = travelPlannerGraph.execute(initialState); // 汇总结果 return buildFinalPlan(finalState); } private String buildFinalPlan(Map<String, Object> state) { return String.format(""" 【旅游规划综合方案】 === 住宿建议 === %s === 行程安排 === %s === 预算分析 === %s 以上方案综合了住宿、行程和预算三个维度的专业建议, 请根据个人偏好灵活调整。 """, state.get("accommodation"), state.get("itinerary"), state.get("budget") ); } }3.5 Controller 接入
@RestController @RequestMapping("/api/travel") public class TravelController { @Autowired private TravelPlannerService travelPlannerService; @PostMapping("/plan") public String planTrip(@RequestBody TravelRequest request) { return travelPlannerService.planTrip(request.getMessage()); } }3.6 核心机制:占位符与状态传递
在上述代码中,你可能注意到了
{user_input}这个写法。这正是 Spring AI Alibaba 多 Agent 协作的关键机制——占位符引用。占位符的工作原理:系统在执行 Agent 的 instruction 时,会自动将
{xxx}占位符替换为状态(OverAllState)中对应的实际值。这实现了 Agent 之间的数据传递,无需手写胶水代码。{input}{outputKey}outputKey存储的输出{stateKey}这意味着你可以这样串联 Agent:
// 第一个 Agent:文章写作 ReactAgent writerAgent = ReactAgent.builder() .name("writer_agent") .instruction("请根据用户的提问进行回答:{input}") .outputKey("article") .build(); // 第二个 Agent:文章润色,引用第一个 Agent 的输出 ReactAgent reviewerAgent = ReactAgent.builder() .name("reviewer_agent") .instruction("请对文章进行评审修正:\n{article}") .outputKey("reviewed_article") .build();四、进阶:从本地协作到分布式多智能体
在实际生产中,所有 Agent 都部署在同一 JVM 里往往会暴露问题:
为了将各 Agent 拆解成独立进程、独立部署,业界引入了 A2A(Agent-to-Agent)协议。该协议由 Google 开发并捐赠给 Linux 基金会,是一种开放标准,定义了智能体发现、能力描述和任务交互的标准化流程。
Spring AI Alibaba 对 A2A 协议有完善的实现,三个核心组件分别是:
五、工程落地注意事项
Agent 粒度是核心设计决策。Agent 不是越细越好。如果粒度过细,Agent 数量会爆炸式增长,编排层逻辑变得极其复杂,通信开销也成倍增加。反之,粒度过粗相当于退回了单 Agent 的老路。通常建议按业务领域切割,比如“订单处理 Agent”“物流查询 Agent”“售后 Agent”,而不是把“查订单状态”和“改订单地址”拆成两个 Agent。
状态传递是关键。多 Agent 协作的本质是状态在多个 Agent 之间的流转。有了状态,后续 Agent 才能访问前面 Agent 的输出。Spring AI Alibaba 用 OverAllState 统一存储状态,Agent 通过
outputKey写入,其他 Agent 通过{outputKey}占位符读取,整个流程非常顺滑。容错兜底不可少。Agent 调用是有可能失败的,可能是模型超时、网络抖动,也可能解析失败。建议在 Workflow 中加入超时控制和降级策略,比如某个子 Agent 执行失败时,Supervisor 兜底答复“暂无法获取该项建议”。
成本控制。三个 Agent 并行调用,Token 消耗是正常对话的 3 倍左右。在实际部署时,请根据业务量合理配置限流措施。
六、总结
多 Agent 协作是 AI 应用从“玩具”走向“工程化”的必经之路。
本文要点回顾:
你的业务里有哪些场景适合用多 Agent 来解决?欢迎在评论区交流。