ReAct推理行动范式详解

ReAct(推理 + 行动)范式详解

1. 核心概念

1.1 什么是 ReAct

ReAct(Reason + Act)是一种让大语言模型交替进行推理行动的框架,通过"思考-行动-观察"的循环,使模型能够利用外部工具和实时信息来解决问题。

核心思想:将复杂任务分解为一系列的推理步骤和行动步骤,模型在每一步中:

  1. 思考:分析当前状态,决定下一步需要做什么
  2. 行动:调用工具获取外部信息或执行操作
  3. 观察:接收工具返回的结果,更新状态
  4. 循环:重复上述过程直到任务完成

1.2 ReAct 的本质原理

ReAct 并没有赋予模型真正的行动能力,它的核心在于把"思考"和"行动"都表达为文本,让模型在文本空间中模拟推理和决策过程。

关键洞察

  • 推理(Reasoning):生成自然语言思考,分析问题、制定计划
  • 行动(Acting):生成结构化工具调用指令
  • 观察(Observation):接收工具执行结果,作为下一步的输入

1.3 ReAct 与 CoT 的关系

技术 核心能力 适用场景 工具使用
CoT 纯推理(思考) 数学题、逻辑题、代码生成 不需要
ReAct 推理 + 行动 需要查询信息、调用工具的任务 必须

对比示例

python 复制代码
# CoT 场景:数学计算
cot_prompt = """
问题:3个人3天用3桶水,9个人9天用几桶水?

让我一步步思考:
"""

# ReAct 场景:查询天气并给出建议
react_prompt = """
问题:北京明天天气怎么样?我需要穿什么衣服?

可用工具:get_weather(city, date)

请按照以下格式回答:
思考:[分析问题]
行动:[调用工具]
观察:[工具返回结果]
...
最终答案:[综合回答]
"""

2. ReAct 的工作流程

2.1 基础流程

复制代码
输入问题 → 思考 → 行动 → 观察 → 思考 → 行动 → 观察 → ... → 得出答案

2.2 详细步骤

python 复制代码
class ReActWorkflow:
    """ReAct 工作流程"""
    
    def __init__(self, llm, tools, max_steps=10):
        self.llm = llm          # 大语言模型
        self.tools = tools      # 可用工具列表
        self.max_steps = max_steps  # 最大步数限制
        self.history = []       # 历史记录
    
    def run(self, task):
        """执行 ReAct 流程"""
        for step in range(self.max_steps):
            # 1. 思考阶段
            thought = self._reason(task)
            self.history.append({"step": step, "thought": thought})
            
            # 2. 判断是否完成
            if self._is_complete(thought):
                return self._summarize()
            
            # 3. 行动阶段
            action = self._decide_action(thought)
            self.history.append({"step": step, "action": action})
            
            # 4. 执行工具
            observation = self._execute_action(action)
            self.history.append({"step": step, "observation": observation})
            
            # 5. 更新任务状态
            task = self._update_task(task, observation)
        
        return "任务未完成,已达到最大步数限制"

3. ReAct Prompt 的结构设计

3.1 四部分组成

组成部分 作用 示例
任务描述 描述问题目标和可用工具 "请查询上海明天的天气"
工具说明 告诉模型有哪些工具可用及使用方式 "get_weather(city, date)"
示例轨迹 展示完整的"思考-行动-观察"循环 见下方示例
当前问题 需要解决的具体问题 "北京明天天气怎么样?"

3.2 完整 Prompt 模板

