Spring AI Alibaba Graph智能工作流-顺序执行

📅 2026/7/23 17:05:31 👁️ 阅读次数 📝 编程学习
Spring AI Alibaba Graph智能工作流-顺序执行

1、官方文档

Graph 工作流编排指南 | Spring AI Alibaba

Spring AI Alibaba Graph 可以改变您构建智能代理的思维方式。使用 Graph 构建代理时,您将首先把它分解为称为**节点(nodes)的离散步骤。然后,描述每个节点的不同决策和转换。最后,通过一个共享的状态(state)**将节点连接起来,每个节点都可以读取和写入该状态。在本教程中,我们将指导您完成使用 Spring AI Alibaba Graph 构建客服邮件处理代理的思维过程。

2、多个Agent顺序执行

核心组件:SequentialAgent(框架内置顺序流水线) 底层基于 Graph 状态机OverAllState列表顺序 = Agent 执行顺序数据传递机制:outputKey+ 指令内{key}占位符自动渲染

核心概念

  • ReactAgent:最小可编排智能体单元(支持工具调用 ReAct)
  • SequentialAgent:顺序编排容器
    • subAgents(List<A,B,C>):严格按 A→B→C 串行
    • 全局状态OverAllState保存所有中间结果
  • outputKey:每个 Agent 输出存入 State 的 key
  • 占位符语法
    • {input}:用户原始输入
    • {自定义key}:读取前面 Agent 输出

3、代码

固定流水线:摘要 → 翻译 → 润色

依赖

<dependency> <groupId>com.alibaba.cloud.ai</groupId> <artifactId>spring-ai-alibaba-agent-framework</artifactId> </dependency>

配置类

package com.ybw.config; import com.alibaba.cloud.ai.graph.agent.ReactAgent; import com.alibaba.cloud.ai.graph.agent.flow.agent.SequentialAgent; import org.springframework.ai.chat.model.ChatModel; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import java.util.List; @Configuration public class SequentialAgentConfig { // ChatModel 由配置自动注入(DashScope/Ollama均可) @Bean public SequentialAgent textPipelineAgent(ChatModel chatModel) { // Agent1:文本摘要 ReactAgent summaryAgent = ReactAgent.builder() .name("summary_agent") .model(chatModel) .outputKey("summary_text") // 输出存入state键名 .instruction("你是文本摘要专家,将下面内容精简为100字摘要:{input}") .build(); // Agent2:中文→英文翻译(读取上一步 summary_text) ReactAgent translateAgent = ReactAgent.builder() .name("translate_agent") .model(chatModel) .outputKey("en_text") .instruction("将下面中文翻译成地道英文,只返回译文:{summary_text}") .build(); // Agent3:英文润色(读取翻译结果 en_text) ReactAgent polishAgent = ReactAgent.builder() .name("polish_agent") .model(chatModel) .outputKey("final_result") .instruction("润色这段英文,优化语句流畅度:{en_text}") .build(); // ========== 顺序编排核心 ========== // List顺序 = 执行顺序:summary → translate → polish return SequentialAgent.builder() .name("text_sequential_pipeline") .subAgents(List.of(summaryAgent, translateAgent, polishAgent)) .build(); } }

执行链路:用户输入→ summary_agent → state ["summary_text"] → translate_agent 读取{summary_text}→ state ["en_text"] → polish_agent 读取{en_text}→ state["final_result"]

测试

package com.ybw.agent; import com.alibaba.cloud.ai.graph.OverAllState; import com.alibaba.cloud.ai.graph.agent.flow.agent.SequentialAgent; import com.alibaba.cloud.ai.graph.exception.GraphRunnerException; import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; import java.util.Optional; /** * @author ybw * @version V1.0 * @className SequentialAgentTest * @date 2026/7/22 **/ @SpringBootTest @Slf4j public class SequentialAgentTest { @Resource private SequentialAgent pipelineAgent; @Test public void runPipeline() throws GraphRunnerException { String userInput = "小松鼠的冬天礼物\n" + "秋风一吹,森林里的树叶就变成了金灿灿的颜色。小松鼠果果忙着收集松果,为即将到来的冬天做准备。它每天早早起床,蹦蹦跳跳地穿梭在林间,把饱满的松果藏进树洞里,不出几天,树洞就堆满了沉甸甸的粮食。\n" + "这天下午,果果路过小兔子的胡萝卜地,看见小兔子正蹲在地上叹气。原来秋风太急,把小兔子储存的胡萝卜叶子全都吹枯了,冬天的食物少了一大半。果果看着难过的小兔子,摸了摸自己满满的树洞,心里悄悄软了下来。\n" + "第二天一早,果果背着小布口袋,装了满满一袋松果送到小兔子家。小兔子又惊讶又感动,连忙摆手推辞:“这是你过冬的粮食,我不能要!”果果笑着摇摇尾巴:“我藏的松果很多,足够我吃一整个冬天啦,我们要一起分享呀!”\n" + "之后的日子里,果果又把松果分给了没有存够粮食的小刺猬和小麻雀。慢慢的,自己的树洞空了大半,果果心里却暖暖的。\n" + "寒冷的冬天如约而至,大雪覆盖了整片森林。就在果果担心食物不够时,小伙伴们纷纷来到它的家门口。小兔子带来了甜甜的胡萝卜,小刺猬带来了酸甜的野果,小麻雀衔来了饱满的草籽。\n" + "大家围坐在果果的树洞里,吃着美食,聊着趣事,温暖的笑声填满了小小的树洞。果果终于明白,真正的快乐不是独自拥有满满一堆粮食,而是真诚分享、互帮互助。这个冬天,因为善意与陪伴,一点都不寒冷。"; // 启动顺序执行 Optional<OverAllState> stateOpt = pipelineAgent.invoke(userInput); if (stateOpt.isEmpty()) { log.info("stateOpt为空"); return; } OverAllState state = stateOpt.get(); // 获取最后一个Agent输出 String finalResult = state.value("final_result") .map(Object::toString) .orElse("无结果"); log.info("finalResult:{}", finalResult); } }