LangChain智能体(Agent)实战指南:从ReAct到LangGraph

发布时间:2026/10/19 19:48:03
LangChain智能体(Agent)实战指南:从ReAct到LangGraph 聊LangChain绕不开的就是Agent。用过ChatGPT的人都知道模型本身再强也只是个“建议者”你问它今天天气如何它只能抱歉地说自己不知道实时数据。但Agent不一样它把模型从“会说话的百科全书”变成了“会动手办事的员工”——给定一个目标它能自己拆解任务、调用工具、查阅外部数据、反复尝试最后把结果交给你。这就是LangChain框架里智能体的核心价值。这篇内容我想从实操角度把LangChain中的智能体拆开讲透适合已经会写几行Python、用过OpenAI或同类大模型API但还没系统搞过Agent编排的开发者。废话不多说直接进入正题。1. 智能体在LangChain中的定位与核心价值1.1 从“一次问答”到“自主完成任务”传统的大模型调用模式是“你问一句模型答一句”Prompt写好了参数调对了输出就固定了。这种模式适合翻译、总结、文本生成等一次性任务但一旦遇到需要多步骤推理、需要实时数据、需要操作外部系统的场景它就完全不够用。举个最简单的例子你想让模型查一下某股票最近三个月的价格走势并计算平均涨幅。如果只是普通调用模型会坦诚地告诉你“我没有实时数据”。但换成Agent架构后它会先把任务拆解成几个子任务第一确定股票的代码和交易所第二调用股票查询工具拉取近90天的历史价格第三用Python工具计算平均涨幅第四把这四个步骤的结果串成一段话回复你。这个过程中用户只给了一个目标中间的步骤全是Agent自己规划出来的。这正是LangChain智能体最核心的价值把大模型从“问答引擎”升级成“任务执行引擎”。它不再是你说一句它答一句而是你下达一个目标它自行规划、调用工具、验证结果、直到完成目标或达到最大迭代次数。1.2 智能体的组成四要素LangChain中一个完整的Agent系统拆开来看其实只有四个核心组成部分模型LLM负责推理、规划、决策。它是Agent的“大脑”所有关于“下一步做什么”的判断都由它做出。工具Tools负责执行具体操作。查询天气、搜索网页、运行代码、操作数据库这些都是工具。工具是Agent的“手脚”。记忆Memory负责保存对话历史、中间结果、关键信息。没有记忆的Agent就像一个失忆的员工每次出发前都得重新交代背景。规划器Planner负责制定行动计划。LangChain里通常通过Prompt引导模型输出Thought思考、Action动作、Observation观察三个部分的循环来完成规划。这四个部分很好记大脑、手脚、记事本、行动计划表。理解了这个模型后面所有代码都不过是在把这四样东西拼装起来而已。2. 核心机制拆解ReAct范式与工具调用循环2.1 什么是ReAct范式LangChain中智能体默认采用的工作模式叫做ReAct全称是Reason and Act直译过来是“推理与行动”。这个范式最早由学术界提出后来被LangChain工程化为Agent的核心执行逻辑。ReAct的核心思想非常朴素模型在每一轮循环中做两件事——先思考给出Thought再行动给出Action然后观察工具返回的结果给出Observation再根据观察继续思考形成行动循环。打个比方你让实习员工去调研一个竞品的定价策略他不会一口气把所有事做完而是一步一步来——先想“我需要知道对方官网的报价”于是打开浏览器搜索看到结果后再想“价格信息在某个页面里”于是他点进那个页面看到具体价格后再想“还需要对比我们自己的定价”于是他调取内部表格……每一步思考和行动交替进行直到任务完成。在LangChain中ReAct循环通常被封装在AgentExecutor或LangGraph的自定义循环里。每一轮循环包含模型根据当前状态输出一个文本片段其中包含Thought和Action指令解析器把Action指令解析成具体的工具名称和参数对应的工具被执行返回Observation观察结果被追加到对话历史中模型拿到新的历史再输出下一轮Thought和Action。整个循环一直重复直到模型输出“Final Answer”或者循环次数达到上限。2.2 工具调用循环的本质很多初学者以为工具调用是模型直接发起一个函数调用其实不是。在LangChain里模型输出的Action本质上是一段结构化文本通常采用JSON格式包含工具名称和参数。LangChain的解析器拿到这个JSON后才真正去Python环境里寻找并执行对应的函数。这段流程拆开看是# 模型输出示例伪代码 Thought: 用户想知道天气我需要调用天气查询工具 Action: {action: get_weather, action_input: {city: 杭州, date: today}}解析器提取到工具名get_weather和参数{city: 杭州}后把它转换为实际的函数调用再把函数的返回值包装成Observation送回模型。模型拿到Observation后继续推理直到能给出最终答案。这种设计的好处是明显的模型不需要真正执行代码它只需要“声明”它想调用什么工具、传入什么参数实际执行交给框架和Python运行时。这大大降低了模型直接操作系统的风险也使得工具的扩展变得非常容易——只要在工具列表里注册一个新函数模型就能在推理中自动发现并使用它。2.3 LangChain与LangGraph的两种实现方式这里必须提一个让很多人困惑的问题新版LangChain中传统AgentExecutor和LangGraph有什么区别老牌的AgentExecutor是LangChain 0.1及以前的主推方案。它把ReAct循环封装在一个高层的Executor类里开发者只需要创建Agent并传入工具列表剩下的循环过程由框架托管。优点是简单、代码量少、上手快缺点是循环过程是黑盒遇到循环卡死、工具调用异常等问题时很难在循环内部做干预。LangGraph则是LangChain团队推出的新一代编排框架它把Agent的循环拆成了显式的图结构节点代表“模型调用”或“工具执行”边代表“下一步去哪”。开发者可以精确控制每个节点的输入输出也可以在任意位置插入条件判断、人工审核、缓存逻辑。我个人的建议是如果你只是在做原型验证、写Demo、快速跑通流程用老牌的AgentExecutor完全没问题代码量少心智负担低。但如果你要做生产级应用、需要精细控制Agent行为、要对循环过程做观测和干预一定要学LangGraph而且越早越好因为LangChain的社区和新特性明显在往LangGraph倾斜。3. 工具定义与选择让智能体真正“动手”3.1 工具的本质是一个带描述的函数LangChain中定义一个工具本质上就是把一个普通Python函数包装成模型可以理解的形式。最关键的不是函数本身而是三个附加信息函数名、功能描述、参数说明。很多人会忽略描述的重要性但实际使用中描述的质量直接决定模型能不能选对工具。我举个反例你定义了一个搜索天气的工具如果你把描述写成“获取天气信息”模型在需要查询天气时确实能选对它。但如果你的系统里有五个工具其中有“获取城市天气”“获取城市空气质量”“获取城市未来一周天气预报”描述如果写得模糊模型就可能选错。所以一个合格的工具描述应当说清楚三个问题这个工具是干什么的、适合在什么场景下使用、参数各代表什么含义。比如from langchain.tools import tool tool def get_city_weather(city: str, date: str today) - str: 查询指定城市在指定日期的天气情况包括温度、降水概率、风力等级。 适用场景用户询问“今天的天气怎么样”“明天会不会下雨”等包含时间地点的问题。 参数说明 - city: 城市名称中文或拼音均可例如“杭州”或“hangzhou” - date: 日期支持today、tomorrow或2025-03-01格式默认为今天 # 这里是调用天气API的实际逻辑 return f{city} {date} 天气晴25°C降水概率10%看到没描述里甚至写清楚了什么时候该用这个工具、参数格式是什么模型选错的概率就会低很多。3.2 工具注册与参数Schema的坑LangChain的tool装饰器会自动从函数的类型注解Type Hints和文档字符串Docstring中提取参数Schema用于告诉模型“这个工具接受哪些参数”。这意味着你函数的类型注解必须写清楚否则很可能出现模型生成了某个参数但在实际调用时因为类型不匹配而报错。举个例子如果你的函数定义是tool def add_numbers(a, b): 计算两个数字的和 return a b没有类型注解的话LangChain解析到的参数Schema就是空泛的模型可能传字符串进去也可能把两个参数合并成一个JSON对象传进来运行时极不稳定。正确写法是tool def add_numbers(a: int, b: int) - int: 计算两个整数a和b的和返回整数结果。 return a b还有一个我踩过的坑参数名要尽量简洁且语义明确。模型在生成JSON时会尽量按照参数名来猜测含义如果你把参数命名为x1、x2这种模型很难判断应该传入什么内容。更好的做法是用query、city、start_date这类自解释的名称。3.3 工具选择不是越多越好很多人觉得工具越多Agent越强大。这个想法大错特错。模型在每一步推理时要把完整的工具列表和描述都放进上下文里工具太多会导致两个问题一是Token消耗暴涨成本直线上升二是模型选择工具的准确率下降它面对一堆相似工具时很容易晕。一个比较实用的经验是同一时间暴露给模型的核心工具最好控制在5到8个以内。如果你的系统有很多工具可以考虑做工具分组或路由让Agent先决定“该去哪一组里挑工具”再具体选择。LangChain 0.2之后的版本支持ToolNode和工具路由能把这层逻辑做得比较优雅。另外一个经验是工具描述里的关键词要和你预期的用户提问方式对应起来。比如你有一个查快递的工具描述里如果写了“查询物流信息”“快递单号”“包裹追踪状态”这些关键词模型在面对用户五花八门的问法时匹配的准确率会明显更高。4. 实操实录从零搭建一个LangChain智能体4.1 环境准备与版本选择我先分享一下我常用的环境版本组合这些版本都经过实测跑通率比较高Python 3.10 langchain0.3.x langchain-openai0.2.x langgraph0.2.x langchain-community0.3.x安装命令很简单pip install langchain langchain-openai langchain-community langgraph需要说明一点很多人分不清langchain和langchain-community的区别。langchain是核心框架负责Chain、Agent的编排逻辑langchain-community里装的是各种第三方集成比如浏览器工具、文件工具、数据库工具等。如果你要做Demo大部分工具类定义都在community包里。4.2 定义一个实用的工具库我以一个“招聘信息助手”为案例来演示这个场景既有工具调用、又有结构化输出非常适合入门。假设我们要做一个小助手它能根据用户输入的城市和岗位查询某招聘平台的职位信息还能根据职位描述计算薪酬中位数。工具库定义如下from langchain.tools import tool tool def search_jobs(city: str, keyword: str) - str: 根据城市和岗位关键词搜索招聘信息返回最多10条职位的标题、公司、月薪范围。 适用场景用户提到“找工作”“招聘”“职位”“岗位”等关键词时。 参数说明 - city: 城市名称如“上海”“北京”“杭州” - keyword: 岗位关键词如“Java开发”“产品经理” # 这里应该调用某招聘平台的API为了演示我们模拟返回结果 jobs [ {title: Java开发工程师, company: 某科技公司, salary: 15k-25k}, {title: 资深后端工程师, company: 某电商平台, salary: 25k-40k}, ] return str(jobs) tool def calculate_median_salary(jobs_str: str) - str: 从职位信息字符串中提取月薪区间计算中位数返回一个总结。 参数说明 - jobs_str: 职位信息字符串通常是search_jobs工具的返回结果 # 用正则提取所有薪水数字计算中位数 import re salaries [] for match in re.findall(r(\d)k-(\d)k, jobs_str): low, high int(match[0]), int(match[1]) salaries.extend([low, high]) if not salaries: return 无法从提供的信息中解析薪水数据 salaries.sort() mid salaries[len(salaries) // 2] return f该列表中年薪中位数约为{mid}k/月这里我刻意设计了两个工具有先后依赖关系先搜索职位再基于搜索结果计算中位数。Agent必须理解这个先后顺序才能正确串联工具。这也是验证Agent推理能力的好案例。4.3 构建Agent并执行任务接下来是核心代码构建一个能自主规划、调用工具的Agentfrom langchain_openai import ChatOpenAI from langchain.agents import create_tool_calling_agent, AgentExecutor from langchain.prompts import ChatPromptTemplate # 初始化模型temperature调低让Agent更专注执行任务 llm ChatOpenAI(modelgpt-4o-mini, temperature0) # 工具列表 tools [search_jobs, calculate_median_salary] # 提示词模板 prompt ChatPromptTemplate.from_messages([ (system, 你是一个专业的招聘信息助手。你可以使用工具查询职位信息并进行分析。回复时请使用简体中文条理清晰。), (human, {input}), (placeholder, {agent_scratchpad}), ]) # 创建Agent agent create_tool_calling_agent(llm, tools, prompt) # 创建执行器 executor AgentExecutor(agentagent, toolstools, verboseTrue, max_iterations5) # 执行任务 result executor.invoke({input: 帮我查一下杭州的Python开发岗位并分析薪资中位数是多少}) print(result[output])执行过程你可以打开verboseTrue参数来看它会打印每一轮的Thought、Action、Observation非常直观。我当时第一跑这个案例的时候看到模型自己规划出“先查职位→再算中位数”的链条确实很震撼。这里要注意的是max_iterations参数。有些任务Agent会绕圈子反复调用同一个工具如果没有上限可能几分钟都跑不完Token费用也刹不住。我一般设为5到8既能覆盖大多数正常任务又能强制终止异常循环。4.4 用LangGraph实现同样的Agent如果你要更精细地控制流程LangGraph的写法是这样from langgraph.graph import StateGraph, END from typing import TypedDict, List class AgentState(TypedDict): messages: List[str] current_tool: str tool_input: dict def call_model(state): # 调用模型让模型决定是调用工具还是给出最终回答 response llm.invoke(state[messages]) return {messages: [response]} def call_tool(state): # 根据模型输出的工具调用指令执行对应工具 tool_name state[current_tool] tool_input state[tool_input] tool_map {t.name: t for t in tools} result tool_map[tool_name].invoke(tool_input) return {messages: [(observation, result)]} def should_continue(state): # 判断是否继续循环模型如果是最终回答则不继续 if state[current_tool] final_answer: return END return tool_node graph StateGraph(AgentState) graph.add_node(model, call_model) graph.add_node(tool_node, call_tool) graph.add_edge(model, tool_node) graph.add_conditional_edges(model, should_continue) graph.set_entry_point(model)LangGraph的核心思路是把“模型决策”和“工具执行”拆成独立的节点中间用条件边控制走向。这种设计让你可以在每个节点前后插入日志、监控、缓存、人工审批等逻辑生产环境里的可观测性会强很多。我实测过两种实现方式结论是如果只是Demo或学习用AgentExecutor就够了代码量少、报错信息友好如果要上线LangGraph是更稳的选择它的状态管理机制让调试和扩展都清晰很多。5. 常见问题与排查技巧实录5.1 Agent陷入无限循环这是使用Agent时最常遇到的问题。表现是Agent反复调用同一个工具每次都拿到相同的结果然后继续调用像个死循环一样永不停止。排查思路有三步。第一步确认是否设置了max_iterations如果没设置很可能费用耗光前循环根本停不下来。第二步打开verboseTrue看最后一两轮的输出通常能发现模型在重复“Observation没变化→Action重复”的模式这说明模型没有从Observation中提取到有效信息或者Prompt里没有明确指示“观察结果不变时应该改变策略”。第三步检查工具返回的结果是否太简短如果Observation只是“查询成功”而没有实际数据模型没有足够信息来决定下一步就会陷入原地打转。我通常会在System Prompt里加一句如果某个工具返回的结果与前一次相同必须选择其他方案或直接给出当前可得到的答案。这条指令能显著减少循环卡死的情况。5.2 工具参数解析失败模型生成了工具调用但实际执行时报参数错误这在中文场景下特别常见。比如日期格式、城市名称格式模型可能自由发挥。解决办法有两个层面。第一层工具的参数描述里写清楚格式示例例子越多越好。第二层在工具函数内部做容错解析比如用正则或字典映射把常见变体归一化成标准格式。我之前做过一个查天气的工具用户说“上海明天天气”模型生成的参数可能是{city: 上海, date: 明天}也可能是{city: shanghai, date: 2025-03-02}如果不做归一化工具很容易报错。后来我在函数里加了日期转换逻辑和城市别名映射问题基本消失。5.3 模型选错工具选错工具通常是工具描述写得不好导致的。比如你的系统里同时有“查询当日天气”和“查询未来一周天气预报”如果两个工具的描述都只写“查询天气”模型根本分不清该用哪个。这种情况下最好的办法是重写描述把使用场景写得非常具体。比如“未来一周天气预报”的描述可以写成“当用户询问未来几天、一周或更长时间的天气时使用。此工具返回每日的最高温、最低温和降水概率。”这样模型在匹配用户意图时依据就明确多了。5.4 上下文长度爆炸Agent循环次数一多每轮的Thought、Action、Observation都会累积在上下文里Token消耗直线上升。尤其是工具返回值非常大的场景比如搜索返回了几万字的文章内容后面所有轮次都会带着这些内容反复重读费用非常吓人。我的做法是工具返回前先做截断或摘要只保留最核心的信息。比如搜索工具只返回前3条结果每条截断到200字以内。另一个做法是定期压缩历史可以用LLM把早期轮次的内容总结成一段摘要替代原始记录。LangGraph里有现成的摘要节点可以接AgentExecutor里则需要自己写逻辑。5.5 常见问题速查表症状可能原因推荐解法Agent反复调用同一工具工具返回信息不足或Prompt缺少循环中断指令增加max_iterations上限在Prompt中指示观察不变时换策略工具调用报参数错误类型注解缺失或描述不具体补全类型注解在描述中给出参数格式示例选错工具工具描述模糊、工具数量太多重写描述明确适用场景精简工具数量上下文Token爆炸循环轮次多工具返回内容过大工具返回前做摘要/截断定期压缩历史费用过高循环无上限、模型选错模型档位设置max_iterations小任务用小模型大任务才用大模型结果格式不可控模型自由发挥输出格式用OutputParser强制结构化输出6. 把Agent推向生产前必须想清楚的几件事6.1 成本与速度的平衡Agent虽然强大但它比一次普通的API调用贵得多。我的实测经验是一个中等复杂的任务通常需要3到6轮循环每轮都要把累计的上下发送给模型Token消耗可能是直接问答的5到10倍。如果你是做Demo用gpt-4o-mini这类轻量模型就够了便宜、速度快。但如果你遇到需要强推理能力的任务比如金融分析、代码生成轻量模型容易在复杂推理环节掉链子。此时可以考虑混合策略简单轮次用轻量模型关键决策轮次切换到大模型。LangGraph里每个节点可以指定不同的模型实现起来并不复杂。6.2 人工审核的兜底机制Agent自主程度越高越需要人工审核的兜底。尤其是在涉及数据库写入、文件删除、发送邮件等“有副作用”的操作时我强烈建议加入“人工确认”环节。LangGraph中实现起来很直接在工具执行节点前插入一个判断如果工具属于高风险的写操作就暂停执行把待执行内容和参数推给人工确认确认通过后再继续。我在项目里就用过这个模式效果非常好。模型负责规划人能保持在关键节点上审核两者配合比完全放手要靠谱得多。6.3 工具权限的粒度控制别把所有工具都无差别暴露给Agent。比如你的系统里既有只读查询工具又有写库工具模型如果有权限直接调用写库工具误操作的风险很大。建议按任务场景工具分组不同场景的Agent挂载不同的工具列表。另外工具的描述本质上是在告诉模型“你有哪些能力”能力越大责任越大。如果某个工具只允许特定场景使用务必在描述里写清楚限制条件。模型虽然不会像人一样“手滑”但它对描述的理解是字面层面的限制条件写清楚它才会避开。最后分享两个小经验一个是我在反复踩坑之后总结的无论你用AgentExecutor还是LangGraph先把verbose打开跑一遍再关掉。很多你觉得“不可思议”的错误只要看见中间过程立刻就明白了。另一个是关于工具描述的——如果你只能优化一个环节优化它而不是优化模型。模型选不选得对工具、用不用得好参数大部分因素都落在工具定义的质量上。这是我调了很久Agent之后最有体感的一条心得。希望这篇内容能帮你少走些弯路。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询