一、核心定义:什么是ReAct?
ReAct = Reasoning(推理) + Acting(行动)
一个让大模型真正「边想边做」的框架,通过与外部工具交互解决复杂任务。
二、ReAct工作流程(四步循环)
1. Thought(思考)
- 模型基于当前目标进行推理
- 决定下一步该做什么
2. Action(行动)
- 选择具体操作(调用API、搜索、计算等)
- 执行决策
3. Observation(观察)
- 获取外部反馈
- 包括:搜索结果、API返回值等
4. 重复 循环直到达成目标
💡 本质:模拟人类「思考→行动→验证」的解决问题过程
三、为什么必须用ReAct?
在 ReAct 之前,主要有两种让 LLM 与外部交互的方式,但它们各有缺陷:
| 方法 | 问题 | 后果 |
|---|---|---|
| 仅推理 (Chain-of-Thought) | 依赖过时/错误训练数据 | 「一本正经地胡说八道」 |
| 仅行动 (Tool Use) | 行为缺乏规划 | 盲目低效,逻辑混乱 |
ReAct 的巧妙之处在于,它将两者融合,取长补短:
🔗 1. 克服模型的局限性
通过行动调用工具,可以获取实时、准确的信息,打破模型的知识时效界限。
🧠 2. 解决幻觉问题
强制模型基于观察到的外部事实进行推理,显著减少
“一本正经地胡说八道” 的情况。
📋 3. 提升可解释性
整个思考链条和行动记录完全可见,便于开发者调试和用户理解,让AI决策过程透明化。
🔄 4. 处理复杂任务
对于 “查天气 → 规划出行路线 → 推荐餐厅” 这类多步骤任务:
- 单纯推理无法执行动作
- 单纯行动缺乏规划性ReAct 完美结合两者优势
总结:ReAct 让大模型从“纸上谈兵”进化为“实战高手”,通过推理与行动的循环配合,真正具备了解决现实复杂问题的能力。
四、 实战实现:两种方法详解
方法一:提示工程实现(掌握原理)
🎯 核心提示词设计
在提示中明确要求模型按照Thought / Action / Observation 的格式输出。例如:
ReAct智能理财助手
你是一个专业的理财助手,能够通过思考和行动来帮助用户解答财务和投资相关的问题。
重要说明:每次必须返回完整的Thought+Action对
每轮必须同时包含Thought和Action(或Final Answer)!
Thought用于展示推理过程,Action用于系统执行工具!
ReAct框架说明
你必须严格按照以下格式进行思考和行动:
每轮回复必须是以下两种格式之一:
格式1 - Thought+Action:
Thought: 分析用户的问题,思考需要采取什么行动
Action: 选择并执行一个工具(search_web 或 calculate)
格式2 - Final Answer:
Final Answer: 当收集到足够信息时,给出最终答案
可用工具
-
search_web(query): 搜索最新的财经信息和市场数据
- 参数: query (str) - 搜索关键词,如"黄金价格"、"股票行情"等
- 返回: 相关的市场信息和数据 -
calculate(expression): 执行数学计算
- 参数: expression (str) - 数学表达式,如"10000/450"、"(1000*12)*0.05"等
- 返回: 计算结果
使用规则
- 每次必须同时包含Thought和Action(或Final Answer)
- Thought展示推理过程,Action用于系统执行
- 系统只处理Action和Final Answer,忽略单独的Thought
- 如果搜索结果不够明确,可以调整搜索词重新搜索
- 计算时要确保表达式正确
- 最终答案要清晰、准确、有用
正确交互示例
用户: "10000元能买多少克黄金?"
助手:
Thought: 我需要查询当前黄金的价格,然后用1万元除以单价,计算能购买多少克黄金。
Action: search_web("黄金价格")
系统: Observation: 今日黄金价格约为1159元/克(24K金),投资金条价格约为1080元/克。
助手:
Thought: 现在我看到黄金价格是1159元/克,需要计算10000元能买多少克。
Action: calculate(10000/1159)
系统: Observation: 计算结果:8.63
助手: Final Answer: 按照当前黄金价格约1159元/克,1万元可以购买约8.63克黄金。
现在开始帮助用户解答理财问题。记住:每轮必须同时返回Thought+Action!
由以下几个部分组成:
1. 角色定义
2. 核心规则说明
· 重要强调:"每次必须返回完整的Thought+Action对"
· 明确要求每轮必须同时包含Thought和Action(或Final Answer)
3. 框架规范
· ReAct框架说明
· 两种标准格式定义:
o 格式1:Thought + Action
o 格式2:Final Answer
4. 工具集定义
· search_web(query):网络搜索工具,包含参数说明和返回内容
· calculate(expression):计算工具,包含参数说明和返回内容
5. 使用规则
·.条具体操作规则
· 强调系统处理机制和用户注意事项
6. 少量样本(Few-Shot)
· 提供少量示例:在提示词中给出1-2个完整的 ReAct 任务解决示例,让模型学会这种格式。
· 完整的用户-助手对话示例,展示从问题到最终答案的完整流程,演示工具的正确使用方法
解析模型输出****
程序需要能够解析模型的响应,识别出Action: 后面的内容(例如正则/json),然后调用相应的工具。
def parse_response(content: str) -> Dict[str, Any]:
"""解析LLM响应内容"""
result = {
"thought": "",
"action": "",
"action_type": ActionType.UNKNOWN,
"action_input": "",
"final_answer": None
}
# 提取思考过程
thought_pattern = r'Thought:\s*(.*?)(?=\nAction:|\nFinal Answer:|$)'
thought_match = re.search(thought_pattern, content, re.DOTALL | re.IGNORECASE)
if thought_match:
result["thought"] = thought_match.group(1).strip()
# 提取动作
action_pattern = r'Action:\s*(.*?)(?=\nObservation:|\nThought:|\nFinal Answer:|$)'
action_match = re.search(action_pattern, content, re.DOTALL | re.IGNORECASE)
if action_match:
action_text = action_match.group(1).strip()
result["action"] = action_text
# 解析动作类型和输入
if '(' in action_text and ')' in action_text:
action_parts = action_text.split('(', 1)
action_name = action_parts[0].strip()
action_input = action_parts[1].rsplit(')', 1)[0].strip('"'')
result["action_input"] = action_input
if action_name == "search_web":
result["action_type"] = ActionType.SEARCH
elif action_name == "calculate":
result["action_type"] = ActionType.CALCULATE
elif action_name == "answer":
result["action_type"] = ActionType.ANSWER
# 提取最终答案
final_answer_pattern = r'Final Answer:\s*(.*?)(?=\nThought:|\nAction:|$)'
final_answer_match = re.search(final_answer_pattern, content, re.DOTALL | re.IGNORECASE)
if final_answer_match:
result["final_answer"] = final_answer_match.group(1).strip()
return result
将工具返回的结果作为 Observation 输入给模型,开启下一轮循环。****
if step.action_type != ActionType.UNKNOWN:
observation = self.tool_executor.execute(
step.action_type.value,
step.action_input
)
step.observation = observation
logger.info(f"观察: {observation}")
# 更新消息历史
messages.append(AIMessage(content=content))
messages.append(HumanMessage(content=f"Observation: {observation}"))
steps.append(step)
循环终止:****
当模型输出Action: Finish[最终答案] 时,循环结束。
# 检查是否有最终答案
if step.final_answer:
logger.info(f"=== 最终答案 ===")
logger.info(f"答案: {step.final_answer}")
steps.append(step)
# 退出时,保存对话历史
self._save_conversation_history(question, steps)
return step.final_answer
完整代码地址:
********
方法二:Agent框架实现(生产环境)
使用成熟的框架,这会大大简化开发流程。
· LangChain
create_agent 方法本身不使用显式的 ReAct 提示词。它依赖于模型的原生 tool calling 能力。
graph = create_agent(
model="anthropic:claude-3-7-sonnet-latest",
tools=[check_weather],
system_prompt="You are a helpful assistant", # 这是唯一的提示词
)
这种方式下, "思考-执行-观察"的循环是通过图结构和工具调用机制隐式实现的,而不是通过提示词中的格式指令
详细查看:
· ~~LangGraph ~~
langchain的1.0版本已经转使用langchain create_agent不再继续跟踪
· AutoGen
autogen没有对ReAct进行封装
只是实现对工具的调用,当依赖模型的思考和调用能力时,和langchain的create_agent也变得类似了
async def main() -> None:
agent = AssistantAgent(
name="assistant",
model_client=tongyi_model_client,
tools=[search_web,calculate],
system_message="You are a helpful assistant.",
max_tool_iterations=10, # 设置最多使用工具次数
)
res = await agent.run(task = "我手上有1万块钱,我能买多少克黄金?")
messages:list[BaseChatMessage] = res.messages
for msg in messages:
print(msg.to_text())
print("="*20)
· AgentScope
其实现方式就和lanchain1.0很类似,但更多的是通过逻辑代码来完成了整个过程,而langchain是通过图的思维来实现
async def main():
# 注册工具
toolkit = Toolkit()
toolkit.register_tool_function(search_web)
toolkit.register_tool_function(calculate)
# 创建 ReAct 智能体
agent = ReActAgent(
name="Assistant",
sys_prompt="你是一个助手,可以调用工具完成任务。",
model=DashScopeChatModel(
model_name="qwen3-max",
api_key=os.environ["DASHSCOPE_API_KEY"],
),
memory=InMemoryMemory(),
formatter=DashScopeChatFormatter(),
toolkit=toolkit,
max_iters=10, # 最多10次推理-行动循环
)
msg = Msg("user", "我手上有1万块钱,我能买多少克黄金?", "user")
# 发送需要多次工具调用的任务
await agent(
msg
)
框架对比总结:
- LangChain:图结构思维,隐式循环
- AutoGen:依赖模型原生能力,配置简单
- AgentScope:逻辑代码驱动,控制灵活
ReAct是一种让大模型「边想边做」的核心策略,通过:交替进行推理与行动,并结合外部工具反馈,显著提升了模型在复杂任务中的表现。其实现主要依赖于精心设计的提示模板、工具调用机制和迭代执行流程,是当前大模型智能体(Agent)架构中的核心技术之一。
想要深入学习和实践?所有完整资料和代码都已准备好:
GitHub仓库:github.com/BaqiF2/ydc_…
从原理理解到实战应用,从基础提示工程到高级框架使用,这个项目为你提供了一站式的ReAct学习路径