LangGraph中的State管理

本教程将介绍如何使用LangGraph库构建和测试状态图。我们将通过一系列示例代码,逐步解释程序的运行逻辑。

1. 基本状态图构建

首先,我们定义一个状态图的基本结构和节点。

定义状态类

from langgraph.graph import StateGraph, START, END
from typing_extensions import TypedDict
from pydantic import BaseModel# 定义整个图的状态(这是在节点间共享的公共状态)
class OverallState(BaseModel):a: str

定义节点函数

def node(state: OverallState):return {"a": "goodbye"}

构建状态图

# 构建状态图
builder = StateGraph(OverallState)
builder.add_node(node)  # 添加节点
builder.add_edge(START, "node")  # 从起始节点开始
builder.add_edge("node", END)  # 在节点后结束
graph = builder.compile()

测试状态图

# 使用有效输入测试图
graph.invoke({"a": "hello"})

输出结果:

{'a': 'goodbye'}

可视化状态图

from IPython.display import Image, displaytry:display(Image(graph.get_graph(xray=True).draw_mermaid_png()))
except Exception:# 这需要一些额外的依赖项,是可选的print("x")pass

请添加图片描述

测试无效输入

try:graph.invoke({"a": 123})  # 应该是字符串
except Exception as e:print("An exception was raised because `a` is an integer rather than a string.")print(e)

输出结果:

An exception was raised because `a` is an integer rather than a string.
1 validation error for OverallState
aInput should be a valid string [type=string_type, input_value=123, input_type=int]For further information visit https://errors.pydantic.dev/2.8/v/string_type

2. 处理无效节点

接下来,我们添加一个返回无效状态的节点,并观察其影响。

定义节点函数

