LangGraph从新手到老师傅 - 4 - StateGraph条件边详解

前言

在LangGraph中,条件边(Conditional Edges)是一个强大的特性,它允许我们根据状态的值动态地选择执行路径。这使得我们可以构建具有决策能力的工作流,根据不同的输入或中间状态执行不同的处理逻辑。本文将通过分析示例,深入讲解条件边的概念、实现方式和应用场景。

条件边基础概念

条件边是StateGraph中的一种特殊边,它不直接连接两个节点,而是根据一个路由函数(router function)的返回值来决定下一步执行哪个节点。这种机制使得我们可以在工作流中实现条件分支逻辑,类似于编程语言中的if-else语句或switch-case语句。

条件边的核心组件包括:

  1. 路由函数:根据当前状态返回目标节点名称的函数
  2. 映射关系:将路由函数的返回值映射到实际节点名称的字典

示例代码

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

print("======= 示例2: 使用条件边 =======")

# 定义状态类型
class ConditionalState(TypedDict):
    number: int
    path: str
    result: str

# 定义节点函数
def check_number(state: ConditionalState) -> ConditionalState:
    """检查数字的节点"""
    return state  # 这个节点仅用于路由,不改变状态

def process_even(state: ConditionalState) -> dict:
    """处理偶数的节点"""
    result = f"{state['number']} 是偶数,已乘以2: {state['number'] * 2}"
    return {"result": result, "path": "even"}

def process_odd(state: ConditionalState) -> dict:
    """处理奇数的节点"""
    result = f"{state['number']} 是奇数,已加1: {state['number'] + 1}"
    return {"result": result, "path": "odd"}

# 创建StateGraph
conditional_graph = StateGraph(ConditionalState)

# 添加节点
conditional_graph.add_node("check_number", check_number)
conditional_graph.add_node("process_even", process_even)
conditional_graph.add_node("process_odd", process_odd)

# 添加边
conditional_graph.add_edge(START, "check_number")

# 添加条件边
def router(state: ConditionalState) -> str:
    """根据数字奇偶性路由到不同节点"""
    if state["number"] % 2 == 0:
        return "process_even"
    else:
        return "process_odd"

conditional_graph.add_conditional_edges(
    "check_number",  # 起始节点
    router,           # 路由函数
    {"process_even": "process_even", "process_odd": "process_odd"}  # 映射关系
)

conditional_graph.add_edge("process_even", END)
conditional_graph.add_edge("process_odd", END)

# 编译图
compiled_conditional_graph = conditional_graph.compile()

# 执行图 - 测试偶数
result_even = compiled_conditional_graph.invoke({"number": 4, "path": "", "result": ""})
print(f"输入偶数: {{'number': 4, 'path': '', 'result': ''}}")
print(f"输出: {result_even}")

# 执行图 - 测试奇数
result_odd = compiled_conditional_graph.invoke({"number": 5, "path": "", "result": ""})
print(f"输入奇数: {{'number': 5, 'path': '', 'result': ''}}")
print(f"输出: {result_odd}")

# 示例说明:
# 1. 这个示例展示了如何使用条件边根据状态值动态选择执行路径
# 2. 定义了一个router函数,根据输入数字的奇偶性决定执行哪个处理节点
# 3. 使用add_conditional_edges方法配置条件路由
# 4. 可以看到对于偶数和奇数输入,会得到不同的处理结果

代码解析:条件边的实现与应用

1. 定义状态类型

python 复制代码
class ConditionalState(TypedDict):
    number: int
    path: str
    result: str

这个状态类型定义了三个字段:

  • number:整数类型,用于存储要判断的数字
  • path:字符串类型,用于记录执行路径("even"或"odd")
  • result:字符串类型,用于存储处理结果

2. 定义节点函数

python 复制代码
def check_number(state: ConditionalState) -> ConditionalState:
    """检查数字的节点"""
    return state  # 这个节点仅用于路由,不改变状态

def process_even(state: ConditionalState) -> dict:
    """处理偶数的节点"""
    result = f"{state['number']} 是偶数,已乘以2: {state['number'] * 2}"
    return {"result": result, "path": "even"}

def process_odd(state: ConditionalState) -> dict:
    """处理奇数的节点"""
    result = f"{state['number']} 是奇数,已加1: {state['number'] + 1}"
    return {"result": result, "path": "odd"}

这里定义了三个节点函数:

  • check_number:一个特殊的节点,它不改变状态,仅作为路由的起点
  • process_even:处理偶数的节点,将数字乘以2并更新结果
  • process_odd:处理奇数的节点,将数字加1并更新结果

3. 创建和配置StateGraph

python 复制代码
# 创建StateGraph
conditional_graph = StateGraph(ConditionalState)

# 添加节点
conditional_graph.add_node("check_number", check_number)
conditional_graph.add_node("process_even", process_even)
conditional_graph.add_node("process_odd", process_odd)

# 添加边
conditional_graph.add_edge(START, "check_number")

这部分代码创建了StateGraph实例并添加了三个节点,然后从START节点连接到check_number节点。

4. 添加条件边

python 复制代码
# 定义路由函数
def router(state: ConditionalState) -> str:
    """根据数字奇偶性路由到不同节点"""
    if state["number"] % 2 == 0:
        return "process_even"
    else:
        return "process_odd"

# 配置条件边
conditional_graph.add_conditional_edges(
    "check_number",  # 起始节点
    router,           # 路由函数
    {"process_even": "process_even", "process_odd": "process_odd"}  # 映射关系
)

conditional_graph.add_edge("process_even", END)
conditional_graph.add_edge("process_odd", END)

这是条件边实现的核心部分:

  1. 首先定义了一个router函数,它接收当前状态,根据number字段的奇偶性返回目标节点的名称
  2. 然后使用add_conditional_edges方法配置条件边:
    • 第一个参数是起始节点名称("check_number")
    • 第二个参数是路由函数(router
    • 第三个参数是映射关系字典,将路由函数的返回值映射到实际的节点名称
  3. 最后,从process_evenprocess_odd节点分别连接到END节点

5. 编译和执行图

python 复制代码
# 编译图
compiled_conditional_graph = conditional_graph.compile()

# 执行图 - 测试偶数
result_even = compiled_conditional_graph.invoke({"number": 4, "path": "", "result": ""})
print(f"输入偶数: {{'number': 4, 'path': '', 'result': ''}}")
print(f"输出: {result_even}")

# 执行图 - 测试奇数
result_odd = compiled_conditional_graph.invoke({"number": 5, "path": "", "result": ""})
print(f"输入奇数: {{'number': 5, 'path': '', 'result': ''}}")
print(f"输出: {result_odd}")

编译图后,我们分别用偶数(4)和奇数(5)测试了图的执行。从输出结果可以看到,对于不同的输入,图会执行不同的处理节点,产生不同的结果。

执行流程分析

让我们详细分析一下整个图的执行流程:

对于偶数输入(例如4):

  1. 初始化invoke()方法接收初始状态{"number": 4, "path": "", "result": ""}
  2. 执行check_number节点 :从START开始,首先执行check_number节点,返回原始状态
  3. 执行路由函数 :调用router函数检查数字的奇偶性,返回"process_even"
  4. 执行process_even节点 :根据路由函数的返回值,执行process_even节点,将number乘以2并更新resultpath字段
  5. 结束 :从process_even节点连接到END节点,执行结束并返回最终状态

对于奇数输入(例如5):

  1. 初始化invoke()方法接收初始状态{"number": 5, "path": "", "result": ""}
  2. 执行check_number节点 :从START开始,首先执行check_number节点,返回原始状态
  3. 执行路由函数 :调用router函数检查数字的奇偶性,返回"process_odd"
  4. 执行process_odd节点 :根据路由函数的返回值,执行process_odd节点,将number加1并更新resultpath字段
  5. 结束 :从process_odd节点连接到END节点,执行结束并返回最终状态

为什么使用条件边?

条件边为StateGraph带来了以下优势:

  1. 动态决策:可以根据运行时的状态值动态选择执行路径
  2. 逻辑分离:将不同条件下的处理逻辑分离到不同的节点中
  3. 可扩展性:可以轻松添加新的条件分支,而不需要修改现有代码
  4. 可视化:条件分支逻辑可以通过图的可视化清晰地展示出来

条件边的实际应用场景

  1. 智能对话系统:根据用户的意图或问题类型选择不同的处理流程
  2. 工作流引擎:根据任务状态或条件选择下一步操作
  3. 决策系统:实现基于规则的决策逻辑
  4. 数据处理管道:根据数据特征选择不同的处理算法

总结

通过本文的学习,我们了解了LangGraph中条件边的概念、实现方式和应用场景。条件边是StateGraph中的一个强大特性,它允许我们根据状态的值动态地选择执行路径,从而构建具有决策能力的工作流。

这个示例展示了如何使用条件边实现基于数字奇偶性的简单路由,但条件边的应用远不止于此。在实际应用中,你可以根据业务需求实现更复杂的路由逻辑,构建更加智能和灵活的工作流系统。

扩展阅读

相关推荐
小鸡吃米…5 小时前
机器学习 - 亲和传播算法
python·机器学习·亲和传播
内存不泄露5 小时前
基于Django和Vue3的文件分享平台设计与实现
后端·python·django
绀目澄清5 小时前
Unity3D AI导航系统完全指南:从核心概念到动画耦合
人工智能·unity
没学上了5 小时前
SLM-多头注意力机制
pytorch·python·深度学习
青稞社区.5 小时前
实录精选!MiniMax M2.1 的 Agent 后训练技术官方解读
人工智能
CCPC不拿奖不改名5 小时前
计算机网络:电脑访问网站的完整流程详解+面试习题
开发语言·python·学习·计算机网络·面试·职场和发展
乘风gg5 小时前
Skill 真香!5 分钟帮女友制作一款塔罗牌 APP
人工智能·ai编程·cursor
大模型最新论文速读5 小时前
「英伟达改进 GRPO」解决多奖励场景优势坍缩问题
人工智能·深度学习·自然语言处理
GISer_Jing5 小时前
Nano Banana+LoveArt三大核心功能解析:重构AI设计全链路,让创意落地更高效
人工智能·设计模式·aigc
OpenMiniServer5 小时前
GitLab AI革命:如何将智能开发融入你的DevOps工作流
人工智能·gitlab·devops