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+ 小伙伴加入学习,欢迎点击围观

面试考察点

  1. 概念广度:面试官想确认你脑子里有没有一张 "Agent 推理模式地图",别一提 Agent 就只蹦出 ReAct 三个字。起码得说出 ReAct、Plan-and-Execute、Reflexion、ReWOO、ToT 这几种主流模式,各自适合什么场景。

  2. 原理深度:问 ReAct "具体怎么实现",考的是你有没有真理解 Thought/Action/Observation 这套循环。Prompt 长什么样?模型怎么决定调哪个工具?循环啥时候停?这些细节都得心里有数。

  3. 工程落地:有没有用 Java 侧框架(Spring AILangChain4j)真跑过 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 系统其实就是这么个循环:

AI Agent 推理决策循环流程
AI Agent 推理决策循环流程

这张图里,"大脑怎么决策" 这一步,就是推理模式在管的事。各种模式的差别,无非是 "什么时候想、什么时候做、做错了要不要回头想" 的编排不同。

没有推理模式的 Agent,就是 "用户问 → LLM 直接答",碰到需要外部信息的场景就开始一本正经地胡说(幻觉)。有了推理模式,Agent 才能做到 "边想边查边改"。

二、5 种主流推理模式详解

1. ReAct:边想边做

ReAct Agent 思考行动观察循环
ReAct Agent 思考行动观察循环

  • 核心思想:推理和行动交替进行,每一步行动后都根据观察结果重新思考
  • 优点:灵活,能动态适应环境变化
  • 缺点:每一步都要调一次 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),不再需要文本解析
  • 框架执行工具后,把结果作为 tool role 的消息拼回对话历史,再发给模型
  • 循环直到模型不再返回 tool_calls,直接输出文本答案

这其实就是 ReAct 的 "工业化版本":Thought 变成模型内部推理,Action 变成 tool_calls,Observation 变成 tool 消息。套路一模一样,只是更稳、更省 Token。

面试时记得主动提一句 "现在主流是 Function Calling 实现,老那套 Prompt 驱动基本淘汰了",能体现你对技术演进的敏感度。

四、Java 代码实战

方式一:Spring AI 实现 ReAct 风格的 Tool Calling

Spring AIChatClient 注册了工具后,内部会自动跑 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 内部的执行流程是:

  1. 模型思考(Thought):需要查北京天气 → 返回 tool_call: getWeather("北京")
  2. 框架执行工具(Action + Observation):拿到 "北京 今天晴,25°C"
  3. 把 Observation 回填给模型,模型继续思考(Thought):25°C 该推荐穿什么
  4. 模型直接输出文本答案(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 有几个常见的坑(这些都是面试加分项):

  1. 死循环:模型可能反复调用同一个工具,或者陷入 "思考 → 行动 → 思考" 无限循环。必须设置 max_steps 兜底,一般设 5-10 步
  2. 工具描述不清@Tooldescription 写得太模糊,模型就会乱调用。工具描述要写清楚 "这个工具做什么、什么时候用、参数是什么"
  3. 上下文爆炸:每一步的 Thought/Action/Observation 都会累积进上下文,多轮后容易超出 Token 限制。需要做上下文压缩或滑动窗口
  4. 错误处理:工具调用失败怎么办?应该把错误信息返回给模型让它自己纠错(这正是 Reflexion 的思路),而不是直接抛异常
  5. 成本控制:ReAct 每步一次 LLM 调用,复杂任务成本飙升。可以考虑用小模型做工具选择,大模型做最终回答;或者切到 ReWOO 模式

面试高频追问

  1. ReAct 和 Function Calling 是什么关系?

    Function Calling 是 ReAct 的工业化实现方式。ReAct 是 "思想"(推理 + 行动交替),Function Calling 是 "载体"(用结构化 API 替代文本解析)。现代框架(Spring AILangChain4j)底层都用 Function Calling 实现 ReAct 循环。

  2. ReAct 和 Plan-and-Execute 怎么选?

    • 任务步骤少(<5 步)、不可预测、需要动态调整 → ReAct
    • 任务步骤多、流程清晰、需要全局规划 → Plan-and-Execute
    • 工程上常把两者组合:用 Plan-and-Execute 做骨架,每个子任务内部用 ReAct 执行
  3. 如何评估一个 ReAct Agent 的效果?

    • 任务成功率(最核心)
    • 平均步数(越少越说明推理高效)
    • 工具调用准确率(参数对不对)
    • Token 消耗(成本指标)
    • 可以用 AgentBenchToolBench 等基准测试集
  4. 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 AILangChain4j)通过 Function Calling 把 ReAct 循环自动化了,开发者注册个 @Tool,框架自己跑循环。面试时把 ReAct 的循环机制、Prompt 结构、Function Calling 演进讲清楚,再甩段 Java 代码,这道题基本就拿下了。