langgraph子图

        一个图可以实现特定的工作流,同时也可以复用到其他更大的图(可称之为父图)中作为子图,借助子图除了可以实现逻辑重用,同时也是多智能体的物质基础。

        本文首先根据是否共享状态数据说明父图和子图如何集成,然后对父子图集成情况下的持久化进行讲解,最后说明如何查看子图的状态。

     1.集成子图

        父图集成子图需要考虑两种情况,一种是父图和子图的中状态有相同的频道(健),另一种是父子图状态中无相同的频道。

      1.1父子图状态相同

        父子图状态相同时,可以直接把子图作为父图中的一个节点,进入子图时携带了共享的频道,在子图中可是设置和使用自己只有的频道,子图完成专有频道的更新后再回到父图,父图并不能感知到;当然父图也可以有自己专有的频道,传入到子图时,子图对父图的专有频道页无感。

        以下代码定义一个子图,子图与父图共享频道v,在子图中增加了自己的专有频道 delta,子图中把delta与父图传入的v相加,并更新v的值。

from typing_extensions import TypedDict
from langgraph.graph import StateGraph, START, END

#子图状态。与父图共享v频道,delta为专有频道

class SubState(TypedDict):
    v: int
    delta: int
def node1(state: SubState):#子图节点1中给delta赋值为10
    return {'delta': 10}    
def node2(state: SubState):#子图节点2中执行v+delta
    return {'v': state['v'] + state['delta']}

#构建子图sub_graph_builder = StateGraph(SubState)
sub_graph_builder.add_node("node1", node1)
sub_graph_builder.add_node("node2", node2)
sub_graph_builder.add_edge(START, "node1")
sub_graph_builder.add_edge("node1", "node2")
sub_graph_builder.add_edge("node2", END)
sub_graph = sub_graph_builder.compile()

#父图状态。与子图共享 v频道

class State(TypedDict):
    v: int
def node(state: State):#在节点中完成v的平方计算
    return {'v': state['v'] * state['v']}

#构建父图,把子图作为一个节点

graph_builder = StateGraph(State)
graph_builder.add_node(node)
graph_builder.add_node("sub_graph", sub_graph)
graph_builder.add_edge(START, "node")
graph_builder.add_edge("node", "sub_graph")
graph_builder.add_edge("sub_graph", END)

graph = graph_builder.compile()
graph.invoke({'v':10})

        运行输出为v*v + delta,具体结果如下:

{'v': 110}

      1.2父子图状态相异

        如果父子图无共享频道,比如在多智能体情况下,每个智能体保存自己专有的对话数据,此时不能把子图作为父图的节点,只能从父图一个节点内部调用子图,在调用前需要适配父图的状态为子图状态,并且把子图的状态适配为父图的状态后再更新状态。

        以下代码在子图中接收父图传入的参数,做3次方运算,把结果更新到子图频道v中。在父图的node节点中进行输入和输出的适配,具体代码如下:

from typing_extensions import TypedDict
from langgraph.graph import StateGraph, START, END

#子图装填,base,exp和v均为专用频道

class SubState(TypedDict):
    base: int
    exp: int
    v: int
def node1(state: SubState): #给exp赋值
    return {'exp': 3}
def node2(state: SubState): #执行3次方运算并写入v频道
    return {'v': pow(state['base'], state['exp'])}

#创建子图

sub_graph_builder = StateGraph(SubState)
sub_graph_builder.add_node("node1", node1)
sub_graph_builder.add_node("node2", node2)
sub_graph_builder.add_edge(START, "node1")
sub_graph_builder.add_edge("node1", "node2")
sub_graph_builder.add_edge("node2", END)
sub_graph = sub_graph_builder.compile()

#父图状态

class State(TypedDict):
    x: int
def node(state: State):#在节点内部调用子图
    ret = sub_graph.invoke({'base': state['x']}) #输入参数适配
    return {'x': ret['v']} #返回参数适配

#构建父图,此时子图不会作为父图节点存在

graph_builder = StateGraph(State)
graph_builder.add_node(node)
graph_builder.add_edge(START, "node")
graph_builder.add_edge("node", END)

graph = graph_builder.compile()
graph.invoke({'x':10}, subgraphs=True)

     2.查看子图状态

        在使用短期记忆时,可以查看子图的状态。在langgraph中仅可以在子图被中断时才可以查看状态,从中断恢复后不能再访问子图状态。

        以下代码中,在子图的node1节点中断等待用户确认,此时可以通过调用图的get_state方法区查看子图的状态,此时除需要传入config外,还必须传入subgraphs=True。

from langgraph.graph import START, StateGraph
from langgraph.checkpoint.memory import MemorySaver
from langgraph.types import interrupt, Command
from typing_extensions import TypedDict

