图片

让Java开发者像写Spring Boot一样开发AI应用——第四课

写在前面

前三天,我们学会了创建单Agent、理解ReAct循环、构建多Agent协作系统。

但有一个问题始终在困扰着许多开发者:ReAct Agent运行时,为什么经常“原地打转”?

明明已经查过天气了,它又查一遍;明明已经得到答案了,它还在继续思考。

这不是你的代码写错了,而是ReAct模式本身存在结构性缺陷。

今天的课,我们不仅要解剖ReAct的三大缺陷,还要引入另一种截然不同的思考方式——Plan-and-Execute,并告诉你什么时候该用哪种模式。

一、ReAct的困境:为什么Agent会“原地打转”?

先快速回顾ReAct的核心循环:

Thought(思考)→ Action(行动)→ Observation(观察)→ Thought → …

ReAct将推理(Reasoning)和行动(Acting)相结合,通过持续观察环境反馈动态调整决策路径。它的本质是:CoT(思维链)+ 工具调用 + 环境反馈闭环。

就像一个经验丰富的老医生——问一句、查一下、想一想,再决定下一步怎么做。

但问题也恰恰出在这里。

缺陷一:无限循环(Infinite Loop)

ReAct最致命的缺陷:Agent可能陷入Thought→Action→Observation的死循环,反复执行相同的操作而无法推进任务。

<span leaf=""><span>Thought</span><span>:&nbsp;</span>我需要查天气</span>

为什么会发生?

  • 模型“忘记”了自己已经做过什么

  • 模型对当前进度缺乏清晰的认知

  • 没有内置的“停止”机制

💡 解决方案:设置最大迭代次数(recursion limit),通常25-30次是合理阈值。

缺陷二:上下文爆炸(Context Explosion)

ReAct的每一步Thought→Action→Observation都会追加到上下文中。随着循环次数增加,上下文越来越长,最终导致:

  • Token消耗激增

  • 触发上下文窗口限制

  • “关键信息遗忘” (Lost in the Middle)问题

💡 就像一个人不停地往背包里塞东西——背包越来越重,最后连钥匙都找不到了。

缺陷三:缺乏全局规划视角

ReAct的“规划”仍是单路径、线性的——它不能并行探索多条方案,也不能在推理链死胡同时回溯。每一步只考虑当前信息,缺乏对整体任务的全盘把握。

💡 提示:ReAct就像一个没有地图的探险家——边走边看,遇到岔路就随机选一条。运气好能走出来,运气不好就在原地打转。

ReAct缺陷总结

| 缺陷

|

表现

|

后果

无限循环

反复执行相同操作

|

任务永远无法完成,API额度刷光

| | 上下文爆炸 |

每一步都追加到上下文

|

Token消耗激增,关键信息丢失

| | 缺乏全局视角 |

每一步只考虑当前信息

|

容易“走弯路”,路径低效

|

ReAct仍然适用的场景

尽管有上述缺陷,ReAct在以下场景中仍然是最佳选择:

  • 动态环境:需要实时响应环境变化的任务(如实时故障修复、股票交易)

  • 探索性任务:解决方案路径不明确,需要边试边找

  • 对话式交互:用户与Agent多轮对话的场景

  • 工具数量有限:工具集在3-5个以内

二、Plan-and-Execute:换个思路解决问题

Plan-and-Execute模式的哲学很简单:先把整个任务想明白,拆解成有序的步骤,然后逐步执行。

<span leaf="">用户输入 → Planner(规划器)生成完整计划 → Executor(执行器)按步骤执行 → 输出结果</span>

两个核心角色

| 角色

|

职责

|

特点

Planner(规划器)

根据用户输入生成详细的任务规划和执行方案

| “想”

 ,不调用工具

| | Executor(执行器) |

依据规划内容执行具体任务

| “做”

 ,按计划调用工具

|

完整流程

第一步:规划阶段(Planning)

Planner Agent接收用户目标,生成一个结构化的任务计划:

