Spring AI Alibaba 实现 Workflow 全指南
Spring AI Alibaba 是阿里云基于 Spring AI 生态扩展的 AI 工程化框架,其 Workflow 模块(结合 Java2AI Graph Core 标准化规范)可实现声明式、可视化、可复用的 AI 工作流编排,核心解决"大模型调用+工具执行+结果聚合"的多步骤 AI 任务编排问题。以下从核心概念、实现步骤、实战示例、最佳实践四部分完整讲解。
一、核心概念对齐
先明确 Spring AI Alibaba Workflow 与 Java2AI Graph Core 的核心概念映射,避免理解歧义:
| 概念 | Spring AI Alibaba Workflow | Java2AI Graph Core | 说明 |
|---|---|---|---|
| 工作流定义 | @Workflow 注解类 |
Graph 定义 | 描述整个工作流的名称、描述、执行规则 |
| 工作流节点 | @WorkflowNode 注解方法 |
Node 节点 | 工作流的最小执行单元(如大模型调用、工具执行、数据校验) |
| 节点依赖 | dependOn 属性 |
Edge 边 | 定义节点执行顺序(如节点B依赖节点A执行完成) |
| 执行上下文 | WorkflowContext |
Context 上下文 | 传递节点参数、执行结果,实现节点间数据互通 |
| 执行引擎 | WorkflowExecutor |
GraphExecutor | 驱动工作流执行,负责节点调度、异常处理、结果聚合 |
二、前置环境准备
1. 依赖引入(Maven pom.xml)
核心依赖包含 Spring AI Alibaba 基础、Workflow 模块、Java2AI Graph Core(可选,标准化节点):
xml
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.5</version>
</parent>
<dependencies>
<!-- Spring AI Alibaba 核心(通义千问/百炼集成) -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>spring-ai-alibaba-dashscope-spring-boot-starter</artifactId>
<version>0.1.0</version>
</dependency>
<!-- Spring AI Alibaba Workflow 核心 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>spring-ai-alibaba-workflow-core</artifactId>
<version>0.1.0</version>
</dependency>
<!-- Java2AI Graph Core(可选,标准化节点定义) -->
<dependency>
<groupId>com.java2ai</groupId>
<artifactId>graph-core</artifactId>
<version>1.0.0</version>
</dependency>
<!-- Spring Boot 基础(Web + 自动配置) -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
</dependencies>
2. 核心配置(application.yml)
配置大模型密钥、Workflow 执行引擎、Java2AI Graph Core 扫描规则:
yaml
# 1. 阿里云大模型配置(通义千问)
spring:
ai:
dashscope:
api-key: ${DASHSCOPE_API_KEY:你的阿里云API密钥} # 替换为实际密钥
chat:
options:
model: qwen-turbo # 模型名称(qwen-turbo/qwen-plus等)
temperature: 0.7
# 2. Spring AI Workflow 配置
workflow:
executor:
thread-pool-size: 8 # 工作流执行线程池大小
timeout: 30000 # 全局超时时间(ms)
persistence:
enabled: true # 开启工作流执行记录持久化(可选)
scan:
base-packages: com.yourpackage.workflow # 工作流扫描包
# 3. Java2AI Graph Core 配置(可选)
java2ai:
graph:
core:
node-package: com.yourpackage.workflow.node # 标准化节点扫描包
executor:
async: true # 开启异步节点执行
三、Spring AI Alibaba Workflow 核心实现步骤
以电商客服智能回复场景为例(典型 AI 工作流:用户问题解析 → 知识库检索 → 大模型生成回复 → 回复校验),完整实现工作流。
步骤 1:定义工作流(@Workflow)
通过 @Workflow 注解声明工作流,@WorkflowNode 注解定义节点,遵循 Java2AI Graph Core 节点规范:
java
package com.yourpackage.workflow;
import com.alibaba.spring.ai.workflow.annotation.Workflow;
import com.alibaba.spring.ai.workflow.annotation.WorkflowNode;
import com.alibaba.spring.ai.workflow.executor.WorkflowContext;
import org.springframework.ai.dashscope.DashScopeChatClient;
import org.springframework.ai.vectorstore.VectorStore;
import org.springframework.stereotype.Component;
/**
* 电商客服回复工作流(遵循 Java2AI Graph Core 节点规范)
* 节点1:解析用户问题 → 节点2:知识库检索 → 节点3:生成回复 → 节点4:校验回复
*/
@Workflow(
name = "customer-service-reply", // 工作流唯一标识
description = "电商客服智能回复工作流",
timeout = 20000 // 工作流单独超时(覆盖全局配置)
)
@Component
public class CustomerServiceReplyWorkflow {
// 注入 Spring AI 组件:大模型客户端、向量库(知识库)
private final DashScopeChatClient dashScopeChatClient;
private final VectorStore vectorStore;
public CustomerServiceReplyWorkflow(DashScopeChatClient dashScopeChatClient, VectorStore vectorStore) {
this.dashScopeChatClient = dashScopeChatClient;
this.vectorStore = vectorStore;
}
/**
* 节点1:解析用户问题(基础节点,无依赖)
* @param context 工作流上下文(传递参数/结果)
* @return 解析后的问题关键词
*/
@WorkflowNode(
name = "parse-question", // 节点唯一标识
order = 1, // 执行顺序
requiredParams = "userQuestion", // 必传参数
description = "解析用户问题,提取关键词"
)
public String parseUserQuestion(WorkflowContext context) {
// 1. 获取入参(用户问题)
String userQuestion = context.getParam("userQuestion", String.class);
// 2. 调用大模型解析问题(提取关键词、意图)
String prompt = String.format("提取以下用户问题的关键词和意图,仅返回结构化结果:%s", userQuestion);
String parseResult = dashScopeChatClient.call(prompt).getResult().getOutput().getContent();
// 3. 将结果存入上下文(供后续节点使用)
context.putResult("parse-question", parseResult);
return parseResult;
}
/**
* 节点2:知识库检索(依赖节点1完成)
*/
@WorkflowNode(
name = "retrieve-knowledge",
order = 2,
dependOn = "parse-question", // 依赖节点1
description = "根据问题关键词检索知识库"
)
public String retrieveKnowledgeBase(WorkflowContext context) {
// 1. 获取节点1的执行结果
String parseResult = context.getResult("parse-question", String.class);
// 2. 向量库检索(知识库匹配)
String knowledge = vectorStore.similaritySearch(parseResult, 3) // 取Top3相似结果
.stream()
.map(doc -> doc.getContent())
.reduce("", (a, b) -> a + "\n" + b);
// 3. 存入上下文
context.putResult("retrieve-knowledge", knowledge);
return knowledge;
}
/**
* 节点3:生成客服回复(依赖节点2完成)
*/
@WorkflowNode(
name = "generate-reply",
order = 3,
dependOn = "retrieve-knowledge",
description = "结合知识库生成合规的客服回复"
)
public String generateReply(WorkflowContext context) {
// 1. 获取上下文数据
String userQuestion = context.getParam("userQuestion", String.class);
String knowledge = context.getResult("retrieve-knowledge", String.class);
// 2. 调用大模型生成回复
String prompt = String.format("""
基于以下知识库内容,回复用户问题,要求友好、合规、准确:
用户问题:%s
知识库内容:%s
""", userQuestion, knowledge);
String reply = dashScopeChatClient.call(prompt).getResult().getOutput().getContent();
context.putResult("generate-reply", reply);
return reply;
}
/**
* 节点4:校验回复(依赖节点3完成)
*/
@WorkflowNode(
name = "validate-reply",
order = 4,
dependOn = "generate-reply",
description = "校验回复是否合规(无敏感词、无虚假承诺)"
)
public String validateReply(WorkflowContext context) {
String reply = context.getResult("generate-reply", String.class);
// 模拟合规校验(实际可调用风控接口)
boolean isCompliant = !reply.contains("绝对") && !reply.contains("保证") && !reply.contains("假货");
String validateResult = isCompliant ? "回复合规" : "回复含违规词汇,需修改";
// 最终结果存入上下文(key固定为finalResult,便于统一获取)
context.putResult("finalResult", isCompliant ? reply : "非常抱歉,您的问题我暂时无法解答,请联系人工客服");
return validateResult;
}
}
步骤 2:执行工作流(WorkflowExecutor)
通过 WorkflowExecutor 执行已定义的工作流,支持同步/异步调用:
java
package com.yourpackage.service;
import com.alibaba.spring.ai.workflow.executor.WorkflowExecutor;
import com.alibaba.spring.ai.workflow.model.WorkflowExecutionResult;
import org.springframework.stereotype.Service;
/**
* 工作流执行服务(封装调用逻辑)
*/
@Service
public class WorkflowExecutionService {
private final WorkflowExecutor workflowExecutor;
public WorkflowExecutionService(WorkflowExecutor workflowExecutor) {
this.workflowExecutor = workflowExecutor;
}
/**
* 同步执行客服回复工作流
* @param userQuestion 用户问题
* @return 最终回复结果
*/
public String executeCustomerServiceWorkflow(String userQuestion) {
// 1. 执行工作流(指定工作流名称 + 入参)
WorkflowExecutionResult result = workflowExecutor.execute(
"customer-service-reply", // 工作流名称(与@Workflow注解一致)
param -> param.put("userQuestion", userQuestion) // 传入节点1所需参数
);
// 2. 获取最终结果(节点4存入的finalResult)
return result.getNodeResult("finalResult", String.class);
}
/**
* 异步执行工作流(推荐,非阻塞)
*/
public CompletableFuture<String> executeCustomerServiceWorkflowAsync(String userQuestion) {
return CompletableFuture.supplyAsync(() -> {
WorkflowExecutionResult result = workflowExecutor.execute(
"customer-service-reply",
param -> param.put("userQuestion", userQuestion)
);
return result.getNodeResult("finalResult", String.class);
});
}
}
步骤 3:暴露业务接口(Controller)
通过 Spring Boot Web 暴露 HTTP 接口,供前端/其他服务调用:
java
package com.yourpackage.controller;
import com.yourpackage.service.WorkflowExecutionService;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/api/workflow")
public class WorkflowController {
private final WorkflowExecutionService workflowExecutionService;
public WorkflowController(WorkflowExecutionService workflowExecutionService) {
this.workflowExecutionService = workflowExecutionService;
}
/**
* 客服回复工作流调用接口
*/
@PostMapping("/customer-service/reply")
public ResponseEntity<String> getCustomerServiceReply(@RequestBody String userQuestion) {
try {
// 执行工作流
String reply = workflowExecutionService.executeCustomerServiceWorkflow(userQuestion);
return ResponseEntity.ok(reply);
} catch (Exception e) {
return ResponseEntity.internalServerError().body("工作流执行失败:" + e.getMessage());
}
}
}
四、进阶特性(结合 Java2AI Graph Core)
1. 标准化节点开发(Java2AI Graph Core)
遵循 Java2AI Graph Core 规范开发可复用节点,实现跨工作流复用:
java
package com.yourpackage.workflow.node;
import com.java2ai.graph.core.annotation.GraphNode;
import com.java2ai.graph.core.node.AbstractNode;
import com.java2ai.graph.core.context.GraphContext;
import org.springframework.ai.dashscope.DashScopeChatClient;
import org.springframework.stereotype.Component;
/**
* 标准化大模型调用节点(遵循 Java2AI Graph Core 规范)
* 可复用在任意工作流中
*/
@GraphNode(
name = "llm-call-node",
description = "通用大模型调用节点",
inputSchema = {"prompt"}, // 输入参数规范
outputSchema = {"llmResult"} // 输出结果规范
)
@Component
public class LlmCallNode extends AbstractNode {
private final DashScopeChatClient dashScopeChatClient;
public LlmCallNode(DashScopeChatClient dashScopeChatClient) {
this.dashScopeChatClient = dashScopeChatClient;
}
@Override
public void execute(GraphContext context) {
// 1. 获取输入参数
String prompt = context.getInput("prompt", String.class);
// 2. 执行大模型调用
String result = dashScopeChatClient.call(prompt).getResult().getOutput().getContent();
// 3. 设置输出结果
context.setOutput("llmResult", result);
}
}
在 Spring AI Workflow 中引用标准化节点:
java
@WorkflowNode(
name = "common-llm-call",
order = 3,
dependOn = "retrieve-knowledge"
)
public String callCommonLlmNode(WorkflowContext context) {
// 适配 Java2AI Graph Core 上下文
GraphContext graphContext = new GraphContext();
graphContext.setInput("prompt", "生成客服回复的prompt...");
// 执行标准化节点
llmCallNode.execute(graphContext);
// 获取节点输出
return graphContext.getOutput("llmResult", String.class);
}
2. 工作流分支/并行执行
支持节点分支(条件执行)、并行执行,满足复杂场景:
java
// 分支节点示例:根据问题类型选择不同知识库
@WorkflowNode(
name = "branch-knowledge-retrieve",
order = 2,
dependOn = "parse-question",
branch = true // 标记为分支节点
)
public String branchRetrieve(WorkflowContext context) {
String parseResult = context.getResult("parse-question", String.class);
if (parseResult.contains("订单")) {
// 执行订单知识库检索
return retrieveOrderKnowledge(context);
} else if (parseResult.contains("售后")) {
// 执行售后知识库检索
return retrieveAfterSaleKnowledge(context);
} else {
return retrieveGeneralKnowledge(context);
}
}
// 并行节点示例:同时检索知识库 + 调用用户画像接口
@WorkflowNode(
name = "parallel-execute",
order = 2,
dependOn = "parse-question",
parallel = true, // 标记为并行节点
parallelNodes = {"retrieve-knowledge", "call-user-profile"} // 并行执行的子节点
)
public void parallelExecute(WorkflowContext context) {
// 无需业务逻辑,仅触发子节点并行执行
}
3. 异常处理与兜底
为节点添加异常处理,保证工作流稳定性:
java
@WorkflowNode(
name = "retrieve-knowledge",
order = 2,
dependOn = "parse-question",
fallback = "retrieveKnowledgeFallback" // 异常兜底方法
)
public String retrieveKnowledgeBase(WorkflowContext context) {
// 业务逻辑(可能抛出异常)
if (vectorStore == null) {
throw new RuntimeException("知识库连接失败");
}
// ...
}
/**
* 节点异常兜底方法(名称与fallback属性一致)
*/
public String retrieveKnowledgeFallback(WorkflowContext context, Exception e) {
context.putResult("retrieve-knowledge", "知识库暂时不可用,使用默认回复模板");
return "知识库暂时不可用,使用默认回复模板";
}
五、最佳实践
1. 工作流设计原则
- 节点粒度:单个节点只做一件事(如"解析问题""检索知识库"分离),便于复用和调试;
- 参数规范 :通过
requiredParams明确必传参数,避免空指针; - 超时控制:为核心节点单独设置超时,避免单个节点阻塞整个工作流;
- 结果命名 :统一最终结果 key 为
finalResult,简化调用方获取逻辑。
2. 性能优化
- 异步执行 :优先使用
CompletableFuture异步执行工作流,避免阻塞主线程; - 缓存复用:对高频节点结果(如知识库检索)添加缓存,减少重复调用;
- 线程池配置 :根据业务量调整
workflow.executor.thread-pool-size,避免线程耗尽。
3. 可观测性
- 日志埋点:在节点执行前后添加日志,记录入参、出参、耗时;
- 指标监控:通过 Spring Boot Actuator 暴露工作流执行指标(执行次数、成功率、耗时);
- 执行记录 :开启
persistence.enabled=true,持久化工作流执行记录,便于问题排查。
4. 版本管理
- 为工作流添加版本号(如
customer-service-reply-v1),避免修改影响存量调用; - 新旧版本并行运行,通过配置动态切换。
六、核心总结
- 核心注解 :Spring AI Alibaba Workflow 基于
@Workflow(工作流)+@WorkflowNode(节点)实现声明式编排,简单易上手; - 数据互通 :通过
WorkflowContext实现节点间参数/结果传递,是工作流的核心数据载体; - 标准化扩展:结合 Java2AI Graph Core 可开发标准化、可复用的节点,提升工作流复用性;
- 工程化能力:内置异步执行、超时控制、异常兜底、持久化等能力,满足企业级生产需求。
通过以上方式,Spring AI Alibaba Workflow 可高效实现从简单到复杂的 AI 任务编排,适配客服、医疗、金融等多领域的 AI 工作流场景。