news 2026/10/14 13:05:58

Spring AI Alibaba实战:Java构建AI Agent的ReAct与图编排

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Spring AI Alibaba实战:Java构建AI Agent的ReAct与图编排

如果你是一个 Java 后端开发者,最近一定会有一种被大模型浪潮甩开的感觉。AI Agent 的教程铺天盖地,但十篇里有八篇是 Python,剩下两篇是 Node.js。Java 团队想跟进,最常见的结局是两选一:要么用 HttpClient 封装一次模型接口,调用一次就结束,根本做不出真正的 Agent;要么干脆把 Agent 核心逻辑外包给一个 Python 服务,Java 通过 REST 转发,链路长了、故障点多了,项目也失去了掌控感。

问题的关键不在于“大模型接口调不通”,而在于 Agent 的核心机制——ReAct 循环、工具调用、状态流转——在 Java 生态里长期缺少工程化承载。Spring AI Alibaba 正是冲着这个问题来的。它把大模型接入、Tool Calling、Agent 编排整合成一套可用的 Java 框架,并且借鉴了 LangGraph 的图编排思想,让 Agent 不再只是 Python 的专利。

这篇文章不打算只讲概念。我会先用一个最小示例跑通 Java 调用大模型,再通过完整代码演示 ReAct/Loop 是怎么运转的,最后解释 Graph Engineering 到底在解决什么问题,并给出一个状态图编排的示例。文章末尾还整理了常见问题和生产环境建议,建议收藏备用。

1. 这篇文章真正要解决的问题

在动手写代码之前,先想清楚一个问题:Java 团队做 Agent,真正难在哪里?

1.1 Java 团队做 Agent 的两条弯路

第一条弯路是硬编码。项目里定义一堆 Service 方法,根据用户输入里的关键词去匹配调用哪个服务。比如用户说“查订单”,就调订单查询接口;说“改地址”,就调地址修改接口。这种方案的痛点很明显:模型输出千变万化,关键词匹配完全不可靠;新增一个工具就要改一次分支逻辑;更麻烦的是,它无法处理多步任务。比如“查一下北京天气,再对比昨天温度,告诉我今天是否需要加衣服”,这种任务需要连续调用多个工具,硬编码完全写不动。

第二条弯路是 Python 返工。很多团队选择用 LangChain 或 LangGraph 在 Python 里做 Agent,Java 只做入口。短期看能跑通,长期问题却不少:两套技术栈意味着两套部署、两套监控、两套排错方式;Java 领域里的登录、权限、订单、工单等业务能力,要集成到 Python 服务里非常别扭;Agent 的决策链路一旦跨服务,链路追踪和排错成本会明显上升。

Spring AI Alibaba 的价值在于,它让 Java 团队在自己熟悉的技术栈里同时拥有“模型调用 + 循环决策 + 图编排”三种能力。业务模型直接复用现有 Spring Bean,Agent 只负责决策,不负责重新实现业务。

1.2 什么样的读者适合读这篇文章

这篇文章适合有 Java 和 Spring Boot 基础,想在大模型项目里落地的后端工程师;也适合团队正在评估 Java Agent 技术选型的技术负责人。即使你对 LLM 原理了解不深,也可以读,因为本文不涉及模型训练,只讲应用层工程。

读完你应该能回答三个问题:

  1. ReAct 和 Loop 到底是什么,为什么 Agent 缺了它就不完整?
  2. Java 里如何通过 Spring AI Alibaba 实现工具调用循环?
  3. Graph Engineering 为什么是 Agent 工程化绕不开的一步?

2. 核心概念:ReAct、Loop 和 Agent

2.1 Agent 不是模型,而是“模型 + 循环 + 工具”

先说一个常见误区:很多人以为 Agent 就是换了一个更强的模型。其实不是。

大模型本身是“一次推理”:给一段输入,返回一段文本。它没有手脚,不能查询数据库,不能调用订单接口,也不能操作外部系统。Agent 是在模型外围套了一层控制逻辑:让模型决定要调用哪些工具,拿到工具结果后继续推理,直到得出结论。

打个比方。大模型像一个知识渊博但没有手脚的专家,Agent 是给这位专家配了助理、资料库和行动流程。专家负责思考,助理负责执行,资料库负责提供信息,行动流程负责让整个协作有序进行。

