ReAct 推理范式深度拆解(让 Agent 可靠完成任务的核心机制)

ReAct(Reason + Act)的核心是把”思考”和”行动”塞进同一个 LLM 解码流——每一步生成 Thought 推理、Action 工具调用,再把 Observation 反馈回上下文,循环往复直到 Finish。在内部 Agent 跑生产时翻车过几次,纯 CoT 经常幻觉事实、纯 Action 不会分解目标,ReAct 把两个失败模式同时治住。下面把范式结构、可靠性机制、生产踩坑点拆开讲清。

一、ReAct 解决了什么具体问题

ReAct 论文(Yao et al., 2022,ICLR 2023)针对的是两类失败模式:

  • 纯 CoT(只思考不行动):推理完全发生在模型内部,与外部世界无交互。优势是擅长算术、常识、符号推理;劣势是知识型任务上幻觉严重——尤其在多跳问答里,编一个桥接实体就整条链废掉。Google Research 的论文里直接给出结论:CoT 在 HotpotQA 上的事实核查准确率是 56.3%,而 ReAct 是 60.9%。
  • 纯 Action(只行动不思考):把文本上下文映射到文本动作,行动直接但无高层规划。WebGPT、SayCan 都是这条路。代价是模型不会分解目标、不会跟踪子目标、碰到意外 Observation 不会回退。

ReAct 的核心主张是这两类失败是互补的——给模型”思考用的草稿纸”和”行动用的手”,放在同一段轨迹里,比二者单独跑都强。论文在 HotpotQA、FEVER、ALFWorld、WebShop 四个 benchmark 上验证了这个判断,ALFWorld 上 ReAct 比 Act-only 提升 34 个百分点。

二、ReAct 的三段式循环

ReAct 的标准循环是 Thought → Action → Observation 三段一循环:

  1. Thought(思考):模型用自然语言写”现在缺什么信息、下一步该查什么”。这一步是 CoT 的延续,承担规划、记忆、异常处理。
  2. Action(行动):从预定义的小动作词汇表里选一个执行。Wikipedia 问答里是 Search[entity]、Lookup[string]、Finish[answer];ALFWorld 里是 go、take、open 这类游戏动词;WebShop 是 search、click[button] 之类。动作词汇保持小且固定,是 few-shot prompting 能 work 的前提。
  3. Observation(观察):环境执行 Action 后返回的字符串,append 到 prompt 里但不参与模型生成。

模型在 Thought 和 Action 之间交替——生成 Thought 后生成 Action,Action 触发的 Observation 注入上下文,解码继续,直到 Action 是 Finish[answer] 终止。Thought 和 Action 共享同一个自回归解码流,因此每一步工具调用都受模型自身先验思考的条件化,每条 Observation 都可以推翻仍在进行的计划。

三、ReAct 与 CoT 的对比

ReAct 不是替代 CoT,而是把 CoT 嵌入 Action 循环。下面把两者在任务类型、失败模式、可解释性三个维度对比。

维度 纯 CoT 纯 Action ReAct
知识型任务 易幻觉 缺规划 推理+外部事实校验
交互型任务 无法行动 无高层规划 规划+行动
失败模式 编造桥接实体 无法回退 思考可审计
可解释性 推理可见,事实不可见 行动可见,规划不可见 思考+行动都可见
工具调用 不可 强 强(条件化于思考)
上下文管理 自包含 需维护 action history Observation 自动注入

ReAct + CoT 组合在 HotpotQA 上做到 35.1% 准确率(6-shot),超过纯 CoT 的 29.4%,也超过纯 Act-only 的 25.7%。这条组合也是论文的核心推荐——内部先做 ReAct 的多跳检索、推理遇到瓶颈再退回 CoT 采样投票。

四、生产环境的五个可靠性机制

ReAct 论文里没强调工程化,但生产里必须补五条才能稳住。

4.1 限制最大步数

LLM 在 Thought/Action 之间可能陷入死循环——同一个工具反复调用、返回同样的 Observation。必须强制 max_steps,超过即中断返回。

4.2 工具错误显式注入

工具调用失败时,模型默认行为是”假装 Observation 是合理的”——这正是幻觉的入口。生产里要捕获异常、把错误信息(如 ToolError: timeout after 5s)显式塞回上下文,让模型决定重试或换路径。

4.3 上下文压缩

ReAct 跑长链路会塞满 Observation。生产中定期对历史 Observation 做摘要,把”原文 1000 token 摘要到 100 token”再回填。

4.4 格式一致性

Thought/Action/Observation 的字面前缀必须严格不变。模型对 prompt 格式非常敏感,一个 Action: 写成 Action:(全角冒号)就解析失败。可以用正则或 Pydantic 强制解析。

4.5 Human-in-the-Loop

Google Research 的论文专门做了实验:允许人类在 ReAct 推理过程中编辑 Thought(比如把幻觉句子改对),下游准确率立刻回升。生产中暴露一个”审阅 Thought、批准 Action”的接口,是处理高风险任务的关键兜底。

五、ReAct 在生产中的实现骨架

下面是一段精简的 ReAct Agent 实现,展示 Thought/Action/Observation 的循环与终止逻辑:

import re

REACT_PROMPT = """你是一个 ReAct Agent。按以下格式回应:
Thought: 你的推理
Action: 工具名(参数)
Observation: 系统回填的执行结果
... 重复直到完成 ...
Final Answer: 最终答案

可用工具: {tools}
"""

def run_react_agent(query, tools, llm, max_steps=10):
    history = [{"role": "user", "content": REACT_PROMPT.format(tools=tools) + f"\nQuestion: {query}"}]
    for step in range(max_steps):
        response = llm.complete(history)
        history.append({"role": "assistant", "content": response})

        if "Final Answer:" in response:
            return response.split("Final Answer:")[-1].strip()

        m = re.search(r"Action:\s*(\w+)\((.*?)\)\s*$", response, re.S)
        if m:
            tool_name, tool_input = m.group(1), m.group(2).strip()
            try:
                observation = tools[tool_name](tool_input)
            except Exception as e:
                observation = f"ToolError: {e}"
            history.append({"role": "user", "content": f"Observation: {observation}"})
        else:
            return f"解析失败:未找到 Action 或 Final Answer(step={step})"
    return "已达最大步数,未得到答案。"

效果上,这段代码展示了 ReAct 的几个工程要点:用正则强制解析 Action、把工具异常显式回填、max_steps 兜底、Final Answer 作为终止信号。生产里再叠加”Observation 摘要压缩””Thought 审计回调””并行工具调用”就能撑住大部分场景。

六、ReAct 之后的演进

ReAct 2022 年提出后,工程界沿三条路径演进:

  • 结构化工具调用:OpenAI Function Calling、Anthropic Tool Use 把 ReAct 的”自然语言 Action”换成 JSON schema,减少解析失败。
  • 有状态图(Stateful Graph):LangGraph 用图替代 ReAct 的线性循环,支持分支、回退、并行节点。LangGraph 的检查点机制把 ReAct 的”中间状态可恢复”工程化。
  • 长期自治 Agent:AutoGPT、MetaGPT、ChatDev 把 ReAct 循环拉长到数百步,配合”任务树 + 子 Agent”管理复杂度。代价是对小模型不友好——循环越长越容易跑偏。

新项目里,ReAct 更像是”协议层”——LangGraph、AutoGen、smolagents、Letta 这些框架的运行内核都能找到 ReAct 的影子。理解 ReAct 才能调好这些上层框架。

到这里,ReAct 范式从论文动机、生产可靠性到代码骨架就讲完了。

常见问题(FAQ)

Q1:ReAct 适合所有 Agent 场景吗?

不适合简单单步任务;多步、需外部信息、有失败回退需求的任务收益最大。

Q2:ReAct 和 CoT 怎么配合?

ReAct 做多跳检索与工具调用,CoT 负责最后推理与汇总,ReAct + CoT 论文里有直接验证。

Q3:ReAct 跑长链路会卡在哪?

容易卡在循环调用、上下文溢出、工具错误幻觉——必须配 max_steps、错误回填、Observation 压缩。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 qiqicto@qq.com 举报,一经查实,本站将立刻删除。
赞 (0)
小码农的头像小码农认证作者

相关推荐

返回顶部