尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

Spring AI Alibaba Graph Workflow:用状态图编排可控且灵活的Agent

Spring AI Alibaba Graph Workflow:用状态图编排可控且灵活的Agent 开发 Agent 项目时团队往往会分成两派一边是 Workflow 派把流程用代码写死稳定可靠但缺乏灵活性另一边是纯 Agent 派让大模型自由决定调用哪些工具灵活聪明但难以控制和定位问题。Spring AI Alibaba 在 1.x 系列中把 Graph Workflow 作为一等公民引入用图结构来编排节点让流程在“可控”与“灵活”之间找到平衡点。本文会从概念讲起用一个完整的“客服工单 Agent”实战项目演示如何在 Spring Boot 中搭建 Spring AI Alibaba Graph Workflow并加入条件路由、工具调用、人工升级分支帮助你掌握可落地的 Agent 项目开发方式。1. 背景为什么 Agent 开发需要 Graph Workflow1.1 纯 Workflow 与纯 Agent 的取舍先看一个常见的业务场景用户问“我想查一下订单 12345 现在到哪了”。如果使用传统 Workflow流程是确定的先解析参数再查数据库最后套用模板返回。这种方案的好处是每个环节都可控、可复现、容易测试但缺点也很明显用户一旦换一种问法比如“我昨天买的那个东西什么时候能到”传统规则就很难匹配需要不断堆关键词和分支。如果使用纯 Agent 方案把问题交给大模型让它自己决定调用什么工具、按什么顺序调用确实能应对更多自然语言变化。但代价是流程不再透明用户可能被引导到错误分支工具调用也可能发散排查成本很高。生产环境里这种“不可控”是团队很难接受的。Graph Workflow 正是为了平衡这两者出现的。它把整个交互拆成一个个节点用边来定义节点之间的流转关系让开发者既能精确控制关键路径又能留出“让模型判断分支”的灵活性。1.2 Spring AI Alibaba Graph 是什么Spring AI Alibaba 是阿里云将 Spring AI 引入 Java 生态后的企业级扩展项目。在 1.x 系列中它除了提供 DashScope、通义千问等模型接入能力还提供了 graph 模块专门用于 Agent 项目的编排开发。graph 模块借鉴了 LangGraph 的设计思路核心思想是把 Agent 的一次运行过程建模为一张有向图。图上的每个节点负责一项独立任务比如意图识别、工具调用、答案生成节点与节点之间通过边连接连接条件可以由代码固定也可以由大模型动态决定。整体有点像一个“可编程状态机”只不过状态里承载的是对话上下文和工具结果。需要注意的是这里的 Graph 指编排图而不是图数据库。它不负责存储“用户和订单之间的关系”而是负责描述“一次 Agent 请求从进入到结束经过哪些步骤”。这个区分很重要很多新手容易把 Graph Workflow 和 Neo4j 这类图数据库搞混。1.3 Graph Workflow 能解决什么问题从工程落地角度看Graph Workflow 带来的收益主要体现在三方面。第一是可观测性。每个节点执行前后都能记录状态可以很方便地打印日志、统计耗时、追踪是哪一步出了问题。相比纯 Agent 的“黑盒调用”图的执行路径是静态可见的。第二是可复用性。一个节点封装一个能力比如“查询订单”“转人工”“生成回复”这些节点可以在不同 Agent 之间复用甚至可以组合成更大的图。项目规模变大后维护成本比一个大循环里堆工具的方式低很多。第三是可控性。你可以在关键路径上使用条件节点把路由逻辑掌握在自己手里也可以把一部分分支交给大模型判断比如由模型决定是否需要调用工具。这种“关键节点可控、语义理解交给模型”的混合模式正是生产级 Agent 需要的。2. 核心概念Node、Edge、StateGraph 与条件路由2.1 三个核心抽象在 Spring AI Alibaba Graph 中最核心的三个抽象是 Node节点、Edge边和 StateGraph状态图。Node 是执行单元。一个 Node 接收当前状态执行一段逻辑再返回更新后的状态。节点内部可以是普通 Java 代码比如查询数据库也可以调用大模型比如判断用户意图。节点之间互相不知道对方存在只通过状态传递数据。Edge 描述节点之间的流转关系。简单边表示“上一个执行完进入下一个”条件边则表示“根据当前状态决定进入哪个节点”。条件边是 Graph Workflow 灵活性的关键它允许一个节点拥有多个出口运行到这一步时再决定走哪条路。StateGraph 是整张图的容器。它负责注册节点、编排边、控制入口和终点最后通过 compile() 编译成可以执行的图对象。执行时StateGraph 会从起始节点开始按照边的关系依次执行直到到达 END 节点。2.2 状态是如何流转的图中的状态通常是一个 Map 结构键是字段名值是字段内容。例如{ question: 我想查一下订单12345现在到哪了, intent: ORDER, orderInfo: 订单【12345】已签收 }每个节点从状态中读取自己需要的字段把计算结果写入状态再返回给图框架。图框架负责把更新后的状态传递给下一个节点。这种设计让节点之间形成了解耦意图识别节点不关心订单查询节点怎么实现订单查询节点也不关心答案生成节点怎么处理结果。需要特别注意一点节点执行时最好在原有状态对象上写入字段而不是返回一个全新的对象。如果节点返回新对象旧对象里的字段可能会丢失导致后续节点读不到上下文。这个问题在真实项目中非常常见后面会在排错部分专门展开。2.3 Agent、Workflow、Graph 的关系用一句话概括Graph 是 Workflow 的超集Agent 是 Graph 上的一种特殊运行方式。传统 Workflow 是预先定义好的固定 DAG有向无环图每个节点的执行顺序在编译时就确定了。Agent 模式则可以理解为图中有更多条件边和循环边甚至节点的路由由大模型按当前状态实时决策。Spring AI Alibaba Graph 允许你在同一张图里混用两种模式有的分支完全固定有的分支交给模型判断。这正是“可控 灵活兼备”的落地点。从团队协作角度看也是这样。资深开发者可以把流程骨架定下来写死关键的约束边业务同学或算法同学则可以在允许的范围内调整条件节点的判断逻辑。图的表达能力比传统流程引擎更强又比纯 Agent 更容易维护。3. 环境准备与依赖配置3.1 版本环境说明开始动手前先交代本文使用的技术环境。由于 Spring AI Alibaba 仍处于快速迭代阶段具体版本号请以你的项目实际使用的版本为准本文重点演示配置思路和代码结构。JDK17 及以上推荐 21。Spring Boot3.4.x 或 3.5.x需要与 Spring AI Alibaba 1.x 的基线版本对齐。Spring AI Alibaba1.x 系列本文以 graph 模块为例。构建工具Maven 3.6。大模型阿里云百炼 DashScope 通义千问也可以按 OpenAI 兼容方式接入 DeepSeek。如果你的项目还没有确定版本建议直接使用 Spring Initializr 创建一个 Spring Boot 3.4 项目再通过 BOM 引入 Spring AI Alibaba 的版本管理。这样能减少依赖版本冲突的概率。3.2 创建项目并引入依赖这里以 Maven 为例。第一步在 pom.xml 中加入 spring-ai-alibaba-bom统一管理相关依赖版本dependencyManagement dependencies dependency groupIdcom.alibaba.cloud.ai/groupId artifactIdspring-ai-alibaba-bom/artifactId version你的SpringAIAlibaba版本/version typepom/type scopeimport/scope /dependency /dependencies /dependencyManagement第二步引入 DashScope 模型接入 starter 和 graph 模块dependencies dependency groupIdcom.alibaba.cloud.ai/groupId artifactIdspring-ai-alibaba-starter-dashscope/artifactId /dependency dependency groupIdcom.alibaba.cloud.ai/groupId artifactIdspring-ai-alibaba-graph/artifactId /dependency /dependencies如果你没有使用 BOM就需要为每个依赖单独写上 version 标签。实际开发中我建议保留 BOM因为 Spring AI Alibaba 的多个模块之间存在版本依赖关系BOM 能避免大量版本对齐问题。3.3 配置大模型接入在 application.yml 中配置 DashScope API Key 和模型名spring: application: name: agent-graph-demo ai: dashscope: api-key: ${DASHSCOPE_API_KEY} chat: options: model: qwen-plus其中 DASHSCOPE_API_KEY 放在环境变量里不要直接把密钥写死在配置文件中。qwen-plus 是通义千问的中等规格模型适合意图识别和答案生成如果你需要更强推理能力可以换成 qwen-max。如果你使用的是 DeepSeek也可以用 OpenAI 兼容方式接入配置如下spring: ai: openai: base-url: https://api.deepseek.com api-key: ${DEEPSEEK_API_KEY} chat: options: model: deepseek-chat这里有一个常见坑base-url 不要写多余的 /v1 路径否则部分版本会出现请求地址拼接错误导致接口无法访问。4. 实战构建一个客服工单 Agent4.1 业务场景与流程设计现在进入核心实战。我们构建一个客服工单 Agent用户输入一句自然语言Agent 需要完成三件事识别用户意图、查询订单信息、生成最终回复。如果用户有投诉或退款诉求则转人工处理。整体流程设计如下用户输入 - 意图识别节点 - 条件路由根据 intent 字段判断 - order查询订单节点 - 生成回复节点 - 输出 - human人工升级节点 - 输出 - chat直接生成回复节点 - 输出这个设计里意图识别节点和条件节点展示了“灵活性”让模型理解用户的语言订单查询节点和人工升级节点则展示了“可控性”关键业务分支由代码固定。4.2 项目结构在 src/main/java/com/example/agent 下创建如下目录结构agent/ ├── AgentApplication.java ├── controller/ │ └── AgentController.java ├── service/ │ └── AgentService.java ├── graph/ │ ├── IntentNode.java │ ├── OrderQueryNode.java │ ├── HumanHandoverNode.java │ ├── AnswerNode.java │ └── IntentRouter.java ├── tool/ │ └── OrderTool.java └── config/ └── AgentGraphConfig.java每个类职责单一方便后续扩展。节点类只关注自己的逻辑路由条件单独拆成一个类图组装放在配置类中入口通过 Service 暴露给 Controller。4.3 定义图状态与工具图状态使用 MapString, Object 承载。为了方便统一管理字段名我建议定义一个常量类或直接使用工具类中的常量。为了演示简洁这里直接在节点里使用字符串 key。接下来定义订单查询工具类。实际项目中这里会调用订单服务或数据库本文用一个简单方法模拟// 文件路径src/main/java/com/example/agent/tool/OrderTool.java Component public class OrderTool { public String queryOrderStatus(String orderId) { if (12345.equals(orderId)) { return 订单【12345】已签收签收时间为2026-01-10 14:30; } return 订单【 orderId 】查询不到请确认订单号后重试; } public String extractOrderId(String question) { if (question ! null question.contains(12345)) { return 12345; } return 未知; } }这里刻意没有让大模型自由决定调用哪个工具而是由节点里的 Java 代码显式调用工具。原因是订单号抽取和订单查询属于强逻辑步骤交给代码执行更稳。4.4 实现节点类第一个节点是意图识别节点它使用 ChatClient 调用大模型把模型返回的意图编码写入状态// 文件路径src/main/java/com/example/agent/graph/IntentNode.java public class IntentNode implements NodeMapString, Object { private final ChatClient chatClient; public IntentNode(ChatClient chatClient) { this.chatClient chatClient; } Override public MapString, Object execute(MapString, Object state) { String question String.valueOf(state.get(question)); String prompt 你是客服系统的意图识别器请判断用户问题的意图。 可能的意图 - ORDER查询订单、物流信息 - HUMAN投诉、退款、需要人工介入 - CHAT其他闲聊 只返回意图编码不要输出额外文字。 ; String intent chatClient.prompt() .system(prompt) .user(question) .call() .content(); state.put(intent, intent null ? CHAT : intent.trim()); return state; } }注意Node 接口的具体包名和泛型签名在不同版本中可能有差异请以你当前依赖的源码为准。核心逻辑是从状态读取 question调用大模型得到 intent再写回状态。第二个节点是订单查询节点。它读取 question从中抽取订单号调用 OrderTool 查询把结果写入 orderInfo 字段// 文件路径src/main/java/com/example/agent/graph/OrderQueryNode.java public class OrderQueryNode implements NodeMapString, Object { private final OrderTool orderTool; public OrderQueryNode(OrderTool orderTool) { this.orderTool orderTool; } Override public MapString, Object execute(MapString, Object state) { String question String.valueOf(state.get(question)); String orderId orderTool.extractOrderId(question); String orderInfo orderTool.queryOrderStatus(orderId); state.put(orderInfo, orderInfo); return state; } }第三个节点是人工升级节点。它不调用大模型直接生成一段固定提示文案保证投诉和退款场景不会被模型随意发挥// 文件路径src/main/java/com/example/agent/graph/HumanHandoverNode.java public class HumanHandoverNode implements NodeMapString, Object { Override public MapString, Object execute(MapString, Object state) { state.put(answer, 已为您转接人工客服工单号 20260101请保持电话畅通。); return state; } }第四个节点是答案生成节点。它会结合查询结果生成一段自然、友好的回复// 文件路径src/main/java/com/example/agent/graph/AnswerNode.java public class AnswerNode implements NodeMapString, Object { private final ChatClient chatClient; public AnswerNode(ChatClient chatClient) { this.chatClient chatClient; } Override public MapString, Object execute(MapString, Object state) { String orderInfo String.valueOf(state.get(orderInfo)); String answer chatClient.prompt() .system(你是一个客服助手请基于查询结果生成友好、简洁的回复。) .user(订单查询结果 orderInfo) .call() .content(); state.put(answer, answer); return state; } }这里可以看到 Graph 的好处答案生成节点并不关心订单信息是来自数据库、外部接口还是缓存它只负责“把已有信息变成用户能读懂的回复”。后续如果接入更多工具这个节点完全不需要改动。4.5 组装 StateGraph节点和边需要组装成图。条件路由单独提出来逻辑更清晰// 文件路径src/main/java/com/example/agent/graph/IntentRouter.java public class IntentRouter { public String route(MapString, Object state) { String intent String.valueOf(state.get(intent)); if (ORDER.equals(intent)) { return order; } if (HUMAN.equals(intent)) { return human; } return chat; } }然后在配置类中完成图组装// 文件路径src/main/java/com/example/agent/config/AgentGraphConfig.java Configuration public class AgentGraphConfig { Bean public GraphMapString, Object agentGraph(ChatClient chatClient, OrderTool orderTool) { IntentNode intentNode new IntentNode(chatClient); OrderQueryNode orderNode new OrderQueryNode(orderTool); HumanHandoverNode humanNode new HumanHandoverNode(); AnswerNode answerNode new AnswerNode(chatClient); StateGraphMapString, Object graph new StateGraph(); graph.addNode(intent, intentNode); graph.addNode(order, orderNode); graph.addNode(human, humanNode); graph.addNode(answer, answerNode); graph.addEdge(START, intent); graph.addConditionalEdge(intent, state - { String intent String.valueOf(state.get(intent)); if (ORDER.equals(intent)) return order; if (HUMAN.equals(intent)) return human; return answer; }); graph.addEdge(order, answer); graph.addEdge(human, END); graph.addEdge(answer, END); return graph.compile(); } }如果是 IDE 自动导包需要注意 StateGraph 和 Graph 两个类不要导入错误。不同版本的 addConditionalEdge 签名可能有差异如果编译报错优先查看当前版本的 StateGraph 源码确认是传 Map 还是传 Function。4.6 编写入口 Service 与 ControllerService 负责创建初始状态、调用图执行、返回结果// 文件路径src/main/java/com/example/agent/service/AgentService.java Service public class AgentService { private final GraphMapString, Object graph; public AgentService(GraphMapString, Object graph) { this.graph graph; } public String chat(String question) { MapString, Object state new HashMap(); state.put(question, question); MapString, Object result graph.invoke(state); return String.valueOf(result.get(answer)); } }Controller 提供 HTTP 接口// 文件路径src/main/java/com/example/agent/controller/AgentController.java RestController public class AgentController { private final AgentService agentService; public AgentController(AgentService agentService) { this.agentService agentService; } PostMapping(/chat) public MapString, String chat(RequestBody MapString, String request) { String answer agentService.chat(request.get(question)); return Map.of(answer, answer); } }4.7 运行与验证启动 Spring Boot 项目后用 curl 模拟用户提问curl -X POST http://localhost:8080/chat \ -H Content-Type: application/json \ -d {question: 我想查一下订单12345现在到哪了}预期返回类似{ answer: 您的订单【12345】已签收签收时间为2026-01-10 14:30。如果您还有其他问题可以随时告诉我。 }再测试一个转人工场景curl -X POST http://localhost:8080/chat \ -H Content-Type: application/json \ -d {question: 我要投诉你们平台退款太慢了}预期返回{ answer: 已为您转接人工客服工单号 20260101请保持电话畅通。 }从两个请求可以看出同一个入口图会根据模型识别的意图走进不同分支这就是条件路由的效果。你可以在日志中打印每个节点执行前后的状态进一步确认流转路径。5. 常见问题与排查思路5.1 Spring AI 连接 DeepSeek 不输出 Content这是 Spring AI 用户群里经常出现的问题。现象是调用 ChatClient 后返回对象不为空但 content() 结果为 null 或空字符串。常见原因有三个。第一模型名配置错误DeepSeek 的模型名应该是 deepseek-chat如果配置成其他名称返回结构可能不符合 Spring AI 的解析预期。第二base-url 配置带了多余的 /v1 路径导致请求地址错误实际请求打到了不存在的接口。第三用了流式调用但代码按非流式方式解析或者响应中的字段名与 Spring AI 预期不同。排查时可以按以下顺序处理。先看请求日志确认请求 URL 和模型名再打印原始响应体观察 content 字段是否为 null最后检查配置里的 base-url确保结尾干净。最简单的方式是用 curl 直接请求 DeepSeek API确认接口本身在返回标准的 chat.completion 结构。另外一个容易被忽略的点是DeepSeek 的 reasoning 模型会返回 reasoning_content 字段而普通 content 字段可能为空。如果使用的是 deepseek-reasoner 模型需要确认 Spring AI 是否支持解析该字段否则会因为读不到 content 而返回空结果。5.2 版本兼容问题Spring AI Alibaba 1.x 系列基于 Spring AI 1.0而 Spring AI 1.0 对 Spring Boot 版本有明显要求。如果看到 NoSuchMethodError、ClassNotFoundException 这类错误大概率是 Spring Boot 或 Spring AI 版本不匹配。建议从三方面排查第一确认 Spring Boot 版本在 Spring AI 支持矩阵内第二尽量使用 spring-ai-alibaba-bom 统一管理依赖版本第三检查是否同时引入了多个模型 starter比如既引入 dashscope 又引入 openai会造成 ChatClient 自动装配冲突。如果升级版本后出现 API 不兼容可以先看官方 release notes再搜索当前版本的迁移文档。Spring AI 生态迭代很快从 0.x 升级到 1.x或者 1.x 内的小版本升级都可能改包名或方法签名。5.3 图执行无法结束或状态丢失图执行不结束通常是条件路由出现了循环且没有到达 END 的边。排查时可以在每个节点入口打印当前节点名和状态快照通过日志确认实际流转路径。只要有一个节点返回了无法匹配任何条件边的结果就可能走到错误的出口。状态丢失则多半是节点返回了新 Map而不是在原有 Map 上写入。解决办法是约定所有节点只修改入参 state不要创建新的 HashMap 后把结果返回。如果有节点确实需要清理字段可以考虑在返回前从原 Map 中 remove 掉对应 key。还有一种情况是 execute 方法返回值被框架忽略。不同版本的 Spring AI Alibaba Graph 对节点返回值的处理可能有差异建议先确认框架是基于返回值覆盖状态还是基于对象引用原地生效。确认后再统一团队的节点编写风格。5.4 工具调用比预期多纯 Agent 模式下大模型可能在一个回答中多次调用同一个工具造成不必要的资源浪费。比如用户只是随口问一句“订单在哪”模型却查询了三遍。这不是模型不聪明而是自由调用模式下缺少约束。在 Graph Workflow 中解决这个问题有几种方式。第一把工具调用放在固定节点中由 Java 代码显式调用一次第二在系统提示词中明确“查询一次即可不要重复查询”第三使用状态中的 mark 字段记录本次会话已经调用过哪些工具出现重复时直接返回已有结果。从可控性角度看最推荐第一种方式。让模型负责理解语义让代码负责关键动作这样既保留自然语言交互的灵活性又避免模型在不该决策的地方瞎决策。6. 工程化与最佳实践6.1 节点设计原则节点是 Graph 的基本单元设计好坏直接影响整个项目的可维护性。我建议遵循单一职责原则一个节点只做一件事。比如“查询订单”和“生成回复”必须拆成两个节点不能图省事揉在一起。如果多个节点都需要访问同一个外部服务建议把外部服务封装成独立的 Component节点只负责调用。这样外部服务变更时不需要修改每个节点只需要修改对应的服务实现。对于需要大模型判断的节点系统提示词要写得足够具体。不要让模型自己猜测输出格式而是明确指定“只返回编码”“必须 JSON”等约束。输出不符合预期时可以在节点中加一层简单的正则或 JSON 解析失败时走兜底分支。6.2 状态管理与命名规范状态字段是节点之间的“协议”命名必须一致且有含义。建议 all state key 使用大写下划线风格例如 ORDER_INFO、HUMAN_TICKET_ID与模型输出的字段名区分开。状态中不要塞入不必要的对象。有些团队喜欢把整个 HTTP Request 或数据库连接对象放入状态这会让状态变量变得不可序列化也不便于日志打印。状态里尽量只放基础类型、字符串、JSON 字符串或轻量 DTO。另外涉及敏感信息时比如用户手机号、身份证号不要把原始值写入状态后在日志中打印。可以先脱敏再放入状态或者在节点内部使用独立对象持有数据只把摘要写入图状态。6.3 可观测性与超时控制Graph 应用上线后最大的问题是“不知道模型这次为什么走了这条路”。所以日志记录比普通 Web 应用更重要。建议在以下位置记录日志图开始执行时记录用户问题每个节点执行完成后记录节点名、耗时、关键状态字段图结束时记录最终回复和链路 ID。如果使用了 Spring Cloud 体系可以把链路 ID 放入状态并透传到所有外部调用。这样当用户反馈回复不对时可以通过链路 ID 快速找回完整执行日志。超时控制同样不能忽视。大模型调用可能因为网络波动变慢如果单个节点执行时间超过 10 秒整个图体验会很差。可以在节点内部对 ChatClient 调用设置超时也可以在图的外层使用 CompletableFuture 配合总超时机制。生产环境建议给每个节点设置独立的超时阈值避免一个慢节点拖垮整条链路。6.4 安全边界与最小权限Agent 项目本质上是把自然语言转换为系统动作所以安全边界必须清晰。第一工具调用权限要最小化。不要让模型能够直接调用所有方法而是通过节点显式暴露允许调用的能力。比如订单查询节点只暴露“按订单号查询状态”这一个方法不暴露“修改订单金额”这样即使提示词被恶意注入也不会扩大影响面。第二对模型输出做校验。模型生成的内容不能直接作为命令执行或注入数据库 SQL。涉及写操作、删除操作时必须由代码明确控制模型只负责生成参数不负责执行动作。第三注意提示词注入。当用户输入被拼接进 system prompt 时用户可能试图覆盖模型指令。可以考虑在节点中对用户输入进行长度限制、敏感词过滤或者把用户输入与系统指令隔离开尽量使用结构化参数传递用户内容。第四密钥管理。所有 API Key、数据库密码、第三方凭证全部放入环境变量或配置中心禁止提交到代码仓库。CI 阶段可以加入密钥扫描防止误提交。6.5 继续扩展MCP 与 Skill当项目变大后会面临“工具越来越多”的问题。Spring AI Alibaba 支持 MCPModel Context Protocol接入外部工具服务可以通过 MCP Server 暴露一组工具让 Agent 动态发现并调用。MCP 的价值是标准化工具接口让模型和工具之间的协议更统一适合中大型团队在多个 Agent 之间共享工具。但 MCP 也会带来可控性问题。工具越多模型越容易选错。建议在 Graph 中仍然保留关键节点的显式调用把 MCP 工具用在语义理解类、检索类等不需要强约束的场景。这样既能享受工具生态也能保证核心链路稳定。Skill 的概念也可以和图节点结合。你可以把一组复杂动作封装成一个 Skill在图里用一个节点表示。比如“退款流程 Skill”内部包含退款校验、审批单创建、通知用户三个步骤。从 Graph 外部看它只是一个节点从内部看它又是一张子图。这种层次化设计能让大项目的图不至于变成一棵难维护的“大杂草”。7. 总结与下一步学习路线本文从纯 Workflow 和纯 Agent 的痛点出发介绍了 Spring AI Alibaba Graph Workflow 的核心概念并用一个客服工单 Agent 完成了一次完整实战。通过实战你已经掌握了 Node、Edge、StateGraph、条件路由的使用方法能够把“意图识别”“工具调用”“人工升级”“答案生成”这些能力组合成一条可控制的图执行链路。接下来可以沿着三个方向继续深入。第一个方向是学习 LangGraph 设计模式因为 Spring AI Alibaba Graph 借鉴了它的很多思想理解 LangGraph 会让你更容易看懂源码演进第二个方向是研究 MCP 工具接入尝试把外部搜索、数据库查询封装成 MCP Server再接入到你的图中第三个方向是工程化能力给项目补充链路追踪、状态持久化
返回列表