LangChain vs LangGraph:如何选择合适的 AI 框架!

发布: (2025年12月4日 GMT+8 16:07)
17 min read
原文: Dev.to

Source: Dev.to

LangChain vs LangGraph:如何选择合适的 AI 框架

在过去的几年里,LangChain 已经成为构建 LLM(大语言模型)驱动应用的事实标准。然而,随着需求的演进,LangGraph 作为一个更专注于图结构和工作流的框架出现,提供了不同的抽象层次和功能。本文将帮助你了解两者的核心区别、适用场景以及如何在项目中做出明智的选择。


目录

  1. 核心概念对比
  2. 主要特性对比表
  3. 何时使用 LangChain
  4. 何时使用 LangGraph
  5. 迁移与互操作性
  6. 结论

核心概念对比

概念LangChainLangGraph
抽象层次链(Chain) 为中心,强调一步步的 顺序执行图(Graph) 为中心,支持 分支、合并和循环 的工作流。
主要目标快速搭建 单一任务(如问答、文本生成)的流水线。构建 复杂、多步骤 的业务流程,尤其是需要 状态管理 的场景。
状态管理通过 Memory 对象在链之间共享上下文,适用于短期记忆。内置 节点状态全局状态,天然支持长期记忆和跨节点数据流。
调度方式线性调用,通常在 Python 中直接调用 chain.run()使用 调度器(Scheduler),可以并行或异步执行节点。
可视化主要依赖 代码结构,缺少官方可视化工具。提供 图形化编辑器可视化 DAG(有时通过 langgraph.visualize())。

主要特性对比表

特性LangChainLangGraph
链式调用✅ 完整的 ChainSequentialChainRouterChain 等实现。❌ 通过 节点(Node)组合实现相同功能,但不是链式 API。
工具集成丰富的 工具(Tool) 接口:搜索、数据库、API 调用等。同样支持工具,但更倾向于 节点 级别的封装。
记忆(Memory)多种内置记忆实现:ConversationBufferMemoryConversationSummaryMemory 等。通过 状态对象 实现记忆,支持 持久化(如向量数据库)。
并行执行需要自行使用 asyncio 或多线程实现。原生支持 并行节点异步调度
错误处理通过 try/except 包装链或使用 ConditionalRouter节点级别的 错误回退重试策略
可扩展性通过自定义 ChainToolPromptTemplate 扩展。通过自定义 节点调度器 扩展。
社区与生态大型社区,丰富的插件与示例。较新,但增长迅速,官方文档提供 图编辑器 示例。
部署适合 单体服务函数即服务(FaaS)更适合 微服务容器编排(如 Kubernetes)以及 工作流引擎

何时使用 LangChain

  • 单一步骤或线性任务:如问答、摘要、文本生成等。
  • 快速原型:想在几行代码内完成一个 LLM 应用。
  • 已有丰富工具链:需要集成搜索、数据库或自定义 API,且不需要复杂的状态管理。
  • 资源受限:项目规模小,部署在单个容器或函数即服务平台上。

示例代码(保持原样,不翻译):

from langchain import OpenAI, LLMChain, PromptTemplate

prompt = PromptTemplate(
    input_variables=["question"],
    template="Answer the following question succinctly: {question}"
)

llm = OpenAI(model="gpt-4")
chain = LLMChain(llm=llm, prompt=prompt)

response = chain.run({"question": "What is the capital of France?"})
print(response)

何时使用 LangGraph

  • 复杂业务流程:需要 分支、循环、并行 的工作流(如多轮对话、审批流、数据管道)。
  • 长期记忆:跨会话、跨用户的状态需要持久化。
  • 可视化需求:希望通过图形化界面查看和编辑工作流。
  • 团队协作:多个开发者负责不同节点,图结构更易于分工。
  • 高并发或分布式部署:需要调度器管理节点的并行执行。

示例代码(保持原样,不翻译):

from langgraph import Graph, Node, Scheduler

def fetch_data(state):
    # ... fetch from DB ...
    return {"data": result}

def process_data(state, data):
    # ... process ...
    return {"processed": processed_result}

graph = Graph()
graph.add_node("fetch", Node(fetch_data))
graph.add_node("process", Node(process_data))
graph.add_edge("fetch", "process")

scheduler = Scheduler(graph)
output = scheduler.run(initial_state={})
print(output)

迁移与互操作性

  1. 从 LangChain 迁移到 LangGraph

    • Chain 中的每一步抽象为 节点(Node)。
    • 使用 状态对象 替代 Memory,将上下文信息放入全局状态。
    • 利用 Graph.add_edge 定义执行顺序或条件分支。
  2. 在同一项目中混用

    • 可以在 LangGraph 的节点内部调用 LangChain 的 Chain,实现 复用
    • 例如,在一个复杂工作流的“文本生成”节点里直接使用 LLMChain.run()
  3. 工具与插件

    • 大多数 LangChain 的工具(如 SerpAPIWrapperSQLDatabaseToolkit)可以直接在 LangGraph 节点中使用,只需包装为函数即可。

