LangGraph 1.0入门:从节点与边到智能体工作流构建完全指南

本文详细介绍了LangGraph 1.0的核心概念与基础架构,包括状态管理、节点设计、边类型(普通边、条件边)以及Reducer处理并行冲突的机制。通过代码示例展示了如何构建简单图、实现并行执行和条件分支,为后续构建复杂智能体工作流奠定基础。


一、LangGraph 核心特性

LangGraph 是一个极其灵活的框架,其核心设计理念可以概括为:它是一种用于构建智能体的“编程语言”

如同任何编程语言都包含数据、函数、控制流等基本要素一样,LangGraph 也提供了功能对等的抽象组件,使开发者能够以声明式的方式编排智能体工作流。其核心特性的对应关系如下:

编程语言要素LangGraph 对应概念说明
数据 (Data)状态 (State)工作流执行过程中传递和更新的信息载体。
函数 (Function)节点 (Node)对状态进行操作(如调用模型、执行工具)的基本单元。
控制逻辑 (Control Flow)边 (Edge)决定节点间执行顺序的逻辑,可以是条件分支静态路径,支持串行与并行。
存储 (Storage)检查点 / 记忆 (Checkpointing / Memory)状态的持久化机制,允许工作流暂停、恢复或具有长期记忆。
中断 (Interrupt)人在回路 (Human-in-the-Loop)通过中断控制流,在关键环节引入人工审核或干预的能力。

通过以上组件,LangGraph 使得构建一个具备复杂逻辑、可持续运行且支持人机协作的智能体系统变得直观且高效。

二、状态State和节点Node

2.1 状态State

LangGraph是一个状态图,状态可以理解为图的数据。在定义图之前首先应该定义一个状态作为初始值,在图的更新过程中状态值是可以被图更新并返回给用户的。

图本身是无状态的,在定义图时,首先要定义图将操作的状态。这个状态由图中的所有节点共享。状态通常是一个Python数据结构。定义状态的方式可以采用类型化字典。比如下面代码就定义了包含名为nList字符串列表的状态值。当图被调用时,状态会被初始化,LangGraph运行时会选择一个节点来执行,然后它会提供当前状态,运行节点,最后更新状态再到结束。

class State(TypedDict):
nlist: List[str]

2.2 节点

在LangGraph中,节点的本质是一个函数。节点函数的输入参数是状态,输出则是对状态的更新。举例如下:

def node_a(state: State):
...
return ({"nlist":[note]})

以上节点函数执行完成后会对字符串列表进行更新。State 可以被持久化(通过 Checkpointing 机制)。这意味着如果节点执行失败或工作流被中断,可以从上一个检查点恢复状态重新运行,保证了工作流的鲁棒性。

2.3 使用LangGraph构建简单图

下面笔者通过一个完整的代码示例,将 State 和 Node 的概念串联起来,构建一个最简单的单节点图。在开始之前,请大家确保已经安装了langgraph相关环境。如未安装,可以运行 pip install -U langgraph命令。

  1. 导入依赖库
from langgraph.graph import START, END, StateGraph
  1. 创建图表的第一步是定义一个State类,类型是字典。它包含一个字符串类型的列表,状态可以是一个Python数据类也可以是一个Pydantic基类模型,关于pydantic的使用大家可以参考笔者的文章: 深入浅出LangGraph AI Agent智能体开发教程(六)—LangGraph 底层API入门, 也可查看pydantic官方文档, 这里不加赘述了
class State(TypedDict):
nList: List[str]
  1. 定义节点,节点实际上就是Python函数,该函数接收状态,打印信息然后返回状态的更新。
def node_a(state):
print(f"noda_a接收到{state['nList']}")
note = "Hello, 我是节点a"
return(State(nList=[note]))
  1. 编译状态图,将节点加入到图中,定义为"a"节点,同时添加从START节点到"a"节点的边,然后添加从"a"到END的边。这里的START和END都是LangGraph定义的常量节点,仅包含语义信息。最后编译图。
builder = StateGraph(State)
builder.add_node("a", node_a)
builder.add_edge(START, "a")
builder.add_edge("a", END)
graph = builder.compile()

以上代码构建了一个如下的简单图。

  1. 接下来测试这个图,首先使用State初始化一个状态变量,然后通过.invoke方法运行图。可以看到节点A接收了初始状态,然后当调用图完成后返回了更新后的状态。
