多智能体实战 | Spring AI Alibaba 监督者交接策略实现旅游行程规划智能体

1. 引言
在多智能体系统中,如何让多个专家 Agent 协同工作是一个核心问题。SpringAI Alibaba 框架提供了多种交接策略(Handoff Strategy),让主节点来决定选择后续需要执启用的子Agent,虽然在官方最新的版本中,移除了 SupervisorAgent 的支持,转而使用 Agent As Tool的方式来实现监督者策略
本教程将基于 /ali/L08-multi-agent-supervisor 项目,介绍一下如何在一个真实的应用场景中你,利用监督者策略,来实现一个旅游行程规划智能体,并简单对比一下SupervisorAgent 和 AgentAsTool两种实现策略的异同
重要提示:在 SpringAI Alibaba 的最新框架中,监督者策略已经被移除,改为将 Agent 作为工具(Agent-as-Tool)的方式来实现类似效果。 若只希望关注最新的应用案例的小伙伴,也可以不需了解SupervisorAgent,直接看下一篇的Agent As Tool即可
- 背景知识
2.1 多智能体交接策略概述
SpringAI Alibaba 框架支持多种多智能体协作模式:

| 模式 | 特点 | 适用场景 |
|---|---|---|
| 路由模式(Router) | 单次决策,将请求路由到最合适的 Agent | 简单的分类和路由任务 |
| 监督者模式(Supervisor) | 多步循环,监督者协调多个专家 Agent | 复杂的多步骤协作任务 |
| 状态驱动交接(State-driven) | 基于状态和条件的 Agent 切换 | 需要精确控制流程的任务,如典型的LangGraph应用案例 |
2.2 监督者策略的核心思想
监督者策略的核心是中心化的任务协调:

-
监督者(Supervisor)
:负责接收用户请求、分解任务、协调专家、整合结果
-
专家 Agent(Specialist)
:专注于特定领域的任务执行
-
循环调度
:监督者可以多次调用不同的专家,直到任务完成
用户请求 → 监督者 → 专家A → 监督者 → 专家B → 监督者 → 整合结果 → 用户
2.3 与其他模式的对比
| 特性 | 路由模式 | 监督者模式 |
|---|---|---|
| 决策次数 | 单次 | 多次 |
| 子 Agent 返回 | 直接结束 | 返回监督者 |
| 占位符支持 | ❌ | ✅ ({input}) |
| 状态聚合 | ❌ | ✅ |
| 复杂度 | 低 | 高 |
- 项目结构
3.1 整体架构
L08-multi-agent-supervisor/├── src/main/java/com/git/hui/springai/ali/│ ├── controller/│ │ ├── TravelPlanController.java # REST 控制器(SSE 流式接口)│ │ └── HookFactory.java # Hook 工厂(日志和监控)│ ├── planer/│ │ ├── TravelSupervisorPlanAgent.java # 监督者 Agent(核心)│ │ ├── AttractionAgent.java # 景点推荐专家│ │ ├── HotelAgent.java # 住宿推荐专家│ │ └── TransportAgent.java # 交通规划专家│ └── L08Application.java # Spring Boot 启动类├── src/main/resources/│ ├── templates/│ │ └── travel-plan.html # 前端界面│ └── application.yml # 配置文件└── pom.xml # Maven 依赖
3.2 依赖配置
<!-- 不能使用 1.1.2.2+ 版本,因为 SupervisorAgent 被删除了 --><dependency> <groupId>com.alibaba.cloud.ai</groupId> <artifactId>spring-ai-alibaba-agent-framework</artifactId> <version>1.1.2.1</version></dependency><!-- SpringAI Alibaba 核心依赖 --><dependency> <groupId>org.springframework.ai</groupId> <artifactId>spring-ai-starter-model-openai</artifactId></dependency><!-- Spring Boot Web --><dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency></dependencies>
3.3 API 配置
spring: ai: openai: api-key: ${silicon-api-key} base-url: https://api.siliconflow.cn chat: options: model: Qwen/Qwen3-8B
- 核心代码解析
4.1 监督者 Agent 实现

TravelSupervisorPlanAgent.java 是整个系统的核心,负责协调各个专家 Agent:
@ComponentpublicclassTravelSupervisorPlanAgent { privatefinal AttractionAgent attractionAgent; privatefinal HotelAgent hotelAgent; privatefinal TransportAgent transportAgent; privatefinal ChatModel chatModel; public Agent agent() { AgentHooklogHook= HookFactory.createLogAgentHook(); SupervisorAgentsupervisorAgent= SupervisorAgent.builder() .name("supervisor_agent") .description("内容管理监督者,负责协调景点推荐、城市规划、住宿推荐等") .model(chatModel) .mainAgent(ReactAgent.builder() .name("main_agent") .model(chatModel) .description("监督者主Agent,负责路由决策") .systemPrompt(""" 你是一个旅行规划监督者,你的任务是帮助用户制定旅行计划。 你可以协调以下专家: - attraction_agent:负责推荐景点、安排游览路线。 - transport_agent:负责规划城市间交通和市内交通。 - hotel_agent:负责推荐酒店、民宿等住宿。 ## 路由决策输出格式 当需要做出路由决策时,请以 JSON 数组格式输出: - 选择单个子Agent: ["attraction_agent"] - 选择多个子Agent: ["transport_agent", "hotel_agent"] - 任务完成: [] 或 ["FINISH"] """) .instruction("用户的请求是: {input}") .outputKey("final_output") .build()) .subAgents(List.of( attractionAgent.agent(), hotelAgent.agent(), transportAgent.agent() )) .hooks(List.of(logHook)) .build(); return supervisorAgent; }}
关键点解析:
-
mainAgent:监督者的主 Agent,负责路由决策
-
subAgents:专家 Agent 列表
-
hooks:用于日志记录和监控
-
{input}占位符:在执行时会被替换为实际的用户输入
-
JSON 路由格式
:监督者通过输出 JSON 数组来决定下一步调用哪个专家(或者哪几个专家)
4.2 专家 Agent 实现
本文的案例主要是为了演示监督者的交接方式,各子Agent的实现相对简陋,大家完全可以丰富子Agent的能力,将其与外部的工具进行联动,比如查询小红书的旅游推荐、地图的导航、美团/携程的酒店预定等能力
@RequiredArgsConstructor@ComponentpublicclassAttractionAgent { privatefinal ChatModel chatModel; public ReactAgent agent() { ReactAgentagent= ReactAgent.builder() .name("attraction_agent") .model(chatModel) .description("景点推荐专家,善于根据用户的需求推荐各种适合游玩的景点") .instruction(""" 你是一个旅行景点推荐专家。请根据用户的目的地、天数、偏好, 推荐合适的景点和游览顺序。 当前已知信息:{input} 如果某些信息不完整,请基于已有信息尽量给出合理建议。 直接返回景点计划,包含每日安排。 """) .outputKey("attraction_plan") .enableLogging(true) .build(); return agent; }}@RequiredArgsConstructor@ComponentpublicclassHotelAgent { privatefinal ChatModel chatModel; public ReactAgent agent() { ReactAgentagent= ReactAgent.builder() .name("hotel_agent") .model(chatModel) .description("住宿推荐专家,善于根据用户需求推荐适合的住宿") .instruction(""" 你是一个住宿推荐专家。请根据用户的景点计划、预算,推荐合适的住宿地点和酒店。 输入:{input} 请返回住宿建议,包括区域和酒店示例。 """ ) .outputKey("hotel_plan") .enableLogging(true) .build(); return agent; }}@RequiredArgsConstructor@ComponentpublicclassTransportAgent { privatefinal ChatModel chatModel; public ReactAgent agent() { ReactAgentagent= ReactAgent.builder() .name("transport_agent") .model(chatModel) .description("交通规划专家,善于根据用户需求规划最佳的出行方式") .instruction(""" 你是一个交通规划专家。请根据用户的出发地、目的地、景点安排,规划交通方式。 输入:{input} 请返回详细的交通方案,包括城际交通和市内交通建议。 """ ) .enableLogging(true) .outputKey("transport_plan") .build(); return agent; }}
关键点:
-
name:Agent 的唯一标识符,用于路由决策
-
description:简短描述,帮助监督者理解 Agent 的职责
-
instruction:详细的指令模板,包含
{input}占位符 -
outputKey:输出结果的键名,用于状态聚合
4.3 Agent 依赖关系
在旅游行程规划中,Agent 之间存在依赖关系:

用户请求 ↓监督者 (Supervisor) ↓景点推荐 (AttractionAgent) ← 必须首先执行 ↓ ├── 住宿推荐 (HotelAgent) ← 依赖景点信息 └── 交通规划 (TransportAgent) ← 依赖景点信息 ↓监督者整合 → 最终方案
监督者通过系统提示中的指令来确保执行顺序:
.systemPrompt(""" 请记得在制定计划时,始终先调用 attraction_agent 来推荐景点、安排旅游路线; 因为 transport_agent 和 hotel_agent 这两个子 Agent 的执行都依赖 attraction_agent 的输出 """)
4.4 Hook 机制
HookFactory 提供了 Agent 执行过程的监控能力:
public static AgentHook createLogAgentHook() { returnnewAgentHook() { @Override public CompletableFuture<Map<String, Object>> beforeAgent( OverAllState state, RunnableConfig config) { System.out.println("BEFORE AGENT: " + getAgentName()); // 记录输入和状态 return CompletableFuture.completedFuture(Map.of()); } @Override public CompletableFuture<Map<String, Object>> afterAgent( OverAllState state, RunnableConfig config) { System.out.println("AFTER AGENT: " + getAgentName()); // 记录输出和结果 return CompletableFuture.completedFuture(Map.of()); } };}
- 实战:旅游行程规划智能体
5.1 系统工作流程

-
接收用户请求
:用户通过 API 提交旅行需求
-
监督者分解任务
:将复杂任务分解为景点、住宿、交通等子任务
-
协调专家执行
:按顺序调用各个专家 Agent
-
结果整合
:汇总所有专家的建议,形成完整的旅行计划
5.2 流式 API 实现
TravelPlanController.java 实现了基于 SSE 的流式接口:
@GetMapping(value = "/plan", produces = MediaType.TEXT_EVENT_STREAM_VALUE)public Flux<ServerSentEvent<String>> planTravelStream( @RequestParam String destination, @RequestParam(required = false, defaultValue = "3") Integer days, @RequestParam(required = false) String budget, @RequestParam(required = false) String preferences) { AgentsupervisorAgent= travelSupervisorPlanAgent.agent(); // 构建用户请求 Stringprompt= String.format("我想去%s旅行%d天,预算%s,我喜欢%s。请帮我制定详细的旅行计划。", destination, days, budget, preferences); // 获取流式输出 Flux<NodeOutput> agentStream = supervisorAgent.stream(prompt, config); return agentStream .filter(nodeOutput -> !(nodeOutput instanceof StreamingOutput<?> so && so.getOutputType() == OutputType.AGENT_MODEL_FINISHED)) .map(nodeOutput -> { // 构建 SSE 事件 Map<String, Object> data = newHashMap<>(); data.put("node", nodeOutput.node()); data.put("agent", nodeOutput.agent()); data.put("content", extractContent(nodeOutput)); data.put("stage", determineStage(nodeOutput.agent())); return ServerSentEvent.<String>builder() .event("message") .data(objectMapper.writeValueAsString(data)) .build(); });}
5.3 阶段标识
系统通过 Agent 名称来确定当前执行阶段:
private String determineStage(String agentName) { if (agentName.contains("attraction")) { return"attraction"; // 景点推荐 } elseif (agentName.contains("hotel")) { return"hotel"; // 住宿推荐 } elseif (agentName.contains("transport")) { return"transport"; // 交通规划 } elseif (agentName.contains("supervisor")) { return"supervisor"; // 监督者统筹 } return"unknown";}
5.4 API 使用示例
# 请求curl -X GET "http://localhost:8080/api/travel/plan?destination=北京&days=5&budget=5000元&preferences=美食,历史文化"# 响应(SSE 流式)event: messagedata: {"node":"attraction_agent","agent":"attraction_agent","content":"推荐景点:故宫、天坛...","stage":"attraction"}event: messagedata: {"node":"hotel_agent","agent":"hotel_agent","content":"推荐住宿:王府井附近...","stage":"hotel"}event: messagedata: {"node":"supervisor_agent","agent":"supervisor_agent","content":"完整方案:...","stage":"supervisor"}
- 流式输出与前端展示
6.1 前端架构
前端采用四面板布局,实时展示各个专家的工作进度:
<div class="content-section"> <!-- 景点推荐面板 --> <divclass="stage-panel"id="attractionPanel"> <divclass="stage-header"> <divclass="stage-icon">🏛️</div> <divclass="stage-title">景点推荐</div> </div> <divclass="stage-content"id="attractionContent"> <divclass="placeholder-text">等待开始规划...</div> </div> </div> <!-- 其他面板... --></div>
6.2 SSE 连接处理
function startPlanning() { const url = `/api/travel/plan?destination=${encodeURIComponent(destination)}&days=${days}`; eventSource = newEventSource(url); eventSource.addEventListener('message', function(event) { const data = JSON.parse(event.data); if (data.stage && data.hasContent) { updateStageContent(data.stage, data.content); activatePanel(data.stage); updateAgentBadge(data.stage); } }); eventSource.addEventListener('done', () => { completePlanning(); });}
6.3 Markdown 渲染
前端使用 marked.js 渲染 Markdown 内容:
function updateStageContent(stage, content) { contentAccumulators[stage] += content; const contentElement = document.getElementById(stage + 'Content'); if (contentElement) { const htmlContent = marked.parse(contentAccumulators[stage]); contentElement.innerHTML = htmlContent; contentElement.scrollTop = contentElement.scrollHeight; }}
6.4 Agent体验
接下来我们来实际体验一下这个agent的表现情况,直接浏览器访问

- 框架迁移:从监督者到 Agent-as-Tool
7.1 监督者模式的局限性
监督者模式虽然强大,但也存在一些问题:
-
复杂度高
:需要维护复杂的路由逻辑和
SUPERVISOR_NEXT_KEY状态管理 -
调试困难
:多步骤的执行流程难以追踪
-
灵活性不足
:Hub-and-spoke 模式限制了 Agent 之间的直接交互
7.2 Agent-as-Tool 模式
在最新版本的 SpringAI Alibaba 中,推荐使用 Agent-as-Tool 模式(也称为 Agent Tool 模式):
import com.alibaba.cloud.ai.graph.agent.ReactAgent;import com.alibaba.cloud.ai.graph.agent.AgentTool;// 创建专家 AgentReactAgentattractionAgent= ReactAgent.builder() .name("attraction_agent") .model(chatModel) .description("景点推荐专家") .instruction("你是一个旅行景点推荐专家...") .build();ReactAgenthotelAgent= ReactAgent.builder() .name("hotel_agent") .model(chatModel) .description("住宿推荐专家") .instruction("你是一个住宿推荐专家...") .build();// 创建主 Agent,将专家 Agent 作为工具ReactAgentsupervisorAgent= ReactAgent.builder() .name("supervisor_agent") .model(chatModel) .instruction("你是一个旅行规划助手,使用工具来完成任务。") .tools( AgentTool.getFunctionToolCallback(attractionAgent), AgentTool.getFunctionToolCallback(hotelAgent) ) .build();// 使用Optional<OverAllState> result = supervisorAgent.invoke("帮我规划北京5日游");
7.3 模式对比
| 特性 | Agent-as-Tool 模式 | |
|---|---|---|
| 实现方式 | SupervisorAgent.builder() |
ReactAgent.builder().tools() |
| 路由机制 | 显式 JSON 路由 | LLM 自动工具选择 |
| 执行模式 | Hub-and-spoke 循环 | 标准工具调用 |
| 子 Agent 返回 | 返回监督者继续循环 | 执行后返回结果 |
| 状态管理 | SUPERVISOR_NEXT_KEY |
标准工具调用状态 |
| 复杂度 | 高 | 低 |
| 可维护性 | 中 | 高 |
7.4 多智能体模式选择指南
根据官方文档,选择合适的多智能体模式:
| 需求场景 | 推荐模式 |
|---|---|
| 集中式工作流控制 | AgentTool (工具调用) |
| Agent 直接与用户交互 | Handoffs (交接) |
| 一次性路由决策 | LlmRoutingAgent (路由) |
| 多步骤迭代路由 | AgentTool (循环工具调用) |
7.5 迁移示例
旧代码(SupervisorAgent - 已弃用):
SupervisorAgent supervisor = SupervisorAgent.builder() .name("supervisor") .model(chatModel) .mainAgent(ReactAgent.builder() .name("main_agent") .systemPrompt("路由任务到 Agent...") .build()) .subAgents(List.of(writerAgent, translatorAgent)) .build();
新代码(Agent-as-Tool - 推荐):
ReactAgent supervisor = ReactAgent.builder() .name("supervisor") .model(chatModel) .instruction("使用工具来完成任务。") .tools( AgentTool.getFunctionToolCallback(writerAgent), AgentTool.getFunctionToolCallback(translatorAgent) ) .build();
7.6 注释代码示例
在 TravelSupervisorPlanAgent.java 中,我们可以看到被注释掉的旧实现:
// 旧的实现方式(已被注释)ReactAgent agent = ReactAgent.builder() .name("supervisor_agent") .model(chatModel) .systemPrompt("你是一个旅行规划监督者...") .saver(new MemorySaver()) .tools( AgentTool.getFunctionToolCallback(attractionAgent.agent()), AgentTool.getFunctionToolCallback(hotelAgent.agent()), AgentTool.getFunctionToolCallback(transportAgent.agent()) ) .build();
学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%免费】

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)