资讯动态

ReAct模式实战:构建AI Agent工具调用与推理循环

发布时间:2026/8/28 6:04:42 来源:尧图企业网站定制
ReAct 模式在 AI Agent 开发里出现频率很高。它解决的问题很直接让大模型不仅会生成答案还能在生成答案之前调用工具、看到结果、再决定下一步怎么做。这篇内容适合三类人刚接触 Agent 的开发者、已经在写 LangChain 却没搞懂执行链路的工程师、以及想让模型调用内部 API 和工具完成自动化任务的落地者。最值得关注的不是 ReAct 这个概念有多高深而是你能不能用一个最小示例把整个循环跑通并且能解释清楚每一步发生了什么。下面按我平时实际跑的流程拆开先讲 ReAct 解决什么问题再给最小可运行代码然后拆解执行链路最后补上批量、接口化和排查思路。1. ReAct 真正解决了什么问题从“生成答案”到“完成任务”1.1 没有 ReAct 时大模型的能力盲区在哪里先从一个常见场景说起。你问大模型“最近一周哪些 AI 编程工具发布了新版本”如果模型训练数据里没有最新内容它只能靠记忆猜或者干脆告诉你不知道。回答“不知道”本身不算错但放在任务系统里就麻烦了Agent 需要得到确定结果而不是概率性文本。ReAct 的做法是让模型在推理过程中插入“行动”。推理负责拆解问题行动负责获取外部信息。拿到信息之后模型再次推理再决定下一步。整个流程形成一个循环Thought思考→ Action动作→ Observation观察结果→ 再次思考。ReAct 这个名称来自论文里 Reasoning 和 Acting 的组合。它不是新模型也不是必须绑定某个框架。大模型只是负责推理和决策的部分真正干活的是工具。你可以用任何支持 Tool Calling 的模型 API 实现它也可以在 LangChain、LlamaIndex 这类框架里使用现成封装。1.2 ReAct 比普通提示词强在哪里普通提示词相当于给模型一张纸和一支笔要求它一次写完答案。ReAct 则给模型一张纸、一支笔外加一个可以查资料的权限并且允许它写几行、查一次、再写。这个差异带来几个实际收益减少幻觉模型可以先查证再回答而不是凭记忆硬编。支持多步任务一个问题可以拆成多次查询和多次判断。结果可追踪每一轮思考和动作都会留下日志方便定位问题。工具组合更灵活多个工具可以按需选择不一定按固定流程执行。有一点要提前说明ReAct 模式并不是让模型“变聪明”而是给模型提供了“查证”和“试错”的机会。真正决定效果上限的往往是工具质量、提示词模板和循环控制策略。1.3 什么时候该用什么时候不该用我见过不少项目把所有模型调用都包装成 Agent结果延迟高、成本翻倍、调试困难。用不用 ReAct可以先看三个判断标准判断维度适合用 ReAct不建议用 ReAct信息需求需要检索数据库、网页、知识库、个人文件直接根据已有知识回答即可任务结构需要多步判断和工具组合单轮问答、文本分类、摘要、翻译延迟容忍度可以接受多轮模型调用和工具调用要求毫秒级响应只能接受单次调用如果只是做文本分类、摘要、翻译不建议上 ReAct。如果任务链路复杂比如“先查用户订单再判断是否退款最后生成通知文本”ReAct 会很合适。下面我用一个实际示例把最小跑通流程拆开。2. 先跑通一个最小 ReAct Agent环境、依赖与代码2.1 运行环境要准备什么运行一个最小的 ReAct Agent条件并不高。Python 3.10 以上即可3.11、3.12 也能跑。一个有可用 API 的大模型接口例如 OpenAI、通义、文心或者本地部署的支持 Tool Calling 的模型。LangChain 相关依赖或者直接用原生 HTTP 请求手写循环。强烈建议在虚拟环境里安装依赖避免污染系统 Python 环境。python -m venv .venv # Windows .venv\Scripts\activate # macOS/Linux source .venv/bin/activate pip install langchain langchain-openai需要注意版本问题。LangChain 的 Agent API 在 0.1.x 到 0.3.x 之间有不少变化不同版本之间的导入路径和函数签名可能不同。实际运行时先执行pip show langchain查看版本再根据版本提示调整导入方式。2.2 最小可运行示例先做一个简单的 Agent只挂一个检索工具让模型回答一个它不可能从训练数据里获得准确答案的问题。from langchain_openai import ChatOpenAI from langchain.agents import create_react_agent, AgentExecutor from langchain.tools import Tool from langchain_community.tools import DuckDuckGoSearchRun model ChatOpenAI( modelgpt-4o-mini, temperature0, ) search_tool DuckDuckGoSearchRun() tools [ Tool( nameweb_search, funcsearch_tool.run, description搜索最新的公开信息适合查新闻、实时数据和事实类问题。, ) ] prompt 你是一个使用 ReAct 模式工作的助手。 请严格按 [思考]、[动作]、[观察] 的流程回答问题。 当你有足够信息时输出 [最终答案]。 agent create_react_agent(model, tools, prompt) executor AgentExecutor(agentagent, toolstools, verboseTrue, handle_parsing_errorsTrue) result executor.invoke({ input: 告诉我最近一周 AI 编程工具领域的热门动态。 }) print(result[output])这段代码在 LangChain 0.2 以上版本可以组成一个最小 ReAct Agent。如果你的环境使用的是更新版本导入路径可能会调整。遇到ModuleNotFoundError时先看报错提示再搜索对应版本的迁移说明。2.3 跑起来之后日志里会看到什么上面代码开了verboseTrue运行时会看到类似下面的日志 Entering new AgentExecutor chain... [思考] 这个问题需要查询最新资料不能只凭训练记忆回答。 [动作] 调用 web_search 工具进行搜索。 [观察] 搜索返回了多条结果…… [思考] 已经拿到资料可以整理最终答案。 [最终答案] 最近一周AI 编程工具的热点主要集中在…… Finished chain.这一段日志就是 ReAct 循环的外显过程。模型内部的思考过程被转成了可阅读、可追踪的文本这也是 ReAct 对工程调试最大的价值问题出在哪一步能直接从日志里定位。2.4 先澄清一个容易混淆的点ReAct 里的 “React” 与前端框架 React 没有关系。ReAct 这个名称来自论文中对 Reasoning 和 Acting 的组合。搜索资料时经常看到“react 教程”“react 面经”“react native 启动白屏”那都是前端开发圈的内容。做 AI Agent 时不要混在一起找资料否则很容易浪费大量时间。判断方法很简单看到“AI Agent”“Thought/Action/Observation”“LangChain Agent”这些词说明讲的是推理行动模式看到“组件”“Vue”“JSX”“Hooks”说明讲的是前端框架。3. 单轮推理流程拆解Thought、Action、Observation 如何协作3.1 一个完整执行链路实际上长什么样ReAct 的每个循环本质上是一次“小计划 小执行”的组合。拆开看Thought模型根据当前任务写出自己对现状的判断。Action模型选出要调用的工具并填入参数。Observation模型拿到工具返回结果。循环模型基于观察继续思考直到输出 Final Answer。举个例子。任务是“查找某公司最近发布的招聘岗位数量”。模型先判断需要实时数据于是调用搜索工具。搜索工具返回多段摘要模型觉得信息不够明确再指定一个站点进行一次深度查询。最终模型综合两次检索结果输出答案。这很像一个人先查地图、再查官网、最后确认路线而不是凭印象回答。3.2 为什么需要模型自己决定下一步你可能会问既然我知道要查某个工具为什么不直接用代码写死因为 ReAct 处理的场景通常是任务不确定。用户输入可能是“分析这个财务报表”也可能是“看看最近有什么新政策”。模型需要自己决定第一步做什么、第二步怎么走。这种动态决策能力是 ReAct 相比固定工作流的核心优势。但代价同样明显模型可能选错工具、参数可能填错、工具返回结果可能不可靠。所以工程实现里工具描述必须写清楚工具返回格式必须稳定。大模型并不是以“完全正确”的方式选择工具而是根据工具名称和描述做推理。只要工具描述含糊模型就很容易选错。3.3 循环必须设置上限ReAct 不能无限循环。实际开发中一定要设置max_iterations。LangChain 的 AgentExecutor 默认有max_iterations15但如果任务复杂或者工具持续返回无效结果模型可能陷入“思考 → 调用 → 失败 → 再思考 → 再调用”的长时间循环。生产环境建议根据任务复杂度设置 3 到 10。此外还要考虑early_stopping_method。当迭代次数用尽时可以设置成generate让模型尝试生成一个最终输出而不是直接抛异常。这能提升用户体感代价是输出质量可能下降。我自己的习惯是能控制循环数的场景绝不给模型“无限次尝试”的机会。尤其是在批量任务里单条任务循环太多会拖垮整体吞吐。3.4 ReAct 提示词模板不要乱写ReAct 对提示词模板有要求。框架默认模板通常已经包含了工具列表、工具描述和执行格式说明。如果你要自定义模板至少要包含当前可用工具列表每个工具的用途与参数输出格式示例如果模型频繁“不知道从哪开始”先检查模板里有没有示例。如果模型频繁输出 JSON 但解析失败先检查格式约束是否过于复杂。根据我的经验保持模板短一点给 1 到 2 个示例比堆一堆规则更有效。这里有一个很容易踩的坑把模板写得非常详细包含十几条“必须”“禁止”结果模型每一步都在纠结格式真实任务反而处理不好。模板的作用是告诉模型“框架长什么样”而不是“把所有情况都列出来”。注意Agent 的思考过程并不总是可靠。模型可能编造一个看起来合理的思考链然后调用错误工具。日志只是排查线索不能完全当作模型真实认知的复述。4. 加入工具后Agent 才真正具备行动能力4.1 工具的本质是函数但不止于函数工具是 ReAct 的行动接口。工具设计好坏直接影响 Agent 能不能完成任务。def calculate_bmi(height_cm: float, weight_kg: float) - float: height_m height_cm / 100 return round(weight_kg / (height_m ** 2), 2) tools [ Tool( namecalculate_bmi, funccalculate_bmi, description输入身高厘米和体重千克返回身体质量指数。, ) ]工具名称要短描述要清楚参数要具体。模型没有“常识”去猜函数用途只能依赖描述。如果描述写“一个计算方法”模型不知道什么时候该调用。把工具设计成“模型视角友好”比“代码视角优雅”更重要。你可以先写一个代码风格很好的函数却因为描述不清导致模型从不调用它。4.2 专用工具和通用工具怎么组合根据实际测试经验组合工具时优先考虑这几类检索类知识库检索、网页搜索、数据库查询。计算类数学计算、单位换算、统计计算。操作类创建文件、发送消息、写数据库记录。代码执行类运行 Python 脚本片段。不要一次性堆太多工具。3 到 5 个通常已经足够。工具数量太多模型选择准确率会下降而且每次请求都要把工具描述发给模型Token 成本也会明显上升。判断工具组合是否合理可以在正式使用前跑一组测试。给模型 5 到 10 个类似任务统计工具选对率和参数填对率。如果选对率低于 70%优先改工具名称和描述而不是调模型参数。4.3 生产项目里最实用的让 Agent 调用内部 API本地计算工具只是入门。真正生产中常用的方案是让 Agent 通过函数调用内部 API例如查询订单、查库存、生成报表。一种做法是定义带requests的函数import requests def get_order_status(order_id: str) - dict: # 示例实际地址以你项目为准 response requests.get( fhttps://api.example.com/orders/{order_id}, timeout10, headers{Authorization: Bearer your-token}, ) response.raise_for_status() return response.json()设计这类工具时要注意几个点给函数加超时避免 Agent 长时间等待。返回 JSON 保持简单返回结构太复杂会让模型“看不懂”。内部接口鉴权要放在函数内部不要输出密钥。敏感操作要加人工审批不建议完全交给 Agent 自动执行。4.4 工具选择的稳定性怎么判断工具适不适合给 Agent 用可以用一个简单测试衡量。准备 5 个工具跑 20 个任务统计指标判断标准工具选对率低于 70% 时需要优化工具描述参数填对率低于 80% 时检查参数说明最终结果准确率低于 60% 时检查工具返回质量平均轮次超过 8 轮说明任务拆解或工具设计有问题平均延迟用于估算成本和用户等待时间“能跑通”和“能稳定使用”是两码事。工具能不能被稳定调用是 ReAct Agent 真正需要长期维护的环节。5. 从单条任务到批量与接口化落地要注意什么5.1 不要一上来就开最大并发本地跑通单条任务很容易但进入批量阶段问题会集中暴露。最常见的是并发拉满后模型 API 限流、内存暴涨、日志混乱、任务失败无法定位。我的建议是先 1 个并发跑 10 条任务观察平均耗时和失败率。正常后再按 2、4、8 逐渐增加。这个过程能帮你摸清当前模型 API、工具服务和机器资源的真实极限。有经验的工程师通常会把“并发控制”当成独立模块来做而不是只靠框架默认。因为不同模型 API 的限流策略不同5 家服务可能有 5 种限流表现。5.2 批量任务的输入、输出、命名与重试批量任务的工程要点集中在四个方面输入统一每一条任务都应该是独立、完整的输入。输出命名建议采用“任务 ID 时间戳”避免覆盖。失败重试对超时、限流、临时网络错误重试 2 到 3 次。断点续跑记录已完成任务重启时不重复执行。我一般会用一个本地 JSON 文件记录任务状态。{ 001: { status: done, output: 处理结果 }, 002: { status: pending, input: 等待处理的任务输入 } }每处理完一个任务更新一次状态。这样即使进程中断也能知道哪些任务已完成哪些需要重新执行。如果是在服务端批量处理更推荐用队列组件例如 Redis 队列或数据库任务表。本地 JSON 适合测试和小批量场景不适合长时间稳定运行。5.3 接口化请求格式、超时与错误返回把 Agent 封装成 HTTP 接口时至少要考虑这四个问题请求体包含什么字段。超时时间设置多少。错误返回结构是否统一。是否支持流式输出。一个简化版设计是 POST/agent/run。{ task_id: task_001, query: 查找最近一周 AI 编程动态, model: default, max_iterations: 5 }响应体最好统一方便前端和调用方处理。{ task_id: task_001, status: done, output: 最终答案文本, trace: [可选的过程日志] }详细日志不建议每次都全量返回。可以把日志保存到后台存储或日志文件接口只返回精简结果需要排查时再单独查询。接口化还有一个容易忽略的问题Agent 接口比普通问答接口慢得多。普通问答可能在 1 到 3 秒返回ReAct Agent 一轮多个工具调用可能要到 10 到 30 秒。接口超时时间要相应延长或者改成异步任务模式。5.4 内存、日志与监控批量跑 ReAct Agent 时最容易忽略的是日志。Agent 一轮会调用多次模型和工具日志量比普通接口大很多。建议记录这些信息时间戳、任务 ID、迭代轮次模型调用耗时和 Token 用量工具名称、调用耗时和返回结果摘要异常信息和重试次数如果进程占用内存持续增长重点排查工具返回结果是否一直被保留在内存里。常见原因是把完整历史结果存在一个 list 或 dict 中排错结果数据越积越多。建议每条工具返回结果只保留截断版本。例如只保留前 1000 个字符既能让模型看到关键信息也能避免上下文被撑爆。6. 常见问题与排查顺序先看现象再追环境6.1 典型报错和可能原因报错现象可能原因检查方向导入失败LangChain 版本变化先pip show langchain看版本按版本提示调整导入工具调用失败工具函数抛异常先直接调用函数确认函数本身正常模型输出格式解析失败提示词模板格式约束不清晰看模型原始输出再调整模板长时间不返回循环卡住或工具超时检查 max_iterations 和工具超时设置输出为空工具返回空结果先看工具返回再看模型概括逻辑内存持续增长工具返回结果过大或缓存累积截断返回清理历史记录6.2 输出为空优先按这个顺序排查第一看输入问题是否清晰是否包含缺失字段。第二看日志工具是否真的调用成功返回内容是否为 None。第三看模型模型是否把工具结果错误地忽略了。第四看输出格式解析代码是否处理了空字符串。很多时候“Agent 不会回答”的根因是检索结果本身为空而不是模型问题。先用搜索工具手动执行一次确认搜索返回有内容再把链路往前推。6.3 Agent 死循环的边界控制预防循环的方法有几种设置max_iterations10。给每个工具函数加超时。工具连续返回异常时让 Agent 终止并输出当前结论。在 Agent 提示词里写“如果工具连续失败两次直接输出最终答案”。不要每轮都重新搜索完全一样的关键词。可以在提示词里注明“如果已有较好结果尽量不要重复调用工具”。这对减少循环次数很有效。6.4 给新手的实验顺序按这个顺序做可以少踩很多坑用现成框架跑通一个最小示例。不接外部工具先把执行日志看明白。增加一个简单计算工具观察调用链路。增加检索工具观察多轮循环。把单条流程改成小批量。加日志、重试、并发控制。考虑接口封装和内部工具接入。这个顺序能避免你一上来就被框架版本、工具协议、并发问题分散精力。ReAct 模式本身不复杂真正消耗时间的是环境差异、版本差异、工具返回结果不可控这一类工程问题。如果你正在开发 Agent 相关功能建议先把单任务跑稳把工具描述写好把循环上限和失败重试加上。多数 ReAct 项目最终遇到的困难并不是模型能力不够而是工具、日志和任务管理没有跟上。等这些基础打牢再慢慢扩展工具数量和接口场景效果会稳定得多。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价