Spring AI StateGraph 多智能体电商支付协作案例详解
前言
什么是 Spring AI StateGraph 多智能体?
你可以把它理解为: AI 团队协作工作流
-
路由智能体:产品经理,拆解需求、分发任务
-
执行智能体:开发 / 设计 / 运营,专注单一能力
-
汇总智能体:项目经理,整理结果、统一输出
-
StateGraph:流程引擎,自动驱动智能体按顺序 / 分支执行
Spring AI 1.0 官方推出 StateGraph 状态图,真正实现多智能体自动化编排。 你只需要定义:
-
智能体节点(咨询、库存、支付、物流、汇总)
-
状态流转(顺序 / 分支 / 并行)
-
业务工具(@Tool)
AI 就能像团队协作一样,自动完成: 咨询商品 → 校验库存 → 创建订单 → 支付宝支付 → 物流查询 → 结果汇总 全流程无需人工干预。
案例一:简易多智能体(入门必备)
场景
用户一句话: 介绍Spring AI,计算128/4,告诉我现在时间
智能体自动分工:
-
路由 Agent → 拆分子任务
-
执行 Agent → 调用知识、计算、时间工具
-
汇总 Agent → 整理友好回复

1. 工具类(业务能力)
import org.springframework.ai.tool.annotation.Tool;
import org.springframework.ai.tool.annotation.ToolParam;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
@Component
public class AgentTools {
// 知识讲解
@Tool(description = "讲解技术知识、概念介绍,用户询问技术内容时调用")
public String explainTech(@ToolParam(description = "需要讲解的内容") String content) {
if ("Spring AI".equals(content)) {
return "Spring AI 是 Spring 官方 AI 框架,统一封装大模型、工具调用、RAG、智能体能力,无缝对接 Spring Boot 项目。";
}
return "暂无相关介绍";
}
// 数学计算
@Tool(description = "数学加减乘除运算,用户需要计算时调用")
public String calculate(double num1, String op, double num2) {
double res = switch (op) {
case "+" -> num1 + num2;
case "-" -> num1 - num2;
case "*" -> num1 * num2;
case "/" -> num1 / num2;
default -> 0;
};
return "计算结果:" + res;
}
// 获取时间
@Tool(description = "获取当前服务器时间,用户问时间、几点时调用")
public String getNowTime() {
return LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
}
}
2. 状态上下文(智能体共享数据)
import lombok.Data;
import java.util.List;
@Data
public class UniversalTaskState {
// 用户原始请求
private String userQuery;
// 动态子任务列表(通用!任意数量)
private List<String> subTasks;
// 动态执行结果列表
private List<String> taskResults;
// 最终返回给用户的结果
private String finalReply;
}
3. StateGraph 多智能体编排(核心)
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.graph.StateGraph;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.ArrayList;
import java.util.List;
@Configuration
public class UniversalAgentConfig {
private final ChatClient chatClient;
private final AgentTools agentTools;
public UniversalAgentConfig(ChatClient.Builder builder, AgentTools agentTools) {
this.chatClient = builder.build();
this.agentTools = agentTools;
}
@Bean
public StateGraph<UniversalTaskState> universalAgentGraph() {
StateGraph.Builder<UniversalTaskState> builder = StateGraph.builder(UniversalTaskState.class);
// ======================
// 节点1:路由智能体(动态拆任意子任务)
// ======================
builder.addNode("router", state -> {
String prompt = """
请把用户的请求拆成多个独立子任务,每行一个。
不要编号,不要多余内容。
用户请求:%s
""".formatted(state.getUserQuery());
String response = chatClient.prompt(prompt).call().content();
List<String> tasks = response.lines()
.map(String::trim)
.filter(line -> !line.isBlank())
.toList();
state.setSubTasks(tasks);
state.setTaskResults(new ArrayList<>());
});
// ======================
// 节点2:执行智能体(自动批量执行所有子任务)
// ======================
builder.addNode("executor", state -> {
List<String> tasks = state.getSubTasks();
List<String> results = state.getTaskResults();
for (String task : tasks) {
String result = chatClient.prompt()
.user(task)
.tools(agentTools)
.call().content();
results.add(result);
}
});
// ======================
// 节点3:汇总智能体(统一输出)
// ======================
builder.addNode("summarizer", state -> {
String allResult = String.join("\n", state.getTaskResults());
String prompt = "请把以下结果整理成友好的自然语言回复:\n" + allResult;
String finalReply = chatClient.prompt(prompt).call().content();
state.setFinalReply(finalReply);
});
// ======================
// 通用流程(不写死任何任务)
// ======================
builder.startWith("router")
.then("executor")
.then("summarizer")
.end();
return builder.build();
}
}
4. 接口入口
import org.springframework.ai.graph.StateGraph;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class UniversalAgentController {
private final StateGraph<UniversalTaskState> graph;
public UniversalAgentController(StateGraph<UniversalTaskState> graph) {
this.graph = graph;
}
@GetMapping("/ai/agent/universal")
public String run(@RequestParam String query) {
UniversalTaskState state = new UniversalTaskState();
state.setUserQuery(query);
state = graph.run(state);
return state.getFinalReply();
}
}
5. 测试
http://localhost:8080/ai/agent/universal?query=介绍Spring AI,算128/4,现在几点
http://localhost:8080/ai/agent/universal?query=现在时间+介绍Java
http://localhost:8080/ai/agent/universal?query=计算99+199
案例二:电商支付多智能体
一、整体架构
用户请求
↓
【路由智能体】解析意图、抽取参数
↓
【咨询智能体】回答商品问题
↓
【库存智能体】校验库存
↓(分支:库存不足直接结束)
【支付智能体】调用支付宝Tool生成订单 & 收银台
↓
【物流智能体】预生成物流状态
↓
【汇总智能体】格式化返回结果
二、环境说明
-
SpringBoot 3.3.4
-
Spring AI 1.0.0-M1
-
支付宝 SDK 4.34.0.ALL
-
无需新增任何依赖(StateGraph 已内置)
-
已有的:AlipayUtil、PaymentTool、yml 配置全部复用

三、第一步:增强版电商工具类
包含:商品咨询、库存、支付宝支付、物流
import lombok.RequiredArgsConstructor;
import org.springframework.ai.tool.annotation.Tool;
import org.springframework.ai.tool.annotation.ToolParam;
import org.springframework.stereotype.Component;
import java.util.UUID;
@Component
@RequiredArgsConstructor
public class EcommerceTool {
private final AlipayUtil alipayUtil;
// 1. 商品咨询
@Tool(description = "用户咨询商品信息、功能、介绍时调用")
public String goodsInfo(
@ToolParam(description = "商品名称") String goodsName) {
return "【商品介绍】" + goodsName + ":官方正版,永久有效,售后无忧";
}
// 2. 库存校验
@Tool(description = "查询商品库存是否足够,是否可购买")
public String stockCheck(
@ToolParam(description = "商品名称") String goodsName) {
// 真实项目对接数据库
return "库存充足(198件),可正常下单";
}
// 3. 创建支付宝订单(核心!)
@Tool(description = "创建支付订单,生成支付宝支付页面,用户确认购买时调用")
public String createAliOrder(
@ToolParam(description = "商品名称") String goodsName,
@ToolParam(description = "支付金额,单位元") String amount) {
String orderNo = "ORD_" + UUID.randomUUID().toString().replace("-", "");
// 调用支付宝工具生成收银台表单
String payHtml = alipayUtil.createPagePay(orderNo, goodsName, amount);
return "订单创建成功!订单号:" + orderNo + "\n支付链接:" + payHtml;
}
// 4. 物流状态
@Tool(description = "根据订单号查询物流状态")
public String logisticsQuery(
@ToolParam(description = "订单编号") String orderNo) {
return "【物流】订单 " + orderNo + ":支付完成后24小时内发货,全程跟踪";
}
}
四、第二步:状态实体(核心上下文传递)
智能体之间共享数据:商品名、订单号、各步骤结果
import lombok.Data;
@Data
public class EcommerceState {
// 用户输入
private String userQuery;
// 抽取的商品名
private String goodsName;
// 订单金额
private String amount;
// 订单号(支付生成后传递)
private String orderNo;
// 各智能体结果
private String infoResult;
private String stockResult;
private String payResult;
private String logisticsResult;
// 最终返回用户
private String finalResponse;
}
五、第三步:StateGraph 多智能体编排(完整版)
包含:顺序流转 + 条件分支 + 参数传递
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.graph.StateGraph;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class EcommerceAgentGraph {
private final ChatClient chatClient;
private final EcommerceTool ecommerceTool;
public EcommerceAgentGraph(ChatClient.Builder builder, EcommerceTool ecommerceTool) {
this.chatClient = builder.build();
this.ecommerceTool = ecommerceTool;
}
@Bean
public StateGraph<EcommerceState> ecommerceStateGraph() {
StateGraph.Builder<EcommerceState> graph = StateGraph.builder(EcommerceState.class);
// ====================== 节点1:路由 & 信息抽取 ======================
graph.addNode("RouterAgent", state -> {
String prompt = """
从用户 query 里抽取:商品名称、金额(默认99元)
输出格式:商品名=xxx;金额=xxx
用户输入:%s
""".formatted(state.getUserQuery());
String extract = chatClient.prompt(prompt).call().content();
String[] arr = extract.split(";");
state.setGoodsName(arr[0].split("=")[1]);
state.setAmount(arr[1].split("=")[1]);
});
// ====================== 节点2:商品咨询智能体 ======================
graph.addNode("InfoAgent", state -> {
String res = chatClient.prompt()
.user("介绍商品:" + state.getGoodsName())
.tools(ecommerceTool)
.call().content();
state.setInfoResult(res);
});
// ====================== 节点3:库存智能体 ======================
graph.addNode("StockAgent", state -> {
String res = chatClient.prompt()
.user("查询库存:" + state.getGoodsName())
.tools(ecommerceTool)
.call().content();
state.setStockResult(res);
});
// ====================== 节点4:支付智能体 ======================
graph.addNode("PayAgent", state -> {
String res = chatClient.prompt()
.user("创建订单:%s,金额:%s".formatted(state.getGoodsName(), state.getAmount()))
.tools(ecommerceTool)
.call().content();
state.setPayResult(res);
// 抽取订单号到上下文
if (res.contains("订单号:")) {
state.setOrderNo(res.split("订单号:")[1].split("\n")[0]);
}
});
// ====================== 节点5:物流智能体 ======================
graph.addNode("LogisticsAgent", state -> {
String res = chatClient.prompt()
.user("查询物流,订单号:" + state.getOrderNo())
.tools(ecommerceTool)
.call().content();
state.setLogisticsResult(res);
});
// ====================== 节点6:汇总智能体 ======================
graph.addNode("SummaryAgent", state -> {
String all = """
商品信息:%s
库存状态:%s
支付订单:%s
物流说明:%s
""".formatted(
state.getInfoResult(),
state.getStockResult(),
state.getPayResult(),
state.getLogisticsResult()
);
String summary = chatClient.prompt(
"整理成友好的购物结果回复给用户:" + all
).call().content();
state.setFinalResponse(summary);
});
// ====================== 流程编排(完整版) ======================
graph.startWith("RouterAgent")
.then("InfoAgent")
.then("StockAgent")
.then("PayAgent")
.then("LogisticsAgent")
.then("SummaryAgent")
.end();
return graph.build();
}
}
六、第四步:Controller 接口(对外提供访问)
import org.springframework.ai.graph.StateGraph;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class EcommerceAgentController {
private final StateGraph<EcommerceState> graph;
public EcommerceAgentController(StateGraph<EcommerceState> graph) {
this.graph = graph;
}
// 多智能体电商购物入口
@GetMapping("/ai/shop")
public String shop(@RequestParam String msg) {
EcommerceState state = new EcommerceState();
state.setUserQuery(msg);
// 自动执行全流程
EcommerceState result = graph.run(state);
return result.getFinalResponse();
}
}
七、测试
访问:
http://localhost:8080/ai/shop?msg=我想买年度会员
自动执行流程(AI 全自动完成)
-
路由智能体:抽取 商品 = 年度会员,金额 = 99 元
-
咨询智能体:返回商品介绍
-
库存智能体:校验库存充足
-
支付智能体:调用支付宝 Tool,生成订单 + 收银台
-
物流智能体:返回物流说明
-
汇总智能体:输出友好结果
返回结果示例
你好,你选择的商品是:年度会员
该商品为官方正版,永久有效,售后无忧。
当前库存充足(198件),可以正常购买。
已为你创建订单,订单号:ORD_xxxxxxx
点击即可进入支付宝收银台完成支付。
支付完成后24小时内发货,全程物流跟踪。
八、生产级增强(可选)
1. 分支判断:库存不足直接终止
graph.conditional("StockCheck", state -> {
if (state.getStockResult().contains("不足")) {
return "EndNode";
} else {
return "PayAgent";
}
});
2. 接入 MCP 远程智能体
把支付 / 物流智能体部署为独立 MCP 服务,实现微服务多智能体。
3. 订单持久化
在 PayAgent 中把订单存入 MySQL。
4. 支付宝回调自动更新状态
九、总结
这是目前 Spring AI 官方标准的多智能体方案:
-
StateGraph = 多智能体编排引擎
-
@Tool = 智能体能力
-
State = 团队共享上下文
-
全自动执行复杂业务流程(无需人工干预)
本案例可直接用于:
-
AI 电商
-
AI 付费会员
-
AI 付费咨询
-
AI 收银台
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐

所有评论(0)