03-Agent 智能体开发实战指南(三):ReAct 框架深度解析

Agent 智能体开发实战指南(三):ReAct 框架深度解析

系列导读:这是《Agent 智能体开发实战指南》系列的第三篇,将深入讲解 ReAct 框架------Agent 智能体的核心思考与行动模式,通过实战案例理解「思考→行动→观察」的完整循环。


一、什么是 ReAct 框架?

1.1 核心概念

ReAct = Reasoning(推理) + Acting(行动)

ReAct 是让 Agent 像人类一样解决问题的关键框架:

复制代码
人类解决问题的过程:
1. 思考:分析问题,制定策略
2. 行动:执行某个步骤
3. 观察:查看结果
4. 再思考:根据结果调整策略
5. 重复 2-4,直到问题解决

ReAct 让 Agent 不再"直接回答",而是"一步步解决"

1.2 ReAct vs 直接回答

方式 示例 适用场景
直接回答 用户:"123×456 等于多少?" → LLM:"56088" 简单问题、LLM 已知知识
ReAct 模式 用户:"计算我的 BMI" → Agent:思考→获取体重→获取身高→计算→回答 复杂问题、需要外部数据

二、ReAct 循环详解

2.1 完整循环流程

复制代码
┌─────────────────────────────────────────────────────────┐
│                      ReAct 循环                          │
│                                                         │
│   ┌──────────┐                                          │
│   │    思考   │ ← 分析当前状态,决定下一步                 │
│   └────┬─────┘                                          │
│        │                                                │
│        ▼                                                │
│   ┌──────────┐                                          │
│   │    行动   │ ← 调用工具执行具体操作                    │
│   └────┬─────┘                                          │
│        │                                                │
│        ▼                                                │
│   ┌──────────┐                                          │
│   │    观察   │ ← 接收工具返回结果                        │
│   └────┬─────┘                                          │
│        │                                                │
│        ▼                                                │
│   ┌──────────┐      是     ┌─────────┐                  │
│   │   完成?  │ ───────────→│ 生成答案 │                 │
│   └────┬─────┘             └─────────┘                  │
│        │ 否                                             │
│        └──────────────────→                             │
│                    回到思考                              │
└─────────────────────────────────────────────────────────┘

2.2 每个阶段的任务

阶段 LLM 的任务 输出内容
思考 分析需求,评估已有信息,决定下一步 自然语言推理过程
行动 选择合适的工具,传入正确参数 工具调用请求
观察 解析工具返回,提取关键信息 内部状态更新

三、实战案例:BMI 计算器

3.1 场景设定

用户问:"计算我的 BMI"

问题拆解

  • BMI 公式:BMI = 体重 (kg) / (身高 (m))²
  • 需要数据:体重、身高
  • 数据来源:需要调用工具获取

3.2 工具定义

python 复制代码
from langchain.agents import create_agent
from langchain_community.chat_models.tongyi import ChatTongyi
from langchain_core.tools import tool


@tool(description="获取体重,返回值是整数,单位千克")
def get_weight() -> int:
    return 90


@tool(description="获取身高,返回值是整数,单位厘米")
def get_height() -> int:
    return 172


agent = create_agent(
    model=ChatTongyi(model="qwen3-max"),
    tools=[get_weight, get_height],
    system_prompt="""你是严格遵循 ReAct 框架的智能体,必须按「思考→行动→观察→再思考」的流程解决问题,
    且**每轮仅能思考并调用 1 个工具**,禁止单次调用多个工具。
    并告知我你的思考过程,工具的调用原因,按思考、行动、观察三个结构告知我""",
)

3.3 执行过程全记录

python 复制代码
for chunk in agent.stream(
    {"messages": [{"role": "user", "content": "计算我的 BMI"}]},
    stream_mode="values"
):
    latest_message = chunk['messages'][-1]

    if latest_message.content:
        print(latest_message.content)

    try:
        if latest_message.tool_calls:
            print(f"工具调用:{[tc['name'] for tc in latest_message.tool_calls]}")
    except AttributeError:
        pass

3.4 完整输出

复制代码
### 思考
要计算 BMI(身体质量指数),需要知道体重(千克)和身高(厘米)。公式为:
BMI = 体重(kg) / (身高(m))^2

由于目前既没有体重也没有身高的数据,我需要先获取其中一个值。
通常,先获取体重或身高都可以,但为了按步骤进行,我选择先获取体重。

### 行动
调用 `get_weight` 工具获取体重。

工具调用:['get_weight']

### 观察
获取到的体重是 **90 千克**。

### 思考
现在我已经有了体重(90 kg),接下来需要获取身高(厘米)才能计算 BMI。
因此,下一步应该调用 `get_height` 工具来获取身高数据。

### 行动
调用 `get_height` 工具获取身高。

