TellWorldAI 世界档案
问档案English

首页›实践›实践

实践

LangGraph 基础:状态、节点与边

LangGraph 用节点、边和状态组织大语言模型应用的流程。本文用一个带条件分支的小图讲清三个基本概念,并说明何时适合使用。

这篇适合已经会写 Python、想搭一个由大语言模型驱动、流程可控的智能体的读者。读完你能说清 LangGraph 的三个基本概念(状态、节点、边),用几十行代码写出一个带条件分支的图,并知道它什么时候比普通 Python 代码更合适。

LangGraph 是什么,和 LangChain 有什么区别

LangGraph 是 LangChain 开发的框架,用来管理集成了大语言模型(LLM)的应用的控制流[2]。LangChain 提供与模型和其他组件交互的标准接口,适用于检索、模型调用和工具调用。LangGraph 可以使用 LangChain 的类,但并不强制要求。两个包相互独立,可以单独使用,网上的大多数资料会把两者一起用[2]。

什么时候该用 LangGraph

设计 AI 应用时,常常要在“控制”和“自由”之间取舍。自由让模型有更多空间发挥创造力,去应对意料之外的问题;控制则保证行为可预测,并设置护栏[2]。

以 smolagents 中的代码智能体为例,它们非常自由,可以在一个动作步骤中调用多个工具,还能自己创建工具。不过这也让它们比用 JSON 格式工作的普通智能体更难预测、更难控制[2]。LangGraph 处在另一端:当你需要控制智能体的执行过程时,它最有价值,能让应用按可预测的流程运行,同时仍然利用大语言模型的能力[2]。

具体来说,LangGraph 适合这几类场景[2]:

  • 需要显式控制流程的多步推理;
  • 需要在步骤之间保存状态的应用;
  • 把确定性逻辑和 AI 能力结合在一起的系统;
  • 需要人工介入的工作流;
  • 多个组件协作的复杂智能体架构。

LangGraph 怎么工作

LangGraph 用有向图来定义应用的流程。节点(Nodes)代表单个处理步骤,比如调用大语言模型、使用工具或做出决策;边(Edges)定义步骤之间可能的跳转;状态(State)由用户定义,在执行过程中被维护,并在节点之间传递,决定下一步去哪里[2]。

和直接写 if-else 相比,LangGraph 内置了状态、可视化、日志(traces)和人工介入等功能。你仍然可以只用普通 Python 实现同样的流程,但 LangGraph 会替你搭好这些工具和抽象[2]。

第一步:定义状态

状态是 LangGraph 的核心概念,它代表在应用中流动的全部信息。状态由用户定义,所以字段要仔细设计,确保包含做决策所需的全部数据。在下面的例子里,状态是一个 TypedDict,只有一个字段 graph_state[1]:

from typing_extensions import TypedDict

class State(TypedDict):
    graph_state: str

第二步:编写节点

节点就是 Python 函数。每个节点接收状态作为输入,执行一些操作,然后返回对状态的更新。节点里可以放大语言模型调用、工具调用、条件逻辑,也可以放人工输入[1]。

下面三个节点各自给 graph_state 追加一段文字[1]:

def node_1(state):
    print("---Node 1---")
    return {"graph_state": state['graph_state'] +" I am"}

def node_2(state):
    print("---Node 2---")
    return {"graph_state": state['graph_state'] +" happy!"}

def node_3(state):
    print("---Node 3---")
    return {"graph_state": state['graph_state'] +" sad!"}

START 和 END 由 LangGraph 直接提供,分别标记整个工作流的开始和结束[1]。

第三步:连接边

边把节点连起来,定义图中可能的路径。边分两种:直接边总是从节点 A 走到节点 B;条件边则根据当前状态选择下一个节点[1]。示例中的 decide_mood 是一个条件函数,返回 node_2 或 node_3。示例用 50/50 的随机数来二选一,实际应用中通常会根据状态做判断[1]:

import random
from typing import Literal

def decide_mood(state) -> Literal["node_2", "node_3"]:
    
    # Often, we will use state to decide on the next node to visit
    user_input = state['graph_state'] 
    
    # Here, let's just do a 50 / 50 split between nodes 2, 3
    if random.random() < 0.5:

        # 50% of the time, we return Node 2
        return "node_2"
    
    # 50% of the time, we return Node 3
    return "node_3"

第四步:用 StateGraph 组装并编译

StateGraph 是容纳整个智能体工作流的容器。下面的代码先用 StateGraph(State) 创建构建器,再依次添加节点、直接边和条件边,最后调用 compile() 得到可运行的图[1]:

from langgraph.graph import StateGraph, START, END

# Build graph
builder = StateGraph(State)
builder.add_node("node_1", node_1)
builder.add_node("node_2", node_2)
builder.add_node("node_3", node_3)

# Logic
builder.add_edge(START, "node_1")
builder.add_conditional_edges("node_1", decide_mood)
builder.add_edge("node_2", END)
builder.add_edge("node_3", END)

# Add
graph = builder.compile()

注意这里的 add_conditional_edges 与 add_edge 的区别:前者的下一步由函数决定,后者固定连接。

第五步:可视化并调用

编译好的图可以画出来。示例用 graph.get_graph().draw_mermaid_png() 生成图片,再用 IPython.display 中的 display 显示[1]:

from IPython.display import Image, display

# View
display(Image(graph.get_graph().draw_mermaid_png()))

调用图用 invoke,传入初始状态字典[1]:

graph.invoke({"graph_state" : "Hi, this is Lance."})

示例的输出是先经过节点 1、再经过节点 3,最后返回追加了文字后的状态[1]:

---Node 1---
---Node 3---
{'graph_state': 'Hi, this is Lance. I am sad!'}

下一步

下一步可以动手搭一个更实际的图:接收邮件、对邮件分类,并在邮件属实时起草一个初步回复[1]。

本文改编自 Hugging Face 开源课程《Agents Course》第 2 单元关于 LangGraph 的内容[1][2],原文以 Apache-2.0 许可证发布。

来源

  1. 1
    Building Blocks of LangGraphHugging Face agents-course (Apache-2.0)
  2. 2
    What is LangGraph?Hugging Face agents-course (Apache-2.0)

引用本页: LangGraph 基础:状态、节点与边. TellWorld, https://www.tellworld.net/zh/practice/practice-langgraph-building-blocks. 更新于 2026-11-14

相关动态