How to use reducers to control how state updates are processed.
We will use messages in our examples. This represents a versatile formulation of state for many LLM applications. See our concepts page for more detail.
Sign up for LangSmith to quickly spot issues and improve the performance of your LangGraph projects. LangSmith lets you use trace data to debug, test, and monitor your LLM aps built with LangGraph — read more about how to get started in the docs.
State in LangGraph can be a TypedDict, Pydantic model, or dataclass. Below we will use TypedDict. See this guide for detail on using Pydantic.
By default, graphs will have the same input and output schema, and the state determines that schema. See this guide for how to define distinct input and output schemas.
Let's build an example graph with a single node. Our node is just a Python function that reads our graph's state and makes updates to it. The first argument to this function will always be the state:
This node simply appends a message to our message list, and populates an extra field.
Important
Nodes should return updates to the state directly, instead of mutating the state.
Let's next define a simple graph containing this node. We use StateGraph to define a graph that operates on this state. We then use add_node populate our graph.
================================[1m Human Message [0m=================================Hi==================================[1m Ai Message [0m==================================Hello!
Each key in the state can have its own independent reducer function, which controls how updates from nodes are applied. If no reducer function is explicitly specified then it is assumed that all updates to the key should override it.
For TypedDict state schemas, we can define reducers by annotating the corresponding field of the state with a reducer function.
In the earlier example, our node updated the "messages" key in the state by appending a message to it. Below, we add a reducer to this key, such that updates are automatically appended:
fromtyping_extensionsimportAnnotateddefadd(left,right):"""Can also import `add` from the `operator` built-in."""returnleft+rightclassState(TypedDict):messages:Annotated[list[AnyMessage],add]extra_field:int
================================[1m Human Message [0m=================================Hi==================================[1m Ai Message [0m==================================Hello!
================================[1m Human Message [0m=================================Hi==================================[1m Ai Message [0m==================================Hello!
This is a versatile representation of state for applications involving chat models. LangGraph includes a pre-built MessagesState for convenience, so that we can have: