Spring AI Alibaba Graph 全解析:从入门到精通
Spring AI + Ollama 深度实战:从 RAG 问答到 Graph Agent 全流程指南:
https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/161199169
一、引言:什么是 Spring AI Alibaba Graph?
Spring AI Alibaba Graph 是 Spring AI Alibaba 框架的核心模块之一,是一个基于有向状态图的工作流编排引擎,专为 Java 开发者构建复杂的 AI 工作流和多智能体应用而设计。
框架采用"节点完成工作,边决定下一步做什么"的设计理念,将智能体拆解为离散节点,通过共享状态通信,由条件边实现动态决策。与传统单智能体方案相比,Spring AI Alibaba Graph 支持更复杂的多步任务流,能够有效解决单个大模型难以处理复杂任务的痛点。
与 Spring AI 的关系:Spring AI 定位为 AI 应用开发的底层框架,提供模型适配、工具定义、向量数据库等原子抽象;而 Spring AI Alibaba 定位为 AI 智能体开发框架,提供基于图算法的智能体编程 Graph 框架。如果说 Spring AI 相当于 LangChain 生态中的 LangChain 框架,那么 Spring AI Alibaba 则相当于 LangChain 生态中的 LangGraph 框架。
二、核心概念深度解析
2.1 StateGraph(状态图)
StateGraph 是工作流的蓝图设计器,负责定义整个工作流的结构和执行逻辑。它采用"先定义后执行"的模式,将工作流的结构定义与实际执行分离,在编译时进行验证和优化。
通过 StateGraph 提供声明式 API,开发者可以定义:
- 节点(Nodes):计算单元
- 边(Edges):节点间的转移关系
- 条件路由:基于状态的动态分支
- 子图(Subgraphs):嵌套工作流
- 入口/出口点:从 START 开始,到 END 结束
创建 StateGraph 的典型方式:
java
StateGraph graph = new StateGraph(keyStrategyFactory);
如果不提供 KeyStrategyFactory,则默认为空的 HashMap 工厂。
2.2 Node(节点)
Node 是工作流的基本执行单元。每个 Node 负责处理特定的业务逻辑,接收状态作为输入,并返回更新后的状态。
节点可以是多种形式:
- LLM 节点:调用大模型处理文本
- 工具节点:执行外部 API 调用
- 业务逻辑节点:执行自定义 Java 代码
- 分类节点:对输入进行分类路由
- 子图节点:嵌套其他 Graph
所有节点都实现 NodeAction 或其变体接口。框架提供了丰富的预定义节点类型(15+),包括 QuestionClassifierNode、LlmNode、ToolNode、KnowledgeRetrievalNode 等。
2.3 Edge(边)
Edge 定义了节点之间的连接关系和流转条件,决定了工作流的执行路径。支持三种类型:
| 边类型 | 说明 |
|---|---|
| 普通边 | 固定顺序执行,由 addEdge() 添加 |
| 条件边 | 基于运行时状态动态路由,由 addConditionalEdges() 添加 |
| 并行边 | 多个节点同时执行 |
2.4 OverAllState(全局状态)
OverAllState 是工作流的数据中枢,像一个共享内存,在各个节点之间传递和管理数据。它采用键值对存储,支持按 key 注册不同的合并/更新策略。
StateGraph 支持三种状态更新策略:
- ReplaceStrategy(覆盖策略):新值完全替换旧值(默认)
- AppendStrategy(追加策略):新值追加到旧值之后,适合消息、日志等需要保留全部记录的场景
- MergeStrategy(合并策略):合并新旧值
所有节点将发出对 State 的更新,通过返回一个包含一系列 key-value 对的 Map,然后图引擎使用指定的 KeyStrategy 将这些更新应用到 State。
2.5 CompiledGraph(编译图)
CompiledGraph 是 StateGraph 编译后的可执行版本,负责实际的节点执行、状态流转和结果输出。它优化了执行路径,提高了执行效率。
调用 stateGraph.compile() 会校验图结构(检查无孤立节点等),并将节点动作转换为线程安全工厂,优化边路由。编译本身并不复杂,只是帮你做图编排的检查、预设置一些 config 参数而已。
2.6 KeyStrategyFactory
KeyStrategyFactory 是理解如何将节点的更新应用到 State 的关键。State 中的每个键都有自己独立的 Strategy 策略。如果没有显式指定,默认使用 ReplaceStrategy。
三、API 详解
3.1 Node Action 接口
Node actions 是定义节点行为的函数式接口。框架提供了从简到繁的接口层级,支持同步与异步执行、配置访问及中断处理等高级特性。
NodeAction(最简同步接口)
最简单的同步接口,适用于只依赖状态、无需额外配置的场景。方法签名:
java
Map<String, Object> apply(OverAllState state);
NodeActionWithConfig(同步 + 配置访问)
同步执行,可通过 RunnableConfig 获取 threadId、元数据等执行设置。方法签名:
java
Map<String, Object> apply(OverAllState state, RunnableConfig config);
AsyncNodeAction(异步执行)
异步无配置执行,适用于需要非阻塞调用的场景,如 HTTP 请求、数据库查询。方法签名:
java
CompletableFuture<Map<String, Object>> apply(OverAllState state);
AsyncNodeActionWithConfig(异步 + 配置)
最常用的接口,推荐大多数节点实现采用此接口。所有内置节点都使用此接口。方法签名:
java
CompletableFuture<Map<String,Object>> apply(OverAllState state, RunnableConfig config);
InterruptableAction(支持中断)
可选能力,支持人机协作(Human-in-the-loop)。提供 interrupt(nodeId, state, config) 和 interruptAfter(nodeId, state, config) 方法,分别在节点执行前和执行后状态合并前触发,用于实现人工审核、用户确认等交互场景。
3.2 Edge Action 接口
与 NodeAction 对应,EdgeAction 用于条件路由。
EdgeAction(同步条件边)
根据当前 State 返回下一个节点的标识符。方法签名:
java
String apply(OverAllState state);
AsyncEdgeAction(异步条件边)
返回 CompletableFuture,适用于需要异步获取路由决策的场景。方法签名:
java
CompletableFuture<String> apply(OverAllState state);
3.3 StateGraph 核心 API
StateGraph 通过链式调用提供丰富的构建方法:
| 方法 | 说明 |
|---|---|
addNode(String nodeId, NodeAction action) |
添加节点,nodeId 唯一标识 |
addNode(String nodeId, AsyncNodeAction action) |
添加异步节点 |
addNode(String nodeId, Graph graph) |
添加子图节点 |
addEdge(String from, String to) |
添加普通边 |
addEdge(START, String to) |
添加起点边 |
addEdge(String from, END) |
添加终点边 |
addConditionalEdges(String source, EdgeAction action, EdgeMappings mappings) |
添加条件边,并约束可达目标节点 |
addParallelEdges(String from, String... to) |
添加并行边 |
compile() |
编译为 CompiledGraph |
3.4 CompiledGraph API
CompiledGraph 是执行入口,提供以下方法:
| 方法 | 说明 |
|---|---|
invoke(Map<String, Object> initialState) |
同步执行工作流 |
invoke(Map<String, Object> initialState, RunnableConfig config) |
带配置同步执行 |
stream(Map<String, Object> initialState) |
流式执行,返回 Flux |
getNodeAction(String nodeId) |
获取指定节点的动作 |
调用 .compile() 方法来编译图:
java
CompiledGraph graph = stateGraph.compile();
3.5 EdgeMappings:约束路由目标
EdgeMappings 类提供了构建器,用于指定从条件边可以到达哪些节点。这种校验在编译时进行,防止运行时因无效路由决策而报错。
java
EdgeMappings mappings = EdgeMappings.builder()
.to("node_a") // 指定可达节点
.to("node_b")
.toEND() // 允许路由到 END
.build();
映射中的键必须与 EdgeAction 返回的值相匹配。编译时框架会校验所有映射的目标节点是否存在于图中。
四、环境搭建与配置
4.1 版本兼容性
Spring AI Alibaba 使用四位版本号管理方式,前三位版本号与 Spring AI 主版本对应,第四位为社区持续迭代版本。
| Spring AI Alibaba | Spring AI | Spring Boot |
|---|---|---|
| 1.1.2.0 | 1.1.2 | 3.2.5 |
| 1.0.0.2 | 1.0.0 | 3.4.5 |
| 1.0.0-M6.1 | 1.0.0-M6 | 3.4.2 |
重要:Spring Boot 3.x 要求最低 JDK 17,不支持 JDK 8、11、14、16。
4.2 Maven 依赖配置
在 pom.xml 中添加以下依赖:
xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.5</version>
</parent>
<groupId>com.example.ai</groupId>
<artifactId>graph-demo</artifactId>
<version>1.0.0</version>
<properties>
<java.version>17</java.version>
<spring-ai-alibaba.version>1.1.2.0</spring-ai-alibaba.version>
<jackson.version>2.16.2</jackson.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Graph Core 核心模块 -->
<dependency>
<groupId>com.alibaba.cloud.ai</groupId>
<artifactId>spring-ai-alibaba-graph-core</artifactId>
<version>${spring-ai-alibaba.version}</version>
</dependency>
<!-- 内置节点模块(提供预置节点) -->
<dependency>
<groupId>com.alibaba.cloud.ai</groupId>
<artifactId>spring-ai-alibaba-starter-builtin-nodes</artifactId>
<version>${spring-ai-alibaba.version}</version>
</dependency>
<!-- DashScope 模型接入 -->
<dependency>
<groupId>com.alibaba.cloud.ai</groupId>
<artifactId>spring-ai-alibaba-starter-dashscope</artifactId>
<version>${spring-ai-alibaba.version}</version>
</dependency>
<!-- 强制锁定 Jackson 版本,解决兼容性问题 -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
</dependencies>
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
</repository>
</repositories>
</project>
4.3 模型配置(application.yml)
yaml
server:
port: 885
spring:
ai:
dashscope:
api-key: ${DASHSCOPE_API_KEY} # 从环境变量读取
chat:
options:
model: deepseek-v4-flash # 或 qwen-max
logging:
level:
com.alibaba.cloud.ai: debug
配置说明:
DASHSCOPE_API_KEY需要提前设置为环境变量- 使用 DashScope Starter 时,Spring Boot 会自动创建 ChatModel Bean
注:
博客:
https://blog.csdn.net/badao_liumang_qizhi
五、完整示例:客户评价分类系统
以下是一个完整的客户评价分类系统,演示从依赖配置到工作流定义到测试的完整流程。
5.1 项目结构
graph-demo/
├── src/main/java/com/example/ai/
│ ├── SpringAiDemoApplication.java # Spring Boot 启动类
│ ├── config/
│ │ └── GraphDemoConfig.java # 工作流配置类
│ ├── controller/
│ │ └── GraphController.java # REST 控制器
│ └── nodes/
│ └── (如果有自定义节点)
├── src/main/resources/
│ └── application.yml # 配置文件
└── pom.xml
5.2 配置类实现
java
package com.example.ai.config;
import com.alibaba.cloud.ai.graph.*;
import com.alibaba.cloud.ai.graph.action.AsyncEdgeAction;
import com.alibaba.cloud.ai.graph.action.NodeAction;
import com.alibaba.cloud.ai.graph.action.AsyncNodeAction;
import com.alibaba.cloud.ai.graph.exception.GraphStateException;
import com.alibaba.cloud.ai.graph.state.strategy.ReplaceStrategy;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advisor.SimpleLoggerAdvisor;
import org.springframework.ai.chat.model.ChatModel;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import static com.alibaba.cloud.ai.graph.StateGraph.END;
import static com.alibaba.cloud.ai.graph.StateGraph.START;
import static com.alibaba.cloud.ai.graph.action.AsyncNodeAction.node_async;
@Configuration
public class GraphDemoConfig {
@Bean
public CompiledGraph customerServiceGraph(ChatModel chatModel) throws GraphStateException {
// 1. 构建 ChatClient(封装 LLM 调用)
ChatClient chatClient = ChatClient.builder(chatModel)
.defaultAdvisors(new SimpleLoggerAdvisor())
.build();
// 2. 一级分类节点:区分好评/差评
AsyncNodeAction feedbackClassifier = state -> {
String userInput = (String) state.value("input").orElse("");
String classification = chatClient.prompt()
.user("请将以下用户评价分类为 'positive' 或 'negative',只返回英文单词,不要有其他内容。\n评价内容:" + userInput)
.call()
.content();
classification = classification.trim().toLowerCase();
String result = classification.contains("positive") ? "positive" : "negative";
Map<String, Object> output = Map.of("classifier_output", result);
return CompletableFuture.completedFuture(output);
};
// 3. 二级分类节点:对差评进行细分
AsyncNodeAction specificQuestionClassifier = state -> {
String userInput = (String) state.value("input").orElse("");
String category = chatClient.prompt()
.user("请将以下用户投诉归类为:'after-sale service', 'transportation', 'product quality', 'others',只返回英文短语,不要有其他内容。\n投诉内容:" + userInput)
.call()
.content();
category = category.trim().toLowerCase();
String result;
if (category.contains("after-sale")) result = "after-sale service";
else if (category.contains("transportation")) result = "transportation";
else if (category.contains("product quality")) result = "product quality";
else result = "others";
Map<String, Object> output = Map.of("specific_classifier_output", result);
return CompletableFuture.completedFuture(output);
};
// 4. 问题处理节点:根据分类给出解决方案
NodeAction problemHandler = state -> {
String classification = (String) state.value("specific_classifier_output").orElse("others");
String solution;
switch (classification) {
case "after-sale service":
solution = "客服将立即联系您处理售后问题。";
break;
case "transportation":
solution = "物流部门会跟进您的运输问题。";
break;
case "product quality":
solution = "质检部门将联系您处理质量问题。";
break;
default:
solution = "您的反馈已记录,客服会尽快与您联系。";
}
return Map.of("solution", solution);
};
// 5. 全局状态的 Key 策略
KeyStrategyFactory keyStrategyFactory = () -> {
Map<String, KeyStrategy> strategies = new HashMap<>();
strategies.put("input", new ReplaceStrategy());
strategies.put("classifier_output", new ReplaceStrategy());
strategies.put("specific_classifier_output", new ReplaceStrategy());
strategies.put("solution", new ReplaceStrategy());
return strategies;
};
// 6. 条件边逻辑:根据一级分类决定后续路径
AsyncEdgeAction routeAfterClassifier = state -> {
String classification = (String) state.value("classifier_output").orElse("");
return CompletableFuture.completedFuture(classification);
};
// 7. 构建路由映射(使用 Map)
Map<String, String> routeMap = Map.of(
"positive", "problem_handler",
"negative", "specific_question_classifier"
);
// 8. 构建工作流
StateGraph stateGraph = new StateGraph(keyStrategyFactory)
.addNode("feedback_classifier", feedbackClassifier)
.addNode("specific_question_classifier", specificQuestionClassifier)
.addNode("problem_handler", node_async(problemHandler))
.addEdge(START, "feedback_classifier")
.addConditionalEdges("feedback_classifier", routeAfterClassifier, routeMap)
.addEdge("specific_question_classifier", "problem_handler")
.addEdge("problem_handler", END);
// 9. 编译并返回
return stateGraph.compile();
}
}
5.3 REST 控制器
java
package com.example.ai.controller;
import com.alibaba.cloud.ai.graph.CompiledGraph;
import com.alibaba.cloud.ai.graph.OverAllState;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
@RestController
public class GraphController {
@Autowired
private CompiledGraph customerServiceGraph;
@GetMapping("/process")
public Map<String, Object> processFeedback(@RequestParam String query) {
Map<String, Object> initialData = new HashMap<>();
initialData.put("input", query);
Optional<OverAllState> result = customerServiceGraph.invoke(initialData);
if (result.isPresent()) {
OverAllState finalState = result.get();
Map<String, Object> responseMap = new HashMap<>();
responseMap.put("input", finalState.value("input").orElse(null));
responseMap.put("classification", finalState.value("classifier_output").orElse(null));
responseMap.put("specific_classification", finalState.value("specific_classifier_output").orElse(null));
responseMap.put("solution", finalState.value("solution").orElse(null));
return responseMap;
} else {
return Map.of("error", "Workflow execution failed.");
}
}
}
5.4 启动类
java
package com.example.ai;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SpringAiDemoApplication {
public static void main(String[] args) {
SpringApplication.run(SpringAiDemoApplication.class, args);
}
}
5.5 测试接口
启动应用后,使用 curl 或浏览器测试:
bash
# 差测测试(产品质量问题)
curl "http://localhost:885/process?query=这个产品质量太差了"
# 差评测试(售后服务问题)
curl "http://localhost:885/process?query=你们的售后客服态度真差"
# 好评测试
curl "http://localhost:885/process?query=产品很好,非常满意"
预期响应格式:
json
{
"input": "这个产品质量太差了",
"classification": "negative",
"specific_classification": "product quality",
"solution": "质检部门将联系您处理质量问题。"
}
工作流执行流程:
input → [feedback_classifier] → 判断好评/差评
↓
├─ 好评 → [problem_handler] → END
│
└─ 差评 → [specific_question_classifier] → [problem_handler] → END
测试效果:

