从 ReAct 框架到底层心智模型,彻底理解 AI Agent 是如何"思考"和"行动"的。


目录


4.1 ReAct 框架深度解析

什么是 ReAct?

ReAct = Reasoning + Acting(推理 + 行动),是当前 AI Agent 领域最主流的框架范式。它由 Google Research 在 2022 年提出,核心思想是让大语言模型在推理(Thought)行动(Action)之间交替循环,从而能够处理需要与外部世界交互的复杂任务。

ReAct 解决了一个根本问题:纯语言模型被困在"知识截止日期"里,而 ReAct 让模型"长出双手",可以主动获取信息、操作工具、观察反馈,再据此调整下一步策略。

ReAct 的核心循环

ReAct 的工作流程可以用一个经典的 Thought → Action → Observation 循环来描述:


💡 图片说明:ReAct 核心循环流程图。任务进入后,Agent 进入"思考 → 行动 → 观察"的循环,直到判断任务完成,输出最终答案。

每一步的含义:

阶段 英文 核心问题 示例
💭 Thought 推理 "我现在知道什么?下一步该做什么?" "用户问的是北京天气,我需要调用天气 API"
🔧 Action 行动 "我具体执行什么操作?用什么工具?" get_weather(city="Beijing")
👁️ Observation 观察 "工具返回了什么?我获得了什么新信息?" {"temp": 25, "weather": "晴"}

完整的 ReAct 示例

让我们通过一个实际案例,看看 ReAct 如何一步步解决"查找北京今天的气温,并判断是否需要带伞"这个问题:


💡 图片说明:一个完整的 ReAct 两轮循环示例。第一轮获取天气数据,第二轮判断不需要带伞并给出最终答案。

完整对话流程如下:

用户: 北京今天需要带伞吗?
​
💭 Thought 1: 用户想知道北京今天是否需要带伞。我需要先查询北京当前的天气情况。
🔧 Action 1: get_weather(city="北京")
👁️ Observation 1: { "temperature": 25, "weather": "多云", "humidity": 65% }
​
💭 Thought 2: 当前北京多云,温度25°C,湿度65%。多云意味着不太可能下雨,65%的湿度也不算极端。综合判断,不需要带伞。
📝 Final Answer: 今天北京多云,气温25°C,湿度65%,不需要带伞。☀️

ReAct 的代码实现

下面是一个 ReAct Agent 的最简实现,用 Python 展示核心逻辑:

import json
from typing import Any, Callable
​
class ReActAgent:
    """
    ReAct Agent 的最小实现
    核心循环:Thought → Action → Observation → 判断是否终止
    """
​
    def __init__(self, llm: Callable, tools: dict[str, Callable], max_steps: int = 10):
        """
        Args:
            llm: 大语言模型调用函数,接收消息列表,返回模型响应文本
            tools: 工具字典,key 是工具名,value 是可调用的工具函数
            max_steps: 最大循环步数,防止无限循环
        """
        self.llm = llm
        self.tools = tools
        self.max_steps = max_steps
​
    def run(self, query: str) -> str:
        """
        执行 ReAct 循环,返回最终答案。
​
        Args:
            query: 用户的问题 / 任务
​
        Returns:
            最终答案文本
        """
        # 初始化对话历史,system prompt 定义了 ReAct 的行为规范
        messages = [
            {
                "role": "system",
                "content": """你是一个 ReAct Agent。请按以下格式响应:
​
Thought: 你的推理过程——分析当前状态,决定下一步行动。
Action: 要调用的工具名称
Action Input: 传递给工具的 JSON 参数
Observation: 工具返回的结果(由系统填入)
​
当任务完成时,请用以下格式给出最终答案:
Thought: 我已收集到足够信息。
Final Answer: 最终答案内容
"""
            },
            {"role": "user", "content": query}
        ]
​
        step = 0
​
        # ─────────── ReAct 核心循环 ───────────
        while step < self.max_steps:
            step += 1
            print(f"\n{'='*50}")
            print(f"📍 Step {step}")
            print(f"{'='*50}")
​
            # 1️⃣ 调用 LLM,获取模型响应
            response = self.llm(messages)
            messages.append({"role": "assistant", "content": response})
            print(f"🤖 LLM 响应:\n{response}")
​
            # 2️⃣ 解析:判断是 Final Answer 还是 Action
            if "Final Answer:" in response:
                # 任务完成,提取并返回最终答案
                final = response.split("Final Answer:")[-1].strip()
                print(f"✅ 任务完成!")
                return final
​
            if "Action:" in response:
                # 提取 Action 和 Action Input
                action = self._extract_action(response)
                action_input = self._extract_action_input(response)
​
                if action not in self.tools:
                    obs = f"错误:工具 '{action}' 不存在。可用工具:{list(self.tools.keys())}"
                else:
                    try:
                        # 3️⃣ 执行工具调用
                        print(f"🔧 执行 Action: {action}({action_input})")
                        result = self.tools[action](**json.loads(action_input))
                        obs = json.dumps(result, ensure_ascii=False)
                    except Exception as e:
                        obs = f"工具执行错误:{str(e)}"
​
                print(f"👁️ Observation: {obs}")
​
                # 4️⃣ 将 Observation 反馈给 LLM,进入下一轮循环
                messages.append({
                    "role": "user",
                    "content": f"Observation: {obs}"
                })
                continue
​
            # 如果既没有 Final Answer 也没有 Action,模型可能偏离了格式
            messages.append({
                "role": "user",
                "content": "请按格式响应:Thought + Action 或 Thought + Final Answer"
            })
​
        return "达到最大步数限制,任务未完成。"
​
    def _extract_action(self, response: str) -> str:
        """从响应中提取 Action 名称"""
        for line in response.split("\n"):
            if line.strip().startswith("Action:"):
                return line.split("Action:")[-1].strip()
        return ""
​
    def _extract_action_input(self, response: str) -> str:
        """从响应中提取 Action Input"""
        for line in response.split("\n"):
            if line.strip().startswith("Action Input:"):
                return line.split("Action Input:")[-1].strip()
        return "{}"
​
​
# ─────────── 使用示例 ───────────
​
# 模拟 LLM 调用(实际使用中替换为真实 API 调用)
def mock_llm(messages):
    """简单的 mock LLM,仅用于演示"""
    last_user_msg = messages[-1]["content"] if messages else ""
​
    if "Observation:" in last_user_msg:
        # 收到工具返回后的第二轮:给出最终答案
        obs_data = last_user_msg.split("Observation:")[-1].strip()
        return f"""Thought: 我已经获取到了天气数据:{obs_data}。
根据这些信息,我可以回答用户的问题了。
Final Answer: 根据查询结果,{obs_data}"""
    else:
        # 第一轮:决定调用工具
        return """Thought: 用户询问天气,我需要调用天气查询工具。
Action: get_weather
Action Input: {"city": "北京"}"""
​
# 注册工具
tools = {
    "get_weather": lambda city: {"city": city, "temp": 25, "weather": "多云"},
    "search_web": lambda query: {"results": [f"{query} 的搜索结果..."]},
}
​
# 运行 Agent
agent = ReActAgent(llm=mock_llm, tools=tools)
answer = agent.run("北京今天天气怎么样?需要带伞吗?")
print(f"\n{'='*50}")
print(f"🎯 最终答案: {answer}")

代码关键设计点解读:


💡 图片说明:ReAct Agent 代码实现的核心循环。LLM 的响应被解析后,如果是 Action 则执行工具并将结果反馈给 LLM 继续循环,如果是 Final Answer 则终止。

关键设计要点:

设计点 说明
System Prompt 格式约束 通过 prompt 严格定义输出格式(Thought / Action / Action Input / Final Answer),让 LLM 的行为可解析
max_steps 上限 防止 Agent 在复杂任务中无限循环,是一种安全兜底机制
Observation 反馈机制 工具执行结果以 Observation: 前缀注入对话历史,LLM 能"看到"外部世界的反馈
错误处理 工具调用失败时,错误信息作为 Observation 返回,LLM 可以据此调整策略
无状态循环 所有"记忆"都存在 messages 列表中,Agent 本身不维护额外状态

4.2 其他 Agent 工作模式

除了 ReAct,还有几种重要的 Agent 工作模式。它们各有侧重,适用于不同场景。

三种模式对比总览


💡 图片说明:三种 Agent 工作模式的对比。CoT 是纯链式推理,Plan-and-Execute 是先全局规划再分步执行,Self-Ask 是通过自问自答拆解复杂问题。


模式 1:Chain of Thought (CoT) — 纯推理

核心思想:让模型在给出最终答案之前,先输出一步步的推理过程。

CoT 是最简单也最基础的推理模式。它不调用外部工具,完全依赖模型自身的知识进行"思维链"推演。


💡 图片说明:CoT 模式示例。模型将复杂问题拆解为逐步推理,每一步都基于上一步的结论,最终汇聚为答案。

CoT 的适用场景:

  • 数学推理、逻辑推理

  • 需要多步骤思考但不依赖外部信息的任务

  • 作为其他 Agent 模式中的"思考组件"

CoT 的局限:

  • 无法获取外部信息(知识截止日期问题)

  • 不能操作工具

  • 推理链一旦出错,后续步骤无从纠正


模式 2:Plan-and-Execute — 先计划后执行

核心思想:把复杂任务分成两个阶段——先制定完整的执行计划,再按计划逐步执行。