结论

  • LangChain 仍是 快速构建单一步骤 LLM 应用 的首选,尤其适合原型和小型服务。
  • LangGraph 则在 复杂、可视化、可扩展的工作流 场景中表现更佳,尤其当你需要 状态管理、并行执行团队协作 时。

选择建议

场景推荐框架
简单问答 / 文本生成LangChain
多轮对话 + 长期记忆LangGraph
数据管道 + 并行处理LangGraph
快速 PoC / 单函数LangChain
需要图形化编辑器LangGraph

随着两者生态的不断成熟,未来可能出现更深层次的融合。保持关注官方更新,结合项目实际需求灵活选型,才能最大化发挥 LLM 的价值。


为什么此比较重要 – LangChain 与 LangGraph

我构建实用的 LLM 驱动软件,已经看到两种模式逐渐显现:直接的线性流水线以及有状态的、代理式工作流。 “LangChain vs LangGraph” 这个问题并非学术讨论;它决定了架构、维护方式以及系统随时间的推理方式。

当我说 “LangChain vs LangGraph” 时,我指的是比较两种不同的设计哲学:

  • LangChain – 为线性序列优化:接受输入,按顺序执行一次或多次 LLM 调用,存储或返回结果。
  • LangGraph – 为图结构优化:节点、边、循环,以及跨多个步骤的持久状态。

LangChain

核心概念

  • Prompt templates – 可复用的模板,接受变量并生成一致的 LLM 输入。
  • LLM‑agnostic connectors – 在 OpenAI、Anthropic、Mistral、Hugging Face 等模型之间轻松切换。
  • Chains – 核心抽象:将多个步骤组合,使每个输出作为下一个步骤的输入。
  • Memory – 短期或长期对话上下文,适用于有状态聊天,但相较于完整状态机仍有限。
  • Agents and tools – 让模型以结构化方式调用 API、计算器或外部服务。

何时使用 LangChain

  • 原型设计提示、构建简单的 RAG 系统,或创建从向量库读取并返回单一响应的问答流水线。
  • 文本转换流水线(摘要、翻译、信息抽取)。
  • 单轮用户交互,如客服响应。
  • 基本的 RAG 系统,执行向量库检索并返回单一合成答案。

LangChain 能让开发者快速提升生产力。它提供即插即用的组件——提示模板、检索器和链组合器——让你无需自行构建编排原语即可快速交付。

Source:

LangGraph

核心概念

  • Nodes – 离散任务:调用 LLM、从数据库获取数据、执行网页搜索或调用摘要器。
  • Edges – 定义条件转移、并行分支或回环路径。
  • State – 在节点之间演进的动态上下文:消息、情景记忆和检查点。
  • Decision nodes – 原生支持条件逻辑和路由到专门的代理。

LangGraph 将应用视为状态机。节点可以循环、重新访问早期步骤,并执行多轮工具调用。这使得反思、迭代检索或逐步细化答案等代理行为成为可能。

何时使用 LangGraph

  • 需要多步骤决策且可以循环直至满足退出条件的场景。
  • 根据上下文将查询路由到专门的代理。
  • 在多个 LLM 调用和用户交互之间保持持久状态。
  • 复杂的工具使用,包括多轮网页搜索、摘要以及外部来源的聚合。

示例: 一个电子邮件草稿代理,能够检索用户偏好、查询日历、起草邮件、请求澄清,并迭代细化草稿,这自然映射到 LangGraph。

实用比较检查清单

方面LangChainLangGraph
工作流风格线性且顺序的循环的、基于图的并带有循环
内存有限的对话记忆丰富且持久的状态,跨节点和会话保持
分支简单分支,一次性工具调用内置条件边、循环、检查点
理想使用场景简单聊天机器人、检索增强生成(RAG)、类似 ETL 的 LLM 流程多代理系统、自治代理行为、长期运行的工作流
人机交互可实现但非原生一流的检查点和人机交互模式

在权衡 “LangChain 与 LangGraph” 时,除了考虑当前需求,还要考虑预期的未来复杂度。如果应用可能会发展为多代理编排,或需要持久状态和重试机制,直接使用 LangGraph 可以避免后期重构。

示例:使用 LangChain 的 RAG(线性)

  1. 安装所需的包并配置 API 密钥。
  2. 创建接受变量(如 objectivetopic)的提示模板。
  3. 通过 Hugging Face、OpenAI 或其他提供商初始化 LLM 或本地模型连接器。
  4. 将文档存储在向量数据库中并创建检索器。
  5. 构建检索增强生成链,以检索上下文并合成答案。

这种模式保持线性:检索相关文档 → 生成答案。它适用于许多 FAQ 机器人、文档助理以及单次流水线。代码简洁,易于迭代。

# Example LangChain RAG pipeline
from langchain import PromptTemplate, LLMChain
from langchain.vectorstores import FAISS
from langchain.llms import OpenAI

# 1. Prompt template
prompt = PromptTemplate(
    input_variables=["question", "context"],
    template="Answer the question based on the context:\n\nContext: {context}\n\nQuestion: {question}"
)

# 2. LLM
llm = OpenAI(model_name="gpt-4")

# 3. Chain
chain = LLMChain(llm=llm, prompt=prompt)

# 4. Retrieval
vector_store = FAISS.load_local("my_index")
retriever = vector_store.as_retriever()

def answer_question(question: str):
    docs = retriever.get_relevant_documents(question)
    context = "\n".join([doc.page_content for doc in docs])
    return chain.run({"question": question, "context": context})

示例:使用 LangGraph 的 RAG(基于图)

  1. 将静态内容从 URL 或文档加载到向量库中。
  2. 创建图节点:retrieveweb_searchdecisiongenerate
  3. 定义状态:跟踪检索结果是否已回答用户问题,存储中间摘要,并记录工具输出。
  4. 使用条件边连接节点:
    • 如果本地检索失败 → 路由到网页搜索。
    • 如果网页搜索产生噪声结果 → 提出澄清性问题。
    • 根据需要循环返回。
  5. 运行图,直至满足停止条件,然后返回最终合成结果。

该模式支持多轮工具使用和代理式推理。在测试中,询问 LangGraph 代理“本月最新的 AI 发展”时,如果本地知识已过时,会触发网页搜索节点,获取、摘要并在呈现答案前检查充分性。

# Example LangGraph workflow (pseudo‑code)
from langgraph import Graph, Node, Edge, State

# Nodes
def retrieve(state: State):
    docs = vector_store.as_retriever().get_relevant_documents(state["question"])
    state["retrieved"] = docs
    return state

def web_search(state: State):
    results = search_api(state["question"])
    state["web_results"] = results
    return state

def decide(state: State):
    if not state["retrieved"]:
        return "web_search"
    if not is_sufficient(state["retrieved"]):
        return "web_search"
    return "generate"

def generate(state: State):
    context = combine(state.get("retrieved", []), state.get("web_results", []))
    answer = llm.generate(prompt=prompt, context=context)
    state["answer"] = answer
    return state

# Graph definition
graph = Graph()
graph.add_node("retrieve", retrieve)
graph.add_node("web_search", web_search)
graph.add_node("decision", decide)
graph.add_node("generate", generate)

graph.add_edge("retrieve", "decision")
graph.add_edge("web_search", "decision")
graph.add_edge("decision", "generate", condition=lambda s: s == "generate")
graph.add_edge("decision", "web_search", condition=lambda s: s == "web_search")
graph.set_entry_point("retrieve")

Decision Heuristics

  • Pattern: Start simple – 如果问题是单次传递的,使用 LangChain 快速验证提示。
  • Pattern: Evolve to graph – 如果你的单次传递流水线累积了条件和有状态的检查点,请逐步重构为 LangGraph 图。
  • Anti‑pattern: Premature complexity – 当不需要循环或持久状态时,避免实现完整的图。过度设计会降低清晰度并增加维护成本。
  • Anti‑pattern: One‑off tool calls – 如果需要重复或多阶段的工具编排,线性链会变得脆弱。LangGraph 的原生边和状态更适合。

可复用模板

模板描述
User query → Retriever → LLM prompt → Result → Store conversation (optional)适用于文档问答、帮助中心和每个请求基本独立的聊天机器人。
User query → Retrieve → Decision node (sufficient?) → If no, Web search node → Summarize → Reflect/loop → Final generate → Persist episodic memory适用于动态信息请求、研究助理以及需要迭代推理的多代理工作流。

Migrating from LangChain to LangGraph

  1. 确定 LangChain 中出现决策逻辑的分支点。
  2. 将提示模板和检索组件提取为可重用的节点。
  3. 定义一个状态模式(schema),用于捕获中间结果、工具输出和记忆。
  4. 用通过条件边连接节点的图结构取代线性链执行。
  5. 根据需要添加检查点或人工介入(human‑in‑the‑loop)节点。

结论

  • 选择 LangChain 当您需要快速开发、工作流是线性的且状态管理最小化时。
  • 选择 LangGraph 当您的应用需要循环、丰富的持久状态、条件路由或多代理编排时。

评估您 AI 系统的当前和未来复杂性将帮助您选择合适的框架,避免以后昂贵的重构。

Back to Blog

相关文章

阅读更多 »

🧠LLMs 作为传感器

为什么 OrKa 0.9.10 将 GenAI 包装在确定性系统内部 我直截了当地说。我喜欢生成式 AI。我每天都在使用它。我围绕它构建。但我不信任它……