AI工程化设计(五)Agent设计范式(1)ReAct

一、介绍

1. 什么是 ReAct

ReAct 是一种很经典的 Agent 设计范式,名字来自 Reason + Act,也就是"推理 + 行动"。

它的核心思想并不复杂:

不要让模型一次性把答案"憋"出来,而是让它在任务过程中不断循环下面几个动作:

  • 先根据当前信息判断,下一步最应该做什么
  • 再执行一个动作,比如搜索、调用工具、查询数据库、读取文件
  • 根据新得到的结果,继续判断下一步

所以,ReAct 的本质并不是"让模型更会思考",而是让模型能够 边想边做,边做边修正

这也是它和普通问答式 Prompt 最大的区别。很多真实任务并不是只靠语言生成就能完成,而是必须与外部世界交互。ReAct 正是为这种场景设计的。


2. 为什么 ReAct 很重要

在很多真实业务里,模型并不能只靠"知道一些知识"就给出可靠答案,它往往还需要去查、去看、去验证。

比如下面这些场景:

  • 信息不完整,需要先检索资料
  • 问题比较复杂,需要逐步拆解
  • 中间可能出现错误,需要根据反馈纠偏
  • 最终结果依赖工具执行,而不是纯文本生成

举个很典型的例子:

如果用户问"某客户的订单为什么失败",模型本身并不知道答案。它需要去查订单数据库、检索服务日志、确认接口状态,甚至比对不同系统之间的数据。没有这些动作,模型再聪明也只能猜。

ReAct 的价值就在这里:
它把"猜答案"变成了"查信息、做动作、再判断"。

3、核心结构

最经典的 ReAct 流程一般可以抽象成下面几个阶段:

  • Thought:当前应该如何推进
  • Action:执行什么动作
  • Observation:动作返回了什么结果
  • 重复上面三步
  • Final Answer:最终输出结果

可以把它理解成一个闭环:

问题 → 判断下一步 → 调工具 / 查信息 → 获取结果 → 再判断下一步 → 最终回答

这个过程看起来很像人处理问题的方式。

人遇到复杂任务时,通常也不是立刻给答案,而是先判断、再操作、再根据结果调整方向。ReAct 把这种过程显式化了。

4、一个简单例子

比如用户说:

帮我订一张下周一下午从上海到北京的高铁,优先 3 点后出发、二等座。

如果是 ReAct Agent,它通常不会立刻输出一个"想象中的结果",而是会这样推进:

  1. 先识别用户约束:出发地、目的地、日期、出发时间偏好、座位类型
  2. 调用车次查询工具
  3. 读取工具返回结果,筛选是否有 3 点后出发且有二等座的班次
  4. 如果没有完全匹配,就尝试寻找次优方案
  5. 在下单前向用户确认
  6. 最后调用订票工具完成操作

这正是 ReAct 特别适合"任务执行型 Agent"的原因。

它不是一次性输出答案,而是在执行过程中动态决策。

5、ReAct 的优缺点

优点

ReAct 之所以经典,是因为它在很多实际场景里确实很好用。

首先,它的可解释性更强。因为整个过程是分步骤推进的,所以更容易看出每一步在做什么,出了问题也更容易排查。

其次,它通常比直接回答更稳。当信息不足时,模型会先去查,而不是直接编造答案。

再者,它也比较容易扩展。只要给 Agent 接入新的工具,它的能力就能被持续增强。

另外,ReAct 还有一个很重要的特点,就是具备纠偏能力。前一步拿到的新信息可能会改变后续判断,这使得系统不像单轮输出那样"一错到底"。

最后,它很接近真实工作流。很多人类任务本来就是"分析一下、操作一下、再看结果",ReAct 和这种方式天然契合。


缺点

当然,ReAct 也不是万能的。

最常见的问题是:步数一多,成本和时延就会上去。

一次任务如果要循环很多轮,那么 token 消耗和工具调用时间都会明显增加。

第二个问题是:工具一多,模型可能会乱用。

如果工具定义不清楚,或者工具能力边界重叠,Agent 很容易频繁调用无效工具。

第三,ReAct 对 Observation 的质量非常敏感

如果工具返回结果不完整、不准确,模型后续的判断就会被带偏。

另外,它对 prompt、工具描述、停止条件也比较敏感。

同样的流程,稍微改一下提示词或工具定义,行为就可能明显不同。

还有一点很现实:对于简单任务,ReAct 反而可能显得太重。

一个本来一句话就能回答的问题,没必要硬走多轮推理和工具调用。


实际落地中的常见做法

因此,很多工程系统并不会"纯用 ReAct",而是把它和其他策略组合使用,比如:

  • 简单任务直接回答
  • 复杂任务再进入 ReAct
  • 高风险动作必须人工确认
  • 大任务先做 Plan,再在子任务里使用 ReAct

这也是 ReAct 在工程上更常见的形态:
**不是唯一范式,而是工作流中的一个核心机制。**所以很多系统不会纯用 ReAct,而是把它和别的范式组合。

6、使用 ReAct 时的几个实践建议

在实际开发中,想让 ReAct 更稳定,通常要注意几件事。

第一,工具描述一定要清楚。

模型是否能正确调用工具,和工具名、参数说明、适用场景描述关系很大。

第二,一步只做一件高价值的事。

不要让模型一口气做太多动作,否则很容易失控。

第三,给它明确的停止条件。

比如"拿到足够证据后结束""最多调用工具 N 次""高风险操作必须确认",这些都很重要。

第四,Observation 尽量结构化。

工具返回结果越清晰,模型越容易做出正确判断。

第五,不要把所有任务都强行套成 ReAct。

简单问题直接回答,复杂问题再进入 ReAct,往往更实用。

二、ReAct 的基本使用方式

常见的 Prompt 模板

在工程实践里,ReAct 常常会被写成类似下面这样的系统提示:

复制代码
你是一个可以使用工具的助手。
目标:解决用户问题,但不要凭空猜测。
规则:
1. 如果信息不足,优先调用工具获取信息
2. 每次只做一个最有价值的动作
3. 根据工具返回结果决定下一步
4. 有充分证据后再给最终答案
5. 如果涉及高风险操作,先请求确认

这个模板背后的思想很简单:

  • 不鼓励"猜"
  • 鼓励先查证
  • 每一步只做最必要的动作
  • 最终输出要建立在证据之上

这其实就是 ReAct 的核心原则。更准确地说是:

  • tool 必须有,尤其是函数名、参数类型、docstring 这几个信息
  • system_prompt 只是行为提示,不是 ReAct 的硬性必需项
  • ReAct 的"循环推理 + 调工具"主要是 agent 运行机制,不是你一定要在提示词里写 "ReAct"

ReAct 真正发挥作用,往往离不开工具系统。常见的工具可能包括:

search_docs(query)

query_db(sql)

read_log(service, time_range)

send_email(...)

有了这些工具,模型就不再只是"说",而是可以"做"。

在这个意义上,ReAct 可以理解为一种调度机制:

它负责根据当前上下文,决定什么时候该查文档、什么时候该查数据库、什么时候该读日志,以及什么时候已经足够给出最终答案。


代码实现

以langchain为例可以使用以下代码:

复制代码
from langchain.agents import create_agent

agent = create_agent(
    llm,
    tools=xxx,
)

result = agent.invoke({"messages": [{"role": "user", "content": question}]})
  • llm.invoke(...) 是一次模型调用,不算ReAct

因为只负责把输入发给模型,最多返回 tool_calls,不会自动帮你执行工具

  • agent.invoke(...) 是启动一个带循环的 agent 运行时

create_agent 会把模型和工具编成一个运行时,内部会在 model node -> tools node -> model node 之间反复跳,直到模型给出最终答案

这里需要注意:

三、ReAct 适合用在哪些场景

ReAct 并不是适合所有任务,但它非常适合那些不能只靠脑补完成的工作。

常见场景包括:

1. 检索问答

需要查网页、知识库、文档,再基于检索结果回答问题。

2. 业务排障

需要查日志、查数据库、看监控、分析接口状态,然后定位问题原因。

3. 办公自动化

需要调用日历、邮件、表格、工单系统等外部工具,完成真实操作。

4. 编码助手

需要读取代码文件、检索仓库、运行测试、根据报错再修复代码。

5. 多步决策任务

任务中途要根据结果改变路线,而不是一开始就把路径固定死。