2.2 ReAct:让模型边思考边行动

ReAct 是 Reason + Act 的缩写,核心思想是让模型在推理过程中穿插行动。

普通调用模式下,用户问“明天北京适合跑步吗”,模型会回答“我无法实时获取天气数据”。ReAct 模式下,模型收到问题后,先推理出“我需要天气信息”,然后生成一次工具调用请求,程序执行天气查询工具,把结果回传给模型,模型再基于真实天气数据生成最终建议。

整个过程可以拆成四步:

  1. 模型收到任务,分析需要哪些信息。
  2. 模型输出工具调用指令。
  3. 程序执行工具,返回真实结果。
  4. 模型读取工具结果,继续推理并输出回答。

工具结果会作为新的上下文进入模型的下一次推理,这就是“思考 - 行动 - 观察 - 再思考”的循环。

2.3 Loop:Agent 为什么必须引入循环

一次模型调用只能完成一轮推理,而现实任务往往需要多次工具调用。例如“帮我分别查询北京和上海未来三天的天气,对比后建议周末去哪个城市出差”,模型可能需要连续查询北京三天、上海三天,最后再汇总分析。

Loop 的意义就在这里:反复把模型输出变成工具输入,再把工具结果变成模型输入,直到模型认为信息足够并生成最终回答。没有 Loop,ReAct 只是空谈;没有 ReAct,Loop 只是无意义的重复调用。两者组合起来,才是 Agent 能够自主完成任务的基础。

Loop 不能无限进行,必须设置最大轮数。这也是工程上最常见的控制点之一,后面会专门讲。

3. Spring AI Alibaba 与图工程:Agent 落地的关键

3.1 Spring AI Alibaba 解决什么问题

Spring AI Alibaba 是阿里开源的 Spring AI 生态实现,重点是让 Java/Spring Boot 项目以统一方式接入 DashScope(阿里云百炼)的大模型服务,同时兼容 Spring AI 的编程模型。它比“手写 HttpClient 调用 OpenAI 格式”多解决了几件事:

  • 自动装配 ChatModel 和 ChatClient,不需要自己管理连接和请求。
  • 统一流式调用、同步调用和异步调用。
  • 对 Tool Calling 提供一站式支持。
  • 对 Agent 编排提供原生集成。
对比维度手写 HTTP 调用Spring AI Alibaba
连接管理自己封装 HTTP Client自动装配
消息历史自己拼接Message 统一管理
工具调用自己解析函数参数@Tool 注解 + 自动循环
Agent 编排自己写状态机图编排支持
高峰期稳定性需要自己重试限流支持统一配置

3.2 为什么 Agent 会走向 Graph Engineering

Agent 的逻辑会随着场景变复杂。简单工具链可以写循环,但一旦涉及多个阶段——意图识别、工具选择、参数补齐、结果校验、多轮对话,纯循环代码会变成面条式 if-else。

Graph Engineering(图工程)把流程建模成“节点 + 边 + 状态”:

  • 节点是一次处理单元,对应一个 Java 方法或一个 Agent 步骤。
  • 边定义节点之间的流转条件。
  • 状态是流程中共享的数据对象,在节点之间传递和更新。

这本质上是把流程控制变成一张有向图。图可以配置化、可视化、复用。每个节点独立测试,每条边独立评估。对于复杂 Agent 来说,这是比“一大段 while 循环”更可控的工程结构。

3.3 三种落地方案对比

实现方式优点缺点
Python LangGraph生态丰富,社区案例多Java 集成成本高,跨语言链路复杂
Java 硬编码 Loop简单直接,无额外依赖流程复杂时维护成本爆炸
Spring AI Alibaba + StateGraphJava 原生,业务复用,图化编排API 迭代快,需要跟随官方演进

从技术选型角度看,Java 团队更稳妥的方向是第三种:既保留 Java 技术栈的业务能力,又能获得图编排的可控性。

4. 环境准备与前置条件

4.1 基础环境

本文示例基于 Spring Boot 3.x 和 JDK 17+,这是 Spring AI 生态的基本要求。具体版本请以官方文档为准,不建议在项目里写死本文中的版本号,因为 Spring AI 的版本迭代速度很快。

