Skip to main content
Not every branch or component in a LangGraph needs the same state shape. As graphs grow, reusing components or composing subgraphs with different data requirements becomes essential. Handling multiple state schemas lets each part of the graph declare the fields it requires without forcing a one-size-fits-all global state.
The image is a flowchart titled "Why Multiple State Schemas?" showing a process starting from a "Start" node, branching into three components (A, B, C) with corresponding states, leading to sub-branches (X, Y), and ending at an "End" node.
For example, a summarization branch might track paragraphs and topic scores, while a QA branch stores citations and tool logs. Forcing all branches to conform to a single schema makes components heavier and harder to reuse. Instead, define the schema that each subgraph or node needs and keep global state optional where components intersect.
The image is a workflow graph illustrating the disadvantages of using a global schema across multiple components, where only Component A benefits, while Components B and C do not.
Why use multiple schemas? They let you:
  • Document assumptions per module.
  • Catch schema mismatches early via typing and tests.
  • Reason locally about each node’s inputs and outputs.
  • Reuse subgraphs across different parent graphs with confidence.
The image is a diagram titled "What Are Multiple Schemas?" showing a workflow graph with subgraphs for retrieval and summarizer, connected through state schemas and type state structures.
Analogy: imagine Ravi carries different forms for deliveries — one for medical items, another for food, another for paperwork — each form contains fields tailored to the task. The same applies to graph state: each subgraph should own the fields it requires.
The image explains "What Are Multiple Schemas?" featuring three points: clear assumptions, early error detection, and local reasoning per node.
When your system handles multiple flows (e.g., summarization and translation), you may share some common fields (like input and response) while each branch tracks its own specialized fields. Keeping separate TypedDicts for these subgraphs clarifies those differences and makes it safe to reuse branches across other graphs. It also helps agents and routers dynamically adapt to context.
The image is a diagram titled "What Are Multiple Schemas?" illustrating two categories: "Medical Delivery" and "Food Delivery," each with specific attributes listed below them.
Practical patterns
  • Local schemas: give each subgraph or node its own TypedDict that documents required and optional fields.
  • Composed parent state: the parent graph can accept a broader GraphState with many total=False fields so subgraphs can coexist.
  • Adapter (transition) nodes: map one schema to another when composing subgraphs.
  • Type guards: verify runtime state before assuming fields are present.
Example typed declarations (useful for IDEs and static checks):
Subgraphs: isolate functionality and preserve contracts A subgraph is a small, self-contained graph with its own state schema. Use subgraphs to encapsulate search, summarization, validation, or any reusable logic.
This example shows a SearchState that requires query but treats search_results as optional. Compile the subgraph and reuse it inside multiple parent graphs. Subgraphs make it easy to test and swap implementations without touching the outer workflow. Adapters: translate state between schemas When composing subgraphs with different schemas, use small adapter nodes to map one shape to another. Adapters perform renames, conversions, enrichments, or cleanup.
Register adapters like any other node (e.g., graph.add_node("adapter", adapter_fn)) and connect them between subgraphs. Adapters are particularly valuable when integrating components from different teams or when evolving schemas over time. Runtime vs static checks: use type guards TypedDicts are development-time tools; at runtime the state is a plain dictionary. Protect nodes that expect specific fields with explicit type guards:
Use guards inside routers or nodes to branch safely and avoid KeyError exceptions. You can create stricter guards that check types with isinstance or raise informative errors when a state is malformed.
Type hints and TypedDicts improve clarity and tooling support. Always validate runtime assumptions with explicit guards or adapter nodes when composing independent subgraphs.
Benefits of multiple schemas
The image outlines the benefits of using multiple schemas: local clarity and simplicity, increased reusability, and easier debugging and maintenance.
  • Local clarity: each node/subgraph documents exactly what it needs.
  • Reusability: isolate functionality, then reuse across projects.
  • Easier debugging: smaller, focused schemas reduce search space for bugs.
  • Safe evolution: change a subgraph’s schema without breaking unrelated branches.
Quick reference table Further reading and references Summary Treat schemas as local contracts for subgraphs and nodes. Use TypedDict and type hints to improve developer experience, introduce adapters to translate state between modules, and protect runtime behavior with explicit type guards. This approach keeps LangGraph workflows modular, easier to reason about, and safer to evolve over time.

Watch Video