Mastering LangGraph – State Management – 01

Mastering LangGraph - State Management - 01
Using Pydantic model as state
Previously, we might have used TypedDict the most, but Pydantic model is also a great choice. Let’s see how this type can serve as the graph state.
Input Validation
from langgraph.graph import StateGraph, START, END
from typing_extensions import TypedDict
from pydantic import BaseModel

# Overall state of the graph (this is the shared public state between nodes)
class OverallState(BaseModel):
    a: str

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

# Build 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 valid input
graph.invoke({"a": "hello"})
When we inherit from BaseModel in OverallState, and define the property a as a str type, if our input is correct, it will output:
{'a': 'goodbye'}
If we do this:
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)
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.10/v/string_type
As we can see, it acts as a form of input validation.
Multiple nodes
Runtime validation also applies to multi-node graphs. In the example below, bad_node will update a to an integer.
Since runtime validation occurs on the input, a validation error will occur when calling ok_node (rather than when bad_node returns a state update inconsistent with the model).
from langgraph.graph import StateGraph, START, END
from typing_extensions import TypedDict
from pydantic import BaseModel

# Overall state of the graph (this is the shared public state between nodes)
class OverallState(BaseModel):
    a: str

def bad_node(state: OverallState):
    return {"a": 123  # Invalid}

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

# Build 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 valid input
try:
    graph.invoke({"a": "hello"})
except Exception as e:
    print("An exception was raised because bad_node set `a` to an integer.")
    print(e)
Note that it will raise an error during conversion, rather than discovering the type mismatch during the update.

Leave a Comment