尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
ReAct模式详解:给大模型装上工具调用的“手和脚”
先问一个问题你让ChatGPT查一下今天实时天气或者让它算一下某只股票当前的价格它是不是经常一本正经地给你编一个答案这不是它笨而是它没有手脚。最近AI应用圈里高频出现的ReActReasoning Acting模式核心思路就是给大模型装上手和脚——让它能调用搜索、计算、数据库等外部工具把工具返回的真实结果再喂回模型循环往复直到得出经过验证的答案。先提个醒这个ReAct和前端那个React没有任何关系经常有朋友搜React结果跑进来看ReAct。前端React是UI库这里的ReAct是大模型工具的动作编排模式名字像完全是两码事。这篇文章我会从最朴素的原理讲起给你一个可以手写的最小实现再拆解LangChain里ReAct Agent的经典模板最后把我自己实际项目中踩过的坑和调优经验一股脑倒出来。适合想自己搭AI Agent但还不太清楚内部机制的读者——无论你做后端、做数据还是做产品应该都能从中拿到能直接落地的东西。1. LLM单打独斗的困局为什么能思考不等于能回答1.1 知识截止日期模型活在一个静态世界里所有大模型都有一个致命问题训练数据有截止日期。训练完成的那一刻它对世界的认知就冻结了。你问它今天的实时汇率是多少某某API这个月刚改的返回结构是什么它根本不知道但它不会老老实实说我不知道。它干的事情是根据问题的上下文从它学过的概率分布里生成一个在语言形态上最像正确答案的文本。这在NLP里有个术语叫合理但错误的幻觉。我早期做客服机器人的时候就吃过这个亏。用户问某某银行最近推出的理财产品利率是多少模型能给你编出一个完整的利率数字连期限都分毫不差但那个产品根本不存在。你要是把这种答案直接上生产环境用户按这个利率去做了决策出问题是要担责任的。1.2 幻觉不是bug是整个推理链路缺乏外部校验有人会说那用CoT思维链让模型一步一步想总行了吧CoT确实能提升复杂逻辑推理的准确率但这里有个根本问题没解决不管你怎么想链条上的每一个节点都只是模型自己脑内的推理没有任何一步能和真实世界碰撞一下。就像一个学生做数学题从头到尾闭卷自推过程写得再漂亮如果前提条件就是错的推理步骤越多离正确答案越远。更麻烦的是模型在对自己编出来的前提进行推理时语言上往往非常自信、非常流畅人类读者很难一眼看出破绽。经过几次线上事故之后我得到一个很深刻的体会对AI应用来说可验证性比流畅性重要得多。你需要在推理路径中嵌入外部世界的真实反馈来强制校验模型的每一步。1.3 本质矛盾模型有大脑但缺手脚我说句直接的话现在的大模型本质上还只是个next token prediction机器它最擅长的是根据上下文生成接下来最可能的文本。你要它做实时问答、做多步计算、做需要查外部系统的任务它根本够不到那些信息。但你给它一对手情况就完全不一样了给它搜索工具它可以去查最新资料给它计算器它可以精确算出结果而不是凭感觉估算给它数据库连接器它可以查私有数据给它API调用器它可以操作真实系统关键不在于有工具而在于让模型在推理过程中实时决定什么时候用哪个工具、用完之后怎么调整思路。这就是ReAct的核心设计。2. ReAct的工作流拆解Thought-Action-Observation循环2.1 ReAct到底改变了什么ReAct源自2022年Shunyu Yao等人的论文《ReAct: Synergizing Reasoning and Acting in Language Models》它不改变模型结构不涉及模型微调而是改变你给模型的推理模式——说白了一句话在prompt里要求模型按思考→行动→观察的循环来工作。一个完整的ReAct流程长这样Question: 用户的任务 Thought 1: 我分析一下这个任务需要哪些信息 Action 1: 调用工具A获取信息 Observation 1: 工具A的返回结果 Thought 2: 根据返回结果我发现还需要数据B Action 2: 调用工具B Observation 2: 工具B的返回结果 ... Thought N: 信息足够了我来整合答案 Final Answer: 最终回答论文原文把这称为inner monologue external feedback即内部独白 外部反馈。模型的Thought是它内在推理的外显化Action是它与外部世界的接口Observation是外部世界对它的反馈。我拿做菜打个比方。CoT模式像是你照着一本菜谱在脑子里把整个做菜过程预演一遍听起来头头是道但你没有真的开火。ReAct是你真的站到灶台前切菜、下锅、尝一口、觉得淡了、加盐、再尝一口、出锅。每一步都根据实际情况实时调整最终端上桌的菜才靠谱。2.2 为什么先想一下再动手这么关键很多人刚接触ReAct时会问既然要调用工具为什么不直接规定一个固定流程比如先搜索、再计算、最后总结那样执行起来还更稳定不会出岔子。问题在于真实任务是开放式的你没法预先把所有路径写死。比如用户说帮我把这份财报里的营收同比增幅算出来然后查一下同行平均增幅做个对比这中间要不要先查财报要不要先搜索同行名单要不要先判断哪些公司算同行这些决策必须由模型根据实际上下文动态判断。Thought就是干这个的让模型在每一轮行动前明确说出我现在的目标是什么我缺什么信息我为什么选择这个工具。这样一来行动有据可循不会乱调工具一旦走偏Observation能立刻暴露问题中间过程全部可审计方便排查错误2.3 Observation闭环反馈是ReAct和CoT最本质的区别我再强调一遍Observation是整个循环的锚点。模型自己说的Thought再漂亮也可能是幻觉但Observation是外部环境的真实响应——搜索返回的真实结果、计算器算出的真实数值、数据库里查询到的真实记录。机制上是这样实现的Agent框架把工具返回的文本作为一条新的对话消息拼进prompt里模型看到后继续生成下一轮Thought。就拿用户问当前北京气温举例Thought我需要实时天气数据先查一下Actionsearch(北京当前气温)Observation北京今日气温 18°C晴空气质量优Thought数据已拿到直接回答用户Final Answer北京今天 18°C晴空气质量优。如果没有Observation这一步模型就只能依靠脑内的过时知识十有八九会编一个数字。有了外部反馈整个推理的每一步都有了现实锚点正确率自然就上来了。3. 和CoT、Plan-and-Execute的横向对比ReAct为什么值得选3.1 CoT纯推理的路径依赖先看最经典的CoT。它的玩法是让模型一步一步思考再给答案。对于纯粹逻辑推导类的问题——比如数学应用题、逻辑谜题——CoT的准确率提升相当明显。但CoT有明显的天花板它没有工具调用能力也没有外部反馈机制。一旦任务需要实时数据或者需要做一次精确计算而不是估算CoT就只能靠模型内部知识硬撑。更麻烦的是模型在CoT过程中一旦迈出了错误的第一步后续推理会在这个错误基础上越走越远而且语言流畅到让你很难发现。我的看法是CoT适合脑内推理ReAct适合需要与真实世界交互的任务。两者并不冲突ReAct的Thought本质上就内嵌了CoT的推理方式只是多了Act和Observe两个环节。3.2 Plan-and-Execute计划很美但缺少应变Plan-and-Execute是另一类常见的Agent设计思路典型代表是BabyAGI这类项目。它分两个阶段先让LLM根据任务制定一个完整的分步计划然后再一步步执行。听起来很合理实际上有隐患。计划是模型基于训练数据里的过时知识凭空制定出来的第一步往往就带着幻觉。比如计划里写调用X接口拉取用户数据但X接口在现实里早已改版参数结构全变了。在这种模式下执行器按计划往下走每一步都可能踩空而模型又没有机制中途停下来重新计划。ReAct的做法完全不同它不做长计划而是干一步看一步。每一轮行动之前只思考现在该做什么行动之后立刻观察结果根据新情况再决定下一步。这像极了人在真实环境中完成复杂任务的方式把大目标拆成一个个临场决策。3.3 三种模式的取舍参数一览我整理了一个表格方便你根据不同场景直接选型维度CoTPlan-and-ExecuteReAct核心思路一步到位的逐步推理先规划后执行边想边做边修正工具调用无有但按预定义计划执行有按实时情况动态决定外部反馈无无执行中不参考反馈调整计划有每个行动都有Observation适用场景逻辑推理、知识问答流程稳定、步骤明确的自动化需要检索、计算、多步验证的动态任务Token消耗低中较高多次模型调用失败可恢复性低错一步全错中可重试但不会改计划高Observation能及时纠偏你看到表里的结论了ReAct的性能优势来自动态决策和外部反馈代价是多次调用模型带来的成本和延迟。在需要信任答案的生产场景里多花几轮token换取可验证性是完全值得的。4. 手写一个最小ReAct Agent不依赖框架看透核心循环4.1 准备工作在动手写代码之前我先交代清楚我们不使用LangChain这类重量级框架直接用OpenAI的Chat Completions接口 两个模拟工具把ReAct循环从头到尾自己实现一遍。之所以这样做是因为框架封装得太好了很多新手根本不知道Agent内部在干什么——出了问题也不知道去哪排查。环境就一个Python文件需要装一个requests库用于调用API。4.2 最小可用的Prompt模板ReAct能否正常工作prompt模板占了六成功劳。我的这套模板是从LangChain的上千条prompt设计里反推出来的最简形式覆盖了Thought、Action、Observation三要素你是一个智能体你需要通过交替使用工具来完成用户的任务。 你可以使用的工具有 - search(query)搜索引擎query是搜索关键词返回网页标题和摘要 - calculator(expression)计算数学表达式返回数值结果 你的工作流程是 Thought: 分析当前情况和需要的信息用中文描述 Action: 调用工具格式为 工具名(参数) Observation: 工具返回的结果 当你有足够信息可以回答问题时请输出 Final Answer: 你的最终答案这里有个容易被忽视的点工具的调用格式必须严格约定。我要求模型输出固定的Action: 工具名(参数)格式程序上用正则就可以解析简单又可靠。你要是放任模型自由发挥我调用一下搜索工具这类自然语言解析代码就会变成一场噩梦。4.3 主循环代码实现说再多不如上代码。这是一个完整的、可运行的最小ReAct示例import json import re import requests API_KEY sk-your-key MODEL gpt-4o-mini BASE_URL https://api.openai.com/v1/chat/completions SYSTEM_PROMPT 你是一个智能体你需要通过交替使用工具来完成用户的任务。 你可以使用的工具有 - search(query)搜索引擎query是搜索关键词返回网页标题和摘要 - calculator(expression)计算数学表达式返回数值结果 你的工作流程是 Thought: 分析当前情况和需要的信息用中文描述 Action: 调用工具格式为 工具名(参数) Observation: 工具返回的结果 当你有足够信息可以回答问题时请输出 Final Answer: 你的最终答案 def call_llm(messages): resp requests.post( BASE_URL, headers{Authorization: fBearer {API_KEY}}, json{model: MODEL, messages: messages, temperature: 0.2}, timeout30, ) resp.raise_for_status() return resp.json()[choices][0][message][content] def search(query): fake_db { 2025年AI行业效率提升: 根据行业报告2025年使用AI工具的企业平均效率提升32% } return fake_db.get(query, f未找到与{query}相关的结果) def calculator(expression): try: return str(eval(expression)) # 注意仅用于演示生产环境禁止直接用eval except Exception as e: return f计算错误: {e} def run_agent(task, max_rounds6): messages [ {role: system, content: SYSTEM_PROMPT}, {role: user, content: task}, ] for step in range(max_rounds): answer call_llm(messages) print(f--- Round {step 1} ---) print(answer) if Final Answer: in answer: return answer.split(Final Answer:, 1)[1].strip() action_match re.search(rAction:\s*(.), answer) if not action_match: print(未找到Action提前终止) return answer action_str action_match.group(1).strip() call_match re.match(r(\w)\((.*)\), action_str) if not call_match: print(fAction格式解析失败: {action_str}) return answer tool_name, tool_input call_match.groups() tool_input tool_input.strip(\) if tool_name search: result search(tool_input) elif tool_name calculator: result calculator(tool_input) else: result f未知工具: {tool_name} messages.append({role: assistant, content: answer}) messages.append({role: user, content: fObservation: {result}}) return 达到最大轮数仍然没有得出最终答案主循环的逻辑其实就是第2章那张流程图调用模型→看是否给出Final Answer→解析Action→执行工具→把Observation拼回消息列表→再来一轮。注意我把每轮的assistant回答也保留在messages里这很重要——模型必须看得到自己之前的Thought和Action才能保持上下文连续。4.4 运行实测一个真实小任务我用这个Agent跑了一个需要搜索计算两步的任务用户问2025年使用AI工具的企业效率提升多少如果某公司原利润100万/年提升后年利润是多少运行时的完整输出大致是这样--- Round 1 --- Thought: 我需要先查到2025年使用AI工具的企业效率提升数据。 Action: search(2025年AI行业效率提升) Observation: 根据行业报告2025年使用AI工具的企业平均效率提升32% --- Round 2 --- Thought: 已查到效率提升32%现在需要计算100万提升32%后的年利润。计算公式为 100 * (1 0.32) 132 万。 Action: calculator(100*(10.32)) Observation: 132.0 --- Round 3 --- Thought: 计算结果为132.0信息已经足够可以直接给出最终答案。 Final Answer: 2025年使用AI工具的企业平均效率提升32%。某公司原利润100万/年提升后的年利润为132万元。你可以看到Agent完全自主地完成了检索→计算→汇总三步动作全程没有任何固定流程的预定义。这就是ReAct的核心价值把复杂任务拆解成模型自己掌控的动态循环。5. 拆解LangChain里的ReActzero-shot-react-description模板逐层解析5.1 模板逐字段拆解为了不重复造轮子大多数人最终会落到LangChain的Agent框架上。其中最经典的是zero-shot-react-description这个Agent类型它使用了一套精心设计的Prompt模板核心部分如下Answer the following questions as best you can. You have access to the following tools: {tools} Use the following format: Question: the input question you must answer Thought: you should always think about what to do Action: the action to take, should be one of [{tool_names}] Action Input: the input to the action Observation: the result of the action ... (this Thought/Action/Action Input/Observation can repeat N times) Thought: I now know the final answer Final Answer: the final answer to the original input question Begin! Question: {input} Thought:{agent_scratchpad}逐行解读一下这些变量和格式要求{tools}工具列表每个工具包含name、description、args几个字段。description是模型决定要不要用这个工具的依据写得好不好直接决定调用准确性。{tool_names}所有工具名的逗号拼接列表用来约束Action字段的取值范围。{agent_scratchpad}之前所有Thought、Action、Action Input、Observation的拼接历史。这是模型在若干轮循环之后记住自己做到哪一步的关键。格式说明里明确写了Thought/Action/... 可以循环N次等于告诉模型这不是一次性问答而是可以多次反复尝试的循环流程。5.2 模型是怎么学会调用工具的你可能好奇模型怎么知道该在什么时候用哪个工具答案在prompt里的工具描述中。LangChain里每个工具的description由开发者自己写。比如Python REPL工具的description通常是Python shell适合执行Python表达式和计算搜索引擎的description是搜索引擎适合查询最新信息。模型在读prompt时会根据当前任务上下文和每个工具的description做语义匹配如果任务需要最新信息它就会选择description带查询最新信息的工具如果任务需要数学推导它就会选执行计算的工具。这其实不是什么高深的技术本质上是大模型的文本匹配能力 prompt里明确的格式约束。但恰恰因为这个机制太依赖description的质量工具描述写得含糊或者出现歧义模型就会开始乱选工具。这一点我会在第6章详细讲。5.3 ReAct和Function Calling的真实关系经常有人把ReAct和Function Calling搞混我帮你理一下Function Calling是OpenAI在API层面提供的能力你声明一批函数模型直接输出结构化的JSON调用参数而不是自然语言文本。它是为了让模型输出机器可解析的工具调用而生的。ReAct是一种通用的Agent模式它并不强制要求模型以结构化JSON输出Action更关注的是Thought→Action→Observation的思考循环。两者是可以结合起来用的。LangChain的openai_functions_agent就是这个思路保留ReAct式的循环但Action不再用自然语言字符串而是换成Function Calling输出的结构化函数调用。这么做的好处是省掉了解析Action文本这个最容易出错的环节模型不需要自己拼动作格式了。我在实际生产中更推荐用OpenAIFunctionsAgent尤其是你用的工具数量超过5个的时候。工具一多纯文本的Action格式容易让模型在格式上出错结构化调用能大幅降低解析失败率。6. 实战避坑与调优经验把ReAct真正用起来的几个关键判断6.1 什么任务适合ReAct什么任务不适合ReAct不是万能药。我见过太多人无脑把Agent套到所有任务上结果运行慢、成本高、效果还差。基于项目经验我总结了两条筛选标准适合ReAct的任务通常满足以下特征之一需要外部信息实时数据、私有数据、过期变动的知识需要多步精确计算不是估算而是要精准结果需要状态验证执行的结果需要被确认后才能继续后续动作需求本身不确定你没法预先写死流程需要模型临场规划不适合ReAct的任务包括纯创意写作比如写文案、写故事工具提供不了多少帮助纯纯浪费token模型内部已有的知识问答比如解释什么是斐波那契数列模型直接答就行超长文本生成如果任务本来就需要一次生成大量内容走Agent循环反而会碎片化遇到这些情况直接用单次Prompt加适当的提示工程就好没必要上Agent。6.2 我在生产环境中踩过的三个坑第一个坑迭代次数耗尽却停不下来。一开始我把max_iterations设成3想着够用了结果Agent反复调用同一个搜索工具三次返回的结果明明一样它还在那里重复搜。问题出在Observation反馈的内容区分度不够——Agent拿到了一样的信息不知道这是新信息还是无用信息。解决办法有两个一是把max_iterations提高到8-10给足探索空间二是在prompt里加一句如果Observation与之前相同且不包含新信息请直接基于已有信息给出答案。第二个坑工具描述写得敷衍模型开始乱调工具。我一度给计算工具写了这么个descriptionA calculator for math.结果模型拿着这个工具去算某个字符串里有多少个单词自然就报错了。后来我把所有工具的description统一改成功能 输入类型 返回内容 适用场景的格式比如calculator(expression): 传入一个数学表达式字符串返回精确计算结果。 适用于任何需要数值计算的场景不适用于文本处理。模型调用准确率肉眼可见地上升了。第三个坑Observation内容太长直接把模型上下文撑爆。当你接一个返回大对象的API时比如查询某个列表接口返回几百条记录全部塞进prompt模型很快就没空间了而且会从一堆噪声里迷失重点。我的做法是在工具执行阶段就对结果做预处理——只截取前N条记录、只保留关键字段、或者直接让一个轻量模型把Observe结果压缩成摘要之后再喂给主Agent。6.3 几个提升成功率的小技巧最后分享一些我经常用的优化技巧成本低、见效快用小模型跑通再换大模型。先用gpt-4o-mini这类便宜模型把整个流程和prompt调顺确认逻辑没问题后再到生产环境换成更强模型。毕竟生产goroutine一旦跑错一个循环成本翻倍。设置提前终止机制。如果连续两轮Observation完全相同或者Thought已经连续两次说信息足够但还没输出Final Answer就强制结束当前循环。省时间也省成本。把不知道作为合法答案。在prompt里明确告诉模型如果经过工具查询后确实找不到答案就如实说无法确认不要编。这能极大减少低质量幻觉输出。不要把最终回答和Agent循环混在一起。我通常让Agent先只负责收集信息这个过程收集结束后把完整的Observation历史丢给另一个角色或单独一轮LLM调用来生成最终答案。这样回答内容的风格和质量更可控也方便在收集信息阶段用结构化格式、在总结阶段用对话式风格。我在实际使用中的体会ReAct让我对大模型应用这个东西有了一个更踏实的判断模型本身可以不够强但只要你把它的思考过程和外部工具的反馈接成闭环很多事情就能做得又稳又准。我做过一个内部客户服务Agent用ReAct模式接上了订单查询、物流查询和退换货规则检索三个工具。刚开始效果很一般反复调试了工具描述和prompt模板之后才稳定下来。之后我越来越确信这类应用真正的天花板不在于模型多聪明而在于你给它的工具好不好用、反馈够不够清楚、边界设得清不清楚。如果你准备在自己的项目里尝试ReAct模式我的建议是先用我第4章那个几十行代码的最小实现跑通一个最简单的搜索计算任务把循环体读透再上LangChain这类框架。否则你会被框架里的AgentExecutor、Memory等一堆概念绕晕出了问题都不知道去哪排查。最后再分享一个小技巧在prompt的system里加一句在每一轮Thought中都要用一句话说明当前进展和下一步计划。这句话能让整个循环的稳定性提高一大截——因为模型被迫持续汇报状态它就不容易在循环里迷路。等你把ReAct跑熟了再去看那些更复杂的Agent框架心里就有底了。
RELATED