#父图和子图共享频道name和answer

class State(TypedDict):
    name: str
    answer: str

# 子图节点中产生中断,等待用户确认

def node1(state: State):
    value = interrupt(f"Is your name right: {state['name']}")
    if value=='y':
         return {"answer": f"Your name is {state['name']}"}
    else:
        return {"answer": f"Your name is incorrect, please confirm"}

#构建子图

subgraph_builder = StateGraph(State)
subgraph_builder.add_node(node1)
subgraph_builder.add_edge(START, "node1")

subgraph = subgraph_builder.compile()

# 构建父图

builder = StateGraph(State)
builder.add_node("subgraph", subgraph)
builder.add_edge(START, "subgraph")

checkpointer = MemorySaver()
graph = builder.compile(checkpointer=checkpointer)

config = {"configurable": {"thread_id": "1"}}

graph.invoke({"name": "davi"}, config)
subgraph_state = graph.get_state(config, subgraphs=True).tasks[0].state  
print(subgraph_state)

graph.invoke(Command(resume="y"), config)

        输出如下,可以看到子图当前的状态:

StateSnapshot(values={'name': 'davi'}, next=('node1',), config={'configurable': {'thread_id': '1', 'checkpoint_ns': 'subgraph:2cf7ed04-daf3-458c-3807-5afd72314233', 'checkpoint_id': '1f0a8d84-4321-61ce-8000-687a815a3c6b', 'checkpoint_map': {'': '1f0a8d84-4302-6e00-8000-7dd4b6147e42', 'subgraph:2cf7ed04-daf3-458c-3807-5afd72314233': '1f0a8d84-4321-61ce-8000-687a815a3c6b'}}}, metadata={'source': 'loop', 'step': 0, 'parents': {'': '1f0a8d84-4302-6e00-8000-7dd4b6147e42'}}, created_at='2025-10-14T08:32:05.901944+00:00', parent_config={'configurable': {'thread_id': '1', 'checkpoint_ns': 'subgraph:2cf7ed04-daf3-458c-3807-5afd72314233', 'checkpoint_id': '1f0a8d84-431a-69f4-bfff-ba93d1a32e32', 'checkpoint_map': {'': '1f0a8d84-4302-6e00-8000-7dd4b6147e42', 'subgraph:2cf7ed04-daf3-458c-3807-5afd72314233': '1f0a8d84-431a-69f4-bfff-ba93d1a32e32'}}}, tasks=(PregelTask(id='6b1b1803-9ca3-736a-d74c-a25353e7795d', name='node1', path=('__pregel_pull', 'node1'), error=None, interrupts=(Interrupt(value='Is your name right: davi', id='0a7f4eeaa60b8b3a5254c36559bf39f5'),), state=None, result=None),), interrupts=(Interrupt(value='Is your name right: davi', id='0a7f4eeaa60b8b3a5254c36559bf39f5'),))

        从中断恢复后,再次查看子图状态将报错。

     3.子图流式输出

        如果调用图时,希望子图也以流式输出,则仅需要在图的graph方法中传入 subgraphs=True参数即可。

for chunk in graph.stream(
    {"foo": "foo"},
    stream_mode="updates",
    subgraphs=True, 
):
    print(chunk)

【EI复现】基于主从博弈的新型城镇配电系统产消者竞价策略【IEEE33节点】(Matlab代码实现)内容概要:本文介绍了基于主从博弈理论的新型城镇配电系统中产消者竞价策略的研究,结合IEEE33节点系统,利用Matlab进行仿真代码实现。该研究聚焦于电力市场环境下产消者(既生产又消费电能的主体)之间的博弈行为建模,通过构建主从博弈模型优化竞价策略,提升配电系统运行效率与经济性。文中详细阐述了模型构建思路、优化算法设计及Matlab代码实现过程,旨在复现高水平期刊(EI收录)研究成果,适用于电力系统优化、能源互联网及需求响应等领域。; 适合人群:具备电力系统基础知识一定Matlab编程能力的研究生、科研人员及从事能源系统优化工作的工程技术人员;尤其适合致力于电力市场博弈、分布式能源调度等方向的研究者。; 使用场景及目标:① 掌握主从博弈在电力系统产消者竞价中的建模方法;② 学习Matlab在电力系统优化仿真中的实际应用技巧;③ 复现EI级别论文成果,支撑学术研究或项目开发;④ 深入理解配电系统中分布式能源参与市场交易的决策机制。; 阅读建议:建议读者结合IEEE33节点标准系统数据,逐步调试Matlab代码,理解博弈模型的变量设置、目标函数构建与求解流程;同时可扩展研究不同市场机制或引入不确定性因素以增强模型实用性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值