Skip to content

6. 什么是 LangGraph?它与 LangChain 有什么区别? ​

难度 P0 必背 · 岗位 应用 · 频率 ★★★ · 预计阅读 14 min

本题阅读地图 ​

  1. 💡 简要回答
  2. 📝 详细解析
  3. 🎯 面试总结

👔面试官:听说过 LangGraph 吗?它是做什么的,跟 LangChain 什么关系?

🙋‍♂️我:LangGraph 是 LangChain 的扩展吧,可以做更复杂的 Agent 工作流。

👔面试官:具体扩展了什么?LangChain 的 Chain 有什么局限?

🙋‍♂️我:Chain 是线性的……只能一步一步执行?LangGraph 可以支持循环?

👔面试官:对。那为什么需要循环?ReAct Agent 不就是循环吗?

🙋‍♂️我:ReAct 是循环,但在 LangChain 里实现比较麻烦?LangGraph 让循环更自然?

👔面试官:接近了。LangGraph 把 Agent 的执行过程建模为「有状态图」,节点是函数,边是流转关系,可以显式表达循环、条件分支、状态共享。还有个关键特性是「Human-in-the-loop」,知道是什么吗?

🙋‍♂️我:人工介入?在关键节点暂停,等人工确认再继续?

👔面试官:对。这在生产环境非常重要,比如执行危险操作前需要人工审批。下面详细说一下。

TL;DR 速记 ​

  • 是什么:LangGraph 是基于 LangChain 的有状态图框架,把 Agent 执行过程建模成节点和边。
  • 解决什么:补上 Chain 不擅长的循环、条件分支、显式状态、人机协同和中断恢复。
  • 怎么答:简单线性流程用 LangChain/LCEL,复杂 Agent 工作流用 LangGraph;核心差异是“线性链”变成“可恢复的状态图”。

图解 ​

💡 简要回答 ​

LangGraph 是基于 LangChain 的有状态图(Stateful Graph)工作流框架,把 Agent 的执行过程建模为节点(Node)和边(Edge)的有向图。

相比 LangChain 的线性 Chain,LangGraph 的核心优势:

  • 支持循环:节点可以跳回前面的节点(ReAct 的推理循环)
  • 条件分支:边可以有条件,根据不同状态走不同路径
  • 显式状态:所有状态保存在 TypedDict 中,节点间共享
  • Human-in-the-loop:支持在任意节点暂停,等待人工介入
  • 状态持久化:可以中断恢复,适合长任务

📝 详细解析 ​

为什么需要 LangGraph ​

LangChain 的 Chain 是线性的:A → B → C,适合简单流程。但复杂 Agent 需要:

规划 → 执行 → 检查 →(未完成)→ 回到规划
                        ↓
                    (完成)→ 结束

这种循环、条件分支在 Chain 里很难优雅实现。

LangGraph 的解决思路:把执行流程建模为有向图。

核心概念:State、Node、Edge ​

python
from langgraph.graph import StateGraph, END
from typing import TypedDict, Annotated
import operator

# 1. 定义状态(所有节点共享的「内存」)
class AgentState(TypedDict):
    messages: Annotated[list, operator.add]  # 消息历史,累加模式
    current_step: str  # 当前步骤标识
    execution_count: int  # 执行次数(防死循环)

# 2. 定义节点(每个节点是一个函数)
def plan_node(state: AgentState):
    """规划节点:决定下一步做什么"""
    plan = llm.invoke(f"基于历史:{state['messages']}\n制定计划")
    return {
        "messages": [("assistant", plan)],
        "current_step": "execute",
        "execution_count": state.get("execution_count", 0) + 1
    }

def execute_node(state: AgentState):
    """执行节点:调用工具"""
    tool_result = tools.execute(state["messages"][-1].content)
    return {
        "messages": [("tool", tool_result)],
        "current_step": "check"
    }

def check_node(state: AgentState):
    """检查节点:判断是否完成"""
    # 这个节点返回的不是状态更新,而是下一步去哪个节点
    if is_task_complete(state["messages"]):
        return "done"  # 去结束节点
    elif state["execution_count"] > 10:
        return "max_iterations"  # 去错误处理
    else:
        return "continue"  # 继续规划

# 3. 构建图
graph = StateGraph(AgentState)
graph.add_node("plan", plan_node)
graph.add_node("execute", execute_node)
graph.add_node("check", check_node)

# 4. 添加边
graph.add_edge("plan", "execute")
graph.add_edge("execute", "check")

# 条件边:根据 check_node 的返回值决定下一步
def route_check(state):
    return state["next_step"]

graph.add_conditional_edges(
    "check",
    route_check,
    {
        "continue": "plan",      # 未完成,循环回规划
        "done": END,            # 完成,结束
        "max_iterations": "error_handler"
    }
)

graph.set_entry_point("plan")
app = graph.compile()

# 5. 运行
result = app.invoke({
    "messages": [("user", "帮我查竞品信息并整理报告")],
    "current_step": "plan"
})

