LangChain 与 LangGraph 在记忆管理上的核心差异,可以概括为:LangChain 是提供记忆工具的“工具箱”,而 LangGraph 则是赋予了 Agent 管理状态能力的“骨架与引擎”

两者并非替代关系,而是在构建复杂 AI 应用中互补协作。下面这个表格可以帮你更清晰地理解它们的区别:

🧐 LangChain vs. LangGraph:核心概念对比表

维度 LangChain LangGraph
核心定位 模块化工具箱(提供各类标准组件) 工作流编排引擎(定义复杂执行逻辑)
核心抽象 链(Chain)、管道(Pipeline) 图(Graph)
执行模型 严格线性,难以实现循环和回溯 支持循环、分支、条件路由和状态回溯
状态/记忆管理方式 通过Memory组件在外部管理,独立于调用逻辑 内置State图对象,作为图的一部分在各节点间共享和流转
状态/记忆实现层级 基础为会话缓冲,支持缓冲窗口、摘要、实体等多种预置类型 核心为图状态的 Checkpoint,并可实现短期、长期、分层混合记忆系统
适用场景 线性问答、RAG、工具链调用 复杂 Agent、多轮对话、人工审批、状态需恢复或审计的场景

为了让理解更透彻,我们通过具体的代码案例,来看看它们在实践中是如何工作的。


🧠 LangChain 案例:使用 ConversationBufferMemory 实现基础记忆

这个例子直接展示了如何让基于 LangChain 构建的对话链拥有短期记忆。

# LangChain Memory 示例
import os
from dotenv import load_dotenv
from langchain_openai import ChatOpenAI
from langchain.chains import ConversationChain
# 使用最简单的内存缓冲区来保存对话历史
from langchain.memory import ConversationBufferMemory

load_dotenv()

# 1. 初始化模型(以阿里云百炼的 Qwen 为例)
llm = ChatOpenAI(
    model="qwen-plus",
    temperature=0.7,
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    base_url=os.getenv("DASHSCOPE_BASE_URL", "https://dashscope.aliyuncs.com/compatible-mode/v1"),
    model_kwargs={"extra_body": {"enable_thinking": False}}
)

# 2. 创建 Memory 和 Chain
memory = ConversationBufferMemory()
conversation = ConversationChain(
    llm=llm,
    memory=memory,
    verbose=True  # 设为 True 可以看到内部处理流程
)

# 3. 多轮对话测试
print("LangChain Memory 示例:")
response_1 = conversation.predict(input="我叫小明,我喜欢编程。")
print(f"助手: {response_1}\n")

response_2 = conversation.predict(input="你还记得我叫什么名字吗?")
print(f"助手: {response_2}\n")

代码分析

  • ConversationBufferMemory 是一个外部组件,负责记录对话历史。
  • ConversationChain 将 LLM、Prompt、Memory 串联成一个线性链条。每次调用时,它会自动从 Memory 中加载历史,并拼接到 Prompt 中。
  • 局限性:这是一种“被动”的记忆。记忆和“思考”(调用模型)是两个分离的步骤,很难处理记忆需要根据模型输出进行复杂更新的场景。

🤖 LangGraph 案例:基于状态图的智能 Agent

这个案例构建了一个能进行多轮对话,并可以根据用户指令“重置记忆”的 Agent。这是 LangGraph 管理的“动态状态”的一个典型应用。

# LangGraph 状态管理示例
import os
from typing import TypedDict, Literal
from dotenv import load_dotenv
from langchain_openai import ChatOpenAI
from langchain_core.messages import HumanMessage, AIMessage
from langgraph.graph import StateGraph, END

load_dotenv()

# 1. 初始化模型
llm = ChatOpenAI(
    model="qwen-plus",
    temperature=0.7,
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    base_url=os.getenv("DASHSCOPE_BASE_URL", "https://dashscope.aliyuncs.com/compatible-mode/v1"),
    model_kwargs={"extra_body": {"enable_thinking": False}}
)

# 2. 定义状态图的状态结构 (TypedDict)
class AgentState(TypedDict):
    messages: list          # 对话历史
    should_reset: bool      # 重置标志

# 3. 定义图节点 (Graph Nodes)
def agent_node(state: AgentState):
    """Agent 节点:调用模型,处理当前状态"""
    messages = state["messages"]
    response = llm.invoke(messages)
    return {"messages": state["messages"] + [response], "should_reset": False}

