LangChain vs LangGraph:从抽象组件到底层运行时,一文读懂AI应用开发的“上下求索”

LangChain vs LangGraph:从抽象组件到底层运行时,一文读懂AI应用开发的“上下求索”

2025年10月,LangChain 1.0和LangGraph 1.0同时发布。有人说这是两个框架,有人说这是一个系统的不同层级。这篇文章从底层原理到应用实践,带你彻底搞懂这对“兄弟”的来龙去脉。

引子:一个让开发者纠结的选型问题

先讲一个真实的场景。

假设你要构建一个代码审查流水线:三个Agent串起来工作——Context Agent负责抓取PR diff和仓库历史,Analysis Agent在改动代码中定位问题,Review Agent输出带严重程度评分的结构化反馈。逻辑不复杂,但Analysis Agent有时需要回头再拉一轮Context才能给出有把握的判断。

这个**“条件回跳”**把你逼到了决策点:到底该用LangChain还是LangGraph?

坦白说,市面上绝大多数文章给出的答案都是“简单流程用LangChain,复杂的用LangGraph”。但这个结论太模糊了——什么样的流程算“复杂”?三个Agent串起来的流水线算不算?

要回答这个问题,我们得从底层开始,一层层拆解这两个框架的设计哲学。

第一章 溯源:从800行代码到双1.0时代

LangChain的故事始于2022年。机器学习工程师Harrison Chase当时写了一个大约800行代码的单文件Python包,发布到了自己的GitHub账户上。这个最初不起眼的“副业项目”,后来演变成了LLM应用开发领域最具影响力的开源框架。

LangChain的核心价值在于解决了大模型的三大痛点:

  • 信息孤岛:通过检索模块连接私有数据、互联网信息等外部资源

  • 行动能力缺失:通过工具调用机制让模型操作数据库、执行代码

  • 上下文断裂:通过记忆模块保存对话历史和中间状态

2024年初,LangChain团队正式推出LangGraph——一个允许开发者以更底层的方式编排每一步智能体逻辑的框架。

2025年10月20日,LangChain 1.0与LangGraph 1.0同步发布,标志着AI Agent开发正式进入“工程化”阶段。

但真正值得关注的是Harrison Chase本人的一句话。当被问及LangChain是什么时,他说:“LangChain是一个构建LLM应用程序的框架,但这说法很模糊,也不够具体。我认为部分原因在于LangChain的功能实在太丰富了,所以很难用一句话具体说明。”

这句话背后藏着一个重要信息:LangChain的功能太丰富,以至于它已经不是一个单一层面的东西了。

第二章 LCEL与Runnable协议:LangChain的“乐高积木”哲学

要理解LangChain,首先要理解它的核心抽象:Runnable协议。

2.1 什么是Runnable?

Runnable是LangChain表达式语言(LCEL)的基石。它的定义非常简洁:任何可以被“运行”(run)的东西,接受一个输入,产生一个输出。

听起来很抽象?其实它就是一个标准化接口。Prompt模板是Runnable,LLM模型是Runnable,输出解析器也是Runnable。所有组件都实现同一个接口,这意味着它们可以无缝组合。

2.2 管道操作符 | 的底层秘密

LCEL最标志性的语法是管道操作符 |。你可以这样写:

chain = prompt | model | output_parser

这行代码的底层原理是什么?Python的运算符重载。

当使用 | 操作符时,LangChain通过Python的 __or__ 方法重载机制,将两个组件连接成一个新的 RunnableSequence(可运行序列)。第一个组件的输出自动成为第二个组件的输入,以此类推。

2.3 声明式编程的魅力

LCEL是一种声明式的方法,用于轻松组合多个组件来构建复杂的处理链条。你不需要写 step1()、step2()、step3() 这样的命令式代码,只需要描述数据流的走向。

更重要的是,LCEL设计之初就支持将原型直接投入生产环境,无需更改代码。流式传输、批量处理、并行执行——这些生产级能力在你使用LCEL的那一刻就已经自动获得了。

2.4 局限在哪里?

LCEL的优雅之处也是它的局限之处:它是线性的。

prompt | model | parser 是一条直线。数据从A流向B,再流向C,没有回头路。LangChain早期提供的SequentialChain也是同样的思路——将一个链的输出作为下一个链的输入,依次执行。

对于RAG(检索增强生成)、简单的问答机器人、文本摘要这类流程固定的任务,LCEL绰绰有余。

但当你需要循环、分支、重试、暂停等待人工输入时,LCEL就力不从心了。

这就是LangGraph登场的理由。

