新闻详情

新闻详情

首页 / 资讯中心 / 详情

LangChain Agent 入门:ReAct 循环、工具调用与记忆管理

发布时间:2026/9/18 12:20:05来源:尧图网络
LangChain Agent 入门:ReAct 循环、工具调用与记忆管理
1. 先把 Agent 是什么这件事说透再谈 LangChain玩 Agent 开发这件事我踩过的第一个坑不是代码写错而是概念没理清就急着上框架。市面上关于 Agent、LangChain、智能体、框架这些词的讨论实在太多有人说 LangChain 是入门首选有人又说它已经过时、该换 LangGraph 了还有一堆 Dify、Coze 之类的平台在旁边晃。新手在这种信息密度下最容易犯的错就是今天学一个框架、明天换一个平台结果哪个都停在 demo 阶段。所以这篇笔记我不打算一上来就贴代码而是先把几个关键概念掰开揉碎再用 LangChain 把第一个能跑起来的智能体拼出来让你知道每一步为什么要这么做。这套内容适合谁看如果你写过一点 Python调过几次大模型 API想让模型不只是聊天、而是能自己决定“调哪个工具、传什么参数、拿结果再继续”那这篇就是给你准备的。我会覆盖 LangChain 里 Agent 的核心构建方式、工具定义、ReAct 循环、记忆管理、常见报错排查以及它和 LangGraph 的关系。全程用从业者的视角讲人话不堆术语能直接抄的代码片段我都会标注清楚关键参数为什么这么设。有一点需要先说明LangChain 的版本迭代很快API 名字换过好几轮你按老教程写的代码很可能一跑就报 ImportError。我下面的示例以当前主流的langchainlangchain-core 独立集成包的结构为基准遇到导入路径差异我会顺手提醒。这是新手最容易被劝退的地方提前打个预防针。2. 拆解 Agent 的核心构成它和普通聊天有什么不一样2.1 从“一问一答”到“自己决定下一步”普通的大模型调用是线性的你把 prompt 丢进去模型吐一段文本结束。整个过程中模型没有“行动”的能力它只能输出文字。而智能体Agent的本质区别在于模型输出的不再只是给人看的文本而可以是“我要调用某个工具参数是这些”然后程序真的去执行这个工具把结果再喂回给模型模型基于新信息继续判断。这个“输出→执行→回灌→再判断”的循环就是 Agent 的心脏。你可以把它想象成一个会自己查资料、自己按计算器、自己翻数据库的实习生。你只给它一个目标比如“帮我查一下上个月销售额最高的三个产品”它会自己拆成几步先调数据库查询工具拿数据再调用排序或计算工具最后组织语言回答你。整个过程你不需要写死流程是模型在运行时动态决定的。理解这一点非常关键因为它直接决定了后面所有的代码结构你需要一个能循环的驱动器、一组它可调用的工具、一套让模型知道“什么时候该调工具”的提示词。LangChain 做的就是把这几个部件的组装工作标准化。2.2 为什么入门阶段我仍推荐从 LangChain 入手网上关于“LangChain 是否过时”的争论很多尤其在 LangGraph 出现之后。我的看法比较务实对于刚接触智能体开发的人LangChain 依然是最快能让你建立直觉的框架。原因是它把 Agent 循环、工具调用、提示词模板这些抽象概念用最短的代码量暴露给你你几十行就能看到一个完整的 ReAct 流程在跑。先用手动挡把离合器、油门、换挡的逻辑摸清楚后面再上自动挡图编排才不会晕。LangGraph 更像是给复杂的、带分支和人工介入的生产流程准备的。它用图结构描述状态流转控制力更强但也意味着你得先理解状态、节点、边这些概念学习曲线更陡。如果你连 ReAct 循环是怎么运转的都没跑通过直接上 LangGraph大概率是抄了个模板却不知道错在哪。所以我的建议路径很明确LangChain 打底跑通一个带工具的 Agent理解每一步的输入输出等你能自己手写一个简易的 Agent 循环时再去碰 LangGraph那时候你会发现它解决的是你真实遇到的痛点而不是为了新而新。2.3 动手前你需要具备的三样基础第一Python 基础要够用至少不怵装饰器、类和字典操作因为工具定义大量用到tool装饰器和类型注解。第二你要理解大模型 API 的调用方式知道什么是 system prompt、user prompt、temperature、max_tokens 这些基本参数否则调试时你不知道该调哪个旋钮。第三要有基本的异步和异常处理意识工具调用失败是常态不做兜底的 Agent 在生产里就是个定时炸弹。这三样不需要精通但缺了任何一样你在遇到报错时都会抓瞎。我见过不少人卡在“模型就是不调用我的工具”这个现象上排查半天最后发现是工具函数的文档字符串docstring写得含糊模型根本不知道这个工具是干嘛的。这类问题的答案都藏在基础里。3. 环境搭建与第一个可运行 Agent 的完整落地3.1 依赖安装与项目结构建议先把环境理干净。我习惯给这类项目单独建虚拟环境避免包冲突因为大模型相关的库依赖链很长混装很容易出问题。核心要装的东西大致分三块LangChain 的核心包、你选用的模型集成包、以及工具可能用到的第三方库。python -m venv venv source venv/bin/activate # Windows 用 venv\Scripts\activate pip install langchain langchain-core pip install langchain-openai # 以 OpenAI 兼容接口为例其他模型有各自集成包 pip install python-dotenv项目目录我会这样分根目录放.env存密钥记得加进.gitignoretools/放自定义工具agent.py放主逻辑。这样等你工具多了不至于全挤在一个文件里。密钥管理这块我给个硬性建议绝对不要把 API key 硬编码进代码然后推到远端仓库用python-dotenv从环境变量读这是每个从业者都该养成的肌肉记忆。注意不同版本的 LangChain 导入路径变化频繁比如AgentExecutor曾在多个包之间迁移。如果你复制代码后报ImportError先别怀疑逻辑去官方文档确认当前版本的导入路径这能省你大量时间。3.2 必须搞懂的四个核心概念在写代码前我把 LangChain 里组装 Agent 会用到的四个概念先对齐一下这是理解后续所有代码的钥匙。LLM / ChatModel负责“思考”的大脑也就是你调用的大模型。在 Agent 里它的角色是决策者判断下一步该做什么。Prompt Template给模型的指令模板。Agent 场景里它不是普通的问答模板而是包含“你有哪些工具、请按 ReAct 格式输出”的这类结构化说明模型靠它来决定行为。Tool模型可以调用的外部能力本质就是一个有明确输入输出和用途说明的函数。可以是查天气、算数学、查数据库、发邮件任何你能写成函数的东西。AgentExecutor驱动器负责跑那个循环。它把你上面的部件串起来反复执行“让模型想→执行工具→把结果喂回去→再让模型想”直到模型给出最终答案或达到停止条件。把这四样理解成“大脑 指令 手脚 循环引擎”整个架构图在你脑子里就立起来了。后面无论换成哪个框架这四个部件都会以不同名字出现。3.3 组装并跑通第一个 ReAct Agent下面给一个尽量精简但完整的例子。先定义一个工具然后把它交给 Agent。我特意把 docstring 写得清楚因为这就是模型判断“要不要用这个工具”的唯一依据。from langchain_core.tools import tool from langchain_openai import ChatOpenAI from langchain.agents import create_react_agent, AgentExecutor from langchain import hub from dotenv import load_dotenv load_dotenv() tool def multiply(a: float, b: float) - float: 计算两个数字的乘积。当用户需要进行乘法运算时使用此工具。 输入应为两个数字输出为它们的乘积。 return a * b llm ChatOpenAI(modelgpt-4o-mini, temperature0) # 拉取一个标准的 ReAct 提示词模板 prompt hub.pull(hwchase17/react) tools [multiply] agent create_react_agent(llm, tools, prompt) executor AgentExecutor(agentagent, toolstools, verboseTrue, max_iterations5) result executor.invoke({input: 帮我算一下 23 乘以 47 等于多少}) print(result[output])跑起来后你会看到verboseTrue打印出的完整思考链模型先想“我需要用乘法工具”然后输出 action 和 action_inputExecutor 执行工具拿到结果再喂回模型模型给出最终答案。这一串日志就是 ReAct 循环的实况强烈建议你第一次运行时逐行读一遍比看十篇文章都管用。temperature0这个参数在 Agent 场景几乎是标配。因为你要的是稳定、可复现的决策而不是有创意的表达。温度高了模型可能天马行空地选错工具或者输出格式不符合解析要求调试阶段会把你逼疯。max_iterations也要设避免模型陷入死循环时无限调用这个后面会细说。4. ReAct 循环拆解模型到底是怎么“边想边做”的4.1 Thought-Action-Observation 三步走ReAct 这个名字来自 Reasoning Acting它的核心是一个固定的文本格式循环。模型每一步都要输出三样东西的思路思考Thought我该怎么解决、行动Action我要调用哪个工具、行动输入Action Input给工具传什么参数。程序解析出 Action 和 Action Input执行对应工具把返回值作为 Observation 追加进上下文然后再让模型基于这个观察继续下一步。这个机制最巧妙的地方在于它把“工具调用”这件结构化的事转化成了模型的文本生成能力。模型不需要专门的函数调用接口只要它能按格式写出Action: multiply和Action Input: 23, 47程序就能解析并执行。这也是为什么提示词模板如此重要——模板规定了模型必须遵守的输出格式一旦格式跑偏解析就失败。你在verbose日志里会反复看到这个循环直到模型判断“信息够了”。判断的标准是模型输出Final Answer: xxxExecutor 检测到这个词就停止循环把答案返回给你。理解了这个终止条件你就能明白为什么有时候 Agent 会一直转圈——模型迟迟不给出 Final Answer。4.2 提示词模板里那些容易被忽略的细节很多人直接用hub.pull(hwchase17/react)拉现成模板就不管了但一旦要定制模板里的几个部分必须保留。模板里会明确列出{tools}和{tool_names}两个占位符前者是工具的完整描述名字、参数、用途后者是工具名列表。模型就是靠这些信息知道有哪些牌可打。如果你自己写模板却漏了工具描述模型会“看不见”工具自然永远不会调用。还有一个细节是{agent_scratchpad}占位符它承载的是前面所有轮次的 Thought/Action/Observation 历史。没有它模型每一轮都像失忆一样不知道上一步做过什么循环就断了。这几个占位符是 ReAct Agent 能运转的骨架缺一不可。我建议你至少完整读一遍默认模板的内容。它不长但把输出格式、工具说明、停止条件全写清楚了。读懂它你就能针对自己的场景微调比如强制模型用中文思考、要求它在最终答案里附上数据来源这些都是改模板就能实现的事。4.3 输出解析与格式错乱的兜底ReAct 的软肋就在这里它依赖模型严格输出特定格式的文本。现实是模型偶尔会多写一句、少写个冒号或者在 Action Input 里加上多余的解释文字导致解析器报OutputParserException。这不是框架的锅是这种基于文本约定机制的固有风险。我的处理策略分三层。第一层选一个指令遵循能力强的模型temperature 设低这是最省事的。第二层在 Executor 里开启handle_parsing_errorsTrue让解析失败时把错误信息回灌给模型提示它“你格式写错了请重新按格式输出”模型往往能自己纠正。第三层对关键的生产流程不要只依赖 ReAct考虑用支持原生函数调用的模型接口它们的工具调用是结构化的 JSON解析稳定性高得多。executor AgentExecutor( agentagent, toolstools, verboseTrue, handle_parsing_errorsTrue, max_iterations5 )这三个参数放在一起是让 demo 走向“不那么容易崩”的最小组合。别小看handle_parsing_errors它能救回相当一部分因为格式问题而中断的对话。5. 工具定义的艺术决定 Agent 好不好用的关键5.1 一个好工具长什么样工具是 Agent 的手脚手脚灵不灵直接决定它能干多少事。而模型判断用不用某个工具几乎全靠工具的name、参数签名和 docstring。所以写工具的第一原则是描述要像写给一个完全不了解你系统的同事看。说清楚这个工具做什么、什么场景用、输入长什么样、输出是什么。举个例子一个查订单的工具如果你只写查询订单模型在用户问“我的包裹到哪了”时可能犹豫甚至不调用。如果你写成根据订单号查询订单的物流状态和预计送达时间。当用户询问订单进度、包裹位置或预计到达时间时使用。输入为订单号字符串。模型判断的准确率会明显提升。这不是玄学是提示工程在工具层的直接体现。参数类型也要用类型注解写清楚。LangChain 会根据函数签名自动生成工具的输入 schema模型看到的参数说明就来自这里。如果一个参数是可选的非必填项记得给默认值否则模型可能编造一个值去填。5.2 工具数量与粒度的权衡新手容易走两个极端要么一个工具都不写要么一口气定义二十个工具啥都想覆盖。工具太多会带来一个隐蔽问题——模型的选择空间变大选错的概率也随之上升而且每个工具的描述都会占用上下文token 成本蹭蹭涨。我的经验是先按用户的高频意图划分工具控制在个位数起步。粒度上一个工具做一件事别搞“万能工具”。比如你把“查询数据库”和“格式化成表格”塞进一个工具模型就很难在只需要其中一半功能时精确调用。反过来也别把一件事切得太碎否则完成一个任务要调七八次又慢又费钱。判断粒度是否合理有个土办法站在一个刚入职的助理角度把工具清单念给他听如果他听完知道每个工具该在什么时候用那这个粒度就是合适的。5.3 工具的异常处理与超时工具执行失败是常态网络抖一下、数据库连接断一下、外部接口限流一下都可能让你的工具抛异常。如果不处理整个 Agent 循环会因为一个工具报错而中断。稳妥做法是在工具函数内部把可预期的异常捕获返回一个有意义的错误字符串让模型读到“这个工具失败了原因是 xxx”它就有机会换个工具或者调整参数重试。tool def query_order(order_id: str) - str: 根据订单号查询订单物流状态。用户询问订单进度时使用。 try: # 实际查询逻辑 result do_query(order_id) return f订单 {order_id} 状态{result} except TimeoutError: return f查询订单 {order_id} 超时请稍后重试 except Exception as e: return f查询订单 {order_id} 失败{str(e)}这种“把异常转成给模型看的信息”的写法是让 Agent 具备一定自愈能力的关键。外部调用还要设超时不能让一个卡住的工具把整个循环拖死。6. 记忆与上下文管理让 Agent 记住聊过什么6.1 短期对话记忆的实现默认情况下Agent 每次invoke都是无状态的你不告诉它历史它就不知道上一轮聊了什么。要实现多轮对话得把历史消息维护起来每一轮把之前的对话拼进输入。LangChain 提供了多种 Memory 组件核心思路都是“存储注入”。from langchain.memory import ConversationBufferMemory memory ConversationBufferMemory(memory_keychat_history, return_messagesTrue)带记忆的 Agent 在构建时要把memory和chat_history占位符接入提示词然后 Executor 会自动在每轮对话前后读写记忆。这里有个坑要提醒加了记忆后提示词模板里必须有对应的占位符否则历史根本没被拼进去你会以为记忆失灵实际上是接线没接对。ConversationBufferMemory简单直接把所有历史原样存着。但对话一长上下文就爆了token 费用也跟着涨。所以它只适合短对话或 demo。6.2 长对话的压缩与检索方案对话变长后有两种主流处理方式。一种是窗口式记忆只保留最近 N 轮对话简单粗暴但会丢掉早期信息。另一种是摘要式记忆用模型把早期对话压缩成一段摘要既省 token 又保留了要点。ConversationSummaryMemory就是干这个的它每几轮就调用一次模型把历史浓缩一次。再进一步就是长期记忆把对话内容向量化存进向量数据库每次对话时检索相关片段拼进上下文。这就是所谓的本地知识库问答的底层逻辑用户问一个新问题系统先从知识库里找出最相关的几段内容连同问题一起喂给模型模型基于这些“资料”回答。这套 RAG 思路和 Agent 结合后威力很大Agent 可以在需要时主动去检索知识库而不是每次都全量拼接。选哪种取决于你的场景。客服机器人可能窗口记忆加检索就够需要长期跟踪用户偏好的助理就得上向量存储。别一上来就追求最复杂方案先用最简单的跑通等真实遇到上下文过长的问题再升级。6.3 token 成本控制的实际手段聊记忆就绕不开成本。Agent 的 token 消耗比普通问答高得多因为每一轮循环都要把完整的历史和工具描述重新发一遍。几轮下来输入 token 轻松翻好几倍。控制手段有几个我常年在用的把工具描述写精炼但完整别啰嗦给记忆设上限超了就用摘要替换能用小模型做初筛的环节就别全程上大模型max_iterations设小一点逼自己优化工具设计而不是靠多轮硬扛。还有一个容易被忽略的点ReAct 的中间思考过程也会占 token如果你的场景允许考虑用更简洁的思考格式。7. 常见问题与排查实录这些坑我都替你踩过了7.1 模型死活不调用工具怎么办这是新手反馈最多的问题。排查顺序我建议这样走第一步看工具的 docstring 是否说清了用途和触发场景描述模糊是头号嫌疑第二步确认提示词模板里{tools}和{tool_names}占位符被正确填充了没填的话模型根本看不到工具第三步看模型本身的能力指令遵循弱的模型在 ReAct 格式上表现很差第四步检查 temperature太高会导致行为不稳定。排查时把verboseTrue打开你会看到模型的原始输出。如果它压根没提工具的事那大概率是工具描述或模板问题如果它想调但格式写错了那是解析问题用handle_parsing_errors兜底。7.2 Agent 陷入死循环或调用次数超限模型反复调用同一个工具、拿一样的结果就是不给出最终答案这通常有两个原因。一是工具返回的信息没解决模型的问题它以为还要再试二是提示词没有明确诱导它输出 Final Answer。处理办法设置max_iterations强制止损避免无限烧钱优化工具返回值让它包含模型判断“够不够了”所需的信息在提示词里强调“如果已经获得足够信息请直接给出最终答案”。我自己遇到过工具返回空字符串导致模型以为查询失败、反复重试的情况后来统一要求工具即使无结果也要返回一句明确的“未找到相关记录”循环立马就正常了。7.3 常见问题速查表现象可能原因排查方向模型不调用工具工具描述模糊 / 模板缺占位符检查 docstring 与{tools}填充解析报错 OutputParserException模型输出格式跑偏开启handle_parsing_errors降低 temperature进度卡住不返回工具阻塞无超时给外部调用加超时异常转字符串返回循环停不下来工具结果不满足模型判断设max_iterations优化返回值信息量多轮后失忆记忆未接入或占位符缺失检查 memory 与chat_history接线token 消耗暴涨历史全量拼接换窗口/摘要记忆精简工具描述这张表建议截图存着出问题时按顺序过一遍能省下大量瞎试的时间。8. LangChain 和 LangGraph 到底怎么选以及后续怎么走8.1 两者不是替代关系是分工关系“LangChain 和 LangGraph 都过时了吗”这类问题我的回答一直是它们解决的是不同复杂度的问题。LangChain 的 Agent 适合流程相对线性、循环结构清晰的场景比如“想→调工具→再想→给答案”这种。它的抽象层级高写得快代价是对复杂流程的控制力有限。LangGraph 把工作流抽象成图节点是处理步骤边是流转条件状态在节点间传递。它擅长的是带分支、带循环、带人工审批节点的复杂流程。比如一个审批 Agent要根据金额大小走不同审批路径中途可能暂停等人工确认这种用 LangGraph 表达就自然得多用 LangChain 硬凑会很别扭。所以别纠结谁取代谁先问自己流程复杂到什么程度。简单场景硬上图编排是过度设计复杂场景硬用链式循环则是自找麻烦。8.2 什么信号说明你该上 LangGraph 了有几个信号出现时我就知道该换工具了。第一你需要在流程中间暂停、等外部输入比如人工审批再继续第二你的流程里有明显的条件分支不同情况走完全不同的路径第三你需要对状态做精细的持久化和恢复比如任务跑一半崩了要能接着跑第四你需要多个 Agent 协作各自负责一块再汇总。这几种需求用 LangChain 的 AgentExecutor 硬实现会越来越拧巴代码里塞满 if-else 和状态标记维护起来痛苦。这时候上 LangGraph你会觉得它的状态和节点设计终于对上了你的问题形状。但前提是你得先把 Agent 的循环本质理解透否则学 LangGraph 只是换个地方迷惑。8.3 我给后续学习排的路线第一阶段把这篇里的 ReAct Agent 跑通、改通能自己加工具、调提示词、排查常见错误。第二阶段给它加上记忆和检索做一个能做本地知识库问答的小助手体会 RAG 和 Agent 结合的效果。第三阶段找 LangGraph 的入门例子把你之前用链式写法实现的一个稍微复杂的流程用图的方式重写一遍对比两者的表达差异。第四阶段才是去看各种平台化产品和多 Agent 协作框架这时候你已经有判断力不会被概念带着跑。学 Agent 开发代码只是表层真正值钱的是你对“模型如何决策、工具如何设计、循环如何收敛”这些机制的体感。框架会换代但这些东西不会。我在实际带人的过程中发现能把一个工具描述改到模型调用准确率明显提升的人后面学什么框架都快因为他抓的是本质。反过来只追新框架、不深挖机制的人永远在抄模板和调 bug 之间循环。这篇笔记里的每个示例都建议你亲手敲一遍、改几个参数看变化比读十遍都有用。
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