需要的工具:

  • JDK 17 及以上。
  • Maven 3.6+ 或 Gradle 7+。
  • Spring Boot 3.x 项目。
  • 一个支持代码提示的 IDE,建议 IntelliJ IDEA。
  • 一个阿里云百炼(DashScope)账号。

4.2 获取模型 API Key

注册阿里云百炼后,在控制台创建 API Key,并开通模型调用权限。建议通过环境变量或配置中心管理 API Key,不要写死在代码里,也不要提交到 Git 仓库。

模型选择上,qwen-plus 适合作为入门默认模型,qwen-max 推理能力更强,qwen-turbo 成本更低。具体可用模型以官方列表为准,本文示例不依赖特定模型,使用通用配置即可。

5. 示例一:用 ChatClient 打通大模型调用

先跑通最小闭环:Java 项目启动后,能够调用一次大模型并返回结果。

5.1 创建项目并引入依赖

创建一个 Maven Spring Boot 项目,在pom.xml中加入必要依赖:

<!-- pom.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>请以官方最新推荐版本为准</version> <relativePath/> </parent> <groupId>com.example</groupId> <artifactId>java-agent-demo</artifactId> <version>1.0.0</version> <properties> <java.version>17</java.version> <!-- 实际使用时请替换为官方最新版本 --> <spring-ai-alibaba.version>请查阅官方文档替换</spring-ai-alibaba.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>com.alibaba.cloud.ai</groupId> <artifactId>spring-ai-alibaba-starter</artifactId> <version>${spring-ai-alibaba.version}</version> </dependency> </dependencies> </project>

这段配置的核心是引入spring-ai-alibaba-starter,它会自动装配 ChatModel 相关组件。如果你使用的是 Gradle,替换为对应的 implementation 写法即可。

5.2 配置 DashScope

在src/main/resources/application.yml中加入配置:

# application.yml spring: application: name: java-agent-demo ai: dashscope: api-key: ${DASHSCOPE_API_KEY} chat: options: model: qwen-plus

配置说明:

  • spring.ai.dashscope.api-key从环境变量DASHSCOPE_API_KEY读取。
  • spring.ai.dashscope.chat.options.model指定默认模型,这里使用 qwen-plus。

如果不想通过环境变量注入,也可以在本地临时使用明文,但仅限于本地开发,生产环境务必使用配置中心或密钥管理服务。

5.3 第一个可运行的聊天接口

新建一个 Controller,注入ChatClient,写一个最简单的聊天接口:

// src/main/java/com/example/javaagentdemo/ChatController.java package com.example.javaagentdemo; import org.springframework.ai.chat.client.ChatClient; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @RestController public class ChatController { private final ChatClient chatClient; public ChatController(ChatClient.Builder builder) { this.chatClient = builder.build(); } @GetMapping("/chat") public String chat(@RequestParam String message) { return chatClient.prompt() .user(message) .call() .content(); } }

启动 Spring Boot 应用后,浏览器访问:

http://localhost:8080/chat?message=你好

如果配置正确,接口会返回模型生成的欢迎语。这一步的意义在于验证 API Key、模型名和 Spring AI 自动装配全部正常。走到这里,你已经在 Java 里完成了第一次真正的大模型调用。

6. 示例二:实现 ReAct/Loop 模式的 Agent

打通模型调用后,下一步是让模型具备调用工具的能力。这是 Agent 和普通聊天接口的分水岭。

6.1 利用 @Tool 让模型自动选择工具

Spring AI 提供了@Tool注解。只要在 Spring 管理的 Bean 方法上标注这个注解,框架就会把方法注册为模型可用的工具。模型在回答问题时,如果判断需要调用工具,会发起工具调用请求,框架自动执行方法,把结果回传给模型,模型再基于结果生成最终回答。整个 Loop 由框架维护,你只需要关注工具实现。

下面定义一个天气查询工具:

// src/main/java/com/example/javaagentdemo/tool/WeatherTools.java package com.example.javaagentdemo.tool; import org.springframework.ai.tool.annotation.Tool; import org.springframework.ai.tool.annotation.ToolParam; import org.springframework.stereotype.Component; @Component public class WeatherTools { @Tool(description = "查询指定城市当天的天气情况") public String getWeather(@ToolParam(description = "城市名称") String city) { // 实际项目中替换为真实天气服务调用 return city + ":晴,25℃~32℃,东南风3级,空气质量优"; } }

