1. 背景
1.1.介绍
ReAct 是一个将 Reasoning(推理) 和 Acting(行动) 相结合的范式,旨在让 LLM 与外部工具(如搜索引擎、计算器、数据库、API等)进行交互,从而更可靠、更准确地解决任务。
- 核心思想:让模型在解决问题的过程中,生成一步一步的推理轨迹,并根据推理决定下一步要执行的动作。这模仿了人类在解决问题时的“思考-行动”循环。
该框架由普林斯顿大学和谷歌的研究员在 2022 年的论文《ReAct: Synergizing Reasoning and Acting in Language Models》中提出。
1.2.为什么需要ReAct
在 ReAct 出现之前,主要有两种让 LLM 与外界交互的方式:
仅行动(Act-only):
- 方式:模型直接根据输入生成要执行的动作(例如,直接调用一个搜索API)。
- 缺点:缺乏透明的推理过程,像一个“黑箱”。当任务复杂时,模型容易迷失方向,做出不合逻辑的动作,且错误难以追溯。
仅推理(Reason-only / Chain-of-Thought):
- 方式:模型通过生成一步步的推理(“让我们一步一步思考...”)来解决问题,但不采取任何实际行动。
- 缺点:模型的知识可能过时、不准确或存在幻觉。对于需要实时、精确信息的任务(如“今天的天气如何?”),仅靠推理无能为力。
ReAct 的解决方案:将两者结合,取长补短。
- 推理 为行动提供了逻辑依据和计划,减少了盲目性。
- 行动 为推理提供了真实、可靠的外部信息,弥补了模型内在知识的不足。
2. 工作原理
2.1. 工作原理
ReAct 的工作流程是一个典型的 Agent(智能体) 工作模式,通常包含三个核心步骤,循环执行直到问题被解决:
步骤 1: 思考(Think / Reason)
- 模型分析当前的状态(包括原始问题、之前步骤的观察结果)。
- 生成一段自然语言的推理,解释它目前的理解、已经知道的信息以及接下来为什么要采取某个行动。
- 示例: “用户想知道爱因斯坦的出生日期和当天的天气。我已经通过搜索知道了他的出生日期是1879年3月14日。现在我需要知道他出生地的天气,所以我需要先查出他的出生地。”
步骤 2: 行动(Act)
- 根据上一步的推理,模型决定并执行一个具体的动作。
- 动作通常以标准化的格式发出,例如
Search[阿尔伯特·爱因斯坦出生地]或Calculate[25 * 38]。 - 这些动作会被发送给预定义好的工具(Tools / APIs)来执行。
步骤 3: 观察(Observe)
- 外部工具执行动作后,将结果返回给模型。
- 示例: 搜索工具返回“阿尔伯特·爱因斯坦出生于德国乌尔姆”。
- 这个观察结果(Observation)被添加到模型的上下文中,作为下一步推理的新依据。
然后,流程回到 步骤1,模型基于新的信息进行下一轮的“思考-行动-观察”,直到它认为已经收集到足够的信息来给出最终答案。
2.2. 简单流程示例
任务:“特斯拉CEO马斯克的妈妈是谁?她今年多大年纪了?”
| 步骤 | 推理(Reason) | 行动(Act) | 观察(Observation) |
|---|---|---|---|
| 1 | 用户想知道特斯拉CEO马斯克的妈妈是谁以及她的年龄。首先,我需要找出特斯拉的CEO是谁。 | Search[特斯拉 CEO] | 特斯拉的CEO是埃隆·马斯克。 |
| 2 | 好的,CEO是埃隆·马斯克。现在我需要找出他的妈妈是谁。 | Search[埃隆·马斯克的母亲] | 埃隆·马斯克的母亲是梅耶·马斯克。 |
| 3 | 现在我知道他妈妈是梅耶·马斯克。接下来我需要找出她今年的年龄,这需要我知道她的出生年份。 | Search[梅耶·马斯克出生年份] | 梅耶·马斯克出生于1948年4月19日。 |
| 4 | 我知道她的出生年份是1948年。现在是2024年,所以我需要计算她的年龄。2024减去1948等于76。不过,我需要确认今年的年份,并且要考虑她今年是否已经过了生日。 | Calculate[2024 - 1948] | 76 |
| 5 | 计算结果是76。今天是2024年10月7日,她的生日是4月19日,已经过去了,所以她现在确实是76岁。我已经收集齐了所有信息。 | Finish | - |
最终答案: 特斯拉CEO埃隆·马斯克的妈妈是梅耶·马斯克,她今年76岁。
2.3. 优势
- 透明性与可解释性:模型的整个思考过程(推理轨迹)是可见的,便于人类理解和调试。如果出错了,我们可以很容易地定位到是哪一步的推理或观察出了问题。
- 提升准确性与可靠性:通过结合外部工具,模型可以减少因自身知识局限或幻觉而产生的错误,答案更加基于事实。
- 强大的任务规划能力:对于需要多步骤分解的复杂任务,ReAct 提供了结构化的解决路径,使模型能更好地处理任务规划。
- 高效性:相比于漫无目的地生成大量文本,ReAct 的步骤通常更精简、目标更明确。
3. 实践示例:System Prompt
3.1. 示例:System Prompt
后续示例中,体现 ReAct 流程的 System Prompt 内容。
这个 Prompt 是放在 system role 中的,目的是告诉模型:
- 它的身份和任务(角色设定)
- 它能用的工具列表(Action 列表,带 schema)
- 它的工作规则(推理、执行、异常处理、终止条件)
- 它的输出格式(Thought → Action → Final Answer)
You are an intelligent ReAct Agent.
Your task is to answer the user's question by reasoning step-by-step (Thought) and performing actions (Action).
You will receive results from actions as Observation messages.
=== Available Actions ===
You can choose ONE Action per step from the following tool list:
1. Search
- Description: Perform a web search for the given query.
- Input schema:
query: string (Required) - The search keywords.
- Output schema:
results: list of string - List of relevant search results in text form.
2. Calculator
- Description: Perform arithmetic calculation on the given expression.
- Input schema:
expression: string (Required) - Mathematical expression, e.g. "2024 - 1982".
- Output schema:
result: number - The numeric result of the calculation.
3. Translate
- Description: Translate given text into target language.
- Input schema:
text: string (Required) - The text to translate.
target_lang: string (Required) - Language code, e.g. "zh" for Chinese.
- Output schema:
translated_text: string - The translated text.
4. Weather
- Description: Get current weather information for a location.
- Input schema:
location: string (Required) - City or region name.
- Output schema:
temperature: string - Temperature value with unit.
condition: string - Weather description.
=== Rules ===
1. Always output reasoning in "Thought" based on ALL previous context (including earlier Thoughts, Actions, and Observations).
2. Then output ONE "Action" to perform, in the format:
Action: <tool_name>[<parameters>]
3. If no available Action fits the current need:
- Try to rephrase the problem to fit an available tool.
- If still impossible, output "Final Answer" with the best reasoning you can provide without tools.
4. If an Action execution returns an error:
- Retry with adjusted parameters (up to 2 retries).
- If still fails, switch to an alternative tool or give best guess.
5. If an Action result does not match the expected goal:
- Adjust the query or parameters and retry.
6. Stop after MAX 6 iterations to avoid infinite loops.
7. Do not repeat the same Action with identical parameters more than 3 times.
8. Always aim to produce a "Final Answer" at the end, even if approximate.
=== Output Format per step ===
Thought: <reasoning>
Action: <tool_name>[<parameters>]
When you are confident or cannot proceed further:
Final Answer: <answer>3.2. 解释说明
先把 Prompt 拆成几个部分,然后逐段解释,并标出变量。
A. 角色设定与任务说明
You are an intelligent ReAct Agent.
Your task is to answer the user's question by reasoning step-by-step (Thought) and performing actions (Action).
You will receive results from actions as Observation messages.作用:
- 告诉模型它是一个ReAct Agent,不是普通聊天机器人。
- 明确任务:要做逐步推理(Thought)和执行动作(Action)。
- 告诉它会收到Observation(工具执行结果)。
变量:
- 这里基本是固定描述,不需要替换。
- 如果你的 Agent 名称不同(比如 “DataAnalysis Agent”),可以替换
"ReAct Agent"。
B. 可用 Action 列表
=== Available Actions ===
You can choose ONE Action per step from the following tool list:
1. Search
- Description: Perform a web search for the given query.
- Input schema:
query: string (Required) - The search keywords.
- Output schema:
results: list of string - List of relevant search results in text form.
2. Calculator
- Description: Perform arithmetic calculation on the given expression.
- Input schema:
expression: string (Required) - Mathematical expression, e.g. "2024 - 1982".
- Output schema:
result: number - The numeric result of the calculation.
3. Translate
- Description: Translate given text into target language.
- Input schema:
text: string (Required) - The text to translate.
target_lang: string (Required) - Language code, e.g. "zh" for Chinese.
- Output schema:
translated_text: string - The translated text.
4. Weather
- Description: Get current weather information for a location.
- Input schema:
location: string (Required) - City or region name.
- Output schema:
temperature: string - Temperature value with unit.
condition: string - Weather description.作用:
- 列出模型可以调用的工具,并详细描述用途。
- 提供输入/输出字段 schema,帮助模型正确构造参数和理解返回值。
变量:
工具名称(Search / Calculator / Translate / Weather)和描述:
- 变量,因为不同项目可用的工具不同。
- 在运行时,你需要根据实际可用的工具来替换或扩展这里的列表。
输入/输出字段 schema:
- 变量,根据工具 API 的实际参数和返回值定义来调整。
C. 工作规则(健壮性)
=== Rules ===
1. Always output reasoning in "Thought" based on ALL previous context (including earlier Thoughts, Actions, and Observations).
2. Then output ONE "Action" to perform, in the format:
Action: <tool_name>[<parameters>]
3. If no available Action fits the current need:
- Try to rephrase the problem to fit an available tool.
- If still impossible, output "Final Answer" with the best reasoning you can provide without tools.
4. If an Action execution returns an error:
- Retry with adjusted parameters (up to 2 retries).
- If still fails, switch to an alternative tool or give best guess.
5. If an Action result does not match the expected goal:
- Adjust the query or parameters and retry.
6. Stop after MAX 6 iterations to avoid infinite loops.
7. Do not repeat the same Action with identical parameters more than 3 times.
8. Always aim to produce a "Final Answer" at the end, even if approximate.作用:
- 让模型知道它必须遵守的推理规则、异常处理规则、终止条件。
- 防止模型陷入死循环。
- 保证即使工具不可用,也能给出答案。
变量:
- MAX 6 iterations → 变量,可根据业务需求调整循环次数。
- 重试次数(up to 2 retries)→ 变量,可改为 1 或 3 次。
- 同一 Action+参数重复次数限制(3 次)→ 变量。
- 如果你的项目有额外的错误处理策略(比如记录日志),可以在这里增加说明。
D. 输出格式要求
=== Output Format per step ===
Thought: <reasoning>
Action: <tool_name>[<parameters>]
When you are confident or cannot proceed further:
Final Answer: <answer>作用:
- 让模型严格按格式输出,方便外部程序解析。
- 确保每轮都有 Thought 和 Action,最终有 Final Answer。
变量:
<reasoning>→ 变量(由模型推理生成,不需预设)。<tool_name>→ 来自工具列表(变量,取决于你定义的工具)。<parameters>→ 根据具体任务动态生成(变量)。<answer>→ 最终结果(模型生成)。
3.3. 模板与变量
在实际代码中,你可以用模板 + 变量替换的方式生成这个 Prompt。
提示词模板
You are an intelligent {AGENT_NAME}.
Your task is to answer the user's question by reasoning step-by-step (Thought) and performing actions (Action).
You will receive results from actions as Observation messages.
=== Available Actions ===
{TOOLS_DEFINITION}
=== Rules ===
1. Always output reasoning in "Thought" based on ALL previous context (including earlier Thoughts, Actions, and Observations).
2. Then output ONE "Action" to perform, in the format:
Action: <tool_name>[<parameters>]
3. If no available Action fits the current need:
- Try to rephrase the problem to fit an available tool.
- If still impossible, output "Final Answer" with the best reasoning you can provide without tools.
4. If an Action execution returns an error:
- Retry with adjusted parameters (up to {MAX_RETRIES} retries).
- If still fails, switch to an alternative tool or give best guess.
5. If an Action result does not match the expected goal:
- Adjust the query or parameters and retry.
6. Stop after MAX {MAX_ITERATIONS} iterations to avoid infinite loops.
7. Do not repeat the same Action with identical parameters more than {MAX_REPEAT_ACTION} times.
8. Always aim to produce a "Final Answer" at the end, even if approximate.
=== Output Format per step ===
Thought: <reasoning>
Action: <tool_name>[<parameters>]
When you are confident or cannot proceed further:
Final Answer: <answer>
变量
这个 Prompt 模板是半固定 + 半变量的结构:
- 固定部分是规则、格式和思路(保证健壮性)。
- 变量部分是工具列表、循环次数、Agent 名称等(适配不同场景)。
这个 Prompt 模板中需要你在运行时替换的变量有:
工具列表:
- 模型必须知道有哪些工具可用,否则会调用不存在的工具。
- 工具的输入/输出 schema 帮助模型正确构造参数,减少错误。
循环与重试次数:
- 直接影响健壮性和性能。
- 不同场景下可能需要更长或更短的推理过程。
Agent 名称:
- 在 Prompt 中明确角色,可以影响模型的回答风格。
- 如果你的 Agent 专注某个领域(金融分析、天气预报),可以在名字中体现。
4. 实践示例:多轮流程
用户问题:
找出 2021 年奥斯卡最佳影片的导演的出生年份,并计算他出生年份到 2024 年的年龄。
第 1 轮调用(第一步有可用 Action)
[
{"role": "system", "content": "You are an intelligent ReAct Agent...(完整 Prompt 模板)"},
{"role": "user", "content": "User Question: 找出 2021 年奥斯卡最佳影片的导演的出生年份,并计算他出生年份到 2024 年的年龄。"}
]模型输出:
Thought: 我需要先找到 2021 年奥斯卡最佳影片的名字,可以使用 Search 工具。
Action: Search["2021 Oscars Best Picture winner"]外部执行 Action:
Observation: Best Picture 2021: "Nomadland"第 2 轮调用
[
{"role": "system", "content": "You are an intelligent ReAct Agent...(完整 Prompt 模板)"},
{"role": "user", "content": "User Question: 找出 2021 年奥斯卡最佳影片的导演的出生年份,并计算他出生年份到 2024 年的年龄。"},
{"role": "assistant", "content": "Thought: 我需要先找到 2021 年奥斯卡最佳影片的名字,可以使用 Search 工具。\nAction: Search[\"2021 Oscars Best Picture winner\"]"},
{"role": "user", "content": "Observation: Best Picture 2021: \"Nomadland\""}
]模型输出:
Thought: 根据之前的Observation,我知道最佳影片是 "Nomadland"。我需要找到这部电影的导演,可以使用 Search 工具。
Action: Search["Nomadland director"]外部执行 Action:
Observation: Error: Network timeout异常处理:Action 执行报错
第 3 轮调用(Prompt 规则触发重试)
[
...(之前历史),
{"role": "assistant", "content": "Thought: 根据之前的Observation,我知道最佳影片是 \"Nomadland\"。我需要找到这部电影的导演,可以使用 Search 工具。\nAction: Search[\"Nomadland director\"]"},
{"role": "user", "content": "Observation: Error: Network timeout"}
]模型输出:
Thought: 上一步 Search 工具报错,我将重试并调整参数。
Action: Search["Nomadland film director"]外部执行 Action:
Observation: Director: Chloé Zhao第 4 轮调用
[
...(之前历史),
{"role": "assistant", "content": "Thought: 上一步 Search 工具报错,我将重试并调整参数。\nAction: Search[\"Nomadland film director\"]"},
{"role": "user", "content": "Observation: Director: Chloé Zhao"}
]模型输出:
Thought: 我知道导演是 Chloé Zhao。下一步是查找她的出生年份,可以使用 Search 工具。
Action: Search["Chloé Zhao birth year"]外部执行 Action:
Observation: Birth year: 1982第 5 轮调用
[
...(之前历史),
{"role": "assistant", "content": "Thought: 我知道导演是 Chloé Zhao。下一步是查找她的出生年份,可以使用 Search 工具。\nAction: Search[\"Chloé Zhao birth year\"]"},
{"role": "user", "content": "Observation: Birth year: 1982"}
]模型输出:
Thought: 我知道 Chloé Zhao 的出生年份是 1982。现在我需要计算她到 2024 年的年龄,可以使用 Calculator 工具。
Action: Calculator["2024 - 1982"]外部执行 Action:
Observation: 42第 6 轮调用(最终答案)
[
...(之前历史),
{"role": "assistant", "content": "Thought: 我知道 Chloé Zhao 的出生年份是 1982。现在我需要计算她到 2024 年的年龄,可以使用 Calculator 工具。\nAction: Calculator[\"2024 - 1982\"]"},
{"role": "user", "content": "Observation: 42"}
]模型输出:
Thought: 根据之前的计算,Chloé Zhao 在 2024 年的年龄是 42 岁。
Final Answer: 42健壮性
第一步没有可用 Action
- Prompt 规则:尝试改写问题以匹配可用工具;如果仍不匹配,直接给出 Final Answer(基于已有知识推理)。
Action 执行报错
- Prompt 规则:调整参数重试(最多 2 次),仍失败则换工具或给出最佳猜测。
执行结果不符合目标
- Prompt 规则:重新分析,调整 Action 参数或换工具。
死循环防护
- 外部控制循环次数(MAX 6)。
- 内部规则:同一 Action+参数最多执行 3 次。
- 触发条件时直接输出 Final Answer(即使是近似值)。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用。你还可以使用@来通知其他用户。