Spring AI Alibaba Graph 全解析:从入门到精通

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 工作流
  • 生产级特性:检查点、状态恢复、并发优化
  • 多智能体协作:以图结构描述复杂业务流程

架构分层

  1. Augmented LLM:基于 Spring AI 的底层原子抽象
  2. Graph Core:底层工作流执行引擎(本专题核心)
  3. Agent Framework:高级 Agent 开发 API(如 ReactAgent)

参考资源

相关推荐
AI客栈1 小时前
云原生 AI 平台搭建:从集群规划到 GPU 调度的全链路设计实践
人工智能
运维小欣1 小时前
AI可观测平台选型指南(2026深度版):从“救火”到“智治”,企业如何选择新一代智能运维底座?
人工智能
Maydaycxc1 小时前
Python 实现 RPA + AI 自动化:大模型 OCR + 网页操作完整源码实战
人工智能·python·opencv·selenium·自动化·ocr·rpa
摇滚侠1 小时前
SpringMVC 入门到实战 异常处理 83-85
java·后端·spring·maven·intellij-idea
Keller-Zhou1 小时前
实体零售货架商品图像识别技术选型:从模型到落地的全链路对比
人工智能
朱大喜1 小时前
数据仓库从零搭建:从分层建模到数据治理的工程化落地
人工智能
闪闪发亮的小星星1 小时前
轨道的不同分类
人工智能·分类·数据挖掘
stephon_1001 小时前
从零设计 Agent 上下文压缩:三级流水线与动态阈值,治好 context too long(附开源实现)
人工智能·python
love530love1 小时前
Anaconda Navigator 升级后图形界面启动失败故障修复实录
人工智能·windows·python·anaconda·navigator