langgraph-state
LangGraph state management patterns. Use when designing workflow state schemas, using TypedDict vs Pydantic, implementing accumulating state with Annotated operators, or managing shared state across nodes.
$ 安裝
git clone https://github.com/yonatangross/skillforge-claude-plugin /tmp/skillforge-claude-plugin && cp -r /tmp/skillforge-claude-plugin/.claude/skills/langgraph-state ~/.claude/skills/skillforge-claude-plugin// tip: Run this command in your terminal to install the skill
name: langgraph-state description: LangGraph state management patterns. Use when designing workflow state schemas, using TypedDict vs Pydantic, implementing accumulating state with Annotated operators, or managing shared state across nodes. context: fork agent: workflow-architect
LangGraph State Management
Design and manage state schemas for LangGraph workflows.
When to Use
- Designing workflow state schemas
- Choosing TypedDict vs Pydantic
- Multi-agent state accumulation
- State validation and typing
TypedDict Approach (Simple)
from typing import TypedDict, Annotated
from operator import add
class WorkflowState(TypedDict):
input: str
output: str
agent_responses: Annotated[list[dict], add] # Accumulates
metadata: dict
MessagesState Pattern (2026 Best Practice)
from langgraph.graph import MessagesState
from langgraph.graph.message import add_messages
from typing import Annotated
# Option 1: Use built-in MessagesState (recommended)
class AgentState(MessagesState):
"""Extends MessagesState with custom fields."""
user_id: str
context: dict
# Option 2: Define messages manually with add_messages reducer
class CustomState(TypedDict):
messages: Annotated[list, add_messages] # Smart append/update by ID
metadata: dict
Why add_messages matters:
- Appends new messages (doesn't overwrite)
- Updates existing messages by ID
- Handles message deduplication automatically
Note:
MessageGraphis deprecated in LangGraph v1.0.0. UseStateGraphwith amessageskey instead.
Pydantic Approach (Validation)
from pydantic import BaseModel, Field
class WorkflowState(BaseModel):
input: str = Field(description="User input")
output: str = ""
agent_responses: list[dict] = Field(default_factory=list)
def add_response(self, agent: str, result: str):
self.agent_responses.append({"agent": agent, "result": result})
Accumulating State Pattern
from typing import Annotated
from operator import add
class AnalysisState(TypedDict):
url: str
raw_content: str
# Accumulate agent outputs
findings: Annotated[list[Finding], add]
embeddings: Annotated[list[Embedding], add]
# Control flow
current_agent: str
agents_completed: list[str]
quality_passed: bool
Key Pattern: Annotated[list[T], add]
- Without
add: Each node replaces the list - With
add: Each node appends to the list - Critical for multi-agent workflows
Custom Reducers
from typing import Annotated
def merge_dicts(a: dict, b: dict) -> dict:
"""Custom reducer that merges dictionaries."""
return {**a, **b}
class State(TypedDict):
config: Annotated[dict, merge_dicts] # Merges updates
def last_value(a, b):
"""Keep only the latest value."""
return b
class State(TypedDict):
status: Annotated[str, last_value] # Overwrites
State Immutability
def node(state: WorkflowState) -> WorkflowState:
"""Return new state, don't mutate in place."""
# Wrong: state["output"] = "result"
# Right:
return {
**state,
"output": "result"
}
Key Decisions
| Decision | Recommendation |
|---|---|
| TypedDict vs Pydantic | TypedDict for internal state, Pydantic at boundaries |
| Messages state | Use MessagesState or add_messages reducer |
| Accumulators | Always use Annotated[list, add] for multi-agent |
| Nesting | Keep state flat (easier debugging) |
| Immutability | Return new state, don't mutate |
2026 Guidance: Use TypedDict inside the graph (lightweight, no runtime overhead). Use Pydantic at boundaries (inputs/outputs, user-facing data) for validation.
Common Mistakes
- Forgetting
addreducer (overwrites instead of accumulates) - Mutating state in place (breaks checkpointing)
- Deeply nested state (hard to debug)
- No type hints (lose IDE support)
Related Skills
langgraph-routing- Using state for routing decisionslanggraph-checkpoints- State persistencetype-safety-validation- Pydantic patterns
Capability Details
state-definition
Keywords: StateGraph, TypedDict, state schema, define state Solves:
- Define workflow state with TypedDict
- Create Pydantic state models
- Structure agent state properly
state-channels
Keywords: channel, Annotated, state channel, MessageChannel Solves:
- Configure state channels for data flow
- Implement message accumulation
- Handle channel-based state updates
state-reducers
Keywords: reducer, add_messages, operator.add, accumulate Solves:
- Implement state reducers with Annotated
- Accumulate messages across nodes
- Handle state merging strategies
subgraphs
Keywords: subgraph, nested graph, parent state, child graph Solves:
- Compose graphs with subgraphs
- Pass state between parent and child
- Implement modular workflow components
state-persistence
Keywords: persist, state persistence, durable state, save state Solves:
- Persist state across executions
- Implement durable workflows
- Handle state serialization
Repository