<span leaf="">{</span>

第二步:执行阶段(Execution)

Executor按计划逐步执行,每一步可调用工具。如果步骤之间相互独立,还可以并行执行。

第三步:(可选)重规划阶段(Replanning)

如果某一步执行失败或环境发生变化,可以触发Replanner重新规划后续步骤。

Plan-and-Execute的优缺点

优点:

| 优点

|

说明

结构清晰

计划一目了然,便于人类理解和调试

| | 避免死循环 |

执行路径由计划决定,不会无限循环

| | 执行效率高 |

大模型只在规划和重规划时被调用

| | 支持并行 |

独立步骤可并行执行,显著缩短总耗时

| | 资源可控 |

可预先评估计算成本

|

缺点:

| 缺点

|

说明

计划可能失真

前期信息不足时,计划可能与真实环境脱节

| | 动态调整弱 |

执行过程中的动态调整和容错能力较弱

| | 灵活性不足 |

偏向静态工作流,难以应对突发变化

| | 单轮对话限制 |

部分实现不支持基于历史上下文的多轮对话

|

Plan-and-Execute的适用场景

  • 步骤繁多、逻辑依赖明确的长期复杂任务

  • 任务可以预先分解为清晰的子任务

  • 对实时性要求较低但对内容丰富度要求较高的任务(如深度分析报告、长篇网页生成)

  • 批量数据处理等静态环境任务

三、ReAct vs Plan-and-Execute:全面对比

核心差异对比表

| 对比维度

|

ReAct模式

|

Plan-and-Execute模式

规划方式

动态生成,每轮迭代更新

|

一次性生成,执行前固定

| | 执行方式 |

边想边做,循环迭代

|

先想后做,按计划执行

| | 工具调用 |

按需调用,可能重复调用

|

按计划调用,顺序明确

| | 状态管理 |

实时更新环境状态

|

仅在计划失败时更新状态

| | 失败处理 |

通过循环自动修正

|

需显式设计重试/回滚机制

| | 环境适应性 |

优秀(动态环境)

|

一般(静态环境更高效)

| | 死循环风险 | | | | 上下文增长 |

线性累积,易爆炸

|

可控

|

性能数据参考

在某自动化测试场景中,Plan-and-Execute模式相比ReAct:

  • 任务完成率提升27%

  • 工具调用次数减少42%

  • 平均执行时间缩短35%

选型决策树

<span leaf="">开始:我有一个任务要交给Agent</span>

💡 核心观点:ReAct和Plan-and-Execute不是二选一的关系,而是两个不同粒度的策略。实战中最好的做法是混合使用——Plan-and-Execute做全局规划,ReAct做每步内的灵活执行。

四、Spring AI Alibaba Graph:底层工作流引擎

在深入代码之前,需要了解一个关键事实:Spring AI Alibaba的Agent Framework底层运行在Graph Runtime之上。

Graph是什么?

Graph是一个低级别的工作流和多智能体编排框架,能够帮助开发者实现复杂的应用程序编排。在底层,Spring AI Alibaba框架会将Agent编排为Graph,组成一个由节点串联而成的DAG(有向无环图)。

Graph的三大核心概念

| 概念

|

说明

状态(State)

在Node与Edge之间传递的数据结构,是一个Map<String, Object>

| | 节点(Node) |

执行逻辑单元,接受State作为输入,执行操作后返回更新的State

| | 边(Edge) |

定义Node间的控制流,可为固定连接或条件分支

|

💡 一句话总结:Node完成工作,Edge告诉下一步该做什么。

Graph的核心能力

  • 流式输出(Streaming) :将每个节点的运行情况实时发送到客户端

  • 人机协同(Human In The Loop) :允许对Agent运行过程中的工具调用进行评估、修改、批准

  • 记忆管理(Memory & Context) :处理短期记忆(会话内)和长期记忆(跨会话)

Agentic API vs Graph API

| | Agentic API

|

Graph API

抽象层次

高层声明式API

|

底层原子化API

| | 使用方式 |

使用预置的Agent模式

|

独立定义每个Node和Edge的逻辑

| | 控制粒度 |

粗粒度

| 细粒度,完全控制 | | 适用场景 |

大多数Agent应用开发

|

需要超高可靠性、大量自定义逻辑的场景

| | 上手难度 | |

中高

|

💡 推荐策略:优先使用Agent Framework内置的Agent抽象(ReactAgent、SequentialAgent、ParallelAgent等)。只有当需要更灵活的编排、更直接的状态控制时,才考虑直接使用Graph API。

五、代码实战:对比两种方案

实战一:用ReAct模式实现“旅行规划Agent”

<span leaf=""><span>@Service</span></span>

观察点:

  • 观察Agent的Thought→Action→Observation循环日志

  • 记录工具调用次数和总耗时

  • 注意Agent是否出现“重复查询”或“循环”现象

实战二:用SequentialAgent模拟Plan-and-Execute

<span leaf=""><span>@Configuration</span></span>

对比结果

| 对比维度

|

ReAct模式

|

Plan-and-Execute模式

执行路径

动态循环,路径不确定

|

固定顺序,路径清晰

| | 工具调用次数 |

可能重复调用

|

按计划调用,无重复

| | 总耗时 |

较长(多次模型调用)

|

较短(2次模型调用+工具执行)

| | 回复质量 |

灵活但可能遗漏信息

|

结构完整,覆盖全面

| | 可调试性 |

较难(路径不确定)

|

容易(计划即文档)

|

六、Spring AI Alibaba中的混合实践

如前所述,实战中最好的做法是混合使用:

<span leaf="">用户需求 → Planner(全局规划)→ 步骤1(ReAct执行)→ 步骤2(ReAct执行)→ ... → 最终结果</span>

混合模式的优势:

  • Planner提供全局视角,避免ReAct“走弯路”

  • 每个步骤内的ReAct提供灵活性,应对局部变化

  • 既有结构又有弹性

Spring AI Alibaba中的实现方式:

  1. 使用SequentialAgent串联多个Agent

  2. 每个子Agent可以是ReActAgent(带工具)

  3. 第一个Agent作为Planner(不带工具,只生成计划)

  4. 后续Agent作为Executor(带工具,执行计划中的各步骤)

这种模式在Spring AI Alibaba的OpenManus实现中已有体现——Planning Agent负责任务分解,多个Manus Agent组成链式可顺序执行的子工作流。

七、观后挑战

任务:分析你的业务场景,判断更适合哪种Agent架构模式

分析框架:

| 分析维度

|

你的答案

任务目标是什么?

| | |

任务步骤是否可以预先明确?

| | |

是否需要实时响应环境变化?

| | |

任务步骤是否繁多(>5步)?

| | |

子任务之间是否可以并行?

| | |

推荐使用哪种模式?为什么?

| |

验收标准:

  • 完成了6个维度的场景分析

  • 给出了明确的模式选择建议及理由

  • 针对所选模式的缺陷提出了应对方案

  • 如果能画出架构图(可选加分)

八、本日核心收获

  1. ReAct有三大缺陷:无限循环、上下文爆炸、缺乏全局视角

  2. Plan-and-Execute是另一种思路:先全局规划,再逐步执行

  3. 两者不是二选一,而是可以混合使用的策略

  4. Spring AI Alibaba Graph是底层工作流引擎,提供State、Node、Edge三大核心概念

  5. 选型决策:动态环境→ReAct;静态复杂任务→Plan-and-Execute;最稳妥→混合模式

📌 本文要点回顾:ReAct是“一步一想”,Plan-and-Execute是“先全局规划,再逐步执行”。前者适合探索性任务,后者适合确定性任务。而实战中最好的做法是混合使用——Plan-and-Execute做全局规划,ReAct做每步内的灵活执行。理解这两种模式的区别和各自的适用场景,是Agent架构设计的关键一步。

有任何问题,欢迎在评论区留言交流!


作者:Java老兵搞AI,专注Java生态下的AI应用开发

如果觉得有用,点个「在看」支持一下吧