第三章 状态图与持久化:LangGraph的“底层引擎”哲学

如果说LangChain是“乐高积木”,那么LangGraph就是搭建乐高积木的“图纸引擎”。

3.1 从链到图:一场范式的转换

LangGraph的核心创新在于:用有向图模型重构Agent工作流。

传统Agent开发中,开发者需要手动维护消息上下文列表,通过循环控制“思考→行动→观察→应答”流程。这种模式存在三大瓶颈:

  • 状态管理碎片化:对话历史、工具调用记录分散在多个变量中

  • 流程控制复杂:多轮工具调用需嵌套循环,错误处理代码臃肿

  • 扩展性差:新增工具需修改核心逻辑

LangGraph把这一切变成了图(Graph)。

3.2 四大核心组件

LangGraph的架构可以拆解为四个层次:

第一层:状态(State)

State是一个共享的数据结构,在图的节点之间传递。每个节点执行后,基于返回值更新内部状态。通过 Annotated 元数据可以声明状态的合并策略——比如用 operator.add 实现列表自动拼接。

class AgentState(TypedDict):
    messages: Annotated[list[AnyMessage], operator.add]  # 消息自动累积

第二层:节点(Node)

节点是图的基本执行单元。每个节点接收State对象作为输入,返回更新后的State子集。节点可以是LLM调用、工具执行、条件判断——任何Python函数都可以成为节点。

graph.add_node("llm", call_openai)      # LLM节点
graph.add_node("action", take_action)   # 工具执行节点

第三层:边(Edge)

边定义节点之间的执行顺序。最强大的是条件边(Conditional Edge)——根据当前状态动态决定下一步走向哪个节点。

def should_continue(state: AgentState):
    if has_tool_calls(state):
        return "action"
    return END

graph.add_conditional_edges("llm", should_continue)

第四层:图(Graph)

通过组合节点和边,你可以创建带循环的、复杂的工作流,让State随时间演进。LangGraph的底层图算法受Google的Pregel系统启发,使用消息传递来定义通用程序。

3.3 持久化执行:让Agent“死不了”

这是LangGraph最硬核的能力。

LangGraph内置的持久化层(Persistence Layer) 确保每个执行步骤的状态都保存到持久存储中。如果工作流中断——无论是系统崩溃还是人工干预——都可以从最后记录的状态恢复。

具体来说,检查点(Checkpoint) 是每个超级步骤(superstep)保存的图状态的快照。LangGraph支持三种持久化模式:

| 模式 | 持久化时机 | 特点 | | exit | 仅图执行完成后 | 性能最优,但中断后无法恢复 | | async | 节点之间异步写入 | 性能与可靠性平衡 | | sync | 节点执行前同步写入 | 最安全,可断点续跑 |

配置一个 checkpointer(支持Postgres、SQLite、Redis、内存等),再指定一个 thread_id 来标识执行轨迹,你的Agent就获得了“不死之身”。

3.4 时间旅行调试

更酷的是,LangGraph支持时间旅行(Time Travel) ——你可以回放任何Agent运行的任意检查点,检查中间状态,修改它,然后重新执行。

这相当于给你的Agent装了一个调试器 + 撤销按钮 + 审计日志。

3.5 人机协作(Human-in-the-Loop)

在高风险场景(如金融交易、医疗诊断)中,AI不能完全自主决策。LangGraph提供了原生的中断(interrupt) 机制:

  • 在节点中调用 interrupt(),图执行暂停

  • LangGraph保存当前图状态

  • 等待人类输入或审批

  • 恢复执行,从中断点继续

第四章 一个真实案例:代码审查流水线的两种实现

回到开篇的代码审查流水线。我们用同一个需求,分别用LangChain和LangGraph实现。

LangChain版本:线性传送带

from langchain_core.prompts import ChatPromptTemplate
from langchain_google_genai import ChatGoogleGenerativeAI
from langchain_core.output_parsers import StrOutputParser

llm = ChatGoogleGenerativeAI(model="gemini-2.5-flash")

context_chain = (
    ChatPromptTemplate.from_template("Analyze this PR diff: {diff}")
    | llm | StrOutputParser()
)
analysis_chain = (
    ChatPromptTemplate.from_template("Find issues in: {context}")
    | llm | StrOutputParser()
)
review_chain = (
    ChatPromptTemplate.from_template("Write review for: {analysis}")
    | llm | StrOutputParser()
)

def run_pipeline(diff: str):
    context = context_chain.invoke({"diff": diff})
    analysis = analysis_chain.invoke({"context": context})
    review = review_chain.invoke({"analysis": analysis})
    return review