然后创建调用入口:

// src/main/java/com/example/javaagentdemo/service/AgentService.java package com.example.javaagentdemo.service; import com.example.javaagentdemo.tool.WeatherTools; import org.springframework.ai.chat.client.ChatClient; import org.springframework.stereotype.Service; @Service public class AgentService { private final ChatClient chatClient; public AgentService(ChatClient.Builder builder) { this.chatClient = builder.build(); } public String ask(String message) { return chatClient.prompt() .user(message) .tools(new WeatherTools()) .call() .content(); } }

这里真正值得关注的是tools(new WeatherTools())。这一行代码告诉模型:回答过程中可以使用我提供的工具。模型在回答“北京适合跑步吗”这类问题时,不会直接说“不知道”,而会先调用天气工具,拿到真实天气数据后再做推理。框架会自动完成“模型请求调用工具 -> 框架执行工具 -> 结果回传模型 -> 模型继续推理”的 Loop。

6.2 手动版 ReAct 循环(原理演示)

@Tool很省事,但容易让人把核心机制当成黑盒。为了理解 ReAct 循环的本质,这里再给一个手动实现版本。它不是生产推荐写法,而是教学演示,帮助你理解循环内部发生了什么。

// src/main/java/com/example/javaagentdemo/agent/ReactLoopDemo.java package com.example.javaagentdemo.agent; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.ai.chat.client.ChatClient; import org.springframework.ai.chat.messages.Message; import org.springframework.ai.chat.messages.SystemMessage; import org.springframework.ai.chat.messages.UserMessage; import java.util.ArrayList; import java.util.List; public class ReactLoopDemo { private static final String SYSTEM_PROMPT = """ 你是一个智能助手。如果需要查询天气,必须输出 JSON: {"action": "get_weather", "city": "北京"} 如果不需要调用工具,直接输出最终回答。 工具返回结果后,基于结果继续推理。 """; private static final int MAX_ITERATIONS = 5; private final ChatClient chatClient; private final ObjectMapper objectMapper = new ObjectMapper(); public ReactLoopDemo(ChatClient chatClient) { this.chatClient = chatClient; } public String run(String userInput) throws Exception { List<Message> messages = new ArrayList<>(); messages.add(new SystemMessage(SYSTEM_PROMPT)); messages.add(new UserMessage(userInput)); for (int i = 0; i < MAX_ITERATIONS; i++) { String reply = chatClient.prompt() .messages(messages) .call() .content(); // 判断模型是否要求调用工具 if (reply.contains("\"action\"")) { JsonNode json = objectMapper.readTree(extractJson(reply)); String action = json.get("action").asText(); String city = json.get("city").asText(); // 执行本地工具 String observation = executeAction(action, city); // 把工具结果作为上下文追加给模型 messages.add(new UserMessage("工具执行结果:" + observation)); } else { return reply; } } return "已达到最大循环轮数,Agent 停止。"; } private String executeAction(String action, String city) { if ("get_weather".equals(action)) { return city + ":晴,25℃~32℃,东南风3级,空气质量优"; } return "未知动作"; } private String extractJson(String text) { int start = text.indexOf("{"); int end = text.lastIndexOf("}"); return text.substring(start, end + 1); } }

这个示例完整展示了 ReAct 循环的四步:模型输出行动指令,程序解析 JSON,执行本地工具,把结果追加到消息列表,然后进入下一轮推理。循环终止条件有两个:模型输出最终回答,或者达到最大轮数。

6.3 循环不终止与最大轮数

手动 ReAct 最容易踩的坑是死循环。模型会反复调用同一个工具,或者工具返回空结果,导致模型觉得“信息不够”继续请求调用。

生产环境中可以从几个方向控制:

  • 设置最大迭代轮数,一般建议 5 到 10 轮。
  • 工具返回结果要结构化,即使无数据也要明确返回“无数据”,而不是空字符串。
  • 在 system prompt 中增加约束,例如“如果工具结果没有提供新信息,请停止调用并基于已有信息回答”。
  • 对重复的工具调用做去重,同一个工具同一组参数只允许调用一次。

