ReAct范式实战:让Agent学会边想边做

说实话,我第一次看到ReAct这个论文标题的时候,内心是拒绝的。

"又是个学术界造的概念吧?"我当时想。

直到我真的在一个实际项目里试了一下,才发现------这玩意儿真的不是花架子。它是Agent从"傻傻地问一句答一句"到"能思考、能行动、能纠错"的关键一步。

这篇文章不讲虚的,直接聊ReAct怎么落地。

问题:单纯的Prompt + Tool Call为什么不够?

你可能会说:"给LLM配几个工具的Function Calling不就行了吗?"

行,但不完全行。

举个我踩过的坑。我让一个Agent帮忙分析用户反馈数据。它需要先查数据库拿到最近一周的反馈,然后做个情感分析,最后输出一个报表。

如果只用Function Calling,LLM会尝试一步到位------"好的,我来查数据、分析情感、生成报表"。但问题是:它不知道自己的查询结果质量如何,也不知道情感分析结果出来后有没有异常需要二次验证。

这就好比一个程序员写完代码不测试就直接上线。能跑是运气,崩了是常态。

核心思想:思考 → 行动 → 观察 → 再思考

ReAct的全称是 Reasoning + Acting。核心就四个字:边想边做

传统的LLM调用流程是:

复制代码
输入 → LLM → 输出

ReAct的流程是:

复制代码
输入 → LLM思考(我要做什么)→ 行动(调用工具)→ 观察(工具返回的结果)→ 再思考(结果是否合理?下一步做什么?)→ 再行动 → ... → 最终输出

这个循环让Agent有了"反馈回路"。每一步的结果都会影响下一步的决策。

一个完整的ReAct循环长什么样

我看过最清晰的解释,是论文里的一个例子。问Agent:"在加州哪里可以买到Xbox?"

  • 思考: 用户想知道Xbox的购买地点。我需要查一下加州的零售信息。
  • 行动: search("加州 Xbox 购买地点")
  • 观察: 搜索结果返回了GameStop、Best Buy、Target和微软官网的链接
  • 思考: 搜索结果包含了实体店和线上渠道。用户问的是"买",可能包括两者。让我进一步搜一下有没有具体的优惠信息。
  • 行动: search("Xbox Series X 加州的库存情况")
  • 观察: 有些店有现货,有些显示缺货
  • 思考: 我可以整理一下哪些店有现货,以及购买渠道。
  • 最终回答: 在加州,你可以去GameStop、Best Buy等实体店购买,或者上微软官网下单。目前GameStop和Best Buy部分店面有现货...

看到了吗?每一步都是"我想一下 → 我做一下 → 我看结果 → 我再想一下"。

工程实现:怎么落地ReAct?

理论说完了,聊点干的。我试过两种实现方式,各有千秋。

方式一:手动管理循环

这是最直接的方式。你手动维护一个"思考-行动-观察"的循环队列。

核心代码框架大概是这样:

python 复制代码
def react_loop(user_input, max_steps=10):
    messages = [
        {"role": "system", "content": REACT_SYSTEM_PROMPT},
        {"role": "user", "content": user_input}
    ]
    
    for step in range(max_steps):
        response = llm.call(messages)
        
        if response.has_final_answer:
            return response.final_answer
        
        action = parse_action(response.text)
        observation = execute_tool(action.name, action.args)
        
        messages.append({"role": "assistant", "content": response.text})
        messages.append({"role": "tool", "content": observation})
    
    return "Max steps reached"

关键点在于system prompt要写得够好。论文里推荐在System Prompt中给出明确的格式要求,让LLM知道每一步应该输出什么。

我用的System Prompt模板是这样的:

复制代码
你是一个智能Agent。你需要通过"思考→行动→观察"的循环来完成任务。

每轮你需要输出:
1. 思考(Thought):分析当前状态,决定下一步做什么
2. 行动(Action):调用一个工具函数
3. 观察(Observation):工具返回的结果(由系统填充)

当你认为任务已经完成时,输出最终答案(Final Answer)。

可用工具列表:
- search(query): 搜索网络信息
- calculate(expression): 执行数学计算
- ...

说实话,这种方式简单直接,但有一个问题------Token消耗大。每一步的思考和行动都会产生大量的Token输出。如果你的task需要5-6步,光是ReAct循环本身的Token消耗就够你心疼的。

方式二:用Agent框架

偷懒的方式是直接用现成的Agent框架。LangChain、LangGraph、CrewAI、AutoGen这些框架都内置了ReAct支持。

以LangGraph为例,它把ReAct封装成了一个Node + Edge的图结构:

python 复制代码
from langgraph.graph import StateGraph, END
from langgraph.prebuilt import ToolExecutor

# 定义Agent节点
def agent_node(state):
    messages = state["messages"]
    response = llm_with_tools.invoke(messages)
    return {"messages": [response]}

# 定义工具节点
def tool_node(state):
    messages = state["messages"]
    last_message = messages[-1]
    tool_calls = last_message.tool_calls
    results = tool_executor.batch(tool_calls)
    return {"messages": results}

# 构建图
graph = StateGraph(AgentState)
graph.add_node("agent", agent_node)
graph.add_node("tools", tool_node)
graph.add_conditional_edges("agent", should_continue, {"continue": "tools", "end": END})
graph.add_edge("tools", "agent")

框架的好处是帮你处理了循环逻辑、上下文管理、错误重试这些脏活。但代价是------你失去了对每一步的精细控制。如果你的场景需要非常定制化的ReAct逻辑,手撸可能更灵活。

踩坑记录

这东西看着简单,但真正用起来有几个坑。

坑1:LLM喜欢"跳过思考"

我遇到过一个奇怪的问题:LLM在某个轮次突然不输出了Thinking,直接给出了Final Answer。

排查后发现,是模型觉得"结果已经够好了"。但这往往是因为它忽略了某些细节。

解决办法:在System Prompt里加上"除非任务明确完成,否则每一步都必须包含思考步骤"的约束。

坑2:循环不终止

有些问题没有明确的"完成"条件,Agent会在工具调用和观察之间来回跳跃,永远不停。

解决方案:设置最大步数限制(我一般设5-8步),超时后返回当前最好的结果。

坑3:观察结果太长

工具返回的数据可能非常长(比如一次搜索返回10条结果),这些内容全部塞进上下文,Token爆炸。

方案:对观察结果进行摘要。只保留关键信息,丢掉冗余内容。这招能省至少30%的Token。

什么时候用ReAct?什么时候不用?

我个人觉得,ReAct最适合的场景是:

  • 多步骤推理任务:需要多次查询/计算才能得出结论的
  • 需要纠错的任务:第一次行动的结果可能不准确,需要二次验证
  • 决策路径不确定的任务:Agent需要根据中间结果动态调整策略

不适合的场景:

  • 简单的QA:用户问"今天天气怎么样?",直接查天气API返回结果就行,不需要思考循环
  • 高实时性场景:ReAct的每一次循环都需要一次LLM调用,延迟不可控
  • Token敏感场景:ReAct的Token消耗比普通问答高一个数量级

写在最后

ReAct不是什么黑魔法。它的核心思想很简单:让LLM的推理过程和实际行动交替进行,互相验证。

这个思路不仅在Agent领域有用,在日常编码中也有启发------别写一段超长的代码再debug,而是一小段一小段地写,每写完一段就跑一下看看结果。高效多了。

如果你也想在项目中引入Agent能力,建议从ReAct开始。它是最基础、最可控的Agent范式,也是理解和实现更复杂Agent架构(比如Tree-of-Thought、Multi-Agent)的基石。

下一篇我打算聊聊Tree-of-Thought,让Agent做更深层次的规划。感兴趣的可以关注一波。

相关推荐
前端若水3 小时前
会话管理:创建、切换、删除对话历史
前端·人工智能·python·react.js
冬奇Lab4 小时前
让 AI Agent 更可靠:Harness Engineering 与多 Agent 系统工程实践
人工智能·llm·agent
放下华子我只抽RuiKe54 小时前
React 从入门到生产(四):自定义 Hook
前端·javascript·人工智能·深度学习·react.js·自然语言处理·前端框架
XinZong4 小时前
OpenClaw 实现双重心跳(Heartbeat)+ clawreach虾聊项目实现
javascript
德思特5 小时前
从 Dify 配置页理解 RAG 的重要参数
java·人工智能·llm·dify·rag
还有多久拿退休金6 小时前
一张栈的图,治好你面试答不出 script 阻塞的病
前端·javascript
光辉GuangHui6 小时前
Agent Skill 也需要测试:如何搭建 Skill 评估框架
前端·后端·llm
zithern_juejin6 小时前
原型与原型链
javascript
_按键伤人_8 小时前
二、从零搭建本地 RAG 知识库
前端·llm·ai编程
_按键伤人_8 小时前
一、理解 RAG:从概念到实践
前端·llm·ai编程