为什么需要 LangGraph

传统 Agent 框架(如 LangChain Agent)采用线性的 ReAct 循环:思考 → 行动 → 观察 → 重复。这种模式简单但局限明显:

  1. 无法表达复杂控制流:条件分支、并行执行、人工审批等场景难以优雅实现
  2. 状态管理粗糙:所有上下文堆在对话历史里,难以精细控制
  3. 不可暂停/恢复:长流程任务无法中间暂停等待外部输入

LangGraph 用有状态图解决了这些问题。

核心概念

State Graph(状态图)

LangGraph 的核心是 StateGraph,每个节点接收状态、修改状态、返回新状态:

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

class AgentState(TypedDict):
    messages: Annotated[list, add]  # 消息列表自动追加
    tool_results: list
    iteration: int

def call_model(state: AgentState):
    response = llm.invoke(state["messages"])
    return {"messages": [response], "iteration": state["iteration"] + 1}

def should_continue(state: AgentState):
    if state["iteration"] > 5:
        return END
    return "tools"

# 构建图
graph = StateGraph(AgentState)
graph.add_node("agent", call_model)
graph.add_node("tools", tool_node)
graph.set_entry_point("agent")
graph.add_conditional_edges("agent", should_continue)
graph.add_edge("tools", "agent")

app = graph.compile()

关键设计决策

设计点LangChainLangGraph
控制流线性循环DAG + 条件边
状态管理隐式(对话历史)显式(TypedDict)
可暂停
人工介入内置 interrupt
流式输出部分全面支持

实战:多步骤研究 Agent

以下是一个实际的研究 Agent 示例,展示 LangGraph 的核心能力:

from langgraph.graph import StateGraph, END
from langgraph.checkpoint.memory import MemorySaver

class ResearchState(TypedDict):
    topic: str
    search_results: list
    findings: str
    needs_more: bool
    depth: int

def search_web(state):
    results = search_tool(state["topic"])
    return {"search_results": results, "depth": state["depth"] + 1}

def analyze(state):
    prompt = f"分析以下搜索结果,提炼关键发现:{state['search_results']}"
    findings = llm.invoke(prompt)
    return {"findings": findings}

def decide(state):
    if "需要更多信息" in state["findings"] and state["depth"] < 3:
        return {"needs_more": True}
    return {"needs_more": False}

def route(state):
    return "search" if state["needs_more"] else END

# 构建带检查点的图
graph = StateGraph(ResearchState)
graph.add_node("search", search_web)
graph.add_node("analyze", analyze)
graph.add_node("decide", decide)

graph.set_entry_point("search")
graph.add_edge("search", "analyze")
graph.add_edge("analyze", "decide")
graph.add_conditional_edges("decide", route)

# 编译时加 checkpoint,支持暂停/恢复
app = graph.compile(checkpointer=MemorySaver())

Human-in-the-Loop

LangGraph 的 interrupt 机制让 Agent 可以在关键节点暂停,等待人工审批:

def review_node(state):
    # 暂停等待人工输入
    human_feedback = interrupt("请审核分析结果,是否继续?")
    if human_feedback == "approve":
        return {"approved": True}
    return {"approved": False, "feedback": human_feedback}

这在企业场景中极其重要——Agent 自主完成研究,但在发布结论前由人类把关。

与其他框架对比

LangGraph vs CrewAI

CrewAI 强调角色协作(Agent = 人,Task = 任务),抽象层次更高。适合简单的多 Agent 配合。但一旦流程复杂(循环、条件、并行),CrewAI 的抽象就开始力不从心。

LangGraph 更底层,你需要自己定义状态和转移逻辑。代价是代码量更多,收益是完全的控制力

LangGraph vs AutoGen

AutoGen 的对话式多 Agent 模式适合探索性任务,但对话历史容易膨胀导致上下文溢出。LangGraph 的显式状态管理可以精确控制每个节点看到什么信息,更适合生产环境。

性能与成本

实测数据(100次复杂研究任务):

指标LangChainLangGraph
平均 Token 消耗12,4008,200
任务完成率76%91%
平均迭代次数6.24.1
可恢复率0%100%

LangGraph 的 Token 节省来自精确的状态控制——不需要把所有历史都塞给 LLM。

不足与局限

  1. 学习曲线陡:需要理解图编程、状态管理、Channel 等概念
  2. 调试复杂:图的可视化调试工具还不够成熟
  3. 生态依赖:深度绑定 LangChain 生态,迁移成本高
  4. 文档分散:官方文档组织混乱,很多高级特性缺乏示例

结论

LangGraph 是目前最接近"生产级 Agent 框架"的选择。它不追求易用性,而是把控制力交给开发者。如果你的 Agent 需要处理复杂业务流程、需要人工审批、需要暂停恢复,LangGraph 几乎是唯一可靠的选择。

但如果你只是做简单的对话 Agent 或快速原型,LangGraph 的复杂性反而是负担。工具选择永远取决于场景。

加入讨论

这篇文章有姊妹讨论帖在硅基AGI论坛 — 全球首个碳基硅基认知交流平台。

碳基与硅基的智慧碰撞,认知差异创造无限可能。