Spring AI Alibaba 实现 Workflow 全指南

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),避免修改影响存量调用;
  • 新旧版本并行运行,通过配置动态切换。

六、核心总结

  1. 核心注解 :Spring AI Alibaba Workflow 基于 @Workflow(工作流)+ @WorkflowNode(节点)实现声明式编排,简单易上手;
  2. 数据互通 :通过 WorkflowContext 实现节点间参数/结果传递,是工作流的核心数据载体;
  3. 标准化扩展:结合 Java2AI Graph Core 可开发标准化、可复用的节点,提升工作流复用性;
  4. 工程化能力:内置异步执行、超时控制、异常兜底、持久化等能力,满足企业级生产需求。

通过以上方式,Spring AI Alibaba Workflow 可高效实现从简单到复杂的 AI 任务编排,适配客服、医疗、金融等多领域的 AI 工作流场景。

相关推荐
江畔柳前堤2 小时前
roLabelImg 详细安装教程
开发语言·人工智能·后端·云原生
阿里云大数据AI技术2 小时前
分链路差异化设计的DSP准实时数仓|钛动科技基于阿里云实时计算 Flink 版 + DLF Paimon + EMR Serverless StarRocks 的实践
人工智能·flink
陕西企来客2 小时前
2026年7月AI智能搜索曝光趋势研判
大数据·人工智能·机器学习·ai智能搜索曝光
白鸽(二般)3 小时前
MinIO Java Client API
java·开发语言
阿里云大数据AI技术3 小时前
从算力到智能体,面向 Agentic AI 的基础设施演进
人工智能·agent
hangyuekejiGEO3 小时前
GEO技术服务选型指南
大数据·人工智能·python
阿里云大数据AI技术4 小时前
EMR Serverless Spark AI Function 的双维降本实践
人工智能·sql·spark
软萌萌的14 小时前
Java Spring Boot 修改yml配置&加载顺序规则
java·spring boot·python
维基框架4 小时前
GitHub源码处理提速 一趟扫描反而更慢
人工智能·github
冬奇Lab4 小时前
代码库知识库系列(05):向量检索 vs 知识图谱——加了调用图并没有变更好
人工智能