def bad_node(state: OverallState):return {"a": 123  # 无效}def ok_node(state: OverallState):return {"a": "goodbye"}

构建状态图

# 构建状态图
builder = StateGraph(OverallState)
builder.add_node(bad_node)
builder.add_node(ok_node)
builder.add_edge(START, "bad_node")
builder.add_edge("bad_node", "ok_node")
builder.add_edge("ok_node", END)
graph = builder.compile()

可视化状态图

from IPython.display import Image, displaytry:display(Image(graph.get_graph(xray=True).draw_mermaid_png()))
except Exception:# 这需要一些额外的依赖项,是可选的pass

请添加图片描述

测试状态图

# 使用有效输入测试图
try:graph.invoke({"a": "hello"})
except Exception as e:print("An exception was raised because bad_node sets `a` to an integer.")print(e)

输出结果:

An exception was raised because bad_node sets `a` to an integer.
1 validation error for OverallState
aInput should be a valid string [type=string_type, input_value=123, input_type=int]For further information visit https://errors.pydantic.dev/2.8/v/string_type

3. 输入和输出状态的分离

接下来,我们定义输入和输出状态的分离。

定义状态类

from typing_extensions import TypedDict# 定义输入状态的架构
class InputState(TypedDict):question: str# 定义输出状态的架构
class OutputState(TypedDict):answer: str# 定义整体架构,结合输入和输出
class OverallState(InputState, OutputState):pass

定义节点函数

def answer_node(state: InputState):# 示例答案和一个额外的键return {"answer": "bye", "question": state["question"]}

构建状态图

# 使用指定的输入和输出架构构建图
builder = StateGraph(OverallState, input=InputState, output=OutputState)
builder.add_node(answer_node)  # 添加答案节点
builder.add_edge(START, "answer_node")  # 定义起始边
builder.add_edge("answer_node", END)  # 定义结束边
graph1 = builder.compile()  # 编译图

可视化状态图

from IPython.display import Image, displaytry:display(Image(graph1.get_graph(xray=True).draw_mermaid_png()))
except Exception:# 这需要一些额外的依赖项,是可选的pass

请添加图片描述

测试状态图

print(graph1.invoke({"question": "hi"}))

输出结果:

{'answer': 'bye'}

4. 处理私有数据

最后,我们展示如何在节点间传递私有数据。

定义状态类

# 整个图的状态(这是在节点间共享的公共状态)
class OverallState(TypedDict):a: str# node_1的输出包含私有数据,不属于整体状态
class Node1Output(TypedDict):private_data: str

定义节点函数

def node_1(state: OverallState) -> Node1Output:output = {"private_data": "set by node_1"}print(f"Entered node `node_1`:\n\tInput: {state}.\n\tReturned: {output}")return output# node_2的输入仅请求node_1后可用的私有数据
class Node2Input(TypedDict):private_data: strdef node_2(state: Node2Input) -> OverallState:output = {"a": "set by node_2"}print(f"Entered node `node_2`:\n\tInput: {state}.\n\tReturned: {output}")return output# node_3仅能访问整体状态(无法访问node_1的私有数据)
def node_3(state: OverallState) -> OverallState:output = {"a": "set by node_3"}print(f"Entered node `node_3`:\n\tInput: {state}.\n\tReturned: {output}")return output

构建状态图

# 构建状态图
builder = StateGraph(OverallState)
builder.add_node(node_1)  # node_1是第一个节点
builder.add_node(node_2)  # node_2是第二个节点,接受node_1的私有数据
builder.add_node(node_3)  # node_3是第三个节点,无法看到私有数据
builder.add_edge(START, "node_1")  # 从node_1开始
builder.add_edge("node_1", "node_2")  # 从node_1传递到node_2
builder.add_edge("node_2", "node_3")  # 从node_2传递到node_3(仅共享整体状态)
builder.add_edge("node_3", END)  # 在node_3后结束
graph = builder.compile()

可视化状态图

from IPython.display import Image, displaytry:display(Image(graph.get_graph(xray=True).draw_mermaid_png()))
except Exception:# 这需要一些额外的依赖项,是可选的pass

请添加图片描述

测试状态图

# 使用初始状态调用图
response = graph.invoke({"a": "set at start",}
)print()
print(f"Output of graph invocation: {response}")

输出结果:

Entered node `node_1`:Input: {'a': 'set at start'}.Returned: {'private_data': 'set by node_1'}
Entered node `node_2`:Input: {'private_data': 'set by node_1'}.Returned: {'a': 'set by node_2'}
Entered node `node_3`:Input: {'a': 'set by node_2'}.Returned: {'a': 'set by node_3'}Output of graph invocation: {'a': 'set by node_3'}

通过以上步骤,我们展示了如何使用LangGraphState管理,包括处理私有数据和状态验证。希望这个教程对你有所帮助!

参考链接:https://langchain-ai.github.io/langgraph/how-tos/state-model/
https://langchain-ai.github.io/langgraph/how-tos/input_output_schema/
https://langchain-ai.github.io/langgraph/how-tos/pass_private_state/
如果有任何问题,欢迎在评论区提问。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/62132.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Go-Web之TCP网络连接

函数学习 net.Listen:用于创建一个TCP监听器,在指定地址上监听传入的连接listrener.Accept:这个方法会阻塞,直到有新的客户端连接,当连接到来时,它会返回一个net.Conn类型的连接对象,表示客户端和服务器之间的TCP连接…

Excel的图表使用和导出准备

目的 导出Excel图表是很多软件要求的功能之一,那如何导出Excel图表呢?或者说如何使用Excel图表。 一种方法是软件生成图片,然后把图片写到Excel上,这种方式,因为格式种种原因,导出的图片不漂亮&#xff0c…

Spring WebFlux SSE(服务器发送事件)的正确用法

在SpringBoot2下SSE实现是返回一个SseEmitter,然后通过SseEmitter的send方法来发送事件. 在SpringBoot3的WebFlux 下SSE实现是返回一个Flux<ServerSentEvent<?>>,但是怎么手动向客户端发送SSE事件搜遍全网也没有看到一个讲清楚的.网上的例子一般都是这样的: GetM…

vue实现滚动条滑动到底部分页调取后端接口加载数据

一、案例效果 二、前提条件 接口返回数据 三、案例代码 子组件 const $emit defineEmits([cloneItem, updateList]);const props defineProps({rightList: {type: Array,},chartTableData: {type: Array as () > ChartListType[],},deleteChartInfo: {type: Object,}…

Ubuntu中使用多版本的GCC

我的系统中已经安装了GCC11.4&#xff0c;在安装cuda时出现以下错误提示&#xff1a; 意思是当前的GCC版本过高&#xff0c;要在保留GCC11.4的同时安装GCC9并可以切换&#xff0c;可以通过以下步骤实现&#xff1a; 步骤 1: 安装 GCC 9 sudo apt-get update sudo apt-get ins…

【Android】RecyclerView回收复用机制

概述 RecyclerView 是 Android 中用于高效显示大量数据的视图组件&#xff0c;它是 ListView 的升级版本&#xff0c;支持更灵活的布局和功能。 我们创建一个RecyclerView的Adapter&#xff1a; public class MyRecyclerView extends RecyclerView.Adapter<MyRecyclerVie…

Kotlin DSL Gradle 指南

本文是关于 Kotlin DSL Gradle 的指南&#xff08;上篇&#xff09;&#xff0c;介绍了 Gradle 作为 Android 开发构建工具的作用及优势&#xff0c;包括初始配置、生命周期、依赖管理、Task 相关内容。如 Task 的创建、自定义、各种方法和属性&#xff0c;以及文件操作等&…

数据库导论

data 数据是数据库中存储的基本数据&#xff0c;描述事物的符号称为数据。 DB 数据库是长期存储在计算机内&#xff0c;有组织&#xff0c;可共享的大量数据的集合。数据库中的数据按照一定的数据模型组织&#xff0c;描述和存储&#xff0c;具有较小的冗余度&#xff0c;较…

HTML实现 扫雷游戏

前言&#xff1a; 游戏起源与发展 扫雷游戏的雏形可追溯到 1973 年的 “方块&#xff08;cube&#xff09;” 游戏&#xff0c;后经改编出现了 “rlogic” 游戏&#xff0c;玩家需为指挥中心探出安全路线避开地雷。在此基础上&#xff0c;开发者汤姆・安德森编写出了扫雷游戏的…

浏览器漫谈HTML--2.2从表单标签看vue的响应式系统 理论+实战

表单标签的双向绑定是一个很有亮点的功能。在不同框架中他实现这个功能大同小异&#xff0c;这里我们介绍几个常见的框架中他是如何实现双向绑定的。 原生的input输入框是没有双向绑定的功能的。取而代之的&#xff0c;它的input上有一个event对象&#xff0c;这个对象中有一个…

Python 爬虫 (1)基础 | 目标网站

一、目标网站 1、加密网站 1.1、关键字比较明确 企名片&#xff1a;https://wx.qmpsee.com/articleDetail?idfeef62bfdac45a94b9cd89aed5c235be 1.2、关键字比较泛 烯牛数据&#xff1a;https://www.xiniudata.com/project/event/lib/invest

Spring Boot英语知识网站:开发策略

5系统详细实现 5.1 管理员模块的实现 5.1.1 用户信息管理 英语知识应用网站的系统管理员可以对用户信息添加修改删除以及查询操作。具体界面的展示如图5.1所示。 图5.1 用户信息管理界面 5.1.2 在线学习管理 系统管理员可以对在线学习信息进行添加&#xff0c;修改&#xff0…

堆优化版本的Prim

prim和dijkstra每轮找最小边的松弛操作其实是同源的&#xff0c;因而受dijkstra堆优化的启发&#xff0c;那么prim也可以采用小根堆进行优化。时间复杂度也由 O ( n 2 ) O(n^2) O(n2)降为 O ( n l o g n ) O(nlogn) O(nlogn)。 测试一下吧&#xff1a;原题链接 #include <i…

研0找实习【学nlp】15---我的后续,总结(暂时性完结)

当下进展成果&#xff1a; nlptransformerpytorchhuggingfacebert简历环境配置表情识别文本分类 断更了快1个月&#xff0c;2个礼拜找实习&#xff0c;1个礼拜伤心&#xff0c;1个礼拜想我要干什么…… 承认自己的才疏学浅&#xff0c;了解了leetcode&#xff0c;和老师商量了…

HTML5和CSS3新增特性

HTML5的新特性 HTML5新增的语义化标签 HTML5 的新增特性主要是针对于以前的不足&#xff0c;增加了一些新的标签、新的表单和新的表单属性等。 这些新特性都有兼容性问题&#xff0c;基本是 IE9 以上版本的浏览器才支持&#xff0c;如果不考虑兼容性问题&#xff0c;可以大量…

width设置100vh但出现横向滚动条的问题

在去做flex左右固定,中间自适应宽度的布局时, 发现这样一个问题: 就是我明明是宽度占据整个视口, 但是却多出了横向的滚动条 效果是这样的 把width改成100%,就没有滚动条了 原因: body是有默认样式的, 会有一定的默认边距, 把默认边距清除就是正常的了 同时, 如果把高度设…

EasyExcel: 结合springboot实现表格导出入(单/多sheet), 全字段校验,批次等操作(全)

全文目录,一步到位 1.前言简介1.1 链接传送门1.1.1 easyExcel传送门 2. Excel表格导入过程2.1 easyExcel的使用准备工作2.1.1 导入maven依赖2.1.2 建立一个util包2.1.3 ExcelUtils统一功能封装(单/多sheet导入)2.1.4 ExcelDataListener数据监听器2.1.5 ResponseHelper响应值处理…

数字ic设计bug:寄存器翻转错误

数字ic设计bug&#xff1a;寄存器翻转错误 bug场景&#xff1a; 寄存器未按指定条件翻转&#xff0c;满足翻转条件&#xff0c;但未翻转 问题描述 always&#xff08;posedge clk or negedge rst_n&#xff09; if(!rst_n)a < 1‘d0; else if(a_condition)a < 1’b1;a…

Linux/Windows/OSX 上面应用程序重新启动运行。

1、Linux/OSX 上面重新运行程序&#xff0c;直接使用 execvp 函数就可以了&#xff0c;把main 函数传递来的 argv 二维数组&#xff08;命令行参数&#xff09;传进去就可以&#xff0c;注意不要在 fork 出来的子进程搞。 2、Windows 平台可以通过 CreateProcess 函数来创建新的…

css:转换

转换 移动 /* transform: translate(100px, 200px); */transform: translateX(100px);transform: translateY(100px); /*一个意思*/ 如果后面跟百分数的意思是移动盒子自身x/y方向长度的百分比&#xff0c;可以用作子绝父相控制盒子水平居中垂直居中 translate里的xy值是相对…