AI AgentTechnical Deep Dive

ReAct 与思维链:AI 的推理模式

发布时间2025/11/29
分类AI Agent
预计阅读8 分钟
作者吴长龙
*

ReAct 和思维链(CoT)是当前 AI Agent 最核心的推理范式。本文深入解析两者的原理、区别以及如何选择合适的推理模式。

01.内容

# ReAct 与思维链:AI 的推理模式

当我们谈论 AI Agent 时,核心问题只有一个:AI 如何推理?

传统聊天机器人只是「输入→输出」的单向映射,而 Agent 的关键在于能够多步思考、持续推理、动态调整。这个能力的基础就是各种推理模式,其中最核心的两个范式是 思维链(Chain of Thought, CoT)ReAct(Reasoning + Acting)

本文将深入解析这两种推理模式的原理、实现方式以及适用场景。

02.1. 思维链(Chain of Thought)

1.1 什么是思维链?

思维链(CoT)是一种让 AI 在给出最终答案前,先展示推理过程的技术。它的核心思想是:与其直接给出答案,不如让模型把思考过程「说出来」。

没有思维链:

code snippetcode
用户: 25 * 4 + 10 = ?
AI: 110

有思维链:

code snippetcode
用户: 25 * 4 + 10 = ?
AI: 先算 25 * 4 = 100,再算 100 + 10 = 110。所以答案是 110。

看似简单的一个变化,却带来了惊人的效果提升。研究表明,CoT 能让大语言模型在数学、逻辑、代码等任务上的性能提升 50% 以上。

1.2 思维链的原理

为什么「说出思考过程」能提升 AI 的能力?这里有几个关键原因:

1. 分布式的计算压力

将复杂问题拆解为多个简单步骤,每个步骤只需少量 Token 就能准确处理。这避免了「一步到位」时需要同时考虑所有因素的认知压力。

2. 中间结果的可追溯性

当 AI 说出「先算 25 * 4 = 100」时,这个中间结果成为了下一步推理的锚点。后续推理可以在这个锚点基础上继续,而不是从头开始。

3. 自我纠错的可能性

如果推理过程中间出现错误,模型可以回头检查中间步骤,发现矛盾点并尝试修正。这是单纯「输入→输出」模式做不到的。

1.3 思维链的实现方式

思维链的实现主要有三种方式:

(1)Few-shot 示例引导

在提示词中给出几个「思考过程」的例子,让模型模仿:

python snippetpython
prompt = """
问题:小明有 5 个苹果,小红给了他 3 个,小明吃了 2 个,现在有多少个?
思考过程:
1. 小明原来有 5 个苹果
2. 小红给了他 3 个,5 + 3 = 8
3. 小明吃了 2 个,8 - 2 = 6
答案:6 个

问题:如果每袋子里有 12 个苹果,小明买了 3 袋子,又买了 2 个散装的,现在有多少个?
思考过程:
"""

(2)显式引导词

简单加一句「让我们一步步思考」:

code snippetcode
问题:如果列文虎克最早发现的细菌是 1676 年,而青霉素是 1928 年发现的,两者相差多少年?
让我们一步步思考。

这种简单的话语就能触发模型的 CoT 模式,效果出乎意料地好。

(3)结构化思维链

对于复杂推理,可以强制模型按固定格式输出:

code snippetcode
请按以下格式回答:
1. 理解问题:...
2. 分析条件:...
3. 推导过程:...
4. 得出结论:...

1.4 思维链的适用场景

思维链特别适合以下场景:

  • 数学计算:需要逐步推导的任务
  • 逻辑推理:涉及条件判断、因果关系的任务
  • 代码生成:需要理解问题→分析→实现的流程
  • 复杂决策:需要权衡多个因素的决策

1.5 思维链的局限性

思维链不是万能的:

  • 对模型规模有要求:一般需要 30B 参数以上的模型才能稳定触发 CoT
  • 可能产生幻觉:推理步骤越多,中间步骤出错的可能性越大
  • 不适用于简单问题:对于「今天天气怎么样」这类问题,CoT 没有意义

03.2. ReAct 范式

2.1 什么是 ReAct?

ReAct(Reasoning + Acting)由 Google 在 2022 年提出,是一种将推理和行动结合的 Agent 架构。

如果说思维链是「在心里想」,那 ReAct 就是「边想边做」:

  • Reasoning:推理当前状态,决定下一步行动
  • Acting:执行行动(通常是调用工具),获取反馈
  • Observing:观察行动结果,更新认知
  • Repeat:循环直到任务完成

2.2 ReAct 的工作流程

code snippetcode
用户:帮我查一下今天北京的天气,如果下雨就提醒我带伞

ReAct 循环:
1. Thought:我需要先查询北京今天的天气
2. Action:调用天气 API
3. Observation:结果显示北京今天有雨,气温 15-20 度
4. Thought:根据天气结果,今天有雨,我需要提醒用户带伞
5. Action:生成提醒文本
6. Output:带伞提醒

注意这个循环中的 Thought → Action → Observation 三步,每一步都是基于前一步的结果动态生成的。

2.3 ReAct vs 思维链

维度思维链 (CoT)ReAct
核心动作纯推理推理 + 行动
外部交互有(工具调用)
反馈机制有(观察行动结果)
适用场景封闭域任务开放域任务
实现复杂度简单较复杂

关键区别:思维链是「想清楚了再做」,ReAct 是「做一做再想」

在某些任务中,ReAct 的效果显著优于单纯的 CoT。例如在 HotpotQA(多跳问答)任务中,ReAct 的准确率比 CoT 提升了 8-10 个百分点。

2.4 ReAct 的实现