initial_state = State(
nList=["Hello Node a, how are you?"]
)
print(graph.invoke(initial_state))

通过以上案例大家应该可以理解在定义图和状态时,图中所有节点可以共享相同的状态。

三、边

在定义了“数据”(State)和“操作”(Node)之后,笔者接下来介绍边 (Edge) 是 LangGraph 中定义工作流执行逻辑的核心。它决定了节点之间的连接关系与执行顺序,是实现串行、并行、条件分支等复杂逻辑的关键。

3.1 普通边

普通边(静态边) 用于连接两个节点,指定了确定无误的执行顺序。它是最简单的控制流,定义了工作流中“下一步该执行谁”。

  • 串行执行

    通过连续的普通边连接多个节点,形成一个线性的执行链。例如:START -> A -> B -> C -> END

  • 并行执行

    一个节点可以同时拥有多个出边(outgoing edges),指向不同的后续节点。LangGraph 运行时会在当前节点完成后,同时触发所有后续节点执行。

3.2 条件边

除普通边外,LangGraph还有另一种条件边。条件边允许工作流根据运行时状态动态决定下一步的执行路径。它需要一个路由函数,该函数接收当前状态,并选择下一个要执行的节点。下图左侧根据条件选择将状态传递给下一级左侧节点进行处理。条件边还有一个特殊情况是MapReduce, 它可以创建可变数量的下游节点,并且每个节点都传递了一个唯一值(笔者之后也会讲到)。

3.3 Reducer详解

当一个节点拥有多个出边(即触发了并行执行)时,多个后续节点可能同时更新 State 中的同一个字段。此时就会产生冲突:以谁的更新为准?默认情况下,节点的更新是覆盖式的。如果节点B和节点C并行执行,都尝试更新state[‘messages’],后完成的节点会覆盖先完成节点的结果,导致数据丢失。

为了更精确的控制,这时就需要用到Reducer(归约器) 来解决解决此问题。它是一个合并函数,定义了当多个更新同时作用于同一个状态字段时,应如何合并这些更新。下面的状态定义中的operator.add就是一个Reducer,它指定了列表状态应该是合并而不是覆写

import operatorfrom typing import TypedDict, Annotatedclass State(TypedDict):    nList: Annotated[list[str], operator.add]

LangGraph 提供了一些开箱即用的 Reducer,下表列出了最常见的几种:

Reducer 函数导入来源适用数据类型主要行为典型应用场景
operator.addoperator (Python标准库)int , float数值累加计数器、计分器
operator.extendoperator (Python标准库)List[T]列表扩展 (list.extend)收集多项结果,如搜索条目
operator.or_operator (Python标准库)Set[T]集合取并集,自动去重收集标签、唯一ID集合
update_dictlanggraph.utilsDict合并字典 ,新值覆盖旧键更新配置或元数据

除了使用内置的Reducer外,开发者甚至可以自定义reducer进行处理。Reducer就是一个合并函数,该函数接收当前值和新传入值作为参数,并在函数中定义处理逻辑。以下是一个自定义Reducer的代码示例:该函数合并新值和旧值并返回去重后结果。

from typing import TypedDict, List, Annotated
from langgraph.graph import START, END, StateGraph
def deduplicate_merge(old_list: List[str], new_list: List[str]) -> List[str]:
"""自定义Reducer:合并列表并去重"""
combined = old_list + new_list
return list(dict.fromkeys(combined)) # 保持顺序的去重
class MyState(TypedDict):
unique_items: Annotated[List[str], deduplicate_merge]
from typing import TypedDict, List, Annotated
class State(TypedDict):
unique_items: Annotated[List[str], deduplicate_merge]
def node_a(state: State) -> State:
print(f"Adding 'A' to {state['unique_items']}")
return State(unique_items=["A"])
def node_A_extra(state: State) -> State:
print(f"Adding 'A' to {state['unique_items']}")
return State(unique_items=["A"])
builder = StateGraph(State)
builder.add_node("a", node_a)
builder.add_node("a_extra", node_A_extra)
builder.add_edge(START, "a")
builder.add_edge("a", "a_extra")
builder.add_edge("a_extra", END)
graph = builder.compile()
initial_state = State(
unique_items = ['Initial String']
)
print(graph.invoke(initial_state))

上面代码的图结构如下所示,按理说列表中应该有两个“A”,但是因为添加时会去重,所以最后列表中只有这一个“A”了。

最后的结果如下:

3.4 探索LangGraph边的并行与数据共享

笔者接下来将构建下图所示的工作流,来帮助大家直观理解并行执行全局状态共享

  1. 第一步同样的需要定义状态,不同的是这里的状态需要用reducer来指明列表的状态是累加而不是覆盖原来的值。
import operator
from typing import TypedDict, List, Annotated
class State(TypedDict):
nList: Annotated[List[str], operator.add]
  1. 下一步来定义节点函数,每个节点都接收状态,并返回对nList字段的更新。
def node_a(state: State) -> State:
print(f"Adding 'A' to {state['nList']}")
return State(nList=["A"])
def node_b(state: State) -> State:
print(f"Adding 'B' to {state['nList']}")
return State(nList=["B"])
def node_c(state: State) -> State:
print(f"Adding 'C' to {state['nList']}")
return State(nList=["C"])
def node_bb(state: State) -> State:
print(f"Adding 'BB' to {state['nList']}")
return State(nList=["BB"])
def node_cc(state: State) -> State:
print(f"Adding 'CC' to {state['nList']}")
return State(nList=["CC"])
def node_d(state: State) -> State:
print(f"Adding 'D' to {state['nList']}")
return State(nList=["D"])
  1. 用状态实例化StateGraph,然后添加定义好的节点并按照参考图中的边将不同的节点连接起来,最后编译图。
builder = StateGraph(State)
builder.add_node("a", node_a)
builder.add_node("b", node_b)
builder.add_node("c", node_c)
builder.add_node("bb", node_bb)
builder.add_node("cc", node_cc)
builder.add_node("d", node_d)
builder.add_edge(START, "a")
builder.add_edge("a", "b")
builder.add_edge("a", "c")
builder.add_edge("b", "bb")
builder.add_edge("c", "cc")
builder.add_edge("bb", "d")
builder.add_edge("cc", "d")
builder.add_edge("d", END)
graph = builder.compile()
  1. 提供一个初始状态来调用图表,大家先来思考一下最后的运行结果。
initial_state = State(
nList = ['Initial String']
)
print(graph.invoke(initial_state))

  • 并行与合并

    节点B和C在同一步骤中并行执行,它们都接收到了来自节点A更新后的状态 [‘Initial‘, ‘A’]。它们的更新(”B””C”)通过Reducer被追加到了nList中。

  • 全局状态共享

    节点BB和CC运行时,它能“看到”的状态包含了其上游节点B的更新(‘B’)也包含了并行分支节点C的更新`(‘C’) 。这是因为LangGraph的状态是全局共享的,边只控制执行顺序,不隔离数据。

3.5 条件边

对于条件边笔者这里直接通过代码讲解,使用条件边实现下图结构,下图中的虚线表示条件边,实线表示普通边。

  1. 定义状态
from langgraph.graph import START, END, StateGraph
import operator
from typing import TypedDict, List, Annotated
class State(TypedDict):
nList: Annotated[List[str], operator.add]
  1. 定义节点函数
def node_a(state: State):
return
def node_b(state: State):
return State(nList=['B'])
def node_c(state: State):
return State(nList=['C'])
  1. 定义图,首先添加实线普通边
builder = StateGraph(State)
builder.add_node("a", node_a)
builder.add_node("b", node_b)
builder.add_node("c", node_c)
builder.add_edge(START, "a")
builder.add_edge("b", END)
builder.add_edge("c", END)
graph = builder.compile()
  1. 学习条件边的定义方法,条件边需要定义条件路由函数,该函数接受状态并返回一个值,这个值代表想要分支到的下一节点。笔者下面定义的函数接收图最近一次写入的状态,然后返回一个值。
def conditional_edge(state: State) -> Literal['b', 'c', END]:
select = state["nList"][-1]
if select == "b":
return 'b'
elif select == 'c':
return 'c'
elif select == 'q':
return END
else:
return END
  1. 在构建图时使用添加条件边的语法来添加条件边
builder.add_conditional_edges("a", conditional_edge)
  1. 测试条件边的逻辑。下面代码笔者从用户那里获取输入作为初始输入状态,然后用该状态调用图表:
user = input('b, c or q to quit:')
input_state = State(
nList=[user]
)
graph.invoke(input_state)

可以看到当用户输入b, 会走到b节点,在b节点中添加字符串’B’, 当用户输入c, 会走到c节点,在c节点中添加字符串‘C’,输入q 则会直接到结束节点,这就是条件边的控制逻辑。

AI时代,未来的就业机会在哪里?

答案就藏在大模型的浪潮里。从ChatGPT、DeepSeek等日常工具,到自然语言处理、计算机视觉、多模态等核心领域,技术普惠化、应用垂直化与生态开源化正催生Prompt工程师、自然语言处理、计算机视觉工程师、大模型算法工程师、AI应用产品经理等AI岗位。

在这里插入图片描述

掌握大模型技能,就是把握高薪未来。

那么,普通人如何抓住大模型风口?

AI技术的普及对个人能力提出了新的要求,在AI时代,持续学习和适应新技术变得尤为重要。无论是企业还是个人,都需要不断更新知识体系,提升与AI协作的能力,以适应不断变化的工作环境。

因此,这里给大家整理了一份《2025最新大模型全套学习资源》,包括2025最新大模型学习路线、大模型书籍、视频教程、项目实战、最新行业报告、面试题等,带你从零基础入门到精通,快速掌握大模型技术!

由于篇幅有限,有需要的小伙伴可以扫码获取!

在这里插入图片描述

1. 成长路线图&学习规划

要学习一门新的技术,作为新手一定要先学习成长路线图,方向不对,努力白费。这里,我们为新手和想要进一步提升的专业人士准备了一份详细的学习成长路线图和规划。
在这里插入图片描述

2. 大模型经典PDF书籍

书籍和学习文档资料是学习大模型过程中必不可少的,我们精选了一系列深入探讨大模型技术的书籍和学习文档,它们由领域内的顶尖专家撰写,内容全面、深入、详尽,为你学习大模型提供坚实的理论基础(书籍含电子版PDF)

在这里插入图片描述

3. 大模型视频教程

对于很多自学或者没有基础的同学来说,书籍这些纯文字类的学习教材会觉得比较晦涩难以理解,因此,我们提供了丰富的大模型视频教程,以动态、形象的方式展示技术概念,帮助你更快、更轻松地掌握核心知识

在这里插入图片描述

4. 大模型项目实战

学以致用 ,当你的理论知识积累到一定程度,就需要通过项目实战,在实际操作中检验和巩固你所学到的知识,同时为你找工作和职业发展打下坚实的基础。

在这里插入图片描述

5. 大模型行业报告

行业分析主要包括对不同行业的现状、趋势、问题、机会等进行系统地调研和评估,以了解哪些行业更适合引入大模型的技术和应用,以及在哪些方面可以发挥大模型的优势。

在这里插入图片描述

6. 大模型面试题

面试不仅是技术的较量,更需要充分的准备。

在你已经掌握了大模型技术之后,就需要开始准备面试,我们将提供精心整理的大模型面试题库,涵盖当前面试中可能遇到的各种技术问题,让你在面试中游刃有余。

在这里插入图片描述

为什么大家都在学AI大模型?

随着AI技术的发展,企业对人才的需求从“单一技术”转向 “AI+行业”双背景。企业对人才的需求从“单一技术”转向 “AI+行业”双背景。金融+AI、制造+AI、医疗+AI等跨界岗位薪资涨幅达30%-50%。

同时很多人面临优化裁员,近期科技巨头英特尔裁员2万人,传统岗位不断缩减,因此转行AI势在必行!

在这里插入图片描述

这些资料有用吗?

这份资料由我们和鲁为民博士(北京清华大学学士和美国加州理工学院博士)共同整理,现任上海殷泊信息科技CEO,其创立的MoPaaS云平台获Forrester全球’强劲表现者’认证,服务航天科工、国家电网等1000+企业,以第一作者在IEEE Transactions发表论文50+篇,获NASA JPL火星探测系统强化学习专利等35项中美专利。本套AI大模型课程由清华大学-加州理工双料博士、吴文俊人工智能奖得主鲁为民教授领衔研发。

资料内容涵盖了从入门到进阶的各类视频教程和实战项目,无论你是小白还是有些技术基础的技术人员,这份资料都绝对能帮助你提升薪资待遇,转行大模型岗位。

在这里插入图片描述
在这里插入图片描述

大模型全套学习资料已整理打包,有需要的小伙伴可以微信扫描下方优快云官方认证二维码,免费领取【保证100%免费】

在这里插入图片描述

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值