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 工作流场景。

相关推荐
core5122 小时前
SGD 算法详解:蒙眼下山的寻宝者
人工智能·算法·矩阵分解·sgd·目标函数
Tezign_space2 小时前
Agent Skills 详解:5大核心能力架构与AI Agent落地实践
人工智能·架构·生成式ai·ai agent·上下文工程·skills·agent skills
m0_466525292 小时前
东软添翼AI 2.0获评医疗健康标杆AI Agent TOP10
大数据·人工智能
用户5191495848452 小时前
Linux PAM环境变量注入漏洞利用工具解析
人工智能·aigc
哔哔龙2 小时前
Langchain中“logprobs”的作用
人工智能
智谱开放平台2 小时前
理解 Claude 的 Agentic 生态:把零散能力组织成可持续的工作流
人工智能·claude
光算科技2 小时前
AI重写工具导致‘文本湍流’特征|如何人工消除算法识别标记
大数据·人工智能·算法
旺仔小拳头..2 小时前
Java ---变量、常量、类型转换、默认值、重载、标识符、输入输出、访问修饰符、泛型、迭代器
java·开发语言·python
合力亿捷-小亿2 小时前
沉浸式体验店咨询转化难?在智能客服机器人如何把“体验预约→到店→复购”串成一条链路
人工智能·机器人