ReAct 的实现需要几个关键组件:

(1)Prompt 模板

python snippetpython
prompt = """
你是一个智能助手,可以调用工具来完成任务。

可用工具:
- search(query): 搜索信息
- calculate(expression): 数学计算

请按照以下格式回答:
Thought: 你对当前情况的分析
Action: 你要执行的行动(如果是最终答案,输出 Finish)
Action Input: 行动的输入
Observation: 行动的结果

开始!

问题:{question}
"""

(2)循环控制

python snippetpython
def react_agent(question, max_iterations=10):
    context = []
    
    for i in range(max_iterations):
        # 1. 生成 Thought + Action
        response = llm.generate(context + [f"问题:{question}"])
        
        # 2. 解析动作
        thought = extract_thought(response)
        action = extract_action(response)
        
        # 3. 执行动作
        if action == "Finish":
            return extract_answer(response)
        
        result = execute_tool(action)
        
        # 4. 添加观察结果
        context.append(f"Thought: {thought}")
        context.append(f"Action: {action}")
        context.append(f"Observation: {result}")
    
    return "达到最大迭代次数"

(3)与工具系统的集成

ReAct 的强大之处在于可以动态选择工具

python snippetpython
available_tools = {
    "search": search_function,
    "calculate": calculate_function,
    "lookup": lookup_function,
    "send_email": send_email_function,
}

def execute_tool(action):
    tool_name, tool_input = parse_action(action)
    return available_tools[tool_name](tool_input)

2.5 ReAct 的进阶变体

ReAct 提出后,社区发展出多种改进版本:

(1)ReAct + CoT(CoT+ReAct)

先用 CoT 全面分析,再用 ReAct 执行:

code snippetcode
Thought:首先让我分析这个问题...(CoT 模式)
Action:基于分析,我需要...(ReAct 模式)

(2)Self-Ask

模型先自问自答,再给出最终答案:

code snippetcode
用户:爱因斯坦什么时候出生?
Self-Ask:我应该先查一下爱因斯坦的出生日期...
Action:search("爱因斯坦 出生 日期")
Observation:1879年3月14日
回答:爱因斯坦出生于 1879 年 3 月 14 日

(3)Plan-and-Solve

先制定计划,再逐步执行:

code snippetcode
Thought:这个任务可以分成三步:1) 查天气 2) 判断是否下雨 3) 生成提醒
Action:先执行第1步
...

04.3. 如何选择推理模式

3.1 决策框架

选择推理模式时,考虑以下因素:

(1)任务是否需要外部信息?

  • 需要 → ReAct
  • 不需要 → CoT

(2)任务是否有明确的步骤?

  • 有明确步骤 → CoT 或 Plan-and-Solve
  • 步骤需要动态决定 → ReAct

(3)任务是否需要工具调用?

  • 需要 → ReAct
  • 不需要 → CoT

(4)模型的规模?

  • 大于 30B 参数 → 两者都可以
  • 小于 30B 参数 → 优先 CoT(ReAct 效果不稳定)

3.2 组合使用

实际项目中,往往需要组合使用多种推理模式

python snippetpython
def hybrid_agent(task):
    # 第一阶段:用 CoT 分析任务
    analysis = cot_analyze(task)
    
    # 第二阶段:根据分析结果选择模式
    if needs_external_data(analysis):
        return react_execute(analysis)
    elif has_clear_steps(analysis):
        return plan_execute(analysis)
    else:
        return cot_generate(analysis)

05.4. 实战:构建一个 ReAct Agent

让我们用 LangGraph 实现一个完整的 ReAct Agent:

python snippetpython
from langgraph.graph import StateGraph, END
from langchain_openai import ChatOpenAI
from langchain.tools import tool

@tool
def search_wiki(query: str):
    """搜索维基百科"""
    # 实现搜索逻辑
    return wikipedia.search(query)

@tool  
def calculate(expr: str):
    """计算数学表达式"""
    return eval(expr)

# 定义状态
class AgentState(dict):
    question: str
    thought: str
    action: str
    action_input: str
    observation: str
    answer: str
    iterations: int

# 推理节点
def reason_node(state: AgentState):
    llm = ChatOpenAI(model="gpt-4")
    
    prompt = f"""
    问题:{state['question']}
    之前的观察:{state.get('observation', '无')}
    
    你需要决定下一步做什么。可用工具:search_wiki, calculate
    请按以下格式回答:
    Thought: 你的分析
    Action: 工具名 或 Finish
    Action Input: 工具输入 或 最终答案
    """
    
    response = llm.invoke(prompt)
    # 解析 response...
    return {"thought": thought, "action": action, "action_input": input_}

# 执行节点
def act_node(state: AgentState):
    tool = get_tool(state["action"])
    result = tool.invoke(state["action_input"])
    return {"observation": result, "iterations": state["iterations"] + 1}

# 构建图
graph = StateGraph(AgentState)
graph.add_node("reason", reason_node)
graph.add_node("act", act_node)
graph.set_entry_point("reason")

# 添加条件边
def should_continue(state):
    if state["action"] == "Finish":
        return "end"
    return "act"

graph.add_conditional_edges("reason", should_continue)
graph.add_edge("act", "reason")

app = graph.compile()

06.5. 总结

模式核心思想适用场景复杂度
CoT说出推理过程数学、逻辑、代码
ReAct边想边做需要工具调用的开放任务
Plan-and-Solve先计划再执行多步骤复杂任务
Self-Ask自问自答需要澄清的任务

理解这些推理模式,是构建高效 AI Agent 的基础。下一篇文章我们将介绍如何选择和比较不同的 LLM API——毕竟,再好的推理模式,也需要强大的模型来支撑。