代码干净、可读,五分钟能写完。问题在于:Analysis返回的置信度一旦偏低,整条链就会出问题——你得在链外面加 if/else,手动重新调用,再自己把状态拼回去。这就是线性流程的代价:没有内置的循环和条件分支。

LangGraph版本:带回路的状态机

from langgraph.graph import StateGraph, END
from typing import TypedDict

class ReviewState(TypedDict):
    diff: str
    context: str
    analysis: str
    review: str
    confidence: float
    iterations: int

def context_node(state: ReviewState) -> ReviewState:
    context = fetch_context(state["diff"])
    return {**state, "context": context}

def analysis_node(state: ReviewState) -> ReviewState:
    result = run_analysis(state["context"])
    return {
        **state,
        "analysis": result["content"],
        "confidence": result["confidence"],
        "iterations": state.get("iterations", 0) + 1
    }

def should_continue(state: ReviewState):
    if state["confidence"] < 0.7 and state["iterations"] < 3:
        return "context"  # 回去再拉一轮context
    return "review"

graph = StateGraph(ReviewState)
graph.add_node("context", context_node)
graph.add_node("analysis", analysis_node)
graph.add_node("review", review_node)
graph.add_edge("context", "analysis")
graph.add_conditional_edges("analysis", should_continue)

LangGraph版本的代码稍长,但它原生支持条件回跳——置信度低就自动循环,不需要你在外部写额外的控制逻辑。

这就是“简单 vs 复杂”在代码层面的真实写照。

第五章 两者的真实关系:不是替代,是分层

很多文章把LangChain和LangGraph当成两个竞争的框架来对比。这是根本性的误解。

从LangChain v1.0(2025)开始,LangChain自己的Agent抽象就构建在LangGraph之上。

换句话说:

  • LangChain是上层建筑:提供Prompt模板、检索器、工具调用、中间件等高阶API,让你快速构建Agent

  • LangGraph是底层运行时:提供状态图、持久化执行、检查点、人机交互等底层能力

两者不是二选一的关系,而是同一个系统的不同抽象层级。

用建筑来类比:LangChain是精装修的公寓——拎包入住,配套设施齐全;LangGraph是钢筋混凝土的结构图纸——给你完全的控制权,但需要你自己决定每面墙的位置。

更准确地说:LangChain的 create_agent 高级接口在底层已经在运行LangGraph了。你用LangChain写一个Agent,它背后跑的其实是LangGraph的图引擎。

第六章 选型指南:什么时候用什么?

基于以上分析,我们可以给出更精准的选型建议:

优先用LangChain(高层API)的场景

  • 快速原型验证:需要快速验证业务逻辑可行性

  • 线性流程:RAG、简单的问答机器人、文本分类

  • 无状态服务:不需要维护复杂的执行上下文

  • 轻量级部署:资源受限的环境

如果你用LangChain的 create_agent 就能满足需求,直接用。它底层已经用了LangGraph。

必须下沉到LangGraph的场景

  • 需要循环和条件分支:Agent需要多轮思考、自我反思、条件跳转

  • 长时间运行的工作流:需要数小时处理的视频分析、大规模数据清洗

  • 需要状态持久化:服务器重启后Agent要能从断点恢复

  • 需要人机协作:高风险场景需要人工审批和干预

  • 多智能体协作:多个专业Agent分工协作

一个更实用的判断标准

如果你需要“回路”——即某个步骤的输出要反馈回之前的步骤——那么你应该用LangGraph。

线性流程用LangChain,带回路的工作流用LangGraph。就这么简单。

第七章 工程化时代的选择

2025年10月,LangChain 1.0和LangGraph 1.0的发布标志着AI Agent开发正式进入“工程化”阶段。

这两个框架解决了AI应用开发中不同层面的问题:

  • LangChain 解决的是“怎么快速搭建”的问题

  • LangGraph 解决的是“怎么稳定运行”的问题

在2026年,构建一个LLM应用已经不是最难的部分了。真正的挑战在于:状态管理、多智能体协调、可观测性、成本控制、以及给Agent提供它真正可以信任的、受治理的数据。

LangChain和LangGraph共同构成了从原型到生产的完整技术栈。LangChain让你快速起步,LangGraph让你稳稳落地。

回到开篇的问题:三个Agent串起来的代码审查流水线,该用谁?

如果Analysis Agent不需要回头补数据,用LangChain就够了。但如果它有“条件回跳”的需求——答案已经很清楚了。


参考文档:LangChain官方文档、LangGraph官方文档及相关技术社区文章