这些控制点在@Tool自动模式下同样适用。Spring AI 框架会自动维护 Loop,但最大轮数和终止策略需要你自己配置或通过 prompt 约束。

7. 示例三:从 ReAct 走向 StateGraph 图编排

ReAct 解决了“模型反复调用工具”的问题,但还没有解决“流程走向可控”的问题。当一个 Agent 需要多个处理阶段时,图编排就派上用场了。

7.1 图工程的三个核心概念

图工程有三个核心概念:

  • 节点(Node):一次处理单元,对应一个 Java 方法。
  • 边(Edge):节点之间的流转关系,可以带条件。
  • 状态(State):流程中共享的数据对象,节点从状态读数据,处理后写回状态。

可以这样类比:把 Agent 流程画成一张流程图,节点是你执行的 Java 方法,边是“从上一步跳到下一步”的判断,状态是流程里所有人共享的白板。

7.2 用状态图编排一个工单查询 Agent

下面用 StateGraph 思路演示一个工单查询 Agent。这个示例侧重讲解建模思想,Spring AI Alibaba 的 Agent API 仍在演进,具体类名和包路径请以你用到的版本为准,但节点、边、状态这三个抽象是通用的。

先定义状态对象:

// State 状态对象(示意) public class AgentState { private String userInput; private String intent; private String orderInfo; private String finalAnswer; // getter/setter 省略 }

再定义节点:

// intent 节点:识别用户意图 public class IntentNode implements Node<AgentState> { @Override public AgentState execute(AgentState state) { // 调用模型识别意图:ORDER_QUERY / WEATHER / UNKNOWN state.setIntent("ORDER_QUERY"); return state; } } // orderQuery 节点:查询订单工具 public class OrderQueryNode implements Node<AgentState> { @Override public AgentState execute(AgentState state) { // 调用订单系统,返回真实订单状态 state.setOrderInfo("订单 T20241001 已发货,预计明天送达"); return state; } } // answer 节点:生成最终回答 public class AnswerNode implements Node<AgentState> { @Override public AgentState execute(AgentState state) { state.setFinalAnswer("您的订单 " + state.getOrderInfo()); return state; } }

最后组装成图:

// 组装 StateGraph(示意) StateGraph<AgentState> graph = new StateGraph<>(AgentState.class) .addNode("intent", new IntentNode()) .addNode("orderQuery", new OrderQueryNode()) .addNode("answer", new AnswerNode()) .addEdge("intent", "orderQuery") .addEdge("orderQuery", "answer") .setEntryPoint("intent") .setFinishPoint("answer"); Agent<AgentState> agent = graph.compile(); AgentState result = agent.invoke(AgentState.builder() .userInput("查一下我的订单状态") .build());

执行流程是:入口是intent节点,模型识别出意图后流转到orderQuery节点,工具查询订单后流转到answer节点,生成最终回答后结束。

7.3 为什么图比硬编码 if-else 更可控

硬编码 if-else 在处理三四个分支时还能撑住,但一旦分支增加到十几个,代码会变得不可维护。图的优势体现在四个方面:

  • 全局视角:整张图的结构一眼可见,节点之间的依赖关系清晰。
  • 独立测试:每个节点可以单独传入状态对象做测试,不必启动完整流程。
  • 统一控制:可以在图层面设置超时、重试、日志和权限校验。
  • 流程复用:同一组节点可以被多张图复用,不同场景组合出不同 Agent。

这正是 Graph Engineering 被引入 Agent 领域的原因。它本质上是用状态机的思想来约束模型的自由度,让 Agent 的行为可控、可观测、可维护。

8. 运行结果与效果验证

8.1 运行方式

示例一和示例二都是 Spring Boot 应用,直接运行主类即可:

mvn spring-boot:run

如果要单独测试 Agent 逻辑,可以写一个CommandLineRunner或者直接用测试类调用AgentService。

StateGraph 示例如果只是演示模型状态流转,也可以在 main 方法中直接调用:

// src/main/java/com/example/javaagentdemo/AgentGraphApp.java public class AgentGraphApp { public static void main(String[] args) { Agent<AgentState> agent = buildGraph(); AgentState result = agent.invoke(AgentState.builder() .userInput("查一下我的订单状态") .build()); System.out.println(result.getFinalAnswer()); } }

