资讯动态

Spring AI Alibaba ReAct Agent实战:从Tool Calling到Agent,企业AI复杂业务该如何设计?

发布时间:2026/8/16 16:41:26 来源:尧图企业网站定制
目录1. 为什么复杂业务任务需要Agent2. ReAct Agent到底是怎么工作的3. 实战设计一个订单异常处理Agent3.1 定义业务请求和返回对象4. 使用Spring AI Alibaba实现ReAct Agent4.1 引入Agent Framework4.2 创建订单查询Tool4.3 创建ReAct Agent4.4 执行Agent5. 一次完整任务到底是如何执行的6. 企业Agent真正难的不是“会调用”而是“可控”6.1 Agent必须有停止条件6.2 Tool调用失败不能让Agent自己猜6.3 查询型Tool和操作型Tool必须分级6.4 Agent必须可观测7. Agent和Workflow到底怎么选Workflow更适合什么Agent更适合什么企业项目中更常见的是混合模式前言如果只是让大模型回答问题现在的实现已经非常成熟。如果需要获取企业系统中的实时数据也可以通过 Tool Calling让模型调用订单、库存、物流、知识库等业务能力。但真正开始做企业 AI 项目后会遇到另一类需求用户给你的不是一个明确的操作而是一个目标。比如我的订单 A1001 三天没发货了帮我看看是什么原因如果是库存问题就帮我创建一个客服工单。这句话看起来简单但真正执行起来并不是调用一个接口就能完成。系统至少需要查询订单 ↓ 判断订单当前状态 ↓ 根据结果决定是否查询物流 ↓ 必要时继续查询库存 ↓ 判断异常原因 ↓ 决定是否创建工单 ↓ 汇总执行结果其中最关键的一点是后面执行哪一步并不能在任务开始前完全确定。如果订单已经发货下一步可能查询物流。如果订单还没出库下一步可能查询库存。如果库存正常又可能需要检查订单审核状态。执行路径依赖上一步的结果动态变化。这就是 Agent 开始发挥作用的地方。这篇文章不准备只演示如何创建一个ReactAgent而是通过一个企业订单异常处理场景完整看看Tool Calling 和 Agent 到底差在哪里ReAct Agent 如何完成多步骤任务Spring AI Alibaba 如何实现 ReAct AgentTool 应该如何设计企业项目为什么不能让 Agent 无限自主执行Agent 和 Workflow 到底应该怎么选。1. 为什么复杂业务任务需要Agent先从最简单的 Tool Calling 开始。用户问查询订单 A1001 当前是什么状态。模型只需要识别用户意图 ↓ 选择 queryOrder ↓ 生成 orderNoA1001 ↓ 执行 Tool ↓ 获得订单状态 ↓ 生成最终回答这是一个非常典型的 Tool Calling 场景。但是如果用户的问题变成我的订单 A1001 一直没有发货帮我查一下原因如果库存异常就创建客服工单。问题就发生了变化。因为模型在任务开始之前并不知道究竟需要调用几个 Tool。可能是queryOrder ↓ queryInventory ↓ createTicket也可能是queryOrder ↓ queryLogistics甚至查询一次之后就已经能够回答用户。这时候真正需要解决的问题已经不是调用哪个 Tool而是为了完成用户目标下一步应该做什么我现在更倾向于这样理解两者的区别Tool Calling解决的是“模型如何使用一个外部能力”。而Agent解决的是“模型如何围绕一个目标持续决定下一步行动”。Spring AI Alibaba 当前的ReactAgent本身就是按照这种循环方式执行模型进行决策需要外部能力时调用 Tool读取 Tool 返回结果后继续执行直到模型生成最终答案或者达到停止条件。2. ReAct Agent到底是怎么工作的ReAct 来自两个单词Reasoning Acting它的核心思想并不复杂。Agent 不要求模型第一次就生成完整答案而是允许它在任务执行过程中不断经历判断当前状态 ↓ 选择下一步行动 ↓ 执行行动 ↓ 观察执行结果 ↓ 再次判断直到任务完成。为了避免把 ReAct 理解得过于抽象我们直接套到订单场景里。用户订单 A1001 为什么还没发货如果是库存问题就创建一个客服工单。Agent 第一步需要获得订单信息Action queryOrder(A1001)Tool 返回订单状态待发货 商品SKUSKU-10086现在 Agent 获得了新的业务事实。下一步可能继续Action queryInventory(SKU-10086)得到可用库存0 预计补货时间2026-08-17这时候 Agent 才能确定订单无法发货与库存不足有关。然后根据用户最开始给出的目标Action createTicket(...)创建工单成功以后系统已经拥有足够信息最后再生成结果订单 A1001 当前处于待发货状态商品库存不足预计 8 月 17 日补货。我已经为该订单创建客服工单 T20260815001。这里真正重要的不是它调用了三个 Tool。而是第二个、第三个 Tool 是否执行是由前面 Tool 的结果决定的。这就是动态任务执行。3. 实战设计一个订单异常处理Agent理解执行方式以后再开始写代码。这次准备四个业务能力queryOrder queryInventory queryLogistics createTicket分别负责Tool作用queryOrder查询订单及商品信息queryInventory查询商品库存queryLogistics查询已发货订单物流createTicket创建客服工单这里有一个我认为非常重要的设计原则不要给 Agent 一个万能 Tool。例如直接设计processOrder(String orderNo)然后在方法内部查订单 查库存 查物流 创建工单技术上当然可以。但这样一来真正决定执行流程的其实还是 Java 代码。Agent 只是调用了一个传统业务接口并没有真正参与任务决策。更合理的方式是把稳定、明确的业务能力拆出来Agent ├── queryOrder ├── queryInventory ├── queryLogistics └── createTicket然后由 Agent 根据当前任务状态动态组合。但是 Tool 也不能拆得无限细。我一般会遵循一个Tool完成一个完整、明确、可审计的业务能力。比如queryOrder是合理的。但如果拆成queryOrderStatus queryOrderAmount queryOrderSku queryOrderCreateTime就很容易变成过度拆分。Tool 数量增加以后不仅增加模型选择难度Tool 名称、描述和输入 Schema 本身也都会成为模型调用上下文的一部分。Spring AI 官方也强调Tool 的名称、描述和参数 Schema 会帮助模型判断什么时候以及如何调用工具。3.1 定义业务请求和返回对象首先准备几个简单对象public record OrderQuery(String orderNo) { } public record OrderInfo(String orderNo, String skuId, String status) { } public record InventoryQuery(String skuId) { } public record InventoryInfo(String skuId, Integer availableStock, String expectedRestockTime) { } public record LogisticsQuery(String orderNo) { } public record LogisticsInfo(String orderNo, String status, String latestNode) { } public record TicketRequest(String orderNo, String reason) { } public record TicketResult(String ticketNo, String status) { }真实项目中这些对象背后可以继续调用MySQL Redis 订单中心 库存中心 物流服务 客服工单系统Agent 不需要知道底层数据从哪里来。它只需要知道我拥有哪些稳定的业务能力。4. 使用Spring AI Alibaba实现ReAct Agent当前 Spring AI Alibaba Agent Framework 可以直接通过ReactAgent.builder()创建 Agent并向 Agent 注册ToolCallback。官方文档也提供了FunctionToolCallback、Memory、Hooks 和 Interceptors 等扩展方式。4.1 引入Agent Framework以官方 Agent Framework 文档中的依赖方式为例dependency groupIdcom.alibaba.cloud.ai/groupId artifactIdspring-ai-alibaba-agent-framework/artifactId version${spring-ai-alibaba.version}/version /dependency模型 Starter 根据项目实际使用的模型选择。例如使用 DashScopedependency groupIdcom.alibaba.cloud.ai/groupId artifactIdspring-ai-alibaba-starter-dashscope/artifactId version${spring-ai-alibaba.version}/version /dependency实际项目建议通过 BOM 或统一版本变量管理依赖版本避免不同模块分别写死版本。4.2 创建订单查询Tool这里使用FunctionToolCallback。Component public class QueryOrderTool implements FunctionOrderQuery, OrderInfo { private final OrderService orderService; public QueryOrderTool(OrderService orderService) { this.orderService orderService; } Override public OrderInfo apply(OrderQuery request) { return orderService.queryOrder( request.orderNo() ); } }注册 ToolToolCallback queryOrderTool FunctionToolCallback.builder( queryOrder, queryOrderToolFunction) .description( 查询订单基础信息。 当需要确认订单是否存在、 当前订单状态以及订单对应商品时使用。 ) .inputType(OrderQuery.class) .build();Spring AI 会根据输入类型生成参数 Schema模型根据 Tool 名称、描述以及 Schema 判断如何调用工具。其他几个 Tool 采用相同方式ToolCallback queryInventoryTool FunctionToolCallback.builder( queryInventory, queryInventoryFunction) .description( 查询商品当前可用库存。 当需要判断订单是否因为库存不足 导致无法发货时使用。 ) .inputType(InventoryQuery.class) .build();物流ToolCallback queryLogisticsTool FunctionToolCallback.builder( queryLogistics, queryLogisticsFunction) .description( 查询已发货订单的物流状态。 仅当订单已经发货 需要确定物流进度时使用。 ) .inputType(LogisticsQuery.class) .build();创建工单ToolCallback createTicketTool FunctionToolCallback.builder( createTicket, createTicketFunction) .description( 为异常订单创建客服工单。 当已经确认订单存在异常 并且需要客服继续处理时使用。 不允许在没有明确异常原因时创建工单。 ) .inputType(TicketRequest.class) .build();这里尤其不要忽略 Tool Description。模型看不到createTicket()里面究竟有什么业务代码。它判断“什么时候调用”主要依赖的就是 Tool Definition。所以 Tool Description 本质上也是 Agent Prompt Engineering 的一部分。4.3 创建ReAct Agent准备系统指令String instruction 你是企业订单异常处理助手。 你的目标是帮助用户分析订单异常原因。 执行原则 1. 涉及实时订单信息时必须调用工具查询 不允许猜测订单状态。 2. 根据订单当前状态决定后续动作。 3. 未发货订单可以继续检查库存。 4. 已发货订单可以查询物流状态。 5. 只有确认存在需要人工继续处理的异常时 才允许创建客服工单。 6. 不允许伪造订单、库存、物流或工单信息。 7. 工具调用失败时明确告诉用户 不允许根据经验补全结果。 完成任务后向用户说明 - 当前订单状态 - 判断出的异常原因 - 已执行的处理动作 ;创建 AgentReactAgent orderAgent ReactAgent.builder() .name(order_exception_agent) .model(chatModel) .instruction(instruction) .tools( queryOrderTool, queryInventoryTool, queryLogisticsTool, createTicketTool ) .saver(new MemorySaver()) .build();到这里一个基础 ReAct Agent 就已经完成。4.4 执行Agent调用非常简单AssistantMessage response orderAgent.call( 我的订单A1001三天没有发货了 帮我看看是什么原因。 如果确认是库存异常 帮我创建一个客服工单。 ); System.out.println(response.getText());可能得到订单A1001当前状态为待发货。 经查询该订单商品SKU-10086当前可用库存为0 预计8月17日补货因此暂时无法正常发货。 已为该订单创建客服工单 T20260815001。 客服人员将继续跟进该订单。代码看起来并不复杂。但和普通 Tool Calling 相比真正发生变化的是执行流程不再完全由开发人员提前写死。5. 一次完整任务到底是如何执行的假设订单数据如下订单A1001 状态待发货 SKUSKU-10086库存SKU-10086 可用库存0 预计补货2026-08-17用户输入订单A1001一直没有发货 帮我查下什么原因。 如果库存有问题 就创建一个客服工单。Agent 第一次处理时并不知道订单是否存在 订单有没有发货 商品是什么 库存是否正常 是否真的需要创建工单因此第一步会调用queryOrder得到{ orderNo: A1001, skuId: SKU-10086, status: 待发货 }因为订单没有发货物流查询没有意义。Agent 可以继续选择queryInventory得到{ skuId: SKU-10086, availableStock: 0, expectedRestockTime: 2026-08-17 }现在才真正确定订单未发货 库存为0 库存异常用户又提前授权如果库存异常就创建客服工单。因此继续createTicket得到{ ticketNo: T20260815001, status: CREATED }信息已经足够Agent 停止调用 Tool生成最终回答。这就是一次完整的 ReAct 循环。这里也能看出Agent真正有价值的地方并不是“能够调用很多Tool”而是能够根据中间结果调整执行路径。如果订单第一次查询出来status 已发货那后面合理的路径就应该变成queryOrder ↓ queryLogistics ↓ 返回物流状态而不是继续查询库存和创建工单。同一个用户入口因为业务状态不同可以形成完全不同的执行链。6. 企业Agent真正难的不是“会调用”而是“可控”如果文章写到这里就结束其实只能算一个 Agent Demo。真正进入企业项目以后我认为 Agent 最难解决的问题并不是怎么让模型调用 Tool而是怎么保证它只在允许的范围里行动。6.1 Agent必须有停止条件ReAct 本质上是一个循环。正常情况Model ↓ Tool ↓ Model ↓ Tool ↓ Model ↓ Final Answer但异常情况下完全可能出现queryOrder ↓ queryInventory ↓ queryOrder ↓ queryInventory ↓ queryOrder ↓ ……如果没有控制就可能带来模型调用次数持续增加Token成本不断增加外部接口反复调用整体请求长时间不结束。Spring AI Alibaba 当前 Agent Framework 已经提供ModelCallLimitHook对模型调用次数进行限制用来避免失控循环和过高调用成本。例如ModelCallLimitHook modelCallLimit ModelCallLimitHook.builder() .runLimit(6) .build();加入 AgentReactAgent orderAgent ReactAgent.builder() .name(order_exception_agent) .model(chatModel) .instruction(instruction) .tools( queryOrderTool, queryInventoryTool, queryLogisticsTool, createTicketTool ) .hooks(modelCallLimit) .saver(new MemorySaver()) .build();实际生产中我还会在 Agent 外层增加整体 Timeout。最终形成Agent最大执行步数 模型调用限制 Tool自身Timeout 整个Agent链路Timeout多层控制。6.2 Tool调用失败不能让Agent自己猜真实企业环境一定会出现数据库超时 RPC失败 库存中心不可用 物流接口异常 参数错误 订单不存在 权限不足如果 Tool 抛异常以后直接把整个 Agent 打成 500用户体验很差。但另一种做法更危险Tool失败以后让模型自己推测结果。比如库存接口失败模型却回答大概率是库存不足。这是企业 AI 中必须避免的。更合理的是把错误转换成明确的 Tool ResultINVENTORY_SERVICE_UNAVAILABLE然后告诉模型当前无法确认库存情况不允许继续推断库存异常。Spring AI Alibaba 当前也提供 Tool Interceptor可用于工具错误处理、重试和失败结果转换官方还提供了ToolRetryInterceptor对适合重试的瞬时错误进行有限重试。但重试也不能无脑使用。例如queryInventory查询失败可以安全重试一次。而createTicket如果请求超时却不能直接判断“没有创建成功”。这时候首先应该依赖幂等Key 业务状态查询确认第一次是否已经成功再决定是否重试。这仍然是传统后端工程问题。Agent 并没有改变这一点。6.3 查询型Tool和操作型Tool必须分级我不会让所有 Tool 都拥有同样的执行权限。例如低风险查询订单 查询库存 查询物流 查询知识库通常经过身份和数据权限校验后可以允许 Agent 自动执行。中风险创建客服工单 生成报表 创建草稿 提交内部任务可以根据业务规则决定是否允许自动执行。高风险退款 删除数据 最终审批 修改权限 付款 批量修改我不会简单地通过 Prompt执行之前一定要询问用户。然后就认为系统安全了。因为 Prompt 是模型约束。真正的企业安全边界应该是代码权限 业务规则 审批/确认 审计高风险 Tool 最好通过 Human-in-the-loop 进行人工确认。Spring AI Alibaba 当前已经提供HumanInTheLoopHook可以针对特定 Tool 暂停 Agent 执行等待人工批准、修改或拒绝这种中断恢复需要配合持久化 Checkpointer 保存 Agent 状态。逻辑可以设计成Agent判断需要退款 ↓ 准备refund Tool Call ↓ 暂停 ↓ 人工/用户确认 ↓ 批准 ├── 否 → 取消 └── 是 → 真正执行refund这也是我认为企业 Agent 和 Demo Agent 最大的差别之一不是Agent越自主越高级。企业真正需要的是在可控边界内自主。6.4 Agent必须可观测传统接口出问题我们通常会看TraceId 接口耗时 SQL RPC 异常日志到了 Agent 场景还要再增加一层。至少应该能够知道一次Agent任务执行了多少步 调用了多少次模型 调用了哪些Tool Tool参数是什么 Tool执行是否成功 每一步耗时多少 整个Agent耗时多少 消耗多少Token 最终任务是否完成否则用户说AI昨天把一个订单处理错了。开发人员连它当时调用过什么Tool 为什么进入下一步 哪一个Tool返回异常都不知道就几乎没有办法定位问题。所以 Agent 真正生产化以后Tracing Tool Audit Token Usage Latency Success Rate都应该纳入监控。这也是后面做 Agent Evaluation 的基础。7. Agent和Workflow到底怎么选理解 Agent 以后另一个很容易出现的问题是既然 Agent 可以动态决定下一步是不是复杂业务全部交给 Agent 就行我认为恰恰相反。越是核心业务越不应该为了“智能”而强行Agent化。Workflow更适合什么如果业务流程天然确定创建订单 ↓ 参数校验 ↓ 库存锁定 ↓ 支付 ↓ 生成订单 ↓ 通知这类流程最重要的是稳定 可预测 可测试 可回滚显然 Workflow 更合适。Agent更适合什么如果只有目标明确但具体执行路径不确定分析这个订单为什么异常并根据情况给出处理方案。系统开始时不知道需要查订单 需要查物流 需要查库存 需要查规则 是否需要创建工单路径依赖运行时信息动态产生。这种场景 Agent 更合适。企业项目中更常见的是混合模式真正让我更认可的一种设计其实是Workflow ↓ 固定确定性流程 ↓ Agent ↓ 处理局部不确定任务 ↓ Human-in-the-loop ↓ Workflow继续执行例如一个售后流程用户提交售后申请 ↓ Workflow完成身份和订单校验 ↓ Agent分析问题与相关资料 ↓ Agent给出处理建议 ↓ 人工确认高风险操作 ↓ Workflow执行退款/换货 ↓ 记录审计结果这里确定的事情交给代码和Workflow。不确定的判断交给Agent。高风险决策交给人。这也是我现在理解企业 Agent 架构非常重要的一条原则Agent不是Workflow的替代品。它更像是给原来完全确定性的企业系统增加了一块能够处理不确定任务的动态决策能力。总结如果只是看代码创建一个 Spring AI AlibabaReactAgent并不复杂ReactAgent.builder() .name(order_exception_agent) .model(chatModel) .tools(...) .instruction(...) .build();真正困难的是代码之外的问题。什么时候应该调用 ToolTool 应该拆多细什么时候继续执行什么时候停止调用失败怎么办哪些 Tool 可以自动调用哪些操作必须人工确认Agent 和 Workflow 应该如何组合这些问题才决定一个 Agent 最后是一个能够演示的Demo。还是一个真正能够进入企业系统的AI能力。我现在更愿意把这几个概念理解成Tool Calling 让AI拥有“做事的能力” Agent 让AI能够围绕目标 动态决定“下一步做什么” Workflow 负责确定性的业务流程 Human-in-the-loop 负责控制高风险决策所以企业 AI 从 Tool Calling 走向 Agent并不是简单地多调用几个 Tool。真正发生的变化是我们开始把一部分原本必须提前写死在代码中的执行路径交给模型根据上下文动态决策。而企业级架构真正需要解决的则是另一半问题如何把这种不确定性限制在一个确定、可观测、可审计、可控制的边界之内。这才是 Agent 真正从 Demo 走向生产的开始。 推荐专栏️企业AI架构与实战从企业真实落地视角持续分享RAG、Agent、Workflow、AI Gateway、工程治理与系统架构设计。 https://blog.csdn.net/qupengkun/category_13192323.htmlJava转AI技术专栏从0到1学习AI应用开发持续分享Spring AI、RAG、Agent与企业级AI项目实战。 https://blog.csdn.net/qupengkun/category_13184360.htmlAI开源项目实战持续分享Java AI业务项目、AI Coding效率工具和工程治理实践。 https://blog.csdn.net/qupengkun/category_13189373.htmlAI转型日记记录一名10年Java开发者从传统后端转向AI应用开发的全过程。 https://blog.csdn.net/qupengkun/category_13183497.html‍ 关于作者QCoding专注AI应用开发与Java技术实践。持续分享Spring AI、RAG、Agent、企业级AI项目实战、架构设计与职业成长。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价