工具调用:['get_height']

### 观察
获取到的身高是 **172 厘米**(即 1.72 米)。

### 思考
现在我已经有了计算 BMI 所需的所有数据:
- 体重 = 90 kg
- 身高 = 172 cm = 1.72 m

代入 BMI 公式:
BMI = 90 / (1.72 × 1.72) ≈ 30.39

根据世界卫生组织(WHO)的标准,BMI ≥ 30 属于 **肥胖** 范围。

因此,最终的 BMI 计算结果约为 **30.39**,属于肥胖范围。

3.5 关键观察点

  1. 思考过程透明化:每一步都有明确的思考说明
  2. 单工具调用:每次只调用一个工具,便于观察
  3. 状态累积:每次观察后,信息逐步完整
  4. 自然终止:信息足够后,直接生成答案

四、system_prompt 的设计艺术

4.1 基础版 vs 进阶版

基础版(不推荐)

python 复制代码
system_prompt="你是一个助手,可以回答用户问题。"

问题

  • 没有指定思考方式
  • 没有约束工具调用行为
  • LLM 可能直接回答,不调用工具

进阶版(推荐)

python 复制代码
system_prompt="""你是严格遵循 ReAct 框架的智能体,必须按「思考→行动→观察→再思考」的流程解决问题,
且**每轮仅能思考并调用 1 个工具**,禁止单次调用多个工具。
并告知我你的思考过程,工具的调用原因,按思考、行动、观察三个结构告知我。

可用工具:
- get_weight: 获取体重(千克)
- get_height: 获取身高(厘米)

回答格式:
### 思考
[你的分析]

### 行动
[你要调用的工具]

### 观察
[工具返回后,记录结果]
"""

4.2 system_prompt 核心要素

要素 作用 示例
角色定义 设定 Agent 身份 "你是严格遵循 ReAct 框架的智能体"
流程约束 规范思考方式 "必须按思考→行动→观察的流程"
工具说明 帮助 LLM 理解可用工具 列出工具名和用途
输出格式 统一响应结构 "按思考、行动、观察三个结构告知"
特殊约束 针对场景的限制 "每轮仅能调用 1 个工具"

五、多步推理场景

5.1 场景:旅行规划助手

用户问题:"我想去深圳玩 3 天,帮我规划一下"

需要的工具

  • get_weather(city) - 查询天气
  • get_hotels(city, budget) - 查询酒店
  • get_attractions(city) - 查询景点
  • get_transport(origin, dest) - 查询交通

ReAct 流程

复制代码
思考 1:需要先了解深圳的天气情况,以便推荐合适的活动
行动 1:调用 get_weather("深圳")
观察 1:深圳晴天,26°C,适合户外活动

思考 2:天气良好,接下来查询深圳的热门景点
行动 2:调用 get_attractions("深圳")
观察 2:获得景点列表:世界之窗、欢乐谷、大梅沙...

思考 3:需要知道用户的出发地才能查询交通
行动 3:调用 get_user_location()
观察 3:用户在北京

思考 4:查询北京到深圳的交通方式
行动 4:调用 get_transport("北京", "深圳")
观察 4:高铁 8 小时,飞机 3 小时...

思考 5:查询酒店信息
行动 5:调用 get_hotels("深圳", 500)
观察 5:获得酒店列表...

思考 6:信息收集完成,整合生成 3 天行程规划
→ 生成最终答案

5.2 代码实现

python 复制代码
@tool(description="查询城市天气")
def get_weather(city: str) -> str:
    pass

@tool(description="查询城市景点")
def get_attractions(city: str) -> str:
    pass

@tool(description="获取用户所在城市")
def get_user_location() -> str:
    pass

@tool(description="查询两地交通,传入出发地和目的地")
def get_transport(origin: str, dest: str) -> str:
    pass

@tool(description="查询酒店,传入城市和预算")
def get_hotels(city: str, budget: int) -> str:
    pass

agent = create_agent(
    model=ChatTongyi(model="qwen3-max"),
    tools=[get_weather, get_attractions, get_user_location, get_transport, get_hotels],
    system_prompt="你是旅行规划助手,按 ReAct 框架逐步收集信息后生成行程规划。"
)

六、ReAct 的高级技巧

6.1 条件分支处理

场景:根据工具返回结果决定下一步行动

python 复制代码
# 示例:根据天气决定推荐活动

### 思考
已获取天气信息:深圳今天下雨。
下雨天不适合户外活动,应该推荐室内景点。

### 行动
调用 get_indoor_attractions("深圳")  # 注意:这里选择了不同的工具

实现方式

  • 在 system_prompt 中说明条件逻辑
  • 训练 LLM 理解"如果...那么..."的推理

6.2 错误恢复

场景:工具调用失败时的处理

python 复制代码
### 行动
调用 get_weather("深圳湾")