364 · 接雨水 II (Heap) 2026/9/18 13:14:18

364 · 接雨水 II (Heap)

。 链接:九章算法 - 帮助更多程序员找到好工作,硅谷顶尖IT企业工程师实时在线授课为你传授面试技巧 题解: 九章算法 - 帮助更多程序员找到好工作,硅谷顶尖IT企业工程师实时在线授课为你传授面试技巧 九章算法强化班 1.从四周向…

阅读更多 →
多智能体协作实战:从单体Agent到生产级系统的完整指南 2026/9/18 13:14:18

多智能体协作实战:从单体Agent到生产级系统的完整指南

先讲个真实场景。上个月一个做电商运营的朋友找我吐槽,他用单个Agent写竞品分析报告,结果大部分时间都耗在“让Agent别跑偏”——让它分析定价,它写着写着开始编产品灵感;让它总结差评,它顺手把促销活动也塞了进来。我…

阅读更多 →
EtherNet/IP数据仿真端搭建 2026/9/18 13:14:18

EtherNet/IP数据仿真端搭建

目录 一、Emulate使用说明 二、Emulate仿真组态 三、Studio 5000组态编程 四、设置TAG 五、RSLINX建立连接 六、模拟仿真效果 前言 EtherNet/IP是应用层的协定,将网络上的设备视为许多的“物件”。EtherNet/IP为通用工业协定为基础而架构,可以存取来自ControlNet及Dev…

