恒美微站
首页
关于我们
建站服务
主题模板
案例展示
资讯中心
联系我们
LangChain三大核心:Chain、Agent与LangGraph全解析
首页
资讯中心
/
LangChain三大核心:Chain、Agent与LangGraph全解析
LangChain三大核心:Chain、Agent与LangGraph全解析
发布时间:2026/9/8 20:57:42
说实话LangChain 这几年在国内外的热度一直没降过但“LangChain 到底是干嘛的”这个问题我每隔几天就能在技术群里看到一次。更常见的情况是很多人跟着官方教程跑通了第一个 Demo却发现自己只会“调库”换个业务场景就不知道怎么下手了。原因其实很简单——LangChain 生态迭代太快概念又叠着概念今天学 Chain明天出来 Agent后天又冒出 LangGraph不把底层逻辑理顺学再多 API 也是散装知识。这篇文章我想换个角度不讲碎片化教程而是把 LangChain 生态里最核心的三样东西——Chain链、Agent代理、LangGraph图化编排——摊开了讲清楚。它们不是三个孤立工具而是同一条演进线上的三个阶段从固定的流程编排到模型自主决策再到可控可恢复的复杂状态机。把这三大核心吃透你不仅能看懂 LangChain 在解决什么问题还能在实际项目里做出合理的技术选型。不管你是刚入门 LangChain 的初学者还是已经写了不少 Agent 但总感觉不可控的开发者这篇文章都值得花十分钟读完。1. 核心一Chain链——把模型调用变成“流水线”1.1 链的本质给无状态的模型套上“工艺流程”先用大白话讲清楚链到底在解决什么问题。大模型本身是什么是一个“输入一句话、输出一句话”的函数。它没有记忆不会主动查数据库也不会在回答完之后自己决定“下一步该干嘛”。你会发现单次调用模型来做真实业务根本不靠谱——你需要先给它一套固定的“动作顺序”先构造提示词再把用户问题填进去调用模型拿到结果然后把结果解析成结构化数据最后可能还要存进数据库。这个过程是固定的、重复的、可预测的。Chain 干的事情就是把这一连串固定动作串联成一条流水线。你定义好流水线之后每次丢一个用户问题进去它自动走完所有工序给你产出结果。这就像开一家快餐店厨师不会每天临场发挥而是按标准作业流程做汉——备菜、煎肉、组装、包装每道工序固定谁来都能上手。1.2 LCELLangChain 的声明式“管道语法”在 LangChain 生态里现在定义链的主流方式叫 LCELLangChain Expression Language也就是 LangChain 表达式语言。它的核心就一个竖线操作符|从左到右把组件串起来数据流经每个组件时被加工一次最终输出结果。先看一个最常见的链长什么样from langchain_core.prompts import ChatPromptTemplate from langchain_core.output_parsers import StrOutputParser from langchain_openai import ChatOpenAI prompt ChatPromptTemplate.from_template( 你是一名资深电商客服。请用简洁友好的语气回答用户的问题{question} ) model ChatOpenAI(modelgpt-4o-mini, temperature0.2) parser StrOutputParser() # 用 | 把所有组件串成一条链 customer_service_chain prompt | model | parser result customer_service_chain.invoke({question: 我的订单延迟发货了怎么申请赔偿}) print(result)别看这段代码简单它其实是理解 LangChain 全生态的钥匙。prompt | model | parser这三个组件都实现了同一个接口——Runnable 协议。Runnable 协议统一了对象的调用方式不管你是模板、模型、解析器还是后面要讲的 Agent 和 LangGraph都能用.invoke()单次调用、.batch()批量调用、.stream()流式输出来操作。这种统一抽象带来的好处在工程上非常明显你可以随时往流水线里插入新环节比如加一个内容审核组件代码只需要改成prompt | model | review_filter | parser其他调用方的代码一行不用动。这就是为什么我建议所有初学者先彻底搞懂 LCEL再碰别的概念——它是整个生态的语法基础。1.3 链的变体分支与并行一条流水线固定走到底肯定不满足所有业务。LangChain 也提供了两个重要变体。第一个是RunnableBranch相当于流水线里的“分拣员”。它可以根据输入内容动态选择走哪条子链。比如客服系统里用户问物流走物流链用户问退款走退款链用户骂人走安抚链用RunnableBranch可以做得非常优雅。第二个是RunnableParallel适合“一个输入要同时喂给多个处理者”的场景例如同时做情感分析、关键词提取、摘要生成三个任务互不依赖可以并行跑最后合并结果。但这里我必须泼一盆冷水链模式虽然在很多场景下够用但它有一个硬伤——它是单向无环的。流程一旦定死模型只能在“选哪条分支”上做选择不能让流程自己回头、循环、中断恢复。比如你要做一个能反复调用工具直到问题解决的智能体用纯 Chain 来表达会非常别扭。这就引出了下一种模式Agent。2. 核心二Agent代理——把“下一步做什么”的决定权交给模型2.1 思维转变从“预设剧本”到“模型自主决策”Chain 的核心哲学是“流程优先”开发者把每个步骤写死模型只是流水线上的一个执行工人。Agent 的核心哲学则反过来——目标优先开发者只告诉模型“你要达成什么目标、你有哪些工具可以用”至于先调哪个工具、调完工具之后下一步干嘛、要不要再调一次这些决策全部由模型自己根据当前情况动态做出。我把这两种模式的区别类比成两种打车方式。Chain 是你提前跟司机说好“先走 A 路、再拐 B 路、最后到 C 点”路线完全固定Agent 是你只告诉司机“去 C 点”怎么走、中途要不要加油、遇到堵车怎么绕司机自己判断。这种动态决策能力让 Agent 在处理开放性问题时优势巨大。比如你丢给它一个问题“帮我查一下北京到上海明天的高铁选最早的一班然后把票价和余票信息整理成表格发到我邮箱。”这个问题没法用一个固定链来写因为模型需要先调用查询工具拿到结果后可能还要再查余票详情最后再调用发送邮件的工具每一步都得看前一步结果来决定。2.2 ReAct 范式Agent 的“思考-行动-观察”循环说到 Agent就绕不开 ReAct 这个范式。ReAct 的全称是 Reason Act核心思想是让模型在一个循环里交替做三件事Thought思考分析当前状态决定下一步要做什么。Action行动选择一个工具并传入参数执行一次具体的函数调用。Observation观察查看工具返回的结果再进入下一轮思考。这个循环会一直持续直到模型认为目标已经达成给出 Final Answer最终答案。ReAct 的设计灵感其实来自人类解决问题的方式——我们在动手之前会先想做完之后会看结果再调整策略而不是闷头一路走到黑。在实际代码层面现代 LangChain Agent 的搭建流程已经简化了很多。核心是三步定义工具 → 创建提示词 → 绑定模型并执行循环。下面这个例子我给你一个最精简但能跑通全流程的结构from langchain_core.tools import tool from langchain_openai import ChatOpenAI from langchain.agents import create_tool_calling_agent, AgentExecutor # 第一步定义工具。tool 装饰器会把普通函数变成一个模型可调用的工具 tool def get_weather(city: str) - str: 查询指定城市的当前天气。参数 city 为城市中文名例如北京 # 这里省略真实 API 调用返回一个模拟结果 return f{city}晴25℃东南风3级 # 第二步创建支持工具调用的模型并绑定工具列表 model ChatOpenAI(modelgpt-4o-mini, temperature0) tools [get_weather] # 第三步组装 Agent 与执行器运行循环直到模型给出最终答案 agent create_tool_calling_agent(model, tools) executor AgentExecutor(agentagent, toolstools, max_iterations5, verboseTrue) result executor.invoke({input: 北京今天适合穿短袖吗}) print(result[output])AgentExecutor是 LangChain 官方封装好的“循环执行器”它会替你把 Thought-Action-Observation 这个循环跑起来直到模型输出最终答案或触发max_iterations上限。你不需要手写 while 循环但对循环的底层逻辑必须心里有数否则出了问题根本无从排查。2.3 工具设计Agent 效果的分水岭外面讲 Agent 的教程很多但大部分都停留在“怎么跑通一个 Demo”很少讲真正决定 Agent 好用不好用的东西——工具设计。工具对于 Agent 来说就像手对于人工具越多、设计得越合理Agent 能做的事越多但工具设计得差模型要么不调用要么乱调用。我从实战里总结出三条原则第一函数的 docstring 就是给模型看的说明书必须写清楚“这个工具是干嘛的、每个参数代表什么、应该传什么格式”。很多初学者把 docstring 随便写几个字甚至不写结果模型压根不知道这个工具在什么时候该用。记住模型是“读文档”来用工具的你的注释质量直接决定工具利用率。第二工具的粒度要适中。太粗的工具比如一个“处理所有订单问题”的工具模型很难理解容易乱调太细的工具比如拆成五个“查询订单状态”的小工具又会增加模型的选择难度。我个人的经验是按“业务动作”划分工具而不是按“函数实现”划分。比如“查询订单物流信息”是一个工具“申请订单退款”是另一个工具而不是把“查物流”再拆成“查商家发货没”“查快递到哪了”“查签收没”。第三工具内部要做好容错。模型生成的参数经常不合法比如日期格式错了、城市名带了个句号。工具层应该尽量接收字符串、内部做清洗而不是直接抛异常。一个动不动就崩溃的工具会让 Agent 的整体体验非常差。2.4 Agent 的真正难点不可控与不经济我必须坦诚说一句Agent 模式虽然强大但在真实生产环境里它并没有想象中那么“智能”。它最大的问题有两个。第一个是不可预测性。模型每一步的决策都有一定随机性同样的输入今天跑给力明天可能就在工具之间来回横跳甚至陷入死循环。所以我每次在代码里都强制设置max_iterations一两轮解决不了的问题宁可直接放弃也不让它无限烧钱。第二个是经济性。Agent 的每一次工具调用都会把“对话历史 工具结果”重新喂给模型Token 消耗随轮数线性上涨。一个看起来简单的任务跑下来可能花了平时十倍以上的 Token 费。我在自己的项目里做过统计同样的“查天气并给建议”任务用 Chain 模式只需要几百 Token用 Agent 模式经常要两三千。那是不是说 Agent 就不该用当然不是。它是处理“无法预先穷举流程”的任务所必需的。关键在于你要知道在什么场景下该用 Agent什么场景下用 Chain 更划算。而 LangGraph 的诞生很大程度上就是为了驯服 Agent 的“野性”。3. 核心三LangGraph——把链与代理统一成“状态图”3.1 为什么需要 LangGraph从“直线”和“死循环”到“有环图”先说说 LangGraph 是 LangChain 生态里最晚出现、也最被低估的组件。它到底是干嘛的如果你用 Chain 做固定流程它是标准的“有向无环图”一条路走到底没有回头路如果你用 Agent 做自主决策它其实是一个“隐式 while 循环”——模型反复思考-行动-观察直到结束。但真实业务往往比这两种模型都复杂流程里既有固定步骤又有需要根据中间结果动态回跳的环节还要支持中途暂停、人工审批、断点续跑。这种情况下Chain 表达不了循环Agent 又没法精细控制循环LangGraph 就是为此而生的。LangGraph 的核心思想是把你整个应用建模成一张图。图上有节点Node和边Edge。节点是你要执行的具体动作比如“调用大模型”“执行工具”“发送通知”边是节点之间的流转关系而且边可以是条件边——由模型或代码根据当前状态决定下一步去哪个节点。最关键的突破是这张图允许有环。也就是说节点 A 执行完可以根据条件决定是去节点 B还是跳回节点 A 再执行一次。这就在保留 Agent 动态决策能力的同时把流程的骨架固定了下来避免了 Agent 那种漫天乱跑的失控感。3.2 LangGraph 的四大核心概念用 LangGraph 写过代码之后你会发现它的概念其实非常清晰就四个状态、节点、边、记忆。**State状态**是整张图的“全局数据总线”。所有节点共享一个状态对象每个节点执行完后可以把新数据写回状态后续节点从状态里读取。状态通常定义成一个 TypedDict 或 Pydantic 模型里面放的消息列表、结果字段等。举个例子from typing import TypedDict, Annotated, List class AgentState(TypedDict): messages: List[dict] # 对话消息列表 next_action: str # 当前决策结果 tool_result: str # 工具返回结果**Node节点**是图里的每个处理单元就是一个普通 Python 函数。函数接收当前 State返回一个字典字典里的键值会更新到 State 上。Edge边定义节点之间的连接重点是条件边——你可以写一个路由函数根据 State 里的内容决定下一步进入哪个节点。下面这段代码是我在做客服机器人时写的一个极简 LangGraph 流程它比纯 Agent 多了一个“先判断要不要调工具”的路由节点流程完全可控from langgraph.graph import StateGraph, START, END from typing import TypedDict, List class State(TypedDict): messages: List[dict] need_tool: bool final_answer: str # 节点1判断是否调用工具 def decide_node(state: State): if 查询 in state[messages][-1][content] or 天气 in state[messages][-1][content]: return {need_tool: True} return {need_tool: False} # 节点2执行工具调用此处简化 def call_tool_node(state: State): result get_weather.invoke({city: 北京}) return {final_answer: result} # 节点3直接生成答案 def generate_node(state: State): return {final_answer: 好的我明白了。} # 建图注册节点、设置入口、用条件边连接 graph StateGraph(State) graph.add_node(decide, decide_node) graph.add_node(call_tool, call_tool_node) graph.add_node(generate, generate_node) graph.add_edge(START, decide) graph.add_conditional_edges( decide, lambda state: call_tool if state[need_tool] else generate, {call_tool: call_tool, generate: generate} ) graph.add_edge(call_tool, END) graph.add_edge(generate, END) app graph.compile()这段代码的价值在于它把“Agent 的内部决策过程”摊开给你看了。你可以清清楚楚地知道什么时候模型需要调工具、什么时候直接回答、工具调用后往哪走。这正是 LangGraph 最核心的价值——让 AI 应用的流程变得可读、可控、可调试。3.3 LangGraph 与 LangChain 原生 Chain 的关键区别很多人搞不清楚 LangGraph 和 LangChain 的关系我这里直接给出一个结论LangGraph 不是要取代 LangChain而是构建在 LangChain 之上的一层状态编排引擎。LangChain 提供零件模型、工具、解析器LangGraph 提供流水线和控制逻辑。两者可以混用并不冲突。为了让你更直观地理解我做了一张对比表对比维度原生 ChainLCELLangGraph流程结构有向无环、线性或简单分支有向有环、灵活跳转循环能力不支持循环天然支持节点回跳状态管理链内传递单次调用结束后状态消失全局 State 持久化可跨轮次保存断点续跑不支持通过 Checkpointer 支持中断与恢复人机协同难以实现原生支持人工审批节点interrupt调试体验黑盒出错难排查可视化地看每一步状态变化适用场景流程固定、追求速度和低成本的场景复杂流程、需要精细控制和状态恢复的场景我还想强调一个 LangGraph 容易被忽略的优势持久化与记忆。在原生 Chain 或 Agent 里对话历史通常要自己塞到 Prompt 里管理一不小心就超出上下文窗口。LangGraph 内置了 Checkpointer 机制可以每执行一步就把状态持久化到存储里内存、数据库都行。这意味着你可以随时暂停一个任务下次用同一个线程 ID 恢复它甚至可以让不同的用户在同一张图上各跑各的状态互不干扰。做客服工单系统、审批流、长任务处理这种能力简直是刚需。3.4 人机协同LangGraph 让 AI 应用第一次“刹得住车”最后单独说说 LangGraph 的interrupt机制因为它代表了一种全新的设计思路。纯 Agent 一旦跑起来人类很难中途干预——它可能在你还没来得及阻止时就把邮件发出去了。LangGraph 允许你在图里设置一个“人工确认节点”当流程走到这里时自动暂停等待人工确认或修改后再继续。举个例子自动退款助手跑完了“核对订单信息”“计算退款金额”两步接下来要执行“提交退款申请”你可以在这个节点前加一个 interrupt让审批人确认金额无误后再放行。这种“人机协同”在实际企业落地中几乎是必需品——技术再先进关键操作也不可能完全交给模型拍板。4. 工程落地三大核心的选型思路、高频面试问题和避坑实录4.1 怎么选Chain、Agent、LangGraph 的取舍建议我经常被问到“这三个我到底学哪个、项目里用哪个”。我的回答是别把它们当三个独立选项而要当成一个决策谱系。首选 Chain 的场景业务流程完全固定输入输出的格式清晰比如简单的问答机器人、内容总结、文本分类、信息抽取。这些任务你用 LangGraph 也能做但没必要——链更轻、更快、Token 消耗更低出问题也更好排查。记住一个原则能用简单方案解决的不要引入复杂框架。选 Agent 的场景任务开放、无法预判用户会提什么需求且需要模型自主选择工具比如一个可以查天气、查股票、算数学、搜新闻的通用助理。但要注意用 Agent 的时候一定做好兜底限制迭代次数、监控 Token 消耗、所有工具调用都记录日志。选 LangGraph 的场景业务流程有循环、有分支、需要长上下文记忆或者需要人工审批和断点续跑。比如工单系统、客服系统、自动化运维流程、内容审核流程。LangGraph 的初始学习成本略高但它能把复杂的 AI 应用做得像传统软件工程一样可控这笔投入非常值。4.2 LangChain 面试高频考点这些概念必须能说透这里顺便整理几个我面试候选人时必问的问题也是你学习时可以自我检验的清单“说说 LCEL 中 Runnable 协议是什么”这个问题考察的是你有没有理解 LangChain 的统一抽象。回答要点所有组件都实现invoke/batch/stream等统一接口因此可以任意组合、替换、复用整个生态都是围绕这个协议扩展的。“Chain 和 Agent 的区别是什么”核心一句话Chain 是开发者预设流程Agent 是模型自主决策。可以进一步说 ReAct 的思考-行动-观察循环以及 Agent 更灵活但同时更不可控。“LangGraph 和 LangChain 原生 Chain 的区别”核心回答是“有向无环 vs 有向有环”展开讲就是 LangGraph 支持循环、全局状态、断点恢复、人工介入适合复杂状态机应用。“怎么让 Agent 调用某个工具”这个实操题看的是工具注册和描述质量。回答时不仅要说用tool装饰器绑定工具还要强调 docstring 对模型的重要性——工具描述写得不清模型大概率不调用。4.3 实战踩坑我自己掉过的五个坑可能你看了上面几个示例觉得挺简单但真正把 LangChain 应用到生产环境坑远比教程里多。我挑几个自己真实踩过的分享给你。第一个坑是Agent 陷入无限循环。有一次我跑测试Agent 在“搜索-总结-再搜索”之间来回跳了二十多轮最后把几百块 Token 烧光了才被max_iterations拦下来。从那以后我所有 Agent 都强制设置轮数上限并加了一层“循环次数过多自动降级给固定答案”的兜底逻辑。第二个坑是工具 docstring 写得敷衍模型就是不调用。我最初写一个get_user_info工具docstring 只写了“获取用户信息”结果模型老是在编数据。后来我改成“根据用户ID查询用户的会员等级和积分余额用户ID为字符串类型例如U12345”模型几乎每次都能正确传参。这让我深刻意识到在 Agent 世界里文档质量就是模型能力的一部分。第三个坑是图的状态结构一旦变更老数据读取就报错。LangGraph 的状态如果后续改了字段名或类型之前用 Checkpointer 保存的历史数据很可能无法被新代码加载。解决方法是状态定义时尽量语义化命名、批准添加字段而不是修改字段并且留好迁移脚本。第四个坑是ChatOpenAI 默认不支持 tools 参数时静默失败。不同模型对工具调用的支持程度差异巨大有的模型你传了 tools 它直接忽略导致 Agent 只会回答不会行动。选模型之前一定要确认它原生支持 Function Calling / Tool Calling并先用最简单的单工具用例测通。第五个坑是过于追求“全自动 Agent”。我在一个项目里想做一个完全自动化的竞品分析 Agent结果发现模型经常查错数据、抓错页面。后来我改变思路用 LangGraph 把流程拆成“采集-清洗-分析-生成报告”四段前两段用固定代码只在后两段引入 Agent 决策。稳定性和成本都立刻变好了。这个教训我想重点说给你AI 不是万能的把流程切开、在合适的位置用 AI比追求全自动现实得多。如果你现在正开始学 LangChain我建议的路径是先用 LCEL 把“提示词 模型 解析器”这条基础链玩熟再尝试构建一个带工具调用的简单 Agent最后再用 LangGraph 把同一个 Agent 改造成带状态和循环的图。三步走完你就拥有了一套完整的 LangChain 生态认知框架之后再看任何新概念都会发现它们只是这三个核心的不同组合方式。我到现在写新项目依然会先问自己一句这个需求是固定流水线还是自主决策还是需要一张图答案出来了技术选型也就不纠结了。