8.2 预期输出与成功标准

如果一切正常,终端或接口会返回类似下面的内容:

--- 进入节点: intent --- 意图识别: ORDER_QUERY --- 进入节点: orderQuery --- 工具调用: 查询订单 T20241001 工具返回: 已发货 --- 进入节点: answer --- 最终回答: 您的订单 T20241001 已发货,预计明天送达

成功标准有三个:

  1. 节点按预期顺序执行。
  2. 工具被正确调用,拿到了真实数据。
  3. 模型基于工具结果生成了合理回答,而不是直接说“我无法查询”。

8.3 失败时的第一排查顺序

如果某个环节没有输出,按下面顺序排查:

  1. API Key 是否有效,是否已开通模型权限。
  2. 模型名是否正确,是否是当前账号可用的模型。
  3. 依赖版本是否匹配,Spring AI 和 Spring Boot 版本冲突是最常见问题。
  4. 工具类是否被 Spring 容器管理,使用@Component并且确认扫描路径。
  5. 消息历史是否正确传递,手动 ReAct 中消息列表是最容易出错的地方。

9. 常见问题与排查思路

问题现象可能原因排查方式解决方案
请求返回 401/403API Key 无效或未开通模型权限检查环境变量和控制台配置重新生成 API Key,确认模型权限
请求返回 429触发限流或并发超限查看控制台配额和调用日志降低并发,开启重试和退避策略
模型回答不符合要求system prompt 约束不够检查提示词,观察原始输出增加格式约束和示例,缩小自由输出空间
工具方法未被调用工具未注册或描述不清晰确认 @Tool 注解和 classpath 扫描补充工具描述,正确传入 tools 参数
Agent 循环不终止工具返回空,模型陷入重复调用打印每一轮消息日志设置最大轮数,规范工具返回结构,提示词增加停止条件
中文乱码编码配置不正确检查控制台和响应头编码统一 UTF-8,配置 Jackson 和 Spring MVC 编码
依赖冲突Spring AI 版本和 Spring Boot 版本不匹配查看 mvn dependency:tree 和启动日志统一使用官方 BOM,对齐版本号

10. 最佳实践与工程建议

10.1 循环与超时控制

Agent 的循环不是越快越好。单次模型调用有耗时的天然上限,工具调用也可能阻塞。生产环境建议做三层控制:

  • 单次模型调用超时,例如 30 秒。
  • Agent 总执行时间超时,例如 2 分钟。
  • 最大迭代轮数,一般建议 5 到 10 轮。

超时后要返回明确的降级文案,而不是让用户一直等待。

10.2 工具权限与安全边界

工具会执行真实业务代码。如果 Agent 可以调用订单、支付、退换货等敏感接口,必须做权限校验。基本原则是:模型只能决定“调用哪个工具”,不能决定“是否允许调用”。

写库、发消息、删除数据、支付这类高危操作,默认禁止 Agent 直接执行。必要场景下增加人工确认环节,遵循最小权限原则。所有工具调用都应该记录审计日志,包括输入参数、执行时间、执行结果和调用方。

不要在 system prompt 中写入密钥、数据库连接串或内部服务地址。模型输出可能被直接返回给用户,敏感信息会随响应泄漏。

10.3 可观测性与测试

Agent 的决策过程不可直接预测,所以可观测性比普通接口更重要。建议在每个节点记录状态摘要,在每次工具调用前后打印输入和输出摘要。线上环境可以在日志中打出 traceId,把同一轮 Agent 的多次模型调用和工具调用串联起来。

测试方面,不要只做端到端测试。为每个节点编写独立的单元测试,mock 模型调用结果,验证状态流转是否正确。为工具类编写真实测试,确保工具本身没有 bug。最后再写少量端到端测试,验证整张图能跑通。

10.4 从最小闭环开始

Agent 项目的复杂度是随着节点数量指数级增长的。建议按这个顺序推进:

  1. 先跑通 ChatClient 调用。
  2. 接入一个确定性工具,验证 @Tool 循环。
  3. 手动实现一个简单的 ReAct 循环,理解内部机制。
  4. 将流程重构为状态图,先 3 个节点,再逐步增加。
  5. 最后接业务知识库、RAG 或多 Agent 协作。

