ReAct 是 Reasoning 与 Acting 的合成词,代表一种让大模型在执行任务时交替进行推理和工具调用的控制方式。它并不是某种单独的模型架构,而是一套提示词工程方案:通过固定输出格式和循环状态,把模型的思考过程变成可执行、可回溯、可纠正的步骤。相比让模型一次性给出最终答案,ReAct 更强调每轮只推进一小步,用工具返回的真实数据替代模型自己的猜测。

一、ReAct 循环的三个核心组件
ReAct 循环由三个字段构成:Thought、Action 和 Observation。它们不是简单拼接,而是承担不同职责。模型每输出一组 Thought 与 Action 后必须停止,等待外部环境给出 Observation,再进入下一轮。这个设计让推理和行动形成闭环,避免模型在没有任何外部信息的情况下连续推理到底。
Thought 负责记录模型当前对任务的理解。它需要说明现在知道什么、缺少什么、下一步打算做什么。Thought 不执行任何操作,只是给自己下一步选择提供依据。例如当用户问某个近期的技术问题时,模型可以写下:这个问题依赖最新文档,而我的训练数据可能不包含该事件,因此需要先检索。这样的显式思考能有效抑制模型直接编造。
Action:模型选择要调用的工具和参数。需要提前定义命名空间,例如search[query]或calculator[expression]。每轮只能有一个 Action,且必须使用规定格式。Observation:工具执行后返回的真实结果。这部分由环境或程序写入,模型不能自行生成。Observation 是后续推理的事实基础。
三者配合后,模型的多步推理就有了明确边界。Thought 回答为什么,Action 回答做什么,Observation 回答实际发生了什么。调试 Agent 时,只需要查看历史记录里的三人组,就能快速定位是推理错误、调用错误还是工具返回信息不足。
二、可直接套用的 ReAct 提示词模板
下面是一个通用的 ReAct 提示词模板。它适合搜索引擎、计算器、数据库查询等工具型场景。模型被要求每轮只输出 Thought 和 Action,Observation 由程序补充。这个模板可以作为基础,根据任务差异继续裁剪。
你是 ReAct Agent。每次输出必须严格包含以下两行: Thought: 你的思考内容 Action: 工具名[参数] 可用工具: search[query]: 搜索互联网 calculator[expression]: 计算数学表达式 finish[answer]: 结束任务并返回答案 规则: 1. 每轮只能输出一个 Thought 和一个 Action。 2. 输出 Action 后立刻停止,等待 Observation。 3. 当信息足够时,使用 finish 工具。 4. 不能重复调用同一工具超过三次。
模板中的工具列表需要写得足够具体,包含工具名、入参和一句话用途。Action 的格式保持统一,可以降低解析难度。比如所有工具都写成 工具名[参数],解析时只需要匹配方括号。如果参数里出现方括号,则需要约定转义规则或改用 JSON 格式。
在工程实现中,这个模板会放到系统提示词里,用户问题作为第一轮输入。每一轮模型输出后,服务端通过正则或状态机提取 Action,调用对应函数,再把返回结果拼成 Observation: ... 追加到对话历史中。然后继续请求模型。下面是一个简化的 Python 循环。
messages = [{"role": "system", "content": PROMPT}]
messages.append({"role": "user", "content": user_question})
for step in range(max_steps):
response = llm(messages)
messages.append({"role": "assistant", "content": response})
action = parse_action(response)
if action.name == "finish":
return action.arguments.get("answer")
observation = tool_registry.run(action.name, action.arguments)
messages.append({"role": "system", "content": f"Observation: {observation}"})
return "达到最大步数仍未完成任务"
这段代码的关键不是函数名,而是历史消息的追加顺序。每一轮必须保留模型的原始输出,也要保留对应的 Observation。如果只把 Observation 替换掉之前的通知,模型会丢失推理线索,后续容易重复调用同一个工具。
三、多步推理中的上下文管理与终止条件
ReAct 任务往往无法在两步内完成。例如一个研究类问题可能需要先搜索关键词,再根据搜索结果打开某个文档,提取片段,最后汇总答案。这个过程会积累多组 Thought、Action 与 Observation。若直接无限次调用,既费 token 也可能陷入循环。因此上下文管理和终止条件必须写进设计。
上下文管理的第一条原则是完整性:所有 Observation 都要原样保留,不要压缩或改写。模型需要依据真实返回内容修正方向,如果中间丢失某个关键观察,后续推理就可能退回错误路径。第二条原则是控制长度:当对话历史变长时,可以只保留最近几轮完整记录,把更早的 Observation 摘要化,但摘要必须明确标注为外部信息而非模型记忆。
终止条件通常包括三类。第一类是任务完成,模型调用 finish[answer=...],程序直接返回答案。第二类是达到最大步数,防止复杂任务耗尽预算。第三类是连续重复检测,如果模型连续两次调用同一个工具且参数相同,应判定为停滞并干预,比如要求它说明下一步差异或直接结束。
终止逻辑最好写进提示词,让模型自己也了解规则。例如可以加入:当你连续两次获得相同结果时,不要第三次重复调用同一工具。这样模型会在 Thought 里主动改变策略,而不是由外部粗暴截断。
四、ReAct 模板的常见变体与调优建议
纯文本的 Thought-Action-Observation 模板易于阅读,但现实项目中经常改为 JSON 输出,因为结构化数据便于程序解析。JSON 变体把所有信息放进同一对象,字段边界更清晰,避免正则匹配时因为模型多写一个空格或换行而失败。下面是一个 JSON 风格的 ReAct 输出格式。
{
"thought": "需要先确认用户问题的关键实体是否存在最新资料",
"action": {
"name": "search",
"arguments": {
"query": "ReAct prompt optimization"
}
}
}
JSON 变体更适合有严格工具调用的生产环境,但也带来两个成本:一是输出 token 会增加,二是模型需要额外遵循任务格式。如果模型基础能力较弱,可以先从纯文本模板开始,逐步迁移到 JSON。另一种变体是支持并行 Action,但要谨慎使用。ReAct 的原始设计强调单步推进,一旦允许多个 Action,就需要额外定义依赖关系与失败回滚逻辑,提示词复杂度会明显上升。
调优时建议记录每一轮 Thought 与最终结果之间的关系。比如哪些 Thought 导致了无意义的 Action,哪些 Observation 被模型忽略。根据这些日志调整工具描述、补充终止示例,或者对容易跑偏的任务增加 few-shot 示例。少量高质量轨迹往往比不断堆规则更有效。最后注意不要让模板过于冗长,确保核心约束在模型上下文中处于稳定位置。
ReAct提示词AI智能体Thought-Action-Observation循环修改时间:2026-09-22 23:46:27