ReAct让AI像人一样“边想边做”,轻松搞定复杂问题!

news2026/3/30 23:25:03
写在前面欢迎回到我们的智能体架构系列。上一期我们聊了工具调用让智能体“长出了手”能去外部世界获取信息。但很快我们就发现光有手还不够。面对“谁是《沙丘》制片公司的CEO以及该公司最近一部电影的预算”这种问题你让智能体调用一次搜索它大概率会把整个问题塞进搜索框然后给你一个不知所云的答案。这就像你让一个新手员工去查资料他直接打开百度把老板的问题原样输入然后把搜出来的第一页结果直接甩给你。你肯定会说“能有点逻辑吗不能分步拆解一下吗”这就是我们今天的主角——ReAct要解决的问题。ReAct全称是“推理行动”Reason Act它的核心思想无比朴素让智能体在执行每个行动前先动脑子想一想看到行动结果后再想一想下一步该干什么。它把智能体从一个只会机械执行指令的工具人变成了一个能动态规划、随机应变的解题高手。这篇文章我们会先动手写一个“有手无脑”的基础版智能体看看它在复杂任务面前如何翻车。然后我们会用 LangGraph 亲手搭建一个完整的 ReAct 智能体并一步步展示它如何通过“思考 → 行动 → 观察”的循环优雅地完成那些让基础版望而却步的任务。什么是 ReAct我们先用一个生活化的类比来理解它。假设你要写一篇关于“国产AI芯片最新进展”的深度报告。基础智能体相当于你打开谷歌输入“国产AI芯片最新进展”然后把排在前面的几篇文章复制粘贴拼凑出一份报告。结果很可能信息陈旧、观点片面。ReAct 智能体则像一位经验丰富的研究员。他会先想“要写这个报告我得先确定最近有哪些主要玩家。” 于是他搜索“2026年国产AI芯片厂商排名”看到了“寒武纪”、“壁仞科技”等名字。接着他又想“光有厂商不行还得看看他们的核心技术。” 于是他针对每个厂商搜索“壁仞科技 BR100 技术解析”。得到信息后他又想“这些技术在业界的评价如何和国外竞品比呢” 于是再次搜索“壁仞科技 BR100 性能评测 对比 Nvidia H100”……如此循环直到信息足够支撑一份有深度、有观点的报告。这就是 ReAct 的精髓推理Reason驱动行动Act行动的结果又反过来促成下一步的推理。正式定义ReAct 是一种智能体设计模式它要求大语言模型在每一步都生成思考推理下一步做什么和行动如调用工具。模型观察行动结果后将其作为新的上下文再次进行思考如此形成一个动态、自适应的闭环直到完成任务。ReAct 工作流程这个流程就像你平时解决复杂问题的思维过程完全可以带入进去理解。接收目标智能体收到一个复杂任务比如“帮我查查XX”。思考智能体开始“自言自语”“要回答这个问题我首先得找到X信息然后才能用X去找Y。”行动基于思考智能体执行一个动作通常是调用一个工具比如执行一次网络搜索web_search(X)。观察智能体收到工具的返回结果。循环智能体将观察结果融入上下文然后返回第2步基于新的信息产生新的思考例如“好现在我知道X了下一步需要用X去搜索Y。”完成循环持续进行直到智能体认为信息足够能给出最终答案。什么时候该用它ReAct 特别适合以下场景多跳问答需要按顺序查找多条信息才能回答的问题比如我们开头的例子。网页导航与研究需要像人一样先搜一个起点阅读内容再根据内容决定下一个搜索词逐步深入。交互式工作流任何环境动态变化无法预先规划所有步骤的任务。比如运维排错、代码调试等。优点和缺点优点自适应与动态计划可以随时根据新信息调整而不是一条路走到黑。处理复杂任务能轻松驾驭那些需要多个依赖步骤才能解决的问题。缺点更高延迟与成本因为涉及多次大语言模型调用思考行动速度会更慢成本也更高。循环风险如果思考指令写得不清晰智能体可能会陷入重复、无效的“思考-行动”死循环需要开发者设计好退出机制。基础与环境准备老规矩我们先搭好环境。这次我们会用到 Nebius、LangSmith 和 Tavily 网络搜索工具。安装核心库# !pip install -q -U langchain-nebius langchain langgraph rich python-dotenv tavily-python导入库并设置密钥在项目根目录下创建.env文件填入你的密钥NEBIUS_API_KEY你的_nebius_api_keyLANGCHAIN_API_KEY你的_langsmith_api_keyTAVILY_API_KEY你的_tavily_api_key plaintext import osfrom typing import Annotatedfrom dotenv import load_dotenv# LangChain 组件from langchain_nebius import ChatNebiusfrom langchain_community.tools.tavily_search import TavilySearchResultsfrom langchain_core.messages import BaseMessagefrom pydantic import BaseModel, Field# LangGraph 组件from langgraph.graph import StateGraph, ENDfrom langgraph.graph.message import AnyMessage, add_messagesfrom langgraph.prebuilt import ToolNode, tools_condition# 用于美化打印from rich.console import Consolefrom rich.markdown import Markdown# --- API 密钥与追踪设置 ---load_dotenv()os.environ[LANGCHAIN_TRACING_V2] trueos.environ[LANGCHAIN_PROJECT] Agentic Architecture - ReAct (Nebius)# 检查密钥是否已设置for key in [NEBIUS_API_KEY, LANGCHAIN_API_KEY, TAVILY_API_KEY]: ifnot os.environ.get(key): print(f{key} 未找到请在 .env 文件中设置。)print(环境变量加载完成追踪已开启。) plaintext 环境变量加载完成追踪已开启。基础方法——单次工具调用智能体在见识 ReAct 的强大之前我们先亲手写一个“有手无脑”的智能体。它能用工具但只能用一次。它会分析用户的问题调用一次搜索然后凭借这次搜索得到的信息强行给出最终答案。这个设计就是为了让它暴露缺点。构建基础智能体我们用 LangGraph 构建一个简单的线性图智能体节点agent负责决定调用什么工具只能一次然后执行工具最后结束。from typing import TypedDictconsole Console()# 定义图谱的状态class AgentState(TypedDict): messages: Annotated[list[AnyMessage], add_messages]# 定义工具和大语言模型search_tool TavilySearchResults(max_results2, nameweb_search)llm ChatNebius(modelmeta-llama/Meta-Llama-3.1-8B-Instruct, temperature0)llm_with_tools llm.bind_tools([search_tool])# 为基础智能体定义 agent 节点def basic_agent_node(state: AgentState): console.print(--- 基础智能体思考中... ---) # 关键提示强制它在一次工具调用后给出答案 system_prompt 你是一个有用的助手。你可以使用网络搜索工具。请基于工具结果回答用户问题。你必须在一次工具调用后给出最终答案。 messages [(system, system_prompt)] state[messages] response llm_with_tools.invoke(messages) return {messages: [response]}# 定义基础的线性图basic_graph_builder StateGraph(AgentState)basic_graph_builder.add_node(agent, basic_agent_node)basic_graph_builder.add_node(tools, ToolNode([search_tool]))basic_graph_builder.set_entry_point(agent)# agent 之后如果调用了工具就去 tools否则直接结束basic_graph_builder.add_conditional_edges(agent, tools_condition, {tools: tools, __end__: __end__})basic_graph_builder.add_edge(tools, END)basic_tool_agent_app basic_graph_builder.compile()print(基础单次工具调用智能体编译成功。) plaintext 基础单次工具调用智能体编译成功。在多步问题上测试基础智能体现在我们用那个经典的“多跳”问题来考验它看看它如何翻车。multi_step_query 谁是科幻电影《沙丘》制作公司的现任 CEO那家公司最近一部电影的预算是多少console.print(f[bold yellow]在多步查询上测试基础智能体[/bold yellow] {multi_step_query}\n)basic_agent_output basic_tool_agent_app.invoke({messages: [(user, multi_step_query)]})console.print(\n--- [bold red]基础智能体最终输出[/bold red] ---)console.print(Markdown(basic_agent_output[messages][-1].content))输出讨论不出所料基础智能体大概率会输出一个错误或不完整的答案。它的一次搜索可能搜到了关于《沙丘》票房的信息但没找到制片公司或者搜到了制片公司但忽略了CEO和最近一部电影的预算。它缺乏“拆解问题”和“利用中间结果”的能力这个失败完美地铺垫了我们引入 ReAct 的必要性。进阶方法——实现 ReAct现在我们来构建真正的 ReAct 智能体。核心区别就在图的结构里我们会引入一个循环让智能体可以反复进行“思考、行动、观察”。构建 ReAct 智能体图我们定义两个核心节点agent思考行动决策和tools执行工具。关键的路由逻辑是如果agent决定调用工具就走tools节点**然后必须从tools再回到agent**让智能体带着工具结果继续思考。def react_agent_node(state: AgentState): console.print(--- REACT 智能体思考中... ---) response llm_with_tools.invoke(state[messages]) return {messages: [response]}# ToolNode 与之前相同react_tool_node ToolNode([search_tool])# 路由逻辑也相同def react_router(state: AgentState): last_message state[messages][-1] if last_message.tool_calls: console.print(--- 路由决定调用工具。 ---) returntools console.print(--- 路由决定结束。 ---) return__end__# 现在定义包含关键循环的图react_graph_builder StateGraph(AgentState)react_graph_builder.add_node(agent, react_agent_node)react_graph_builder.add_node(tools, react_tool_node)react_graph_builder.set_entry_point(agent)react_graph_builder.add_conditional_edges(agent, react_router, {tools: tools, __end__: __end__})# 关键区别边从 tools 回到 agent形成闭环react_graph_builder.add_edge(tools, agent)react_agent_app react_graph_builder.compile()print(包含推理循环的 ReAct 智能体编译成功。) plaintext 包含推理循环的 ReAct 智能体编译成功。对比测试我们再次用同一个复杂查询考验我们的 ReAct 智能体这次我们重点关注它的“思考过程”。在多步问题上测试 ReAct 智能体我们用流式方式输出这样就可以清晰地看到它是如何一步步迭代推理的。console.print(f[bold green]在同样的多步查询上测试 ReAct 智能体[/bold green] {multi_step_query}\n)final_react_output Nonefor chunk in react_agent_app.stream({messages: [(user, multi_step_query)]}, stream_modevalues): final_react_output chunk console.print(f--- [bold purple]当前状态[/bold purple] ---) chunk[messages][-1].pretty_print() console.print(\n)console.print(\n--- [bold green]ReAct 智能体最终输出[/bold green] ---)console.print(Markdown(final_react_output[messages][-1].content))输出讨论大功告成看看智能体的“内心独白”思考 1“要回答这个问题我需要先找出《沙丘》的制作公司。”行动 1调用web_search搜索“《沙丘》电影制作公司”。观察 1搜索结果明确指向“传奇影业”。思考 2“知道了制作公司是传奇影业下一步我需要找出它的现任CEO。”行动 2再次调用web_search搜索“传奇影业 CEO”。观察 2得到“乔什·格罗德”等信息。思考 3“还差一个问题需要找到传奇影业最近一部电影的预算。”行动 3第三次调用web_search搜索“传奇影业 最近电影 预算”。观察 3得到相关数据。整合最后智能体将收集到的所有信息整合成一个完整、准确的答案。这个清晰的“思考-行动-观察”循环完美展示了 ReAct 模式在解决复杂、多步问题上的绝对优势。定量评估为了让对比更客观我们请出“大语言模型裁判”分别给两个智能体的表现打分。class TaskEvaluation(BaseModel): 评估智能体完成任务能力的评分模式。 task_completion_score: int Field(description1-10分智能体是否成功完成了用户请求的所有部分。) reasoning_quality_score: int Field(description1-10分智能体展现的逻辑流程与推理质量。) justification: str Field(description分数的简要理由。)judge_llm llm.with_structured_output(TaskEvaluation)def evaluate_agent_output(query: str, agent_output: dict): trace \n.join([f{m.type}: {m.content}for m in agent_output[messages]]) prompt f你是一位专门评估 AI 智能体的裁判。请为以下智能体在给定任务上的表现打分1-10分。10分表示任务完成完美1分表示完全失败。**用户任务**{query}**完整智能体对话追踪**{trace} return judge_llm.invoke(prompt)console.print(--- 评估基础智能体的输出 ---)basic_agent_evaluation evaluate_agent_output(multi_step_query, basic_agent_output)console.print(basic_agent_evaluation.model_dump())console.print(\n--- 评估 ReAct 智能体的输出 ---)react_agent_evaluation evaluate_agent_output(multi_step_query, final_react_output)console.print(react_agent_evaluation.model_dump())输出讨论裁判的评分让差距一目了然。基础智能体task_completion_score和reasoning_quality_score双双低分。因为它没能收集齐所有信息过程缺乏逻辑性。ReAct 智能体获得了近乎满分的评价。裁判认可了它的迭代式推理过程并成功完成了任务的所有部分。这个量化的结果确凿地证明了 ReAct 架构的价值——它是解锁智能体解决复杂、多跳问题能力的钥匙。本章总结在这篇笔记中我们不仅亲手用 LangGraph 实现了 ReAct 架构更重要的是我们通过一个直观的对比实验清晰地展示了它相对于基础单次调用方法的绝对优势。三个核心记忆点核心原理ReAct 通过“推理 → 行动 → 观察”的循环让智能体能够动态规划解决需要多步推理的复杂问题。实践关键用 LangGraph 实现 ReAct 的核心是在图中构建从tools节点回到agent节点的循环边。避坑指南ReAct 虽然强大但要警惕无限循环的风险需要在系统提示词或代码逻辑中设置合理的停止条件。写在最后看到这里你可能会觉得 ReAct 是一个很“重”的方案。确实它会带来更高的成本和延迟。但在那些需要深度分析和多步推理的真实业务场景中——比如智能客服的复杂工单处理、运维系统的根因分析、金融领域的多源信息求证——ReAct 带来的智能水平提升足以让我们接受这笔开销。技术的演进就是这样总是在“快”与“准”之间寻找平衡。ReAct 给了我们一个选择为了让AI更聪明我们可以允许它多“想”几步。假如你从2026年开始学大模型按这个步骤走准能稳步进阶。接下来告诉你一条最快的邪修路线3个月即可成为模型大师薪资直接起飞。阶段1:大模型基础阶段2:RAG应用开发工程阶段3:大模型Agent应用架构阶段4:大模型微调与私有化部署配套文档资源全套AI 大模型 学习资料朋友们如果需要可以微信扫描下方二维码免费领取【保证100%免费】配套文档资源全套AI 大模型 学习资料朋友们如果需要可以微信扫描下方二维码免费领取【保证100%免费】

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2466537.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringBoot-17-MyBatis动态SQL标签之常用标签

文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…

网络编程(Modbus进阶)

思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…