相关推荐

Docker容器化AI工具:环境一致性与安全隔离实践

Docker容器化AI工具:环境一致性与安全隔离实践

1. Docker容器运行AI CLI工具的核心价值在AI工具链快速迭代的当下,开发环境配置已成为阻碍技术落地的首要障碍。上周团队新来的算法工程师花了整整两天时间配置TensorFlow环境,期间遭遇CUDA版本冲突、Python依赖地狱等问题。这让我再次意识到&#xff1a…

📅 2026/10/27 12:05:06
窄隧道无影照明方案:光学设计与工业应用

窄隧道无影照明方案:光学设计与工业应用

1. 项目背景与核心需求窄隧道环境下的照明一直是个技术难题。传统照明方案在狭窄空间里会产生严重的反光和阴影干扰,影响作业人员的视觉判断。我在工业检测设备集成项目中就遇到过这种情况——当我们需要在直径不到30cm的管道内部进行视觉检测时,普通环形…

📅 2026/10/27 12:05:06
AI开发语言选型:从Python到TypeScript的工程实践

AI开发语言选型:从Python到TypeScript的工程实践

1. AI开发语言选择:工程视角下的核心考量第一次接触AI项目时,我犯了个典型错误——直接选用当时最热门的Python框架。结果在交付企业级推荐系统时,遭遇了性能瓶颈和团队协作噩梦。这个教训让我明白:AI开发语言的选择绝非跟风那么简…