六、常见问题及排查
6.1 条件边映射为空(edge mapping is empty!)
错误现象:
GraphStateException: edge mapping is empty!
原因 :addConditionalEdges 的第三个参数为空或无效。
解决方案:确保传入非空的 Map 或 EdgeMappings,且 EdgeAction 返回的键与映射中的键一一对应。
java
// 正确示例
Map<String, String> routeMap = Map.of("key1", "nodeA", "key2", "nodeB");
graph.addConditionalEdges("sourceNode", edgeAction, routeMap);
6.2 找不到路由映射(cannot find edge mapping for id)
错误现象:
GraphRunnerException: cannot find edge mapping for id: 'some_key' in conditional edge with sourceId: 'some_node'
原因:EdgeAction 返回的键在 EdgeMappings 中不存在,例如返回了 "positive_feedback" 但映射表中只有 "positive"。
解决方案:检查 EdgeAction 返回值与映射表的键是否完全一致(区分大小写)。建议使用常量或枚举确保一致。
6.3 异步节点类型不匹配
错误现象:
addNode("node_id", asyncAction) // AsyncNodeAction 直接传入时报错
原因 :addNode 方法期望 NodeAction 类型,而 AsyncNodeAction 是其子类型。在多数版本中,异步节点可以直接传入;但如果报错,可使用 node_async 包装。
解决方案:
java
// 对于 NodeAction,用 node_async 包装
.addNode("node_id", node_async(syncNodeAction))
// 对于 AsyncNodeAction,直接传入即可
.addNode("node_id", asyncNodeAction)
6.4 Jackson 版本冲突(NoSuchMethodError: ObjectMapper.treeToValue)
错误现象:
java.lang.NoSuchMethodError: 'java.lang.Object com.fasterxml.jackson.databind.ObjectMapper.treeToValue(...)'
原因:Spring AI Alibaba 1.1.2.0 需要 Jackson 2.16+,但 Spring Boot 3.2.5 默认使用 Jackson 2.15.4。
解决方案:在 pom.xml 中强制锁定 Jackson 2.16.2 版本。
xml
<properties>
<jackson.version>2.16.2</jackson.version>
</properties>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
6.5 自动加载上一次执行结果
问题现象:Graph 会自动载入上一次的执行结果,导致状态污染,节点执行了错误的分支。
原因:框架底层使用 CheckpointSaver 根据 threadId 获取上一次的执行结果,合并进 OverAllState 中再执行各节点逻辑。当 threadId 为空时使用默认的 "$default"。
解决方案:
方法一:编译时指定空的 SaverConfig
java
CompileConfig compileConfig = CompileConfig.builder()
.saverConfig(SaverConfig.builder().build())
.build();
CompiledGraph compiledGraph = stateGraph.compile(compileConfig);
方法二:每次调用时传入不同的 threadId
java
RunnableConfig config = RunnableConfig.builder()
.threadId(UUID.randomUUID().toString())
.build();
OverAllState result = compiledGraph.invoke(initialState, config);
方法三:每次调用前重新编译图
java
CompiledGraph compiledGraph = stateGraph.compile();
OverAllState result = compiledGraph.invoke(initialState);
6.6 流式处理阻塞超时
问题现象 :在 WebFlux 的 Reactor 线程中执行阻塞操作,导致超时,错误信息包含 "block()/blockFirst()/blockLast() are blocking, which is not supported in thread reactor-http-nio"。
原因:在响应式环境中,StreamingChatNode 使用了错误的 API,返回了 AsyncGenerator 类型而非标准格式。
解决方案:
- 避免在异步节点中使用阻塞操作
- 流式节点应返回 Flux 类型而非 AsyncGenerator
- 使用框架标准的 FluxConverter 处理流式响应
6.7 预置节点模板为 null
错误现象:
NullPointerException: Cannot invoke "java.util.List.stream()" because "templates" is null
at QuestionClassifierNode.renderTemplates(QuestionClassifierNode.java:121)
原因:QuestionClassifierNode 使用较为复杂,某些版本需要额外提供系统提示或模板参数。
解决方案:避免使用预置节点,改为自定义 AsyncNodeAction 实现分类逻辑(如上述示例所示),这样更可控且文档更完善。
6.8 依赖版本冲突
问题现象:Maven 依赖下载失败或版本不兼容。
解决方案:
- 确保添加 Spring Milestones 仓库
- 检查
~/.m2/settings.xml中的 mirror 代理配置 - 统一项目中所有 Spring AI Alibaba 相关依赖的版本
6.9 节点返回类型不匹配
错误现象:
Required type: CompletableFuture<Map<String,Object>>
Provided: Map<String,String>
原因:AsyncNodeAction 必须返回 CompletableFuture,不能直接返回 Map。
解决方案:
java
// 错误写法
AsyncNodeAction node = state -> {
return Map.of("key", "value"); // ❌ 编译错误
};
// 正确写法
AsyncNodeAction node = state -> {
return CompletableFuture.completedFuture(Map.of("key", "value"));
};
七、进阶主题
7.1 使用预置节点
框架提供了 15+ 预定义节点类型,包括:
- QuestionClassifierNode:对输入进行分类路由
- LlmNode:调用大模型处理
- ToolNode:执行外部工具调用
- KnowledgeRetrievalNode:知识库检索
使用预置节点可快速构建工作流,但需要注意某些版本的稳定性问题。
7.2 人机协作(Human-in-the-loop)
框架原生支持 Human-in-the-loop,通过 InterruptableAction 接口实现。当遇到需要人工审核或决策的场景时,工作流可以暂停等待用户输入,恢复后继续执行,无需重新执行已完成节点。这得益于框架基于有向无环图的设计及内置检查点与状态恢复能力。企业级应用中,用户可直接在网页上修改状态、审批或输入信息,实现复杂的人机协作流程。
7.3 多智能体协作
Spring AI Alibaba Graph 支持多智能体协作。以订单助手为例,可将意图识别、商品咨询 Agent、订单查询 Agent、退款 Agent 等分别定义为不同的节点,通过条件边实现智能路由,构建清晰的状态图。
7.4 并行节点执行
对于不相互依赖的节点,可以使用 addParallelEdges 实现并行执行,充分利用系统资源,提升吞吐量。
java
.addParallelEdges("source", "nodeA", "nodeB", "nodeC")
7.5 检查点与状态持久化
框架支持检查点机制,可保存工作流执行状态。当工作流中断时,可从最近的检查点恢复执行,无需从头开始。
八、总结与资源
Spring AI Alibaba Graph 为 Java 开发者提供了一套强大的工作流编排引擎,其核心价值在于:
- 声明式 API:通过链式调用构建复杂工作流,代码清晰
- 灵活的状态管理:支持多种 KeyStrategy 满足不同场景
- 丰富的预置节点:快速构建常见 AI 工作流
- 生产级特性:检查点、状态恢复、并发优化
- 多智能体协作:以图结构描述复杂业务流程
架构分层:
- Augmented LLM:基于 Spring AI 的底层原子抽象
- Graph Core:底层工作流执行引擎(本专题核心)
- Agent Framework:高级 Agent 开发 API(如 ReactAgent)
参考资源:
- 官方文档:java2ai.com
- GitHub 仓库:github.com/alibaba/spring-ai-alibaba
- 示例项目:spring-ai-alibaba-examples
- 技术白皮书:Spring AI Alibaba Graph 工作流编排技术白皮书