LangChain vs LangGraph 对比 ​

维度LangChain ChainLangGraph
执行模型线性(A→B→C)有向图(支持任意拓扑)
循环支持❌ 不支持✅ 天然支持
条件分支❌ 需要额外逻辑✅ 条件边
状态管理隐式(Memory)显式(TypedDict)
可视化❌ 无✅ Mermaid 图
人工介入❌ 不支持✅ Human-in-the-loop
中断恢复❌ 不支持✅ 检查点持久化
适用场景简单线性流程复杂多步骤 Agent

Human-in-the-loop 人工介入 ​

生产环境很多场景需要人工审批:

python
from langgraph.checkpoint.sqlite import SqliteSaver

# 创建检查点存储
checkpointer = SqliteSaver.from_conn_string("agent_state.db")

# 编译图,在 execute 节点前设置中断点
app = graph.compile(
    checkpointer=checkpointer,
    interrupt_before=["execute"]  # 执行前暂停
)

# 第一次调用,执行到 execute 前暂停
thread_id = "task_001"
result = app.invoke(
    initial_state,
    config={"configurable": {"thread_id": thread_id}}
)
# → 暂停,等待人工确认

# 人工确认后,继续执行
app.invoke(None, config={"configurable": {"thread_id": thread_id}})

适用场景:

  • 执行危险操作前(删除数据、转账)
  • 调用敏感 API 前
  • 生成内容发布前审核
  • 预算超限时的确认

状态持久化:长任务的保障 ​

python
# 任务执行过程中,状态自动保存到检查点
# 即使程序崩溃,也可以从检查点恢复

# 查询当前状态
snapshot = app.get_state(config)
print(snapshot.values)  # 当前所有状态
print(snapshot.next)    # 下一个要执行的节点

# 从任意检查点恢复
app.invoke(None, config)  # 继续执行

常见踩坑与反例 ​

踩坑 1:只说“LangGraph 支持循环” ​

错误描述:「LangGraph 就是能把节点连回去。」

正确做法:循环只是表象。面试要讲到有状态图、条件边、共享状态、检查点、人机协同,这些才是生产价值。

踩坑 2:把 State 当普通全局变量 ​

错误描述:「节点之间用变量传一下就行。」

正确做法:State 是图执行的契约。字段、更新方式、累加策略都要显式定义,否则调试、恢复和并发执行都会混乱。

踩坑 3:迁移时全量重写 Chain ​

错误描述:「上 LangGraph 就要把原来的 LangChain 全拆掉。」

正确做法:简单链路继续保留,复杂分支和循环才迁到 Graph。LCEL 链也可以包装成节点逐步迁移。

踩坑 4:忽略检查点和人工介入 ​

错误描述:「Graph 跑起来就行,暂停恢复以后再说。」

正确做法:长任务、危险操作、审核发布都要提前设计 checkpointer 和 interrupt,否则无法恢复,也无法在关键节点审批。

面试官可能继续追问 ​

  • 追问 1:LangGraph 的 State 应该怎么设计? 答题要点:先定义任务必需字段,如 messages、step、tool_result、status;区分覆盖字段和累加字段;避免把无关大对象都塞进状态。

  • 追问 2:Human-in-the-loop 怎么落地? 答题要点:编译图时设置 interrupt 节点,配合 checkpointer 保存 thread 状态;人工确认后用同一个 thread_id 继续执行。

  • 追问 3:什么时候不该用 LangGraph? 答题要点:线性、短链路、无循环、无状态恢复需求的任务没必要上 Graph,LCEL 或普通 Workflow 更简单。

  • 追问 4:循环失控怎么防? 答题要点:在 State 中记录步数、失败次数和状态终态;路由函数同时判断任务完成、最大步数、超时和转人工条件。

🎯 面试总结 ​

LangGraph 解决的是 LangChain Chain 「只能线性执行」的局限。

面试回答抓住四个核心:

  1. 图模型:节点(函数)+ 边(流转),支持循环和条件分支
  2. 显式状态:TypedDict 共享内存,所有节点可操作
  3. Human-in-the-loop:任意节点可暂停,等待人工确认
  4. 状态持久化:检查点机制,支持中断恢复

选型建议:简单流程用 LangChain,复杂 Agent 用 LangGraph。现在很多项目直接用 LangGraph 构建 Agent,跳过 Chain 那层抽象。


第五分类「五、AI Agent」全部完成,共覆盖题目 158-200(Agent 基础/CoT/ReAct/工具调用/MCP/多 Agent/记忆/LangChain/LangGraph)

第五分类「五、AI Agent」全部完成,共覆盖题目 158-200(Agent 基础/CoT/ReAct/工具调用/MCP/多 Agent/记忆/LangChain/LangGraph)


章节首页 · ← Q5 · Q7 →

最后更新2026-05-01
难度P0
频率medium
阅读14 min
主题framework
觉得有帮助?把这个链接转给正在求职的朋友 · 用 Ctrl + K 全站搜索其它题