如何使用 Pydantic 模型作为状态¶
一个 StateGraph 在初始化时接受一个 state_schema
参数,该参数指定图中节点可以访问和更新的状态的“形状”。
在我们的示例中,我们通常使用 python 本地的 TypedDict
作为 state_schema
(或者在 MessageGraph 的情况下,使用 list),但 state_schema
可以是任何 类型。
在本操作指南中,我们将了解如何使用 Pydantic BaseModel。可以用于 state_schema
,以在 **输入** 上添加运行时验证。
已知限制
- 此笔记本使用 Pydantic v2
BaseModel
,需要langchain-core >= 0.3
。使用langchain-core < 0.3
将导致错误,因为混合了 Pydantic v1 和 v2BaseModels
。 - 目前,图的
output
**不会** 是 pydantic 模型的实例。 - 运行时验证仅在进入节点的 **输入** 上发生,而不是在输出上。
- 来自 pydantic 的验证错误跟踪不会显示错误出现在哪个节点中。
设置¶
首先,我们需要安装所需的包
In [1]
已复制!
%%capture --no-stderr
%pip install --quiet -U langgraph
%%capture --no-stderr %pip install --quiet -U langgraph
In [2]
已复制!
import getpass
import os
def _set_env(var: str):
if not os.environ.get(var):
os.environ[var] = getpass.getpass(f"{var}: ")
_set_env("OPENAI_API_KEY")
import getpass import os def _set_env(var: str): if not os.environ.get(var): os.environ[var] = getpass.getpass(f"{var}: ") _set_env("OPENAI_API_KEY")
输入验证¶
In [4]
已复制!
from langgraph.graph import StateGraph, START, END
from typing_extensions import TypedDict
from pydantic import BaseModel
# The overall state of the graph (this is the public state shared across nodes)
class OverallState(BaseModel):
a: str
def node(state: OverallState):
return {"a": "goodbye"}
# Build the state graph
builder = StateGraph(OverallState)
builder.add_node(node) # node_1 is the first node
builder.add_edge(START, "node") # Start the graph with node_1
builder.add_edge("node", END) # End the graph after node_1
graph = builder.compile()
# Test the graph with a valid input
graph.invoke({"a": "hello"})
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) # node_1 是第一个节点 builder.add_edge(START, "node") # 从 node_1 开始图 builder.add_edge("node", END) # 在 node_1 之后结束图 graph = builder.compile() # 使用有效输入测试图 graph.invoke({"a": "hello"})
Out[4]
{'a': 'goodbye'}
使用 **无效** 输入调用图
In [5]
已复制!
try:
graph.invoke({"a": 123}) # Should be a string
except Exception as e:
print("An exception was raised because `a` is an integer rather than a string.")
print(e)
try: graph.invoke({"a": 123}) # 应该是一个字符串 except Exception as e: print("因为 `a` 是一个整数而不是一个字符串,所以抛出了异常。") print(e)
An exception was raised because `a` is an integer rather than a string. 1 validation error for OverallState a Input should be a valid string [type=string_type, input_value=123, input_type=int] For further information visit https://errors.pydantic.dev/2.9/v/string_type
多个节点¶
运行时验证也将在多节点图中起作用。在下面的示例中,bad_node
将 a
更新为一个整数。
因为运行时验证发生在 **输入** 上,所以验证错误将在调用 ok_node
时发生(而不是在 bad_node
返回与模式不一致的状态更新时)。
In [6]
已复制!
from langgraph.graph import StateGraph, START, END
from typing_extensions import TypedDict
from pydantic import BaseModel
# The overall state of the graph (this is the public state shared across nodes)
class OverallState(BaseModel):
a: str
def bad_node(state: OverallState):
return {
"a": 123 # Invalid
}
def ok_node(state: OverallState):
return {"a": "goodbye"}
# Build the state graph
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()
# Test the graph with a valid input
try:
graph.invoke({"a": "hello"})
except Exception as e:
print("An exception was raised because bad_node sets `a` to an integer.")
print(e)
from langgraph.graph import StateGraph, START, END from typing_extensions import TypedDict from pydantic import BaseModel # 图的整体状态(这是跨节点共享的公共状态) class OverallState(BaseModel): a: str 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() # 使用有效输入测试图 try: graph.invoke({"a": "hello"}) except Exception as e: print("因为 bad_node 将 `a` 设置为一个整数,所以抛出了异常。") print(e)
An exception was raised because bad_node sets `a` to an integer. 1 validation error for OverallState a Input should be a valid string [type=string_type, input_value=123, input_type=int] For further information visit https://errors.pydantic.dev/2.9/v/string_type