重构 Agent 思维链:LangGraph 核心架构的深度解构与实战

一、从 Chain 到 Graph:一次思维范式的跃迁

早期的 LLM 应用开发,习惯用 Chain 的线性思维:输入、处理、输出。但真实业务场景远比这复杂------Agent 需要调用工具、根据工具结果决定下一步、甚至在出错时自我修正。线性 Chain 在这些场景下捉襟见肘。

LangGraph 的核心价值,在于将 Agent 工作流建模为一个"有状态图"(Stateful Graph)。这不是简单的库替换,而是思维模式的升级:

  • Chain 是函数式编程,关注数据流转。
  • Graph 是状态机编程,关注状态变迁与生命周期。

一句话概括:Node 负责做事,Edge 负责决定下一步,State 负责保存整个过程中的数据。

二、核心架构三要素:State、Node、Edge

LangGraph 把 Agent 工作流建模成图,所有节点围绕同一个 State 协作。理解 State、Node、Edge 这三个概念,就掌握了 LangGraph 的核心。

2.1 State:全局共享的"单一事实来源"

很多初学者误以为 State 就是聊天历史(messages),这是极大的误区。State 是图运行时的共享快照,是业务数据的结构化载体。

在真实项目中,State 应该保存结构化业务数据,而不只是聊天历史:

python 复制代码
from typing_extensions import TypedDict

class AgentState(TypedDict):
    user_input: str       # 用户原始输入
    intent: str           # 识别出的意图
    order_id: str         # 提取的订单号
    messages: list        # 对话历史
    tool_result: dict     # 工具执行结果
    final_answer: str     # 最终回复

State 设计原则:

  1. 字段语义清晰 ------不要把所有东西塞到 messages 或 metadata 里。
  2. 只放流程需要的数据 ------无关数据不进全局 State。
  3. 中间结果结构化 ------order_status 比自然语言"订单还没发货"更容易判断。
  4. 注意并行更新 ------多个节点写同一字段时,必须定义 Reducer。
  5. 区分 State 和 Context ------user_id、trace_id 这类不一定要持久化的上下文,考虑用 runtime context。

2.2 Node:原子化的执行单元

Node 是图中真正"做事"的地方。Node 可以是普通函数、异步函数、LLM 调用、Tool 调用、Agent,甚至是子图。

节点函数签名很简洁:输入当前 State,输出 State 的增量更新(Partial State)。

python 复制代码
def classify_intent(state: AgentState):
    text = state["user_input"]
    if "订单" in text:
        return {"intent": "order"}
    if "快递" in text:
        return {"intent": "logistics"}
    return {"intent": "general"}

关键点:节点不返回完整 State,只返回需要更新的字段。 LangGraph 会自动合并。

Node 设计原则:

  • 职责单一------一个 Node 只做一件事。
  • 输入输出清晰------State 进,Partial State 出。
  • 不偷偷修改外部全局状态------返回结构化更新。
  • 出错时容易定位------利于 Tracing 调试。

反面教材: 把意图识别、数据库查询、LLM 生成、审批判断全塞进一个"巨型 Node"。更好的做法是拆成 classify_intent -> extract_order_id -> query_order -> decide_need_human -> generate_answer,每个节点职责单一。

2.3 Edge:控制流的决策者

Edge 决定图如何流动。LangGraph 提供两类核心连接:

|------------------|------------------|------------|
| 类型 | 说明 | 适用场景 |
| 普通 Edge | 固定从 A 到 B | 固定流水线、线性审批 |
| Conditional Edge | 根据 State 动态选择下一步 | 意图识别、分类路由 |

Conditional Edge 是 LangGraph 动态路由的核心能力。 它接收 State,根据业务逻辑返回下一个节点的名称:

python 复制代码
def route_by_intent(state: AgentState):
    if state["intent"] == "order":
        return "query_order"
    if state["intent"] == "logistics":
        return "query_logistics"
    return "general_answer"

架构原则: Edge 中的路由函数应当是轻量的。复杂判断逻辑下沉到 Node 中,Router 只做基于 State 字段的简单分发。不要在路由函数里查数据库、调模型、写日志。

三、消息传递模型:LangGraph 的执行本质

LangGraph 的执行不是简单的函数调用链,而是图消息传递模型 。理解这一点,就理解了 LangGraph 的运行时行为:

  1. 某个节点收到当前 State。
  2. 节点执行业务逻辑。
  3. 返回部分 State 更新。
  4. LangGraph 合并更新到全局 State。
  5. 沿 Edge 激活下一个节点。