def check_reset_node(state: AgentState):
    """分析是否需要重置状态"""
    last_message = state["messages"][-1].content
    # 如果用户说了“重置会话”,则将 should_reset 标志设为 True
    if "重置会话" in last_message:
        print("🔔 检测到重置指令,准备清空记忆...")
        # 清空历史消息,保留最新一条是 AI 的响应
        return {"messages": [], "should_reset": True}
    return {"should_reset": False}

def reset_node(state: AgentState):
    """执行状态重置,并给出提示"""
    return {"messages": [AIMessage(content="好的,我已经重置了我们的对话记忆。")], "should_reset": False}

# 4. 定义条件路由
def should_continue(state: AgentState) -> Literal["continue", "reset", "end"]:
    if state.get("should_reset"):
        return "reset"
    # 若没有重置指令,判断是否是结束
    if state["messages"] and "退出" in state["messages"][-1].content:
        return "end"
    return "continue"

# 5. 构建状态图 (StateGraph)
builder = StateGraph(AgentState)
builder.add_node("agent", agent_node)
builder.add_node("check_reset", check_reset_node)
builder.add_node("reset", reset_node)

builder.set_entry_point("agent")
builder.add_edge("agent", "check_reset")
builder.add_conditional_edges(
    "check_reset",
    should_continue,
    {
        "continue": "agent",
        "reset": "reset",
        "end": END
    }
)
builder.add_edge("reset", "agent")  # 重置后回到 agent 节点继续对话
graph = builder.compile()

# 6. 运行测试
print("LangGraph 状态管理示例:")
initial_state = {"messages": [HumanMessage(content="我叫小明,我喜欢编程。")]}
final_state = graph.invoke(initial_state)
print(f"助手: {final_state['messages'][-1].content}\n")

# 告诉 AI 要重置会话
second_state = graph.invoke({"messages": final_state["messages"] + [HumanMessage(content="重置会话")]})
print(f"助手: {second_state['messages'][-1].content}\n")

# 重置后再次对话
third_state = graph.invoke({"messages": second_state["messages"] + [HumanMessage(content="你还记得我叫什么吗?")]})
print(f"助手: {third_state['messages'][-1].content}")

代码分析

  • AgentState 是图的核心messagesshould_reset 这两个字段共同构成了 Agent 的“记忆”。
  • agent_nodecheck_reset_node 都能读取这个共享状态。check_reset_node 根据模型输出,动态修改 should_reset 标志,触发了 reset_node 重置 messages 的操作。
  • 这里的“记忆”(messages)不再是独立组件,而成为了 Agent “思考”(agent_node)和“行动”(路由到不同节点)的内在燃料

🤝 LangChain 与 LangGraph:协同工作的两种模式

在实际开发中,你不需要二选一,因为 LangGraph 本身就是 LangChain 生态的一部分。它们通常以以下方式协同:

  • LangGraph 是“骨架”,LangChain 是“血肉”LangGraph 定义整个 Agent 的工作流(骨架),而每个图节点内部的具体任务,如“调用 LLM”、“加载文档”等,则由 LangChain 提供的工具和模块来完成。
  • 分层的记忆体系:你可以使用 LangChainConversationSummaryMemory 对长对话生成摘要,解决 LLM 上下文窗口限制;然后,将这个摘要作为“压缩后的历史”,存入 LangGraph 的状态State中,供后续节点使用。

✨ 实践建议与面试准备

  • 今日实践

    1. 修改 LangChain 案例中的 Memory 类型为 ConversationBufferWindowMemoryConversationSummaryMemory,感受不同记忆策略的行为差异。
    2. LangGraph 案例中,为 AgentState 添加一个 user_preference 字段,并在对话中根据用户输入更新这个偏好,让 Agent 表现得更加个性化。
    3. 尝试将 LangChainConversationSummaryMemory 集成到 LangGraphagent_node 中,实现一个分层记忆的 Agent。
  • 面试准备

    • 问:LangChain 和 LangGraph 能替代对方吗?
      • :不能。两者是互补而非替代关系。LangChain 提供构建块,LangGraph 负责将这些块编排成复杂流程。LangGraphLangChain 生态向高复杂度场景的自然演进。
    • 问:什么时候该用 LangGraph 而不是 LangChain?
      • :当你的 Agent 需要 支持循环和回溯,或需要 长对话记忆与中断后恢复,或需要 人工介入审批,又或是涉及多 Agent 协作时。
    • 问:LangGraph 如何实现持久记忆?
      • :通过它的 Checkpointer 接口。它能在每一步执行后将整个图的状态State保存下来。当用户再次发起请求时(如重启后的对话),我们可以加载之前的 checkpoint,让 Agent 无缝“回忆”起之前的所有信息。

如果对某个细节想要更深入的了解,随时可以告诉我~

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