📅 2026/10/27 12:00:06
MORE NEWS

更多资讯

📰

OpenCV多角度多尺度模板匹配技术详解

1. 多角度多尺度模板匹配技术解析 在工业视觉检测、医学影像分析等领域,我们经常需要从复杂背景中定位特定目标物体。传统模板匹配方法存在两大痛点:一是目标可能出现任意旋转角度,二是目标尺寸可能发生缩放变化。这正是多角度多尺度模板匹配…

📰

Windows本地Flink CDC实现MySQL实时同步实战指南

1. 为什么要在 Windows 上折腾 Flink 与 MySQL 同步 很多做数据处理的同行一听到“Flink 跑在 Windows 上”,第一反应是皱眉头——生产环境清一色 Linux,本地搞 Windows 图什么?我最初也是这个态度,直到实际带过几个项目之后才发现…

📰

零基础转型AI大模型:四阶段实战路线图

1. 项目概述:零基础程序员如何系统转型AI大模型领域 去年我帮团队里三位Java后端开发成功转型成大模型算法工程师,完整走通了从编程基础到工业级落地的全流程。这个四阶段学习路线图就是根据实战经验提炼的黄金路径,特别适合有编程基础但缺乏…

📰

基于MySQL的图书管理系统实战:从建表到借书事务与并发控制

简介:这份资源是面向高校学生与数据库初学者的MySQL图书管理系统课程设计完整包,可作为数据库期末大作业的参考实现。系统围绕图书表、读者表、管理员表、借阅表与逾期处罚表五类核心数据表展开,实现了借还书流程、模糊查询以及按权限区分用户…

📰

Camunda工作流邮件通知实战:Mail Task与JavaDelegate委托详解

工作流引擎跑到生产环境之后,业务方提的需求里十有八九会冒出一条:某个审批节点要通过邮件通知到人。Camunda 本身把「发邮件」这件事做成了引擎内置的一等公民,但真到落地的时候,坑往往不在「能不能发出去」,而在「模…

📰

Apache SeaTunnel二次开发实战与生态解析

1. 从Meetup看Apache SeaTunnel的生态活力 上周参加完本地技术社区的Meetup活动,对Apache SeaTunnel这个开源数据集成工具又有了新的认识。作为一款源自国内的开源项目,SeaTunnel在近两年快速崛起,已经成为大数据领域不可忽视的力量。活动现场…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