阅读更多 →
【Stable Diffusion】OneButton 生成高质量提示词 2026/9/18 13:14:18

【Stable Diffusion】OneButton 生成高质量提示词

在数字创作日益普及的今天,图像生成工具成为了艺术家和创意从业者们的强大助力,尤其是稳定扩散(Stable Diffusion, SD)技术的广泛应用。然而,使用这些工具时常常面临着提示词的构思困难和图像效果不达预期的问题。为了让用户更好地探索创意的广度和深度,One Button Promp…

阅读更多 →
AUTOSAR Arxml文件可视化:从XML解析到交互式图表的工程实践 2026/9/18 13:14:18

AUTOSAR Arxml文件可视化:从XML解析到交互式图表的工程实践

1. 从一个让人头大的Arxml文件说起如果你在汽车电子软件行业待过哪怕半年,大概率都经历过这样的场景:打开一个AUTOSAR项目,面对动辄几万行、嵌套层级深到让人怀疑人生的Arxml文件,想找一个特定ECU的CAN报文配置,结果在…

阅读更多 →
电力系统机组组合优化:基于MILP的Matlab实现与工程落地 2026/9/18 13:11:17

电力系统机组组合优化:基于MILP的Matlab实现与工程落地

1. 项目概述:这不是一个“调参小技巧”,而是一次对电力系统调度底层逻辑的硬核重写你有没有遇到过这样的场景:某天凌晨三点,调度中心大屏上跳动着几十台机组的实时出力曲线,负荷预测突然上浮5%,风电出力又骤…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