一句话总结就是:

只要任务不是"光靠生成文字就能完成",ReAct 往往都比一次性回答更靠谱。

四、demo

用户询问

复制代码
帮我判断一下北京明天下午适不适合跑步

ReAct

复制代码
import importlib
import json
import os

from langchain.agents import create_agent
from langchain_core.tools import tool
from langchain_openai import ChatOpenAI


@tool
def get_weather(city: str, day: str) -> str:
    """查询某个城市某一天的天气;有真实工具时优先调用,否则返回 mock 数据。"""
    module_name = os.getenv("WEATHER_TOOL_MODULE")
    if module_name:
        try:
            module = importlib.import_module(module_name)
            result = module.get_weather(city, day)
            return result if isinstance(result, str) else json.dumps(result, ensure_ascii=False)
        except Exception:
            pass

    fake_db = {
        ("北京", "明天"): {
            "weather": "多云",
            "temp_c": 24,
            "wind_level": 2,
            "rain": False,
        }
    }
    return json.dumps(
        fake_db.get(
            (city, day),
            {"weather": "未知", "temp_c": None, "wind_level": None, "rain": None},
        ),
        ensure_ascii=False,
    )


llm = ChatOpenAI(
    model="gpt-5.1",
    base_url="https://llm-gateway.xxx.xxx.xx/v1",
    api_key="dummy",
    default_headers={
        "X-Api-Key": "******",
    },
    temperature=0,
    use_responses_api=False,
)

agent = create_agent(
    llm,
    tools=[get_weather],
    system_prompt="你是一个遵循 ReAct 风格的助手。信息不足时先调用工具,拿到结果后再给出结论。",
)


def main() -> None:
    question = "帮我判断一下北京明天下午适不适合跑步"
    result = agent.invoke({"messages": [{"role": "user", "content": question}]})
    print(result["messages"][-1].content)


if __name__ == "__main__":
    main()

输出:

根据明天北京下午的天气情况(多云、约24℃、微风2级、无降雨),整体来说是很适合跑步的。

简单建议:

  • 时间:下午 4 点以后更舒适,避免日照最强时段。

  • 装备:短袖+短裤即可,带一小瓶水。

  • 配速:如果是平时有跑步习惯,可以正常训练配速;如果最近较少运动,可以适当放慢,当成轻松跑。

不适合跑步的情况(即使天气不错也要注意):

  • 近期感冒、发烧、咳嗽、身体明显疲劳。

  • 心率异常、胸闷、头晕等不适症状。

如果你告诉我你的跑步习惯(比如每周几次、单次几公里),我可以帮你具体设计一下明天下午的跑步计划。

测试发现去掉system_prompt,效果是一样的。

相关推荐
qq_283720051 小时前
2026 最新 Python+AI 零基础入门实战教程:从零搭建企业级人工智能项目
人工智能·python·#机器学习·#python #ai零基础·#大模型开发·#rag·#ai避坑
Kevin_Kung1 小时前
A2A-多智能体协作的“高速公路”
人工智能
小花皮猪1 小时前
2026 SERP + LLM 训练数据采集指南(Bright Data MCP + Dify)
人工智能·爬虫·工作流·dify·serp
CoderJia程序员甲1 小时前
GitHub 热榜项目 - 日榜(2026-04-23)
人工智能·ai·大模型·github·ai教程
叹一曲当时只道是寻常1 小时前
memos-cli 安装与使用教程:将 Memos 笔记同步到本地并支持 AI 语义搜索
人工智能·笔记·golang
财经资讯数据_灵砚智能1 小时前
基于全球经济类多源新闻的NLP情感分析与数据可视化(夜间-次晨)2026年4月22日
大数据·人工智能·python·信息可视化·自然语言处理
JAVA学习通1 小时前
AI Agent 工具调用机制与 Spring Boot 工程集成(2026 实战指南)
人工智能·spring boot·后端
叹一曲当时只道是寻常1 小时前
Reference 工具安装与使用教程:一条命令管理 Git 仓库引用与知识沉淀
人工智能·git·ai·开源·github
程序员威哥2 小时前
Java调用YOLO模型性能优化实战:CPU/GPU加速与内存优化全指南
java·人工智能·后端