### 观察
错误:城市"深圳湾"不存在

### 思考
工具返回错误,可能是城市名称不准确。
尝试使用更标准的名称"深圳"重新查询。

### 行动
调用 get_weather("深圳")

system_prompt 建议

python 复制代码
system_prompt="""...
如果工具调用失败或返回错误:
1. 分析错误原因
2. 尝试调整参数重新调用
3. 如果多次失败,告知用户并寻求更多信息
..."""

6.3 提前终止

场景:信息已足够,无需继续调用工具

python 复制代码
### 思考
用户只问了天气,已经获取到完整信息。
无需调用其他工具,直接回答即可。

七、调试与优化

7.1 打印完整执行轨迹

python 复制代码
for chunk in agent.stream(input_dict, stream_mode="values"):
    for msg in chunk['messages']:
        msg_type = type(msg).__name__
        
        if msg_type == "HumanMessage":
            print(f"👤 用户:{msg.content}")
        elif msg_type == "AIMessage":
            print(f"🤖 Agent: {msg.content}")
            if hasattr(msg, 'tool_calls') and msg.tool_calls:
                print(f"🔧 工具调用:{[tc['name'] for tc in msg.tool_calls]}")
        elif msg_type == "ToolMessage":
            print(f"📦 工具返回:{msg.content}")
        print("-" * 50)

7.2 常见问题与解决

问题 现象 解决方案
跳过思考 Agent 直接调用工具 在 prompt 中强调思考步骤
无限循环 反复调用同一工具 添加"避免重复调用"约束
工具选择错误 调用不相关的工具 优化工具 description
参数错误 传入错误参数类型 在 description 中明确参数格式

7.3 性能优化

问题:ReAct 循环次数过多,响应慢

优化策略

  1. 限制最大循环次数
python 复制代码
agent = create_agent(..., max_iterations=10)
  1. 并行调用独立工具
python 复制代码
# LangChain 支持并行调用无依赖的工具
# 如同时获取体重和身高
  1. 缓存工具结果
python 复制代码
# 对不变的数据(如用户信息)进行缓存
# 避免重复调用

八、本章小结

核心要点

  1. ReAct 循环:思考→行动→观察→再思考
  2. 透明化思考:让 Agent 输出推理过程,便于调试和信任
  3. system_prompt 设计:明确角色、流程、约束、格式
  4. 错误处理:工具失败时的恢复策略
  5. 提前终止:信息足够时直接回答

下章预告

下一篇我们将讲解 流式输出与状态管理,学习:

  • stream_mode 的各种模式详解
  • 如何实时展示 Agent 思考过程
  • 状态快照与调试技巧
  • 生产环境的流式处理

  1. Agent 智能体开发实战指南(一):从 LLM 到 Agent 的认知升级
  2. Agent 智能体开发实战指南(二):工具调用系统深度解析
  3. Agent 智能体开发实战指南(三):ReAct 框架深度解析(本文)
  4. Agent 智能体开发实战指南(四):流式输出与状态管理
  5. Agent 智能体开发实战指南(五):中间件系统与动态提示词
  6. Agent 智能体开发实战指南(六):RAG 与向量存储实战
  7. Agent 智能体开发实战指南(七):项目架构设计与工程化实践
  8. Agent 智能体开发实战指南(八):UI 集成与生产部署

本文是《Agent 智能体开发实战指南》系列的第三篇,下一篇将深入讲解流式输出与状态管理。

相关推荐
小程故事多_802 小时前
CLI Agent设计详解,架构、原理与流程实现(含业务Agent交互)
人工智能·架构·aigc·交互·ai编程
H Journey2 小时前
opencv中,把图片变成灰度图有什么用
人工智能·opencv·计算机视觉
铁蛋AI编程实战2 小时前
最新版 Kimi K2.5 进阶实战全攻略:从开源部署到 Agent 集群搭建(视频理解 + 多模态开发 + 高并发调优)
人工智能·python·开源·音视频
海兰2 小时前
OpenClaw安全保命指南:Skill 插件投毒风险全解析及应对措施
人工智能·安全·agent·openclaw
zh路西法2 小时前
【宇树机器人强化学习】(三):OnPolicyRunner和VecEnv以及RolloutStorage的python实现与解析
开发语言·python·深度学习·机器学习·机器人
Balrog-v2 小时前
2026最新保姆级教程:Windows 下使用 uv 从零配置 Python (OpenCV) 环境指南
windows·python·uv
梯度下降中2 小时前
Transformer原理精讲
人工智能·深度学习·transformer
weixin_6682 小时前
Agent 应该中 PDF 工具方案分析报告 - AI分析分享
人工智能·pdf
EZ_Python2 小时前
如何在 Windows 上将 Python 脚本打包为 macOS 原生应用
windows·python·macos