💡 图片说明:Plan-and-Execute 模式流程图。左侧橙色区域为"计划阶段",生成完整执行计划;右侧绿色区域为"执行阶段",按计划逐步执行每个步骤。

Plan-and-Execute 的优势:

优势 说明
全局视野 先规划全貌,避免"走一步看一步"导致的局部最优
可审核性 用户可以在执行前审查计划,调整方向
任务分解 复杂任务被拆解为可管理的子任务
可控性 执行过程有章可循,出问题时可以定位到具体步骤

与 ReAct 的关键区别: ReAct 是"边想边做"(思考一步、执行一步、观察反馈),Plan-and-Execute 是"想好了再做"(全局规划后再逐步执行)。


模式 3:Self-Ask — 自问自答

核心思想:面对复杂问题时,模型主动向自己提出子问题,逐个回答,最后综合所有答案得出结论。


💡 图片说明:Self-Ask 模式示例。模型将一个复杂的历史问题拆解为 3 个子问题,逐一回答后综合得出结论。

Self-Ask 与 CoT 的区别:

维度 CoT Self-Ask
推理方式 线性链式推理 显式提问 + 回答
结构 连续的推理步骤 树状或图状的问答结构
适用场景 数学、逻辑推理 需要多角度分析的问题
是否需要工具 可选择性地调用工具回答子问题

Self-Ask 的核心价值: 它将"隐式推理"变为"显式提问",使得思考过程更加结构化,也更容易被审查和调试。


四种模式全景对比


迭代 + 工具 = 最强迭代 + 纯推理线性 + 纯推理线性 + 工具ReActPlan-and-ExecuteSelf-AskCoT不依赖工具依赖工具线性推理迭代式推理Agent 工作模式对比

💡 图片说明:四种 Agent 模式的二维对比图。横轴为"依赖工具"程度,纵轴为"迭代式推理"程度。ReAct 位于右上角,是迭代 + 工具的最强组合。

模式 核心机制 是否使用工具 推理方式 典型场景
CoT 逐步推理链 线性 数学、逻辑题
Self-Ask 自问自答拆解 ⚠️ 可选 树状 分析类问题
Plan-and-Execute 先规划后执行 阶段性 复杂多步骤任务
ReAct 推理-行动循环 迭代循环 需要外部交互的任务

4.3 理解 Agent 的三种视角

理解了 Agent 的工作模式之后,我们还需要建立一个心智模型来真正"理解" Agent。以下三种视角从不同层次帮你建立这个模型。

三种视角的关系


💡 图片说明:三种理解视角的关系。视角 1(员工)最直观,适合入门;视角 2(循环系统)最工程化,适合开发者;视角 3(大脑+工具)最底层,适合深度理解。三者层层递进。


视角 1:把 Agent 看作「员工」

一句话概括:Agent 就像一个刚入职的聪明员工——你给它目标、工具和边界,它自己想办法完成。


💡 图片说明:将 Agent 类比为员工。管理者(你)分配任务并提供工具,Agent 自己完成"理解→规划→执行→汇报"的完整流程,管理者审查后可以调整指令。

这个视角帮助你想清楚三个问题:

问题 Agent 对应概念 举例
它要做什么? System Prompt / 任务描述 "你是一个专业的客服 Agent,帮助用户解决售后问题"
它能用什么? Tools(工具集) 订单查询 API、退款接口、知识库搜索
它的边界在哪? 约束条件 / 权限控制 "退款金额超过 500 元需要人工审核"

类比例子:

你(老板):"帮我整理这份合同的风险点"
Agent(员工):
  1. 先通读合同全文(理解任务)
  2. 识别关键条款(分析)
  3. 查阅法律知识库(调用工具)
  4. 标注 5 个风险点(产出结果)
  5. "老板,我标记了 5 个风险点,其中第 3 条我不太确定,
     需要您确认"(汇报 + 请求反馈)

这个视角的优点: 直观易懂,适合产品经理、业务人员理解 Agent 的定位和边界。

局限: 过于拟人化,容易产生不切实际的期待——Agent 不是真的"理解",它只是在做模式匹配。


视角 2:把 Agent 看作「循环系统」

一句话概括:Agent 的本质是一个 "感知 → 决策 → 执行 → 感知" 的闭环控制系统。


💡 图片说明:从循环系统视角看 Agent。输入(用户输入 + 上下文 + 记忆)→ 决策(LLM 推理)→ 输出(动作 / 回复)→ 反馈(结果 / 错误)→ 回到输入,形成闭环。

把 Agent 拆成四个子系统:

┌─────────────────────────────────────────────────────┐
│                   Agent 系统架构                      │
├───────────┬─────────────────────────────────────────┤
│ 📥 输入层  │ 用户消息、system prompt、工具返回值、      │
│           │ 对话历史、RAG 检索结果                     │
├───────────┼─────────────────────────────────────────┤
│ ⚙️ 决策层  │ 大语言模型(LLM)                          │
│           │ → 理解当前状态                             │
│           │ → 推断下一步行动                           │
│           │ → 生成结构化输出                           │
├───────────┼─────────────────────────────────────────┤
│ 📤 输出层  │ → Action: 调用工具(API、数据库、计算器)   │
│           │ → Speak: 直接回复用户                      │
│           │ → Think: 内部推理(不对外)                 │
├───────────┼─────────────────────────────────────────┤
│ 🔄 反馈层  │ 工具执行结果 → 作为新的"输入"回到决策层     │
│           │ 错误信息 → 触发重试或策略调整               │
│           │ 用户反馈 → 修正理解或改变方向               │
└───────────┴─────────────────────────────────────────┘

这个视角的关键洞察:

🔑 Agent 的强大不在于 LLM 本身,而在于 LLM + 循环系统的组合。

单次 LLM 调用 = 一个聪明但"被困住"的大脑。 加上循环系统 = 大脑长出了眼睛和双手,可以在世界中行动。

工程上的指导意义:

设计考量 说明
循环终止条件 何时停止?靠 LLM 判断?靠步数上限?靠外部信号?
状态管理 对话历史怎么裁剪?长期记忆怎么存储?
错误恢复 工具调用失败了怎么办?重试?换工具?降级?
可观测性 每轮循环做了什么?怎么调试?怎么监控?

视角 3:把 Agent 看作「大脑 + 工具」

一句话概括:Agent = 推理引擎(大脑)+ 工具调用能力(双手)+ 记忆系统(经验)。


💡 图片说明:Agent = 大脑 + 工具 + 记忆。大脑(LLM)负责推理和规划,工具负责扩展能力边界(搜索、计算、操作外部服务),记忆系统负责在时间维度上保持上下文连贯。

三个组件的功能划分:

🧠 大脑(LLM)
├── 世界知识:预训练阶段学到的所有知识和模式
├── 推理能力:将复杂问题拆解为可执行的步骤
├── 语言理解:理解用户意图,哪怕表达不精确
├── 规划能力:制定多步骤的行动计划
└── 反思能力:根据新信息修正自己的判断

🔧 工具
├── 补全大脑的"知识缺口"(搜索最新信息)
├── 补全大脑的"能力缺口"(精确数学计算)
├── 补全大脑的"操作缺口"(发送邮件、操作数据库)
└── 原则:大脑负责"知道做什么",工具负责"实际做"

💾 记忆
├── 工作记忆:当前轮次正在处理的信息(类似人脑的工作记忆,容量有限)
├── 短期记忆:本次对话的所有历史记录
└── 长期记忆:关键信息的持久化存储(向量数据库、知识图谱等)

这个视角的核心哲学:

传统编程:    程序员 → 精确的代码逻辑 → 固定输出
Agent 编程:  描述目标 → 大脑自行规划 → 工具辅助执行 → 动态输出

关键转变:从"告诉计算机怎么做"到"告诉计算机你想要什么"

为什么需要三者结合?

只有大脑 只有工具 大脑 + 工具
知识截止到训练日期 需要精确指令才能执行 大脑决定调用哪些工具
无法操作外部世界 无法判断何时使用哪个工具 工具扩展大脑的能力边界
复杂数学容易出错 不能理解模糊的自然语言指令 两者互补,覆盖更广的场景

总结:三种模式与三种视角的统一

4.2(工作模式)4.3(理解视角) 放在一起,你会看到一张完整的 Agent 认知地图:


💡 图片说明:工作模式与理解视角的统一。工作模式(How)回答"Agent 怎么工作",理解视角(Why)回答"Agent 为什么这样工作"。两者互相印证,构成对 Agent 的完整理解。

核心要点串讲:

层次 核心问题 关键结论
ReAct Agent 如何思考与行动? Thought → Action → Observation 循环,是最主流的 Agent 范式
其他模式 还有哪些工作方式? CoT(纯推理)、Plan-Execute(先规划)、Self-Ask(自问自答),各有适用场景
三种视角 如何建立心智模型? 员工视角(业务层)→ 循环视角(工程层)→ 大脑+工具(认知层),逐层深入

最终心法:

🌟 Agent 不是魔法,它只是一个被设计成"循环调用"的 LLM。

它的智能来自于三个要素的组合:

  1. 大模型的推理与语言能力(大脑)

  2. 工具系统的扩展能力(双手)

  3. 循环反馈的自我纠正能力(经验)

理解了这三者的关系,你就真正理解了 Agent。


本文为 Agent 工作原理系列的第 4 章。如需进一步了解具体实现,建议参考 LangChain、AutoGPT、CrewAI 等框架的源码。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