一位老刑警接手失窃案,不会先写结论再找证据。他会先调监控(观察)、推断窃贼作案手法(思考)、去现场提取指纹(行动)、拿到化验结果再修正判断(观察→思考)……如此循环往复,直到证据链闭合才最终下结论。过去的 AI 就像“闭门断案”的侦探:面对问题,凭记忆一次性给出答案,错了也不自知。ReAct 框架则让大模型学会老刑警的办案方式——把“思考(Thought)”与“行动(Action)”交替进行,借助外部工具获取真实反馈(Observation),边想边做、边做边改,最终交出有依据的答案。这就是推理与行动交替的智能循环:先用思考拆解问题,再用行动触碰真实世界,最后用观察修正判断,三者的循环迭代,让 AI 从“纸上谈兵”走向“真刀真枪”。
掌握 ReAct 是成为 AI Agent 工程师的必修课:它让大模型不再停留在“聊天”,而是能调用工具、执行任务、根据反馈动态纠错。
目录
可视化演示
展示ReAct框架核心机制:Thought-Action-Observation三段循环的协同工作、线性执行轨迹的逐步推理过程、以及与直接推理的准确性对比。
本节配有交互动效(进入视口后自动加载,约 3KB)。
三段循环:Thought→Action→Observation协同 Thought:显式推理当前状态和下一步 Action:执行工具调用获取外部信息 Observation:消化反馈结果更新认知 三段循环让AI边思考边执行,持续修正。
1. 什么是ReAct
假设警局里坐着两位侦探。第一位叫“纯推理”,他从不出门,只把卷宗在脑中回放一遍,然后凭直觉写下凶手名字,字写得漂亮但经常抓错人。第二位叫“老刑警”,他翻完卷宗会去现场,一边观察一边推演,还会布置警力去验证,错了立刻换方向。ReAct 要做的,就是让 AI 成为第二位侦探。
ReAct 是 Reasoning(推理)与 Acting(行动)的组合词,于 2022 年由研究者提出。它的核心思想是让语言模型在执行任务时,把思考轨迹和外部动作交错编排:推理负责拆解问题、规划步骤,行动负责调用工具获取真实信息,两者共享同一个上下文,互相促进。
这种设计源自一个朴素的观察:大模型“想”得再好,也无法触碰真实世界,知识有截止日期;而纯工具调用若没有推理引导,就像无头苍蝇到处乱撞。ReAct 把两者放进同一个循环,既保留了思维链的可解释性,又获得了外部信息的真实性与时效性。
“纯推理”侦探读再多书也看不到现场的血迹。ReAct 让 AI 从“坐堂先生”变成“亲临现场”的探长——这正是它成为 AI Agent 技术基石的根本原因。
- 左侧结果ReAct 指代整个框架的名字,它描述的是一套交替执行的行为模式,而非单个动作。
- 推理组件Reasoning 代表模型用自然语言进行的内部思考,对应侦探在脑内推演案情、制定计划。
- 行动组件Acting 代表模型对外部环境发起的真实动作,如调用搜索工具或计算器,对应侦探出门走访查证。
- 组合方式加号表示两者交替穿插而非简单拼接——先推理后行动、行动后又继续推理。
2. 三要素循环
老刑警办案有个雷打不动的习惯:笔记本上固定三栏——“我的推断”、“我去查证”、“查到什么”。每推进一轮,三栏就刷新一遍,案情也随之清晰一分。
在 ReAct 循环中,模型每一步的输出也被规范成这三栏。Thought(思考)是模型写下的推理文本,例如“用户提到订单未到,我需要查询物流状态”;Action(行动)是决定执行的外部动作,例如调用 get_logistics(order_id);Observation(观察)是工具返回的结果,例如“包裹已签收”。三者拼成上下文里的一行记录。
三个要素按固定顺序衔接成一个闭环:先产出一个 Thought,紧接着一个 Action;Action 被程序解析并真实执行;环境返回 Observation 拼回上下文,触发下一轮 Thought。如此反复,直到某轮思考认为证据足够、可以作答。
侦探的三栏笔记本越写越厚,案情越来越清晰。ReAct 的三要素每轮都在上下文里累积,模型看到的信息越多,判断依据就越扎实——这就是“边想边做”的力量。
- 第 t 轮思考Thought_t 是模型输出的推理文本,记录它当前对任务的理解和下一步计划。
- 行动指令Action_t 是思考催生的具体动作,通常是“工具名(参数)”的形式,等待程序解析执行。
- 环境反馈Observation_t 是工具执行后返回的真实结果,被追加到上下文,成为新的信息来源。
- 下一轮思考观察结果触发 Thought_{t+1},模型在更多信息基础上继续推理,循环往复直到收网。
3. 与CoT对比
警局里还有第三位侦探叫 CoT(思维链)。他喜欢在书房里把推理过程写成长长的“心流”,逻辑连贯、文采斐然,但所有依据都来自脑中旧档案——一旦卷宗过时,结论必然跑偏。
CoT 是让模型在给出答案前先生成一段推理链,本质上仍是“一次性作答”,中间无法验证也无法纠错。ReAct 则把推理过程暴露到真实世界:每多一次 Observation,就等于多拿到一份新证据,之前的事实错误有机会被当场修正。
从概率视角看,两种范式的信息条件截然不同。CoT 只以原始问题为条件,模型被迫依赖内部参数里存储的知识;ReAct 以问题加全部观察为条件,每一次工具反馈都在为答案增加依据。
如果说 CoT 是“写作前的提纲”,ReAct 就是“边查文献边修改的论文”。侦探若只凭记忆断案,永远不会发现自己早已过时。
- 条件概率表示P(Answer | 条件) 表示“在给定条件下模型答对的概率”,这是评估两种范式差异的数学视角。
- CoT 的条件右边只以原始问题 q 为条件,模型只能依赖训练时记住的知识作答,无法核查。
- ReAct 的条件左边除了 q 还包含 o_1 到 o_t 共 t 条外部观察,每一条都是来自真实环境的证据。
- 对比符号vs 表示两种范式在信息条件上的本质区别,也是 ReAct 纠错能力的概率来源。
4. Prompt设计
再厉害的侦探也要按手册办事。警局手册里写着:先记推断、再记查证、后记发现,还附了三个完整案例和专家联系方式。手册越规范,新侦探越不容易跑偏。
ReAct 的 Prompt 就是这本手册,通常包含四部分:系统提示词(定义角色与能力边界,如“你是一个可以调用工具的智能代理”)、少量示例(展示一个完整的 Thought→Action→Observation 样例)、工具清单(列出可用工具的名称与用途)、格式约束(要求按槽位输出,便于程序解析)。
工程上,格式约束往往决定成败。如果模型自由发挥,Action 字段就无法被解析成工具调用,整个循环会当场断裂。因此 Prompt 必须写清楚输出模板,让模型“填空”而不是“作文”。
办案手册写得细,新侦探犯的格式错误就少。同理,Prompt 设计越规范,Agent 循环越稳定——这往往比调模型参数更立竿见影。
- 思考槽位要求模型先填写推理理由,强制“先想后做”,避免不假思索地乱调工具。
- 行动槽位Action 后必须是“工具名(参数)”的规范写法,解析器据此抽取真实的函数调用。
- 观察槽位Observation 由环境回填真实返回结果,模型只读不写,保证信息来源可靠。
5. 工具调用机制
侦探从不自己验指纹——他呼叫法医;不翻二十年前的旧档案——他呼叫档案员。工具就是模型背后的“专家助手团”,弥补模型自身知识与能力的不足。
工具调用的工程链路包含五步:注册(把函数的名称、参数、用途以元信息形式暴露给模型)、决策(模型在 Action 中写下工具名和参数)、解析(程序用正则或 JSON 解析出真实调用)、执行(在外部环境真实运行)、回传(把返回值作为 Observation 写回上下文)。
异常处理同样关键:工具超时、参数非法、API 报错……这些错误信息不应被静默丢弃,而应作为 Observation 原样回传,让模型“看到”这次行动失败了,从而调整策略或换一个工具。
法医的一句话可能让整个案件反转。工具返回的 Observation 同样可能推翻模型之前的判断——这正是 ReAct 纠错能力的工程来源。
- 历史上下文h_t 是第 t 轮的全部上下文,包括原问题以及之前所有轮次的思考、行动与观察。
- 决策生成LLM(h_t) 表示大模型读完历史后输出行动指令 a_t,推理在这里把信息转化为决策。
- 真实执行Env(a_t) 表示外部环境(搜索引擎、数据库、计算器等)根据 a_t 的参数真实执行并返回结果。
- 反馈闭环o_t 不是模型生成的,而是环境回传的,它将作为下一轮 h_{t+1} 的一部分继续参与推理。
6. 终止条件
侦探何时结案?证据链闭合就结案;查了三个月毫无进展,时限到了也得交阶段性报告;花费超出预算,警局也会强制叫停。Agent 循环同样需要一套“结案规则”。
ReAct 的终止条件通常分四类:答案识别(当前 Action 不是工具调用,而是以“答案:”开头的最终回答)、最大轮数(预设 T_max,防止无限循环烧钱)、置信度阈值(模型对当前答案信心不足时继续收集信息)、安全熔断(累计 Token 或异常次数超限后强制停止)。
实际系统中这四类条件通常叠加使用:先做答案识别,再查轮数上限,同时实时监控资源开销。缺少终止条件的 Agent 会在失败任务上无限重试,造成灾难性的延迟与经济成本。
聪明的侦探知道何时收手,成熟的 Agent 同样如此。终止条件不是限制,而是保护系统不被意外拖垮的安全阀。
- 存在量化∃ 表示“只要存在某一轮”,不要求所有轮都满足,一有答案即可收手。
- 步数上限T_max 是预先设置的最大循环轮数,防止 Agent 在失败任务上无限重试消耗资源。
- 答案判定a_t ∈ Answer 表示第 t 轮的 Action 不是工具调用,而是以“答案:”开头的最终回答。
- 停止触发⟹ 表示条件成立就立刻终止循环并对外输出答案,避免多余开销。
7. 实际应用
侦探事务所业务繁忙:寻人、追赃、打假,每种案件都逼着侦探反复出门验证。与此对应,ReAct 在真实世界中也有三大主战场。
第一是 AI Agent 开发,让模型不再只是聊天,而是完成任务:订机票、查库存、改配置。第二是多跳问答,问题需要多次检索才能回答,例如“获得金棕榈奖的那位导演还执导过哪些作品”——必须先查出导演身份,再查其作品。第三是流程自动化,把多步业务操作交给 Agent 动态执行,根据中间反馈调整方案。
实验数据也支持这一判断。在 HotpotQA 这类需要多跳推理的数据集上,ReAct 的准确率显著高于只靠 CoT 的模型,因为每一次检索都能修正之前的事实错误,而不是将错就错。
侦探擅长的事,Agent 正在学:不只是“回答你的问题”,而是“办成你要的事”。ReAct 正是这条从问答走向行动的桥梁。
- 准确率指标Acc 是回答的准确率,反映模型在该任务上最终答对的比例。
- 方法对比下标 ReAct 与 CoT 代表两种方法,不等式说明前者在多跳问答上系统性占优。
- 适用边界括号标注“多跳问答”限定了结论的适用范围;简单常识问题上两者差距不大,甚至 CoT 更快更省。
8. 局限与挑战
老刑警也有翻车时刻:线人给错情报、自己钻进牛角尖、连续蹲守三天三夜累到判断失误。ReAct 的局限同样来自信息、推理与资源三个层面。
最核心的问题是误差累积。每一轮 Thought 或 Action 都可能出错,而错误会留存于上下文,影响后续所有轮次。假设每轮正确率相同,则轮次越多,整体成功率越低——这是数学上的必然。
其次还有三重挑战:延迟成本上,每轮都是一次完整的大模型调用加工具调用,Token 消耗数倍于单次回答;幻觉放大上,错误的 Observation 反而会强化模型的错误信念;安全边界上,模型可能调用危险工具或越权访问,必须用权限白名单约束。
因此工程上的态度应是“信任但验证”:用好终止条件、异常处理和权限控制,让侦探在错误情报面前及时掉头,而不是越陷越深。
- 单步错误率ε_t 表示第 t 轮思考或行动出错的概率,例如搜索关键词错误或推理偏差。
- 全部正确1 − ε_t 表示第 t 轮不出错的概率,连乘号把 n 轮“都正确”的概率乘在一起。
- 总错误率用 1 减去“全部正确”的概率,得到至少一步出错的概率;当 n 增大时它迅速逼近 1。
AI 应用场景
智能客服多轮工单处理 Agent
阶段:Agent 推理与工具调用(推理执行阶段)
解决的问题:传统客服机器人只能匹配 FAQ,遇到需要查订单、查物流、改地址的多步问题就卡壳。ReAct 让机器人先判断需要什么信息(Thought),再调用订单查询接口(Action),根据返回状态决定下一步(Observation),全程像侦探一样逐步收拢线索。
具体案例:用户吐槽“上周买的鞋还没到”。客服 Agent 循环:思考“需要订单号和物流接口”→ 调用查询订单工具 → 观察“物流显示已签收”→ 思考“可能放快递柜了”→ 调用快递柜查询工具 → 观察“取件码 1234”→ 输出安抚话术。全程 3 轮循环,零人工介入。
科研文献多跳检索助手
阶段:多跳检索与知识增强(RAG 检索生成阶段)
解决的问题:用户问“模型 A 相比模型 B 在长文本任务上表现如何”,需要查论文、读实验、比数据,一次推理根本答不准。ReAct 把检索动作拆进推理循环,每轮观察修正下一轮搜索关键词,避免传统 RAG“检索一次就定生死”的局限。
具体案例:助手先搜索“模型 A 长文本评测”→ 观察论文摘要发现基准数据集名称 → 思考后继续搜索该数据集上的对比实验 → 观察具体指标 → 输出带出处的对比结论。用户拿到的是可溯源的答案,而非编造的综述。
自动化运维故障排查 Agent
阶段:自主决策与工具编排(AIOps 自动化阶段)
解决的问题:生产环境报错时,传统脚本只能按固定步骤排查,无法根据现象动态调整路径。ReAct Agent 根据观察到的日志动态决策下一步命令,像侦探根据新线索不断缩小嫌疑范围,大幅缩短故障定位时间。
具体案例:Agent 先观察“数据库连接超时”日志 → 思考“先查数据库负载”→ 执行 top 命令 → 观察 CPU 打满 → 思考“定位慢查询”→ 执行慢查询分析 → 观察某 SQL 全表扫描 → 输出优化建议并通知值班人员。
Python 演示
# -*- coding: utf-8 -*-"""ReAct 循环极简模拟 - 让侦探 Agent 边想边做查天气""" import re class ReActAgent: def __init__(self, max_steps=5): self.max_steps = max_steps self.history = [] def think(self, question, observation): """模拟大模型: 根据当前观察输出 Thought 和 Action""" if observation is None: return "我需要先查一下当地的天气", "get_weather(city='北京')" if "晴" in observation and "24" in observation: return "天气晴朗且 24 度, 可以直接给穿衣建议", "答案: 晴天 24 度, 建议穿薄外套" return "信息还不够, 我再查一下湿度", "get_humidity(city='北京')" def call_tool(self, action): """执行 Action, 返回真实的 Observation""" match = re.match(r"get_weather\(city='(.+?)'\)", action) if match: return match.group(1) + ": 晴, 24 度" match = re.match(r"get_humidity\(city='(.+?)'\)", action) if match: return match.group(1) + ": 湿度 45%" return "无法识别的动作" def run(self, question): observation = None for step in range(1, self.max_steps + 1): thought, action = self.think(question, observation) self.history.append({"step": step, "thought": thought, "action": action}) print(f"Step {step}") print(f" Thought : {thought}") print(f" Action : {action}") if action.startswith("答案"): return action.split(": ", 1)[1] observation = self.call_tool(action) print(f" Observe : {observation}") return "达到最大步数, 未能给出答案" if __name__ == "__main__": agent = ReActAgent(max_steps=5) result = agent.run("北京今天穿什么?") print("最终答案:", result)
thought, action = self.think(question, observation)每一轮先“思考”再“行动”,上一轮的观察作为本轮输入。observation = self.call_tool(action)执行行动并拿到真实观察,这是闭环的关键一环。if action.startswith("答案"):终止条件判断:一旦 Action 是最终回答,立即跳出循环。return action.split(": ", 1)[1]剥离“答案:”前缀,输出干净的最终回答。self.history.append({"step": step, "thought": thought, "action": action})记录完整轨迹,保证过程可追溯、可解释。for step in range(1, self.max_steps + 1):最大轮数控制,防止 Agent 无限循环。match = re.match(r"get_weather\(city='(.+?)'\)", action)用正则解析 Action 里的工具名和参数,相当于“接线员”。
常见误区
误区很多人觉得“ReAct 不就是让大模型能调用函数吗?我在代码里给模型加几个工具函数,不就实现了 ReAct?”于是只做函数接入,不做循环设计。
正解工具调用只是 Action 的一个环节。ReAct 的独特之处在于 Thought 显式推理驱动 Action,Observation 反馈再修正 Thought,三者构成闭环。只接入工具而缺少循环,模型只是“猜一次工具调用”,错了不会回头——就像侦探乱拨电话却不听对方说什么。
为何常见:初学者最早接触的多是“Function Calling“能力,容易把 ReAct 简化为”模型能调函数”,忽略了循环与反馈才是灵魂。
误区“Observation 不就是模型自言自语解释一下结果吗?反正 Prompt 里都是文本,谁生成的都一样。”
正解Observation 必须来自外部环境的真实反馈——工具返回值、搜索结果、数据库记录,绝不是模型编出来的。这正是 ReAct 对抗幻觉的关键:模型只能“看”不能“造”。若观察结果也由模型生成,整个循环就成了自说自话,误差只会越滚越大。
为何常见:观察结果在上下文里同样是文本,初学者误以为凡是上下文中的 token 都出自大模型之手。
误区“反正能纠错,让 Agent 多循环几十轮,答案肯定更准。”于是把 max_steps 调到很大,结果又慢又错。
正解每轮都引入延迟和金钱成本,而且错误会累积——单步 90% 正确率的推理,5 轮后全程正确只有约 59%。ReAct 应在证据足够时及时停止,用终止条件(答案明确、轮数上限、置信阈值)控制循环,而不是盲目贪多。
为何常见:人们习惯类比“思考越久越聪明”,但 Agent 的每一步都可能出错,轮数多绝不等于质量高。
误区“循环逻辑写在代码里就行,Prompt 随便给个'你是助手'就够了,模型自然会懂。”
正解ReAct 高度依赖 Prompt 中 Thought/Action/Observation 的格式约束和少量示例。没有格式约束,模型的输出无法被程序解析成工具调用;没有示例,模型不知道什么时候该调工具、什么时候该收尾。Prompt 就是侦探的办案手册,手册乱写,侦探必然跑偏。
为何常见:循环确实在代码里,容易让人误以为模型行为全由代码控制,忽略了上下文中的“剧本”对模型行为的决定性影响。
面试题
Q1. 在 ReAct 循环中,Thought(思考)的主要作用是什么?
- A.产生可解析的工具调用指令
- B.显式记录推理过程的思路← 正确答案
- C.直接输出最终答案给用户
- D.保存工具返回的原始数据
答案:B。Thought 是模型显式的推理轨迹,记录“为什么这么做”,用来指导 Action 的选择,也让过程可解释。A 是 Action 的职责,C 是终止后的输出,D 是 Observation 的职责。
Q2. Observation(观察)的数据来源是?
- A.大模型内部记忆生成
- B.用户输入的问题文本
- C.外部工具环境的返回结果← 正确答案
- D.Prompt 中预设的示例
答案:C。Observation 必须来自外部环境执行 Action 后的真实反馈。如果由模型自己生成,就失去了纠错和对抗幻觉的意义,如同侦探自己编造证人证词。
Q3. 与 CoT 相比,ReAct 的核心优势在于?
- A.推理过程速度明显更快
- B.能获取外部信息并动态纠错← 正确答案
- C.不需要任何 Prompt 设计
- D.完全避免模型产生幻觉
答案:B。ReAct 在推理中调用工具获取真实信息,并根据 Observation 修正思路;CoT 只凭内部知识一次推完。ReAct 更慢而非更快,不能完全消除幻觉,也离不开精心设计的 Prompt。
Q4. 工具调用失败(如 API 报错)时,正确的处理方式是?
- A.忽略错误直接输出答案
- B.把错误作为观察值继续循环← 正确答案
- C.终止整个 Agent 进程
- D.直接修改模型的权重参数
答案:B。错误信息本身就是一种 Observation。把它回传给模型,模型可以根据错误调整参数或换工具,这正是 ReAct 闭环的价值;忽略错误会让后续推理建立在不存在的“成功”前提上。
Q5. 设每轮循环成功率 90%,则 5 轮循环全程正确的概率约为?
- A.百分之四十五左右
- B.百分之五十九左右← 正确答案
- C.百分之九十左右
- D.百分之百正确
答案:B。各轮独立时总成功率是 0.9 的 5 次方,约 0.59。这直观解释了误差累积:轮次越多,整体成功率越低,因此要谨慎设计循环轮数与终止条件。
Q6. ReAct 中 Action 字段的典型形式是?
- A.自然语言的即兴发挥
- B.工具名加括号的参数调用← 正确答案
- C.图片音频等多媒体数据
- D.压缩后的配置文件内容
答案:B。Action 需要被程序解析执行,因此必须是结构化形式,如 search(“北京天气”)。自然语言感想是 Thought 的职责,多媒体与配置文件无法直接作为工具指令解析。
Q7. 以下哪些属于 ReAct 循环的终止条件?
- A.Action 被识别为最终答案← 正确答案
- B.循环轮数达到预设上限← 正确答案
- C.置信度过低时模型直接停止
- D.安全或资源异常触发熔断← 正确答案
答案:ABD。常见终止条件包括答案识别、最大轮数、安全熔断。C 说反了——置信度低说明还没把握,应该继续收集信息,而不是停止。
Q8. 关于 ReAct 的误差累积问题,下列说法正确的是?
- A.每轮推理都可能引入错误← 正确答案
- B.错误会随反馈传播累积← 正确答案
- C.轮次越多整体错误率越低
- D.可用置信阈值控制循环质量← 正确答案
答案:ABD。每轮都可能出错且错误随上下文传播,整体成功率是各轮成功率的连乘(0.9^5≈59%),轮次越多错误率越高,C 错误。设置置信阈值、及时终止可以抑制累积。
Q9. 在 ReAct 的 Prompt 设计中,少量示例(few-shot)的主要作用是?
- A.增加输入 Token 的数量
- B.示范思考行动的循环格式← 正确答案
- C.替代外部工具的调用
- D.对用户输入进行加密
答案:B。示例让模型模仿“先想→再做→再观察”的循环节奏,包括何时调用工具、何时收尾给答案。没有示范,模型容易在格式和节奏上双双跑偏。
Q10. 以下哪些任务更适合用 ReAct 而非 CoT?
- A.需要实时数据查询的多跳问答← 正确答案
- B.涉及多步骤操作的流程执行← 正确答案
- C.纯记忆性的简单常识问题
- D.需动态调用各类工具的任务← 正确答案
答案:ABD。ReAct 适合需要外部信息、多步操作、动态决策的任务。纯记忆性常识问题 CoT 一步就能答好,引入工具调用反而增加延迟与出错面,属于“杀鸡用牛刀”。