不要在第一天就规划十个节点的图。先把一个节点跑稳,再扩展成图,遇到问题也更容易定位。

11. 总结与后续学习方向

这篇文章讲清楚了四件事:Agent 的本质是“模型 + 循环 + 工具”,ReAct/Loop 是 Agent 的核心运转机制,Java 里通过 Spring AI Alibaba 可以低成本实现工具调用循环,Graph Engineering 通过节点、边、状态解决了 Agent 流程的可控性问题。

从实践角度来看,建议你今天就做一个小实验:用 Spring AI Alibaba 接入一个天气或订单类工具,让模型通过 @Tool 自动完成一次工具调用。跑通之后,再尝试把流程拆成三个节点,用 StateGraph 思路做一次图编排。

Agent 技术迭代很快,Spring AI Alibaba 的 API 也在持续演进。写代码时多参考官方文档和 release 日志,不要盲目照搬旧版本示例。如果团队正在选型,优先确认依赖版本兼容性,再对比具体实现方案。

工程化没有银弹,Agent 也不例外。先把最小闭环做稳,再谈复杂编排。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/14 13:05:55

SpringBoot集成Dubbo实战:服务拆分与RPC调用避坑指南

1. 从一个真实的服务拆分场景说起去年下半年&#xff0c;我接手了一个挺典型的改造项目。原本是一个单体架构的电商后台&#xff0c;订单、库存、用户、营销几个模块全塞在一个工程里&#xff0c;代码量到了后期&#xff0c;改一个订单状态流转的逻辑&#xff0c;得把整个项目重…

作者头像 李华
网站建设 2026/10/14 13:05:53

开源在线客服系统部署实战:架构、网关与高频坑位避让

简介&#xff1a;开源版在线客服管理系统源码包&#xff0c;面向需要快速搭建客户服务通道的中小企业、技术团队及独立开发者。系统以网页/移动端/社交媒体多渠道接入为核心&#xff0c;提供客服工作台、AI聊天机器人自动应答、客户信息管理、工单处理、数据报表分析、CRM/ERP集…

作者头像 李华
网站建设 2026/10/14 13:05:43

ENVI SAR数据预处理全流程:从斑点噪声抑制到地形校正

简介&#xff1a;这是一份面向遥感初学者与ENVI使用者的SAR数据预处理操作文档&#xff0c;围绕ALOS PALSAR数据&#xff0c;系统梳理了从数据导入、多视处理、滤波到地理编码与辐射定标&#xff0c;以及镶嵌匀色的完整流程。文档对每一步操作均给出面板路径、关键参数选取依据…

作者头像 李华
网站建设 2026/10/14 13:05:36

YOLO车辆检测训练指南:9767张数据集的格式整理与避坑

简介&#xff1a;面向YOLO系列算法训练与评估的车辆检测数据集&#xff0c;覆盖公交车、卡车、摩托车、行人、自行车、小型车六类目标&#xff0c;适合目标检测初学者及算法工程师快速开展模型训练、验证与测试&#xff0c;并可用于实际项目部署前的算法验证。数据集已按训练/验…

作者头像 李华
网站建设 2026/10/14 13:05:33

怀化二手车交易平台选择与风险防范指南

1. 怀化二手车市场现状与平台需求分析怀化作为湖南西部重要的交通枢纽城市&#xff0c;二手车交易市场近年来呈现稳定增长态势。随着私家车保有量持续上升&#xff0c;二手车流通需求日益旺盛&#xff0c;传统线下交易模式已无法完全满足买卖双方的需求。在这个背景下&#xff…

作者头像 李华
网站建设 2026/10/14 13:05:07

具身智能落地实践:从大模型任务规划到仿真部署避坑指南

简介&#xff1a;哈尔滨工业大学社会计算与信息检索研究中心的专题报告&#xff0c;聚焦大模型时代的具身智能。资源以图文形式梳理了从公元前9世纪偃师机器人、古希腊机械鸽到达芬奇人形草图&#xff0c;再到现代工业机器人、类人机器人的发展脉络&#xff0c;并阐释智能机器人…

作者头像 李华