python 复制代码
def build_react_prompt(task, tools, examples):
    """构建 ReAct 提示词"""
    prompt = """你是一个能够使用工具的智能助手。请按照"思考-行动-观察"的模式解决问题。
    
可用工具:
"""
    
    # 添加工具说明
    for tool in tools:
        prompt += f"- {tool['name']}: {tool['description']}\n"
        prompt += f"  参数:{tool['parameters']}\n\n"
    
    # 添加示例轨迹
    prompt += "示例:\n"
    for example in examples:
        prompt += f"问题:{example['question']}\n"
        for step in example['trajectory']:
            prompt += f"思考:{step['thought']}\n"
            if 'action' in step:
                prompt += f"行动:{step['action']}\n"
            if 'observation' in step:
                prompt += f"观察:{step['observation']}\n"
        prompt += f"答案:{example['answer']}\n\n"
    
    # 添加当前问题
    prompt += f"问题:{task}\n"
    prompt += "思考:"
    
    return prompt

# 使用示例
tools = [
    {
        "name": "get_weather",
        "description": "获取指定城市指定日期的天气信息",
        "parameters": {"city": "城市名称", "date": "日期(格式:YYYY-MM-DD)"}
    },
    {
        "name": "search_flight",
        "description": "搜索航班信息",
        "parameters": {"from": "出发城市", "to": "到达城市", "date": "日期"}
    }
]

examples = [
    {
        "question": "上海明天天气怎么样?",
        "trajectory": [
            {"thought": "我需要查询上海明天的天气信息"},
            {"action": "get_weather(city='上海', date='2024-01-15')"},
            {"observation": "上海明天晴,温度15-22摄氏度,微风"}
        ],
        "answer": "上海明天晴,温度15-22摄氏度,建议穿薄外套。"
    }
]

prompt = build_react_prompt("北京明天天气怎么样?我需要穿什么衣服?", tools, examples)
print(prompt)

4. ReAct 的实现示例

4.1 基础 ReAct Agent

python 复制代码
class ReActAgent:
    """基础 ReAct 智能体"""
    
    def __init__(self, llm, tools):
        self.llm = llm
        self.tools = tools
        self.max_steps = 10
        self.format_instructions = """
        请按照以下格式输出:
        
        思考:[分析当前情况,决定下一步行动]
        行动:[工具名称](参数1=值1, 参数2=值2)
        观察:[等待工具返回结果]
        
        如果不需要工具,直接输出:
        思考:[分析问题]
        答案:[最终回答]
        """
    
    def _parse_action(self, response):
        """解析模型输出中的行动指令"""
        import re
        pattern = r'行动:(\w+)\((.*)\)'
        match = re.search(pattern, response)
        
        if match:
            tool_name = match.group(1)
            params_str = match.group(2)
            
            # 解析参数
            params = {}
            for param in params_str.split(','):
                if '=' in param:
                    key, value = param.split('=', 1)
                    params[key.strip()] = value.strip().strip("'\"")
            
            return {"tool": tool_name, "params": params}
        
        return None
    
    def _execute_tool(self, tool_name, params):
        """执行工具调用"""
        if tool_name in self.tools:
            return self.tools[tool_name](**params)
        return f"未知工具:{tool_name}"
    
    def run(self, task):
        """执行任务"""
        prompt = f"""
        {self.format_instructions}
        
        可用工具:
        {self.tools.keys()}
        
        任务:{task}
        
        思考:
        """
        
        for step in range(self.max_steps):
            response = self.llm.generate(prompt)
            print(f"步骤{step+1}: {response}")
            
            # 检查是否包含答案
            if "答案:" in response:
                return response.split("答案:")[-1].strip()
            
            # 解析行动
            action = self._parse_action(response)
            if action:
                observation = self._execute_tool(action["tool"], action["params"])
                print(f"观察:{observation}")
                
                # 更新 prompt
                prompt += f"{response}\n观察:{observation}\n思考:"
            else:
                # 没有行动,直接结束
                return response
        
        return "任务未完成,已达到最大步数限制"

# 定义工具
def get_weather(city, date):
    """模拟天气查询工具"""
    return f"{date} {city}天气晴,温度15-25度"

def search_web(query):
    """模拟网页搜索工具"""
    return f"搜索结果:{query} - 相关信息..."

