
上周在社群里看到一位同学贴出的代码他写了一整串LCEL代码用RunnableLambda把好几个函数硬生生串起来试图做一个多步推理的流程最后跑来问我为什么我这段代码跑一遍就结束了我想让它循环到答案满意为止。这个问题特别典型。它恰好戳中了langchain和langgraph的本质差距langchain的设计目标是把 LLM 调用编排成一条链而langgraph的目标是把 LLM 调用放进一张可循环、有状态、能持久化的图里。如果你准备走 agent 应用开发学习路线不把这两者的区别搞明白后面学什么都容易绕弯路。这篇内容我尽量用实操视角去拆不搬官方文档。适合刚接触大模型应用的初学者也适合已经搭过几个 demo、但被循环流程、记忆管理卡住的人。我会先讲清两个框架各自的定位再讲决定性的技术差异最后给你一份我自己梳理的学习路线。1. 两个框架的本质定位一条链和一张图很多新人第一次接触langchain的时候会看到一个很舒服的写法from langchain_core.prompts import ChatPromptTemplate from langchain_core.output_parsers import StrOutputParser prompt ChatPromptTemplate.from_template(请把这句话翻译成英语{text}) chain prompt | llm | StrOutputParser()这个写法本身没什么问题它就是langchain的核心抽象链Chain。你用|符号把 prompt、model、parser 串起来数据沿着这条链路单方向流动输入进去输出出来完事。1.1 LangChain 的初心简化 LLM 调用的组装langchain解决的核心问题是编排。它想把提示词模板、模型调用、结果解析、外部工具调用这些零散的组件变成可以像乐高积木一样拼装的东西。这也就是为什么它的核心叫 LCELLangChain Expression Language用一套统一的接口把一切包装成 Runnable。在这个阶段它适用的场景非常明确把一段 prompt 发给模型拿到结构化输出在调用模型之前先查一下数据库或调用某个 API把多个模型调用按固定顺序串起来比如先写大纲再写正文简单 RAG检索出来拼上下文直接回答。这类需求的特点是流程固定、没有来回、不需要在多次会话之间保留复杂状态。就好比你走进一间快餐店下单、取餐、走人一条直线走完这就是langchain擅长的地方。1.2 LangGraph 的诞生背景链解决不了回到起点但实际业务里很多问题不是一条直线能走完的。我被问得最多的一种场景是我需要一个智能客服它能先判断用户诉求再查订单库如果退款条件不足还要追问补充材料补充完之后重新评估最后给出结论。这种流程里有判断、有循环、有走到某一步发现不对要回退的情况。你用chain a | b | c | d这种模式根本表达不了如果条件不满足跳回去重新走一遍。langgraph就是为这个而生的。它是 LangChain 官方团队在链式抽象之外推出的图编排框架核心模型叫StateGraph。你别把它理解为LangChain 的全新版本它更像是 LangChain 生态里负责流程控制的那块拼图。在langgraph里你的基本单位是节点Node和边Edge。节点负责干活边负责定义流程怎么走。干活的时候你携带一个全局状态State每个节点都可以读状态、改状态改完交给下一个节点。最关键的是图允许你定义条件边让流程自己决定下一步去哪甚至可以形成环。from typing import TypedDict, Optional from langgraph.graph import StateGraph, START, END class State(TypedDict): draft: str review_count: int approved: bool def draft_node(state: State) - dict: return {draft: 这是初稿内容, review_count: state.get(review_count, 0) 1} def review_node(state: State) - dict: if state[review_count] 3: return {approved: True} return {approved: False} def should_continue(state: State) - str: if state[approved]: return end return review graph StateGraph(State) graph.add_node(draft, draft_node) graph.add_node(review, review_node) graph.add_edge(START, draft) graph.add_edge(draft, review) graph.add_conditional_edges(review, should_continue, {review: review, end: END}) app graph.compile()这段代码里draft和review两个节点形成环review节点返回的状态决定流程是再来一轮还是直接结束。这是langchain的链式写法做不到的也是两者最本质的差别。1.3 版本号带来的认知混乱很多人在学习时会被版本号搞得晕头转向。现在的langchain和langgraph已经分化为两个独立的 PyPI 包版本迭代速度很快API 也在持续调整。比如早期的langchain.agents还在用AgentExecutor那一套现在官方主推的方式是用create_react_agent直接构建基于图的 agent。网上大量教程还在教旧的调用方式你一搜langchain教程搜出来的代码可能连langchain的版本都和你本地装的不一致。我建议你记住一个判断方法凡是看到教程里在讲chain、讲pipeline、大量使用RunnableSequence的属于 LangChain 系凡是看到state、node、edge、graph、checkpointer这些词的属于 LangGraph 系。新手没必要把每个历史版本都吃透抓住概念本质比背 API 重要得多。2. 决定性的技术差异状态、循环与可控性如果只用一句话概括我会说langchain默认是无状态的线性管道langgraph是有状态的图执行引擎。这个有状态三个字是整个差异的核心。2.1 显式状态从参数传递到全局状态用langchain写链的时候数据怎么流动从一个 Runnable 的输出直接流到下一个 Runnable 的输入。如果你想在中间某个环节保留一点额外信息要么改造 prompt 模板要么写一个自定义的RunnableLambda去手动传参。流程一复杂你会发现参数的传递越来越乱。langgraph里的State是一个你可以自定义的类通常用TypedDict定义。整个图执行过程中这个 State 对象会被持续传递。每个节点函数接收当前 State返回一个字典作为增量更新这些更新会合并进全局状态。打个比方langchain的链像流水线每个工人只负责接住上一站传来的一个零件langgraph的图像一个项目作战室墙上挂着一张项目状态表任何工种都可以看表、改表改完留给下一环。这个差异直接决定了你写多轮 agent 时的体验。比如让 agent 记录用户已经提供了地址还缺收货时间在langchain里你大概率得把这些信息塞进一个自定义的 memory 对象里还得小心处理链的输入输出。在langgraph里你直接在 State 里加两个字段就行哪个节点需要哪个节点读清清楚楚。2.2 可循环的控制流图的威力LLM 应用和普通程序最不一样的地方是什么是不确定。一次调用模型你无法保证它一定给对结果。所以真实的业务逻辑里经常需要不满意就再来一遍的循环。langchain不是不能写循环你可以用 Python 的for循环在外面包一层每轮调用同一个 chain。但问题是这个循环的状态你得自己维护一旦某一步出错想恢复现场、重新从某个中间节点开始管理成本就很高。langgraph把循环变成了图结构的一部分。它可以做到条件边根据当前 State 的内容决定下一步走向哪个节点循环边允许从 A 节点走回 A 节点形成自愈流程中断与恢复配合 checkpointer可以随时暂停图的执行下次从暂停点接着跑。我用过的一个真实案例是写稿 agent。第一版我用langchain写写稿节点 - 评审节点 - 再写稿节点我用for循环包了三轮勉强能跑。但后来需求变成评审不过就改最多改五轮用户中途还能插话改要求这套逻辑就崩了。改用langgraph之后我只需要设计一个review条件边让流程根据评审结果自己决定是回到写稿节点还是走到结束节点代码结构反而更简单了。2.3 并发分支与图编译langgraph还支持并行分支。比如说你让 agent 同时搜索三个不同来源的资料各自成为一个分支最后在汇总节点合并结果。这在langchain里要靠asyncio.gather手写并发在langgraph里你可以用add_parallel_edge之类的 API 把多个节点挂到同一个前驱节点下框架层面管理并发。这里补充一个概念langgraph执行前需要先compile()这会让框架把整个图的拓扑结构预先检查一遍确定哪些节点可以并行哪些边有冲突。用一句话概括相比起langchain的解释执行风格langgraph更像一个编译执行的流程引擎。对比维度langchainlanggraph核心抽象链Chain/ LCEL图StateGraph数据流单向线性有向图可循环状态管理依赖外部 Memory内置 State Checkpointer分支/并行需要手动编排图结构天然支持循环控制需要外部循环条件边原生支持适合场景固定流程、RAG、轻量工具多轮 agent、复杂流程、生产级应用学习成本低中高2.4 持久化记忆LangGraph 的检查点机制langgraph另一个杀手级特性是 checkpointer。它可以把每一次节点执行后的 State 快照保存到外部存储里比如 SQLite、Postgres 或者 Redis。这意味着图在执行到一半的时候宕机了你可以恢复到最后一次检查点重新接管执行流程。这个能力在做企业级 agent 的时候特别关键。试想一下用户跟你的 agent 对话了四十多轮突然网络断了。如果 agent 没有持久化状态所有上下文都要靠前端重发有了 checkpointer你只需要存一个thread_id下次用户回来就能无缝继续对话像什么都没发生一样。新手容易混淆的一点是这里的记忆和你在langchain里用的ConversationBufferMemory不是一回事。checkpointer 是执行层的状态断点不是单纯的对话历史记录。它保存的是整个图的 State 快照包括流程走到哪一步、各节点中间产出是什么、当前变量值是多少。理解了这个区别你才真正理解为什么生产级 agent 开发会优先选langgraph。3. 实际选型什么时候用 LangChain什么时候用 LangGraph我经常收到一个灵魂拷问现在大家都推 LangGraph我还有必要学 LangChain 吗答案是学但重心要分清。它俩是配合关系不是竞争关系。3.1 优先选 LangChain 的场景如果你的目标是把一次模型调用做得很顺滑比如做一个翻译工具输入中文直接输出英文做一个 RAG 问答机器人查库、拼接、回答做一个摘要提取服务喂长文出短摘要写一个调用外部 API 的简单工具 agent流程固定不需要多轮自我反思。那langchain依然是最高效的选择。你甚至可以直接用prompt | model | parser三行代码搞定没必要为了用图而用图。小工具杀鸡用牛刀反而是给自己找麻烦。我自己的习惯是凡是能确定流程只有一条路径的优先用 LCEL 写。它轻量、直观、调试起来极其方便出问题打一行日志就能定位。3.2 优先选 LangGraph 的场景换几种情况你就应该直接上langgraph流程中存在判断后再走的节点比如内容审核通过/不通过需要多次循环调用模型自己反思、修改、再验证一个 agent 需要调用多类工具并且工具调用结果会改变后续步骤用户可能在多轮对话中随时打断、修改目标流程需要动态响应你希望具备断点续跑能力图执行到一半能保存现场。最常见的例子是create_react_agent。官方把 ReAct 模式的推理-行动-观察循环封装成了一个函数你只需要提供模型和工具列表剩下的循环控制交给图来跑。这种 agent 一旦落地你会发现让模型下次调用更好这件事本质上就是在一个循环里不断积累观察结果再回到推理节点重新决策。这正是langgraph的长项。3.3 混合使用把 LangChain 组件塞进 LangGraph 的节点里这里要重点澄清一个误解用langgraph不是要你抛弃langchain。实际开发中langgraph的每个节点内部完全可以调用langchain的模型、prompt、parser、retriever。图负责流程链负责单步工作。以我最近写的客服 agent 为例结构大概是入口节点接收用户消息存入 State意图识别节点内部用ChatPromptTemplatellmStrOutputParser这条小链去判断用户意图返回分类结果分支节点根据分类结果走向订单查询子图或人工介入节点订单查询节点调用工具去查订单 API把结果写入 State人工介入节点触发interrupt等人工回复后再继续。你看到了吗第 2 步那个小链完全就是langchain的普通写法。langgraph负责的是外面这层大骨架langchain负责的是骨架里每一块肌肉。只学langgraph不学langchain你会发现自己连节点里最基本的 prompt 封装都写得别扭只学langchain不学langgraph你会发现自己永远被困在线性思维里做不出真正有智能体感的应用。4. 一份务实的 LangChain 到 LangGraph 学习路线扯了这么多我知道你真正想要的是路径。下面这条路线是我自己带了不少人跑过的周期大概六到八周前提是你每天能保证一两个小时的实战时间。不强求一口气看完但每一步我都建议配上代码练习。4.1 第一周LLM 应用的基本功也别急着啃 LangChain很多人一上来就安装库开始抄代码结果连结构化输出tool calling是什么都没搞清。我的建议是第一周先不做框架直接裸调 API重点搞懂四件事prompt 基础尤其是 system message、temperature 这些基础参数的作用结构化输出让模型返回 JSON而不是纯文本tool calling让模型自己决定要不要调用某个函数传入函数定义拿到调用参数流式输出处理 token 流理解stream和invoke的差别。为什么先做这一步因为langchain和langgraph只是工具底子还是你对模型能力的理解。如果你连 tool calling 都不清楚学langgraph的 ReAct 循环会非常痛苦。顺便说一句langchain入门教程确实多但很多教程只是把 API 文档抄了一遍。我建议你选官方文档里的 LangChain 0.x 新教程来看不要看那种整天教你链模板写诗的旧教程。那些东西学完除了能发朋友圈对你的 agent 开发没有实际帮助。4.2 第二三周用 LangChain 把小工具做顺手这时候可以开始装langchain了。目标不是什么高级功能就是熟练使用这几个组件之间的搭配ChatPromptTemplate管理人设提示和用户提示各类模型封装ChatOpenAI这类记住一个抽象就是model 也是 Runnable输出解析器StrOutputParser、JsonOutputParser、PydanticOutputParser检索器接一个向量数据库做一个最简单的 RAGLCEL 的管道写法prompt | model | parser理解.invoke()、.stream()、.batch()。这个阶段不要深挖记忆和工具更不要花大量时间去背旧版的AgentExecutor用法。把你写出来的代码当成一颗颗小小的积木学会怎么捏积木就行了。等进了langgraph这些积木会被直接用到图节点里。我通常会给学员一个作业用 LCEL 写一个读后感生成器输入一本书输出包括核心观点、摘抄点评、推荐人群三部分的 JSON。代码量不大但能逼你把 prompt 设计、结构化解析、流式输出全走一遍。4.3 第四五周切入 LangGraph学核心三件套进入langgraph那天把之前的链式思维暂时放一放。单纯从学习角度建议死磕三个概念其他都先不管State你的数据模型。试着定义一个TypedDict花点时间想清楚你的节点需要共享哪些字段。节点函数入参是当前 State返回值是增量更新。养成一个习惯节点函数里只干一件事。边和条件边add_edge管固定路线add_conditional_edges管动态分流。搞清楚START和END的作用。练手项目我推荐一个最简单但又最有代表性的循环写手。设计三个节点draft写稿、critic点评、revise修改然后让critic返回一个分数分数低于 80 分就回到revise高于 80 分才走到END。这个项目练完你基本就掌握了图的感觉。之后再上手一个更接近实战的项目给一个create_react_agent配上 2 到 3 个自定义工具比如获取当前时间查天气计算器。观察模型是怎么自主决定调用工具、拿到结果继续推理的。4.4 第六周左右状态持久化与人工介入走到这一步你已经能写会自动循环的图了。但这离生产还差关键一环就是可恢复性。学习 checkpointer我推荐先从 SQLite 起步因为零配置。你只需要在compile(checkpointer...)时传一个持久化实例然后在invoke时传一个config{configurable: {thread_id: 唯一ID}}就能实现按会话隔离状态。试试跑一张图跑到一半停掉再用同一个thread_id继续执行。你能直观看到断点续跑是怎么生效的。接下来学interrupt和Command。这俩是人工介入的基础。举个生活化例子一个机票预订 agent在扣款之前必须停下来等用户确认。用interrupt可以暂停图把人机交互插入流程中间用户说确认之后图再从断点继续。没有这个能力你的 agent 永远只敢在沙盒里玩不敢接真实业务。这部分内容对新手是有门槛的但这是 agent 应用开发学习路线上绕不开的一环。以后你去面大模型应用岗位十有八九会被问到你的 agent 做到一半想让人干预怎么办。4.5 冲刺阶段从 Demo 到生产剩下时间建议你做一个完整的项目把前面零散知识点连起来。我推荐的项目是多工具协同的行业顾问 bot用户提出一个问题agent 决定是否调用搜索工具、文档检索工具、计算工具回答之前自动检查是否漏了关键信息如果模型自己觉得信息不够就继续追问或搜第二轮全程把每次交互保存到数据库支持用户中断后再次进入继续对话。这个项目做完你会碰到很多细节问题怎么避免模型陷入死循环、怎么设定最大步数、怎么把长历史塞进 limited context、怎么给图加超时。这些问题都不是看文档能解决的必须踩坑。到时候你可以体会到我前面说的那句话langgraph是编译执行的流程引擎它的调试方式甚至有点像老派的后端服务日志、状态快照、断点一个都不能少。5. 我踩过的坑和一些反直觉经验最后这部分把你可能踩的坑提前说几个。字字都是实操换来的。5.1 别再用链的思想写图我见过最多的问题有人把langgraph的节点函数写成了一个超级函数里面又串了十几步LCEL然后问我为什么图跑起来很慢。原因很简单他把一个节点当成了一条链的容器一个节点里干了几十件事图的分步状态优势完全没发挥出来。正确的做法是一个节点只做一件完整的事。如果这个节点内部确实需要多个步骤尽量在节点内部又用图或子图而不是塞一个巨大的调用。这样你才能利用langgraph的检查点、断点、并行能力。5.2 记忆不是你想的那种记忆很多人学到记忆就以为是把所有的对话都塞到 prompt 里。这确实是老版本的思路但它有两个硬伤一是 token 太长二是无关信息会干扰模型判断。在langgraph的世界里记忆要拆开看对话历史用消息列表管理该清空就清空该摘要就摘要流程状态用 State 管理长期记忆用向量库或数据库管理。三种东西混在一起谈越学越乱。学习的时候用数据库表的思维方式去看状态管理而不是用聊天记录的思维。5.3 看教程要带版权意识关于学习资源我说句可能不中听的现在搜出来的很多langchain中文教程、学习路线文章发布时间差的可能有大半年。大模型圈半年意味着一个时代。你照着老教程去安装老版本 API完全可能跑出一堆废弃警告。我自己的习惯是任何新框架都以官方文档和官方 GitHub 仓库的 examples 为基准第三方博客只看思路不抄代码。遇到 API 调用不对第一时间去翻官方 API Reference。尤其注意当前langchain和langgraph的版本号很多接口名变了比如langchain老版本和 0.3 版本相差很大。5.4 从 LangChain 升级到 LangGraph不是从旧升到新最后说一个心态问题。langgraph不是langchain的高配版不是学会langgraph就不碰langchain了。纯 LLM 直接调用、简单 RAG 固定流程老老实实写LCEL就够了复杂 agent 编排、多轮循环、人工介入、生产级状态恢复再上langgraph。两者是一套生态里的不同工具没有绝对的高下。我个人在实际操作中的体会是现在学习的大方向确实已经全面倒向langgraph几乎所有新出的 agent 框架都以图编排为核心你不学好状态和循环连别人的代码都看不懂。但真正写好、写熟练langgraph的人没有一个会轻视langchain的基础组件积累。所以我的建议很直接第一周练好裸模型基本功第二三周快速过一遍 LangChain 组件然后重心果断切到 LangGraph。别在链式思维里待太久也别把 LangChain 跳过去。两条腿走路才能走稳这条 agent 开发学习路线。如果你正在个人项目里纠结这两个框架记住那句最朴素的选择标准流程是直线还是绕圈直线用链绕圈用图。等你想清楚这个问题你的学习路线也自然清晰了。