1. LangChain与LangGraph的本质差异
LangChain和LangGraph都是当前AI应用开发领域的热门框架,但它们的定位和适用场景有着根本性区别。LangChain更像是一个"工具箱",而LangGraph则是一个"装配流水线"。
LangChain的核心价值在于提供大量预构建的模块化组件(如文档加载器、文本分割器、向量存储接口等),开发者可以像搭积木一样快速组装出各种AI应用。它特别适合需要快速实现RAG(检索增强生成)或简单Agent的场景。比如你想构建一个本地知识库问答系统,LangChain提供了从文档处理到检索再到生成的完整链条组件。
而LangGraph的定位是"低级别编排框架",专注于解决长期运行、有状态Agent的构建难题。想象你需要开发一个能持续运行数周、记住上下文并能从故障中恢复的智能客服Agent——这正是LangGraph的设计目标。它提供了状态管理、持久化执行、人工干预接口等底层机制,让开发者能构建真正工业级的Agent系统。
关键区别:LangChain解决"用什么组件"的问题,LangGraph解决"如何可靠运行"的问题。
2. 技术架构对比:模块化 vs 状态机
2.1 LangChain的管道式架构
LangChain采用典型的管道(Pipeline)架构,数据流经一系列处理节点。例如一个典型的RAG流程:
文档加载 → 文本分割 → 向量化 → 存储 → 检索 → 生成回答每个环节都可以替换不同实现,这种设计带来极大灵活性。但问题在于:
- 状态管理薄弱:每次调用都是独立的,难以维持长期对话上下文
- 容错能力有限:管道中间环节出错需要完全重启
- 缺乏执行控制:难以实现"先问用户澄清问题再检索"这类复杂逻辑
2.2 LangGraph的图状态机架构
LangGraph的核心抽象是"状态图"(State Graph),将Agent行为建模为:
节点(Node):执行特定操作(如调用LLM、查询数据库) 边(Edge):定义状态转移条件(如"如果用户要求修改则跳转到编辑节点")这种架构天然支持:
- 持久化状态:每次执行自动保存检查点(Checkpoint),崩溃后可从断点恢复
- 复杂逻辑:支持条件分支、循环、并行等控制流
- 人工干预:运行时可以暂停并注入人工输入
典型代码结构对比:
# LangChain典型用法(线性流程) chain = load_chain() response = chain.invoke("问题") # LangGraph典型用法(状态机) builder = StateGraph() builder.add_node("generate", llm_node) builder.add_node("validate", validation_node) builder.add_edge("generate", "validate") graph = builder.compile() response = graph.invoke({"input": "问题"})3. 应用场景选择指南
3.1 何时选择LangChain
以下场景更适合使用LangChain:
- 需要快速实现标准RAG流程
- 主要处理无状态的一次性请求
- 需要利用丰富的现有组件(如100+文档加载器)
- 项目周期短,不需要长期运行的Agent
典型案例:
- 本地知识库问答系统
- 一次性文档摘要工具
- 简单的聊天机器人
3.2 何时选择LangGraph
以下场景必须使用LangGraph:
- Agent需要记住多轮对话历史
- 业务流程包含复杂决策分支
- 要求故障后自动恢复
- 需要人工审核中间结果
- 执行时间可能长达数小时/天
典型案例:
- 保险理赔处理Agent(需要多次收集材料)
- 智能电商导购(持续跟踪用户偏好)
- 自动化客服工单系统
4. 实际开发中的关键差异
4.1 开发体验对比
LangChain开发更"即插即用":
from langchain_core.prompts import ChatPromptTemplate from langchain_openai import ChatOpenAI prompt = ChatPromptTemplate.from_template("回答:{input}") chain = prompt | ChatOpenAI()LangGraph开发更"精细控制":
from langgraph.graph import StateGraph def llm_node(state): # 需要手动处理状态 return {"response": llm.invoke(state["input"])} builder = StateGraph() builder.add_node("llm", llm_node) builder.set_entry_point("llm") graph = builder.compile()4.2 调试与运维差异
LangChain的调试主要靠:
- LangSmith跟踪单个链的执行
- 打印中间步骤结果
LangGraph的调试工具更强大:
- 可视化执行流程图
- 检查任意时刻的状态快照
- 回放特定节点的执行历史
- 注入测试用例重放错误
4.3 性能考量
LangChain优势:
- 轻量级启动
- 适合短时任务
- 组件优化程度高
LangGraph优势:
- 长期运行成本低(检查点机制)
- 更好的资源复用(保持连接)
- 支持分布式执行
5. 进阶使用模式
5.1 混合使用方案
实际上两者可以配合使用:
# 用LangChain构建组件 search_chain = create_retrieval_chain() # 用LangGraph编排流程 def search_node(state): results = search_chain.invoke(state["query"]) return {"results": results} builder = StateGraph() builder.add_node("search", search_node)5.2 LangGraph特有功能
- 人工干预接口:
def human_review(state): display(state["draft"]) return {"approved": input("是否批准?")} builder.add_node("review", human_review)- 持久化检查点:
from langgraph.checkpoint import FileSystemCheckpointer graph = builder.compile( checkpointer=FileSystemCheckpointer("./checkpoints") )- 超时与重试:
from langgraph.prebuilt import ToolNode tool_node = ToolNode( tools=[search_tool], timeout=30, retry_policy=ExponentialBackoff() )6. 从LangChain迁移到LangGraph
对于已有LangChain项目的升级路径:
- 识别状态管理需求:
- 是否需要记住超过3轮对话?
- 业务流程是否超过5个步骤?
- 重构为节点函数:
# 原LangChain代码 chain = prompt | llm # 重构为LangGraph节点 def llm_node(state): messages = state["history"] + [HumanMessage(state["input"])] return {"response": llm.invoke(messages)}- 设计状态结构:
class AgentState(TypedDict): input: str history: list draft: Optional[str] approved: bool- 逐步迁移:
- 先迁移核心链路
- 保留原有链作为子组件
- 最后实现高级功能(如人工干预)
我在实际项目中发现,复杂的客服系统迁移到LangGraph后,异常恢复时间从平均47分钟降到了2分钟以内,主要得益于其完善的检查点机制。但也要注意,过度设计简单场景反而会增加维护成本——曾经有个团队用LangGraph实现单轮问答,最终不得不简化回LangChain。