# 创建智能体
tools = {"get_weather": get_weather, "search_web": search_web}
# agent = ReActAgent(my_llm, tools)
# result = agent.run("北京明天天气怎么样?")

4.2 带记忆的 ReAct Agent

python 复制代码
class ReActAgentWithMemory:
    """带记忆的 ReAct 智能体"""
    
    def __init__(self, llm, tools):
        self.llm = llm
        self.tools = tools
        self.memory = []  # 短期记忆
        self.max_steps = 10
    
    def _store_memory(self, content):
        """存储记忆"""
        self.memory.append(content)
        # 保持记忆在合理范围内
        if len(self.memory) > 20:
            self.memory = self.memory[-10:]
    
    def run(self, task):
        """执行任务"""
        history = "\n".join(self.memory)
        
        prompt = f"""
        你是一个带记忆的智能助手。
        
        历史记录:
        {history}
        
        当前任务:{task}
        
        可用工具:{self.tools.keys()}
        
        请按照思考-行动-观察的模式解决问题。
        """
        
        for step in range(self.max_steps):
            response = self.llm.generate(prompt)
            
            if "答案:" in response:
                answer = response.split("答案:")[-1].strip()
                self._store_memory(f"任务:{task},答案:{answer}")
                return answer
            
            action = self._parse_action(response)
            if action:
                observation = self._execute_tool(action["tool"], action["params"])
                self._store_memory(f"行动:{action['tool']},结果:{observation}")
                prompt += f"\n{response}\n观察:{observation}"
        
        return "任务未完成"

5. ReAct 的进阶技术

5.1 Reflexion(反思)

核心思想:在每次行动后进行反思,评估行动效果,调整策略。

python 复制代码
class ReflexionAgent(ReActAgent):
    """带反思的 ReAct 智能体"""
    
    def __init__(self, llm, tools):
        super().__init__(llm, tools)
        self.reflection_prompt = """
        请反思刚才的行动:
        1. 行动是否正确?
        2. 是否有更好的选择?
        3. 下一步应该怎么做?
        """
    
    def run(self, task):
        for step in range(self.max_steps):
            # 正常的思考-行动-观察流程
            thought = self._reason(task)
            action = self._decide_action(thought)
            observation = self._execute_action(action)
            
            # 反思阶段
            reflection = self.llm.generate(f"""
            当前任务:{task}
            思考:{thought}
            行动:{action}
            观察:{observation}
            
            {self.reflection_prompt}
            """)
            
            # 根据反思结果调整
            if "修正" in reflection or "更好" in reflection:
                # 重新规划
                task = self._adjust_task(task, reflection)
            
            if self._is_complete(observation):
                return self._summarize()
        
        return "任务未完成"

5.2 工具选择优化

核心思想:为每个工具添加使用条件,让模型更好地选择合适的工具。

python 复制代码
class ToolSelector:
    """工具选择器"""
    
    def __init__(self, tools):
        self.tools = tools
        self.selection_prompt = """
        根据以下任务,选择最合适的工具:
        
        任务:{task}
        
        可用工具:
        {tool_descriptions}
        
        请选择一个工具,并说明理由。
        """
    
    def select(self, task):
        """选择工具"""
        tool_descriptions = "\n".join([
            f"- {name}: {info['description']}(适用:{info['conditions']})"
            for name, info in self.tools.items()
        ])
        
        prompt = self.selection_prompt.format(
            task=task,
            tool_descriptions=tool_descriptions
        )
        
        # 调用 LLM 选择工具
        # response = self.llm.generate(prompt)
        # return parse_tool_selection(response)
        
        return None

# 使用示例
tools_with_conditions = {
    "get_weather": {
        "description": "获取天气信息",
        "conditions": "查询天气、气温、穿衣建议"
    },
    "search_web": {
        "description": "网页搜索",
        "conditions": "查询新闻、知识、最新信息"
    },
    "calculate": {
        "description": "数学计算",
        "conditions": "数学题、统计计算"
    }
}

