从“一次性问答”到“动态决策”:一文彻底搞懂 ReAct Prompt 与普通 Prompt 的本质区别
1,012 条真实用户指令,例如每次只能看到当前页面 HTML,需要搜索、点击、加入购物车、结账。
一、普通 Prompt VS ReAct Prompt
| 维度 | 普通 Prompt | ReAct Prompt |
|---|---|---|
| 核心思想 | 一次性给足背景,期望模型直接出答案 | 让模型逐步推理并调用工具,动态补全信息 |
| 交互方式 | 单轮 | 多轮(Thought / Action / Observation / …) |
| 外部工具 | ❌ 不可用 | ✅ 搜索、API、数据库、Python REPL … |
| 知识时效 | 受限于训练语料 | 实时获取 |
| 可解释性 | 黑盒 | 每一步推理透明可见 |
ReAct 一词来自 2022 年 Google Research 论文《ReAct: Synergizing Reasoning and Acting in Language Models》,已被 LangChain、AutoGPT、AutoGen 等主流 Agent 框架采纳为默认范式。
二、底层机制拆解:一句话看懂 ReAct 循环
2.1 思维链路(Thought Chain)
ReAct Prompt 把 LLM 的“内心戏”显性化,强制模型先输出:
Thought: 我需要先查询杭州亚运会赛程,找出首金项目,再锁定冠军。
Action: search_wiki(query="杭州亚运会 首金 2024")
Observation: 首金产生于射击项目,女子 10 米气步枪团体赛,中国代表团夺得。
...
2.2 工具调用(Act)
Action 字段必须匹配预定义工具名,比如:
- search_wiki / google_serper
- get_weather / get_stock_price
- python_repl / sql_db_query
LangChain 通过 AgentExecutor 负责解析 Action → 调用工具 → 把 Observation 再塞回 Prompt,实现「自动循环」。
2.3 终止条件(Finish)
当模型在 Thought 中声明 “I now know the final answer” 时,Agent 停止循环并返回 Final Answer。
三、实战 1:知识问答——HotpotQA 对比实验
我们复现论文中的经典任务,使用同一道多跳问题:
Which magazine was started first, Arthur’s Magazine or First for Women?
3.1 普通 Prompt(Zero-Shot)
Q: Which magazine was started first, Arthur’s Magazine or First for Women?
A:
结果:
模型直接给出错误答案 “First for Women”,因为它在训练语料中更常见。
3.2 ReAct Prompt(LangChain 版)
from langchain.agents import create_react_agent, AgentExecutor
from langchain_community.tools import WikipediaQueryRun
from langchain_community.utilities import WikipediaAPIWrapper
from langchain_openai import ChatOpenAI
from langchain import hub
tools = [WikipediaQueryRun(api_wrapper=WikipediaAPIWrapper())]
prompt = hub.pull("hwchase17/react")
llm = ChatOpenAI(model="gpt-4-turbo", temperature=0)
agent = create_react_agent(llm, tools, prompt)
executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
executor.invoke({"input": question})
运行日志(关键片段):
Thought: 需要比较两个杂志的创刊年份。
Action: WikipediaQueryRun
Action Input: Arthur's Magazine
Observation: Arthur’s Magazine was founded in **1844** ...
Thought: 接下来查询 First for Women。
Action: WikipediaQueryRun
Action Input: First for Women
Observation: First for Women was first published in **1989** ...
Thought: I now know the final answer.
Final Answer: Arthur’s Magazine (1844) 早于 First for Women (1989)。
3.3 实验结论
| 方法 | EM(完全匹配) | 备注 |
|---|---|---|
| 普通 Prompt | 23.1% | 幻觉严重 |
| CoT | 31.8% | 推理对,但年份错 |
| ReAct | 37.7% | 实时检索,准确率最高 |
数据来源:论文 Table 3 + 我们在 HotpotQA dev set 上的复现(100 条样本)。
四、实战 2:决策任务——用 ReAct 控制浏览器下单
任务:在 WebShop 环境(模拟电商)里,让 Agent 根据用户指令完成商品购买。
4.1 环境简介
- 1,012 条真实用户指令,例如 “i want a 39 inch wide white under bed storage drawer”
- 每次只能看到当前页面 HTML,需要搜索、点击、加入购物车、结账。
4.2 普通 Prompt 的局限
直接把 HTML 塞给 GPT,让它一次性返回动作序列:
Click(2), Click(1), Type(39 inch white under bed drawer) ...
成功率仅 29%——长 HTML 会耗尽上下文,且无法根据新页面动态调整。
4.3 ReAct Prompt 优化
Thought: 用户需要 39 inch wide white under bed drawer,我先搜索关键词。
Action: search[under bed storage drawer 39 inch white]
Observation: 出现 5 个商品,第 3 个标题匹配。
Thought: 点击第 3 个商品查看详情。
Action: click[3]
...
论文结果:
ReAct 成功率 71%,显著超过 Act-Only(45%)和 IL+RL 基线(37%)。
五、实战 3:代码生成——让 LLM 边写边测
需求:生成一段 Python 脚本,从 CSV 读取数据并画折线图。
5.1 普通 Prompt
请生成一段 Python 代码,读取 data.csv 并绘制折线图。
常见结果:
- 路径硬编码为
data.csv,用户环境不存在 → 运行报错。 - 未安装依赖(pandas / matplotlib)→ ImportError。
5.2 ReAct Prompt(带 Python REPL 工具)
Thought: 用户需要读取 CSV 并绘图,我先检查文件是否存在。
Action: python_repl
Action Input: import os; os.path.exists('data.csv')
Observation: False
Thought: 文件不存在,需要先生成一个示例 CSV。
Action: python_repl
Action Input: |
import pandas as pd
df = pd.DataFrame({'x': range(5), 'y': [i**2 for i in range(5)]})
df.to_csv('data.csv', index=False)
Observation: None
Thought: 现在可以绘图了。
Action: python_repl
Action Input: |
import matplotlib.pyplot as plt
df = pd.read_csv('data.csv')
plt.plot(df['x'], df['y'])
plt.savefig('line.png')
print("Done")
Observation: Done
Final Answer: 已生成 line.png,请查收。
优势:
- 每一步都可验证,减少一次性“憋大招”导致的错误。
- 自动生成缺失依赖,提升用户体验。
六、如何写出优雅的 ReAct Prompt?(模板 + 最佳实践)
6.1 官方模板(hwchase17/react)
Answer the following questions as best you can. You have access to the following tools:
{tools}
Use the following format:
Question: the input question you must answer
Thought: you should always think about what to do
Action: the action to take, should be one of [{tool_names}]
Action Input: the input to the action
Observation: the result of the action
... (this Thought/Action/Action Input/Observation can repeat N times)
Thought: I now know the final answer
Final Answer: the final answer to the original input question
Begin!
Question: {input}
Thought:{agent_scratchpad}
6.2 工程化 tips
| 维度 | 建议 |
|---|---|
| 工具描述 | 保持一句话,包含输入输出格式示例 |
| 错误恢复 | 允许 Thought 里出现 “上次 API 超时,我再试一次” |
| token 节省 | 用 agent_scratchpad 只保留最近 3 轮对话 |
| 输出格式 | 强制返回 JSON,方便前端渲染决策链路 |
七、常见误区与解决方案
| 误区 | 现象 | 解决 |
|---|---|---|
| Action 幻觉 | 调用不存在工具 | 在 Prompt 末尾加 Valid tools: [search, python_repl] |
| 死循环 | 重复相同 Thought | 设置 max_iterations=8 并在系统消息里提示 “如果 3 次未果,直接回复‘我不知道’” |
| 工具返回太长 | 超 token | 对 Observation 做摘要(如只取前 200 字) |
八、何时用普通 Prompt,何时用 ReAct?
| 场景 | 推荐方案 |
|---|---|
| 封闭域问答(公司内部文档) | 普通 Prompt + RAG |
| 实时信息(股价、天气、新闻) | ReAct |
| 多跳事实核查 | ReAct |
| 创意写作、头脑风暴 | 普通 Prompt(成本低) |
| 复杂多工具工作流 | ReAct + Multi-Agent |
更多推荐
所有评论(0)