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中的一个强大特性,它允许我们根据状态的值动态地选择执行路径,从而构建具有决策能力的工作流。

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

扩展阅读

相关推荐
聚客AI3 小时前
💥下一代推理引擎:vLLM如何重塑AI服务架构?
人工智能·架构·llm
华科云商xiao徐3 小时前
极简Dart代码搞定App内实时数据抓取
爬虫·python·数据分析
花花无缺3 小时前
函数和方法的区别
java·后端·python
stjiejieto3 小时前
中小企业 AI 转型难?成本、技术、人才三重困境下,轻量化解决方案来了
人工智能
Brian-coder3 小时前
机器学习与深度学习的 Python 基础之 NumPy(2)
python·深度学习·机器学习
Ronin-Lotus3 小时前
深度学习篇---SGD+Momentum优化器
人工智能·深度学习·机器学习
Cold_Rain023 小时前
利用 Python 绘制环形热力图
python·数学建模·数据可视化
在钱塘江3 小时前
LangGraph从新手到老师傅 - 3 - StateGraph基础入门
人工智能·python
洛阳泰山3 小时前
MaxKB4j智能体平台 Docker Compose 快速部署教程
java·人工智能·后端