# selector = ToolSelector(tools_with_conditions)
# tool = selector.select("北京明天天气怎么样?")

6. ReAct 在不同场景的应用

6.1 信息查询

示例任务:查询 Python 3.11 的新特性

ReAct 流程

复制代码
思考:我需要查询 Python 3.11 的新特性,这需要使用搜索工具
行动:search_web(query="Python 3.11 新特性")
观察:Python 3.11 引入了更快的解释器、模式匹配增强、更好的错误信息等
思考:搜索结果已经提供了足够的信息,可以总结回答
答案:Python 3.11 主要新特性包括:...

6.2 数据分析

示例任务:分析销售数据,找出销售额最高的产品

ReAct 流程

复制代码
思考:我需要分析销售数据,首先需要获取数据
行动:query_database(sql="SELECT product, SUM(sales) FROM sales GROUP BY product")
观察:产品A: 10000, 产品B: 8000, 产品C: 12000
思考:数据已经获取,可以直接分析得出结论
答案:销售额最高的产品是产品C,销售额为12000。

6.3 代码生成与调试

示例任务:编写一个 Python 函数来计算斐波那契数列,然后测试它

ReAct 流程

复制代码
思考:我需要编写一个斐波那契数列函数
行动:code_generator(language="python", task="编写斐波那契数列函数")
观察:def fibonacci(n): ...
思考:代码已生成,需要测试它是否正确
行动:code_executor(code="print(fibonacci(10))")
观察:输出:55
思考:测试结果正确,可以总结
答案:斐波那契数列函数已编写完成,测试通过。

7. ReAct 实践最佳实践

7.1 工具设计原则

  1. 单一职责:每个工具只做一件事
  2. 清晰描述:提供详细的工具描述和参数说明
  3. 返回结构化数据:工具返回结果尽量结构化
  4. 错误处理:工具应该处理异常情况

7.2 Prompt 设计技巧

python 复制代码
def advanced_react_prompt(task):
    """高级 ReAct 提示词"""
    return f"""
    你是一名专业的问题解决专家,能够使用各种工具来获取信息和执行操作。
    
    你的任务是解决以下问题:
    {task}
    
    可用工具:
    1. search_web(query) - 搜索互联网信息
    2. get_weather(city, date) - 获取天气信息
    3. calculate(expression) - 数学计算
    4. code_executor(code) - 执行代码
    
    工作流程:
    1. 思考:分析问题,决定需要什么信息或操作
    2. 行动:选择合适的工具并调用
    3. 观察:分析工具返回的结果
    4. 循环:根据观察结果决定下一步
    5. 总结:当获取足够信息后,给出最终答案
    
    注意事项:
    - 只在需要时调用工具
    - 如果已经有足够信息,直接回答
    - 如果工具调用失败,尝试其他方法
    - 保持思考过程清晰
    
    开始解决问题:
    """

7.3 错误处理策略

python 复制代码
class RobustReActAgent(ReActAgent):
    """健壮的 ReAct 智能体"""
    
    def _execute_tool_with_retry(self, tool_name, params, max_retries=3):
        """带重试的工具执行"""
        for attempt in range(max_retries):
            try:
                return self._execute_tool(tool_name, params)
            except Exception as e:
                print(f"工具调用失败(第{attempt+1}次):{e}")
                if attempt == max_retries - 1:
                    return f"工具调用失败:{str(e)}"
    
    def _handle_tool_error(self, error):
        """处理工具错误"""
        recovery_prompt = f"""
        工具调用失败:{error}
        
        请分析失败原因,并选择以下方案之一:
        1. 重试(使用不同参数)
        2. 使用其他工具
        3. 基于已有信息回答
        4. 告知用户无法完成
        """
        
        # decision = self.llm.generate(recovery_prompt)
        # return decision
        return "重试"

8. ReAct 与其他范式的结合

8.1 ReAct + RAG

python 复制代码
class ReActWithRAG:
    """ReAct + RAG 智能体"""
    
    def __init__(self, llm, tools, rag_system):
        self.llm = llm
        self.tools = tools
        self.rag_system = rag_system
    
    def run(self, task):
        # 首先检索相关知识
        context = self.rag_system.search(task)
        
        if context:
            # 如果找到相关知识,先基于知识回答
            prompt = f"""
            相关知识:{context}
            
            问题:{task}
            
            请根据以上知识回答问题,如果需要更多信息可以调用工具。
            """
            
            response = self.llm.generate(prompt)
            
            # 如果模型表示需要更多信息,则使用 ReAct
            if "需要" in response or "查询" in response:
                return self._react_flow(task)
            else:
                return response
        else:
            # 没有相关知识,直接使用 ReAct
            return self._react_flow(task)

8.2 ReAct + Plan-and-Execute

python 复制代码
class ReActWithPlanning:
    """ReAct + 规划智能体"""
    
    def __init__(self, llm, tools):
        self.llm = llm
        self.tools = tools
    
    def run(self, task):
        # 第一步:制定计划
        plan_prompt = f"""
        请为以下任务制定详细计划:
        
        任务:{task}
        
        可用工具:{self.tools.keys()}
        
        计划格式:
        步骤1:[描述]
        步骤2:[描述]
        ...
        """
        
        plan = self.llm.generate(plan_prompt)
        print(f"计划:{plan}")
        
        # 第二步:执行计划(使用 ReAct)
        for step in plan.split("\n"):
            if step.strip():
                result = self._react_step(step.strip())
                print(f"步骤结果:{result}")
        
        # 第三步:总结
        summary = self.llm.generate(f"""
        任务:{task}
        计划执行结果:{result}
        
        请总结任务完成情况。
        """)
        
        return summary

9. 常见问题与解决方案

Q: ReAct 适合什么场景?

A: ReAct 特别适合需要以下能力的场景:

  • 需要实时获取外部信息(如天气、新闻)
  • 需要调用工具执行操作(如数据库查询、代码执行)
  • 需要多步骤推理的复杂任务
  • 需要验证答案正确性的任务

Q: 如何评估 ReAct 智能体的性能?

A: 可以从以下几个方面评估:

  1. 任务成功率:能否正确完成任务
  2. 步骤效率:完成任务需要多少步
  3. 工具使用准确性:是否使用了合适的工具
  4. 错误恢复能力:遇到错误能否恢复
  5. 答案质量:最终答案的准确性和完整性

Q: ReAct 有什么局限性?

A:

  1. Token 消耗大:思考过程会消耗大量 Token
  2. 执行延迟:每步都需要调用模型和工具
  3. 工具依赖:需要预先定义好工具集
  4. 规划能力有限:模型可能无法制定最优计划

Q: 如何在实际项目中应用 ReAct?

A:

  1. 识别需求:确定哪些任务需要工具调用
  2. 定义工具:设计和实现工具接口
  3. 构建 Prompt:设计 ReAct 提示词模板
  4. 实现循环:编写思考-行动-观察的循环逻辑
  5. 优化迭代:根据实际效果调整 Prompt 和工具

10. 总结

ReAct 是一种强大的智能体框架,通过"思考-行动-观察"的循环,使大语言模型能够利用外部工具和实时信息来解决复杂问题。

核心要点

  • 推理与行动交替:模型先思考再行动,行动结果作为下一步的输入
  • 工具调用能力:通过结构化指令调用外部工具
  • 适用场景广泛:信息查询、数据分析、代码生成等
  • 可扩展性强:可以与 RAG、规划、反思等技术结合

应用价值

  • 解决需要实时信息的问题
  • 完成需要多步骤操作的任务
  • 提高答案的准确性和可靠性
  • 扩展模型的能力边界

通过掌握 ReAct 范式,可以构建更强大、更实用的 AI 应用。