Agent 推理模式有哪些?ReAct 具体是怎么实现的?
一则或许对你有用的小广告
欢迎加入小哈的星球,你将获得:专属的实战项目(4个项目都能学) / 1v1 提问 / 简历修改 / Java 学习路线 / 社群讨论 / 学习打卡 / 每月赠书
《Spring AI 项目实战(问答机器人、RAG 智能客服、联网搜索)》已完结,基于
Spring AI + Spring Boot 3.x + JDK 21...,查看介绍《从零手撸:仿小红书(微服务架构)》 已完结,基于
Spring Cloud Alibaba + Spring Boot 3.x + JDK 17...,查看介绍;演示链接:http://116.62.199.48:7070/《从零手撸:前后端分离博客项目(全栈开发)》 2 期已完结,演示链接:http://116.62.199.48/
新开坑项目:《从零手撸:秒杀系统高并发优化实战》 正在更新中...,查看介绍
截止目前,星球内专栏累计输出 150w+ 字,讲解图 5110+ 张,还在持续爆肝中.. 后续还会上新更多项目,已有 4700+ 小伙伴加入学习,欢迎点击围观
面试考察点
-
概念广度:面试官想确认你脑子里有没有一张 "Agent 推理模式地图",别一提 Agent 就只蹦出 ReAct 三个字。起码得说出 ReAct、Plan-and-Execute、Reflexion、ReWOO、ToT 这几种主流模式,各自适合什么场景。
-
原理深度:问 ReAct "具体怎么实现",考的是你有没有真理解 Thought/Action/Observation 这套循环。Prompt 长什么样?模型怎么决定调哪个工具?循环啥时候停?这些细节都得心里有数。
-
工程落地:有没有用 Java 侧框架(
Spring AI、LangChain4j)真跑过 Tool Calling?知不知道现在框架已经把 ReAct 循环自动化了?这块一问就知道你是纸上谈兵还是真上手做过。
核心答案
推理模式说白了就是大模型 "怎么想、怎么做、做错了怎么改" 的几种套路。主流的有 5 种:
| 推理模式 | 核心思想 | 适用场景 | 代价 |
|---|---|---|---|
| ReAct | 推理 + 行动交替进行(想一步,做一步) | 动态、不可预测的任务 | 中等,步数多时易跑偏 |
| Plan-and-Execute | 先做全局规划,再分步执行 | 长流程、结构化任务 | 规划成本高,但执行稳定 |
| Reflexion | 在 ReAct 基础上加自我反思 | 需要反复纠错的任务 | 多轮反思,Token 消耗大 |
| ReWOO | 一次性规划完所有步骤,减少 LLM 调用 | 工具调用多的任务 | 省钱省时,但灵活性差 |
| Tree of Thoughts (ToT) | 树形探索多条推理路径,可回溯 | 复杂搜索、谜题类任务 | 计算量极大 |
ReAct(Reasoning + Acting) 是最经典、用得最多的一种。它让大模型在处理任务时,交替地 "思考(Thought)" 和 "行动(Action)",再根据拿到的 "观察(Observation)" 决定下一步,组成一个紧凑的循环。
一句话:ReAct = CoT(链式思考)+ Tool Use(工具调用),两个拼一块儿。
深度解析
一、为什么需要推理模式?先看 Agent 到底在干嘛
讲具体模式前,先把底层逻辑理一下。一个 Agent 系统其实就是这么个循环:
这张图里,"大脑怎么决策" 这一步,就是推理模式在管的事。各种模式的差别,无非是 "什么时候想、什么时候做、做错了要不要回头想" 的编排不同。
没有推理模式的 Agent,就是 "用户问 → LLM 直接答",碰到需要外部信息的场景就开始一本正经地胡说(幻觉)。有了推理模式,Agent 才能做到 "边想边查边改"。
二、5 种主流推理模式详解
1. ReAct:边想边做
- 核心思想:推理和行动交替进行,每一步行动后都根据观察结果重新思考
- 优点:灵活,能动态适应环境变化
- 缺点:每一步都要调一次 LLM,Token 消耗大;步数多时容易陷入死循环
- 适用场景:信息检索、客服问答、网页浏览等动态任务
2. Plan-and-Execute:先规划后执行
- 核心思想:先用一个 Planner LLM 生成完整的步骤计划,再用 Executor 逐步执行
- 优点:全局视角强,适合长流程任务;执行阶段可以用小模型省钱
- 缺点:计划一旦定下就难调整,遇到突发情况不够灵活
- 适用场景:数据分析报告、多步骤工作流、多 Agent 编排
3. Reflexion:自我反思
- 核心思想:在 ReAct 基础上,任务失败后让 Agent "反思" 自己哪儿做错了,把经验存进记忆,下次重试
- 优点:能从失败中学习,适合对准确率要求高的任务
- 缺点:多轮重试成本高
- 适用场景:代码生成、数学推理、需要打磨质量的任务
4. ReWOO:一次规划完所有调用
- 核心思想:Plans-without-Execution,第一步就让 LLM 把所有要调用的工具、参数、依赖关系全写出来,后面用轻量执行器跑完,最后一次性把所有结果喂给 LLM 生成答案
- 优点:LLM 只调用 1-2 次,极大降低成本和延迟
- 缺点:不能根据中间结果动态调整
- 适用场景:流程相对固定、工具调用链明确的任务
吐槽一句:不少读者跟我抱怨过,做企业项目时老板眼睛就盯着 "Token 成本",而 ReAct 多轮调用是真烧钱。ReWOO 就是冲着这个痛点来的,代价是灵活性差了点。工程上哪有银弹。
5. Tree of Thoughts (ToT):树形探索
- 核心思想:把推理过程组织成一棵树,每个节点是一个 "思考状态",可以并行探索多条路径,支持回溯
- 优点:能解决需要全局搜索的复杂问题(如 24 点游戏、填字游戏)
- 缺点:计算量爆炸,实用场景有限
- 适用场景:科研探索、博弈类任务
三、ReAct 具体怎么实现的?(重点)
ReAct 的实现有两种主流方式:
- Prompt 驱动的经典实现:通过 Few-shot Prompt 教 LLM 输出固定格式(Thought/Action/Observation),框架解析文本去执行
- Function Calling 原生实现:现代 LLM(GPT-4、Claude、Qwen 等)原生支持 Tool Calling,框架直接用 API 的
tool_calls字段,不用再解析文本
分开说。
1. Prompt 驱动的经典实现
ReAct 原论文( Yao et al., 2022 )的 Prompt 是 Few-shot 形式,长这样(简化版):
Question: 科罗拉多造山运动延伸到的地区海拔范围是多少?
Thought 1: 我需要搜索科罗拉多造山运动,找到它延伸到的地区,然后查找该地区的海拔范围。
Action 1: Search[科罗拉多造山运动]
Observation 1: 科罗拉多造山运动是 ... 延伸到了高地地区。
Thought 2: 它延伸到了高地地区。我需要搜索高地地区的海拔范围。
Action 2: Search[高地地区]
Observation 2: 高地地区的海拔范围是 1800-2400 米。
Thought 3: 高地地区的海拔范围是 1800-2400 米。
Action 3: Finish[1800-2400 米]
几个关键点(面试官最爱抠这些):
- Thought 是模型的 "内心戏",本质上就是 CoT 链式思考,强迫模型把推理过程写出来,减少幻觉
- Action 是模型决定调用的工具,格式固定为
工具名[参数],方便框架用正则解析 - Observation 是工具执行后的返回值,会被拼回 Prompt 的下一轮
- Finish 是终止信号,表示可以输出最终答案了
- 循环终止条件有三种:遇到
Finish、达到最大步数(防止死循环)、或工具调用出错
整个循环的伪代码:
1. 用 Few-shot Prompt 初始化 LLM 上下文
2. while not finished and step < MAX_STEPS:
3. output = LLM(prompt) # 模型输出 Thought + Action
4. action = parse(output) # 解析出要调用的工具和参数
5. if action.name == "Finish": # 终止
6. return action.input
7. observation = tools[action.name](action.input) # 执行工具
8. prompt += output + observation # 拼接进上下文
9. step += 1
2. Function Calling 原生实现(现代方式)
Prompt 驱动有个硬伤:模型经常吐出格式不对的文本,解析直接挂掉。2023 年 OpenAI 推出 Function Calling 后,主流做法变成了:
- 框架把工具用 JSON Schema 描述好,随 API 请求一起发给模型
- 模型直接在响应里返回
tool_calls字段(结构化 JSON),不再需要文本解析 - 框架执行工具后,把结果作为
toolrole 的消息拼回对话历史,再发给模型 - 循环直到模型不再返回
tool_calls,直接输出文本答案
这其实就是 ReAct 的 "工业化版本":Thought 变成模型内部推理,Action 变成 tool_calls,Observation 变成 tool 消息。套路一模一样,只是更稳、更省 Token。
面试时记得主动提一句 "现在主流是 Function Calling 实现,老那套 Prompt 驱动基本淘汰了",能体现你对技术演进的敏感度。
四、Java 代码实战
方式一:Spring AI 实现 ReAct 风格的 Tool Calling
Spring AI 的 ChatClient 注册了工具后,内部会自动跑 ReAct 循环(模型返回 tool call → 执行工具 → 结果回填 → 再次调用模型),开发者不用手写循环。
Maven 依赖(Spring AI 1.0 / 2.0):
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-model-openai</artifactId>
</dependency>
定义工具(用 @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) {
// 实际项目中这里调天气 API
return city + " 今天晴,25°C,微风";
}
@Tool(description = "查询股票实时价格")
public String getStockPrice(@ToolParam(description = "股票代码") String code) {
return code + " 当前价格 88.50 元,涨 2.3%";
}
}
调用 ChatClient(自动 ReAct 循环):
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class AgentService {
private final ChatClient chatClient;
private final WeatherTools weatherTools;
@Autowired
public AgentService(ChatClient.Builder builder, WeatherTools weatherTools) {
this.chatClient = builder.build();
this.weatherTools = weatherTools;
}
public String ask(String question) {
return chatClient.prompt()
.user(question)
.tools(weatherTools) // 注册工具,Spring AI 自动跑 Thought→Action→Observation 循环
.call()
.content();
}
}
问一句 "北京天气怎么样?适合穿什么?",Spring AI 内部的执行流程是:
- 模型思考(Thought):需要查北京天气 → 返回
tool_call: getWeather("北京") - 框架执行工具(Action + Observation):拿到 "北京 今天晴,25°C"
- 把 Observation 回填给模型,模型继续思考(Thought):25°C 该推荐穿什么
- 模型直接输出文本答案(Finish)
这就是一个完整的 ReAct 循环,只是被框架封装成了一行 .tools(weatherTools)。
方式二:LangChain4j 的 AI Service 实现
LangChain4j 的 AI Service 更接近 "声明式 Agent",定义一个接口就能自动获得 ReAct 能力。
Maven 依赖:
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-open-ai-spring-boot-starter</artifactId>
<version>1.0.0</version>
</dependency>
定义工具:
import dev.langchain4j.agent.tool.Tool;
import dev.langchain4j.agent.tool.P;
import org.springframework.stereotype.Component;
@Component
public class WeatherTools {
@Tool("查询指定城市的实时天气")
public String getWeather(@P("城市名") String city) {
return city + " 今天晴,25°C";
}
}
声明 AI Service 接口:
import dev.langchain4j.service.SystemMessage;
import dev.langchain4j.service.UserMessage;
import dev.langchain4j.service.spring.AiService;
@AiService
public interface WeatherAgent {
@SystemMessage("你是一个天气助手,可以查询天气并给出穿衣建议")
String chat(@UserMessage String userMessage);
}
自动注入即可使用(LangChain4j 的 Spring Boot Starter 会自动扫描 @Tool Bean 并注册到 AI Service):
@Autowired
private WeatherAgent weatherAgent;
public String ask() {
return weatherAgent.chat("上海今天适合穿什么?");
}
LangChain4j 底层也会自动跑 ReAct 循环,开发者基本不用操心这些细节。
两个框架的对比:
Spring AI是 Spring 官方亲儿子,和 Spring 生态深度融合;LangChain4j社区更活跃,API 设计更接近 Python 版 LangChain。生产环境选哪个都行,看团队技术栈。
五、ReAct 的坑与最佳实践
实际落地中,ReAct 有几个常见的坑(这些都是面试加分项):
- 死循环:模型可能反复调用同一个工具,或者陷入 "思考 → 行动 → 思考" 无限循环。必须设置
max_steps兜底,一般设 5-10 步 - 工具描述不清:
@Tool的description写得太模糊,模型就会乱调用。工具描述要写清楚 "这个工具做什么、什么时候用、参数是什么" - 上下文爆炸:每一步的 Thought/Action/Observation 都会累积进上下文,多轮后容易超出 Token 限制。需要做上下文压缩或滑动窗口
- 错误处理:工具调用失败怎么办?应该把错误信息返回给模型让它自己纠错(这正是 Reflexion 的思路),而不是直接抛异常
- 成本控制:ReAct 每步一次 LLM 调用,复杂任务成本飙升。可以考虑用小模型做工具选择,大模型做最终回答;或者切到 ReWOO 模式
面试高频追问
-
ReAct 和 Function Calling 是什么关系?
Function Calling 是 ReAct 的工业化实现方式。ReAct 是 "思想"(推理 + 行动交替),Function Calling 是 "载体"(用结构化 API 替代文本解析)。现代框架(
Spring AI、LangChain4j)底层都用 Function Calling 实现 ReAct 循环。 -
ReAct 和 Plan-and-Execute 怎么选?
- 任务步骤少(<5 步)、不可预测、需要动态调整 → ReAct
- 任务步骤多、流程清晰、需要全局规划 → Plan-and-Execute
- 工程上常把两者组合:用 Plan-and-Execute 做骨架,每个子任务内部用 ReAct 执行
-
如何评估一个 ReAct Agent 的效果?
- 任务成功率(最核心)
- 平均步数(越少越说明推理高效)
- 工具调用准确率(参数对不对)
- Token 消耗(成本指标)
- 可以用
AgentBench、ToolBench等基准测试集
-
ReAct 中的 Thought 真的有用吗?
有用。Thought 说白了就是 CoT,逼着模型把推理过程写出来,能减少幻觉、让工具选得更准。原论文做过实验:把 Thought 去掉只留 Action,效果掉得明显。
常见面试变体
- "说一下 ReAct 的原理,以及它解决了什么问题?"
- "ReAct、Plan-and-Execute、Reflexion 这三种 Agent 架构有什么区别?"
- "你在项目里是怎么实现 Tool Calling 的?用的是哪种推理模式?"
- "为什么需要 Reflexion?ReAct 不能自我纠错吗?"
记忆口诀
五大模式记一句话:ReAct 边想边做、Plan-Execute 先规划、Reflexion 会反思、ReWOO 一次规划、ToT 树形搜索。
ReAct 循环三件套:Thought(思考)→ Action(行动)→ Observation(观察),循环到 Finish 为止。
总结
推理模式管的就是大模型 "什么时候想、什么时候做、做错了怎么办" 的编排,主流五种:ReAct、Plan-and-Execute、Reflexion、ReWOO、ToT。ReAct 最经典、工程上用得最多,核心就是 Thought/Action/Observation 这套循环。现在 Java 框架(Spring AI、LangChain4j)通过 Function Calling 把 ReAct 循环自动化了,开发者注册个 @Tool,框架自己跑循环。面试时把 ReAct 的循环机制、Prompt 结构、Function Calling 演进讲清楚,再甩段 Java 代码,这道题基本就拿下了。