节点之间不直接互相调用,而是通过状态更新和边 来协作。这种解耦设计意味着每个节点只关心"读什么、写什么",不需要知道上下游节点的存在。

StateGraph 只是构建器,不能直接执行。 必须调用 compile() 编译后才能使用:

python 复制代码
builder = StateGraph(State)
builder.add_node("node", node_func)
builder.add_edge(START, "node")
builder.add_edge("node", END)

# 编译后才能执行
graph = builder.compile()
graph.invoke(inputs)
graph.stream(inputs)

compile() 会做结构检查:是否有入口、节点名是否存在、是否有孤立节点、图结构是否合法,以及是否配置 checkpointer 等运行能力。

四、实战:构建一个完整的客服路由 Agent

下面通过一个完整的客服场景,展示 LangGraph 的编排能力。目标:输入用户问题 -> 识别意图 -> 根据意图动态路由 -> 查询订单或物流 -> 生成最终回答。

4.1 定义 State 和节点

python 复制代码
from typing_extensions import TypedDict
from langgraph.graph import StateGraph, START, END

class ServiceState(TypedDict):
    user_input: str
    intent: str
    order_id: str
    result: str
    final_answer: str

# 意图识别节点
def classify_intent(state: ServiceState):
    text = state["user_input"]
    if "订单" in text:
        intent = "order"
    elif "物流" in text or "快递" in text:
        intent = "logistics"
    else:
        intent = "general"
    return {"intent": intent}

# 提取订单号
def extract_order_id(state: ServiceState):
    return {"order_id": "10086"}

# 查询订单
def query_order(state: ServiceState):
    return {"result": f"订单 {state['order_id']} 当前状态:已支付"}

# 查询物流
def query_logistics(state: ServiceState):
    return {"result": f"订单 {state['order_id']} 的物流状态:运输中"}

# 通用回答
def general_answer(state: ServiceState):
    return {"result": "我可以帮你查询订单或物流。"}

# 最终回答
def final_answer(state: ServiceState):
    return {"final_answer": state["result"]}

4.2 定义路由函数

路由函数和节点的关键区别:路由函数返回字符串(下一个节点名),节点返回 State 更新。 两者都需要接收 State。

python 复制代码
def route_by_intent(state: ServiceState):
    if state["intent"] == "order":
        return "query_order"
    if state["intent"] == "logistics":
        return "query_logistics"
    return "general_answer"

4.3 构建 StateGraph

python 复制代码
builder = StateGraph(ServiceState)

# 添加节点
builder.add_node("classify_intent", classify_intent)
builder.add_node("extract_order_id", extract_order_id)
builder.add_node("query_order", query_order)
builder.add_node("query_logistics", query_logistics)
builder.add_node("general_answer", general_answer)
builder.add_node("final_answer", final_answer)

# 添加边
builder.add_edge(START, "classify_intent")
builder.add_edge("classify_intent", "extract_order_id")

# 条件路由:核心亮点
builder.add_conditional_edges(
    "extract_order_id",
    route_by_intent,
    {
        "query_order": "query_order",
        "query_logistics": "query_logistics",
        "general_answer": "general_answer",
    },
)

# 汇聚到 final_answer
builder.add_edge("query_order", "final_answer")
builder.add_edge("query_logistics", "final_answer")
builder.add_edge("general_answer", "final_answer")
builder.add_edge("final_answer", END)

# 编译
graph = builder.compile()

4.4 执行与流式输出

生产环境中通常使用 stream 模式获取实时反馈:

python 复制代码
# 同步执行
result = graph.invoke({"user_input": "帮我查一下订单物流"})
print(result["final_answer"])

# 流式执行:每次打印 State 中变更的内容
for chunk in graph.stream(
    {"user_input": "帮我查一下快递到哪里了"},
    stream_mode="updates"
):
    print(chunk)

流式输出的每一步都体现 State 的增量变更------你能看到意图被识别、订单号被提取、物流被查询、最终答案被组装的完整过程。

五、进阶:Runtime Context 与 State 的分离

除了 State,LangGraph 还支持 Runtime Context。两者各司其职:

  • State :保存图运行过程中会变化、需要持久化的业务数据。可以被 Checkpoint。
  • Context :保存运行时配置,如 user_id、tenant_id、trace_id、数据库连接信息、权限信息。不持久化。
python 复制代码
from dataclasses import dataclass
from langgraph.runtime import Runtime

@dataclass
class UserContext:
    user_id: str
    tenant_id: str

class State(TypedDict):
    userId: str

builder = StateGraph(state_schema=State, context_schema=UserContext)

def get_user_id(state: State, runtime: Runtime[UserContext]):
    user_id = runtime.context.user_id
    return {"userId": user_id}

builder.add_node(get_user_id)
builder.add_edge(START, "get_user_id")
builder.add_edge("get_user_id", END)

graph = builder.compile()
result = graph.invoke(
    {"userId": ""},
    context=UserContext(user_id="1000000001", tenant_id="0001")
)

简单记忆:State 管业务流程走到哪了,Context 管这次运行是谁、在哪个环境、带着什么配置。

六、常见图结构

|-------|---------------------|------------------------------|
| 图结构 | 特点 | 适用场景 |
| 线性图 | A -> B -> C | 固定审批、文档处理 |
| 条件分支图 | A -> B 或 C | 意图识别、分类路由 |
| 循环图 | A -> B -> C -> B | Tool Calling Agent、代码 review |
| 并行图 | A -> B + C -> D | 多路检索、多 Agent 并行 |
| 子图 | Parent -> Subgraph | 大型项目模块化 |

循环图需要注意设置终止条件,避免无限循环。并行图经常需要 Reducer 来处理多节点对同一字段的并发写入。

七、避坑指南:常见误区

误区一:LangGraph 就是画流程图。 不是。LangGraph 的重点不是画图,而是让图可执行、可持久化、可恢复、可观测。

误区二:Node 必须调用 LLM。 不是。Node 可以是普通函数、工具调用、数据库查询、规则判断、Agent 或子图。有些 Node 只做业务逻辑,不碰 LLM。

误区三:State 就是 messages。 不是。messages 只是 State 的一个字段。真实项目中应该使用结构化 State,而非把所有东西塞进 messages。

误区四:Edge 只能固定连接。 不是。LangGraph 支持 Conditional Edge、Command、Send 等动态控制方式。

误区五:compile 后图结构还能改。 通常不会直接改 Compiled Graph。需要修改时,应该改 Builder 后重新 compile。

误区六:Reducer 是可选项。 只要有并行更新、Map-Reduce、多 Agent 汇总,就必须理解 Reducer。

八、总结

LangGraph 的核心架构可以浓缩成一句话:State 是数据,Node 是动作,Edge 是流程。

构建 LangGraph 应用的基本步骤:

  1. 定义 State
  2. 编写 Node
  3. 添加 Node(add_node)
  4. 添加 Edge(add_edge / add_conditional_edges)
  5. 编译(compile)
  6. 执行(invoke / stream)

后续所有高级能力------Memory、Human-in-the-loop、Multi-Agent、Subgraph------本质上都是围绕这套 State + Node + Edge 架构展开的。掌握了这个三位一体,就掌握了 LangGraph 的根基。

相关推荐
寻道码路1 天前
大模型工程化实战(五):LLM 网关到底怎么选 - 2026 自研 / LiteLLM/Portkey/Kong/One API 全面对比
大模型·llmops·llm网关·ai网关·ai工程化
rising start4 天前
LangGraph 中断、工具调用与部署
langgraph
梅雅达编程笔记5 天前
Day 18 · 综合实战 B:AI 客服 Agent(专栏收官)
python·智能客服·ai agent·意图识别·ai客服·大模型应用·ai办公自动化
闲猫6 天前
LangGraph / Capabilities / Fault tolerance
python·agent·langgraph
闲猫6 天前
LangGraph / Capabilities / Stores
python·agent·langgraph
minhuan6 天前
大模型AI服务工程化部署与运维实践:推理性能调优、接口开发、监控告警全流程实操25.0
大模型应用·流程监控·大模型ai服务工程化部署·ai服务运维·推理性能调优
梦想的颜色7 天前
Pi‑Agent 深度硬核解析:极简主义编程智能体,OpenClaw 底层内核源码剖析
大模型应用·ai 编程·codingagent·openclaw·piagent·agent 框架源码·2026ai 工具
赵广陆8 天前
企业实战:Web服务端搭建
前端·langchain·langgraph
赵广陆8 天前
RAG企业实战:SSE快速入门
pycharm·langchain·langgraph