1. 背景

1.1.介绍

ReAct 是一个将 Reasoning(推理)Acting(行动) 相结合的范式,旨在让 LLM 与外部工具(如搜索引擎、计算器、数据库、API等)进行交互,从而更可靠、更准确地解决任务。

  • 核心思想:让模型在解决问题的过程中,生成一步一步的推理轨迹,并根据推理决定下一步要执行的动作。这模仿了人类在解决问题时的“思考-行动”循环。

该框架由普林斯顿大学和谷歌的研究员在 2022 年的论文《ReAct: Synergizing Reasoning and Acting in Language Models》中提出。

1.2.为什么需要ReAct

在 ReAct 出现之前,主要有两种让 LLM 与外界交互的方式:

  1. 仅行动(Act-only)

    • 方式:模型直接根据输入生成要执行的动作(例如,直接调用一个搜索API)。
    • 缺点:缺乏透明的推理过程,像一个“黑箱”。当任务复杂时,模型容易迷失方向,做出不合逻辑的动作,且错误难以追溯。
  2. 仅推理(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. 优势

  1. 透明性与可解释性:模型的整个思考过程(推理轨迹)是可见的,便于人类理解和调试。如果出错了,我们可以很容易地定位到是哪一步的推理或观察出了问题。
  2. 提升准确性与可靠性:通过结合外部工具,模型可以减少因自身知识局限或幻觉而产生的错误,答案更加基于事实。
  3. 强大的任务规划能力:对于需要多步骤分解的复杂任务,ReAct 提供了结构化的解决路径,使模型能更好地处理任务规划。
  4. 高效性:相比于漫无目的地生成大量文本,ReAct 的步骤通常更精简、目标更明确。

3. 实践示例:System Prompt

3.1. 示例:System Prompt

后续示例中,体现 ReAct 流程的 System Prompt 内容。

这个 Prompt 是放在 system role 中的,目的是告诉模型:

  1. 它的身份和任务(角色设定)
  2. 它能用的工具列表(Action 列表,带 schema)
  3. 它的工作规则(推理、执行、异常处理、终止条件)
  4. 它的输出格式(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

健壮性

  1. 第一步没有可用 Action

    • Prompt 规则:尝试改写问题以匹配可用工具;如果仍不匹配,直接给出 Final Answer(基于已有知识推理)。
  2. Action 执行报错

    • Prompt 规则:调整参数重试(最多 2 次),仍失败则换工具或给出最佳猜测。
  3. 执行结果不符合目标

    • Prompt 规则:重新分析,调整 Action 参数或换工具。
  4. 死循环防护

    • 外部控制循环次数(MAX 6)。
    • 内部规则:同一 Action+参数最多执行 3 次。
    • 触发条件时直接输出 Final Answer(即使是近似值)。

KerryWu
679 声望171 粉丝

保持饥饿