langgraph-subgraphs
SKILL.md
LangGraph Subgraphs
Compose modular, reusable workflow components with nested graphs.
Two Primary Patterns
Pattern 1: Invoke from Node (Different Schemas)
Use when subgraph needs completely isolated state.
from langgraph.graph import StateGraph, START, END
# Parent state
class ParentState(TypedDict):
query: str
analysis_result: dict
# Subgraph state (completely different)
class AnalysisState(TypedDict):
input_text: str
findings: list[str]
score: float
# Build subgraph
analysis_builder = StateGraph(AnalysisState)
analysis_builder.add_node("analyze", analyze_node)
analysis_builder.add_node("score", score_node)
analysis_builder.add_edge(START, "analyze")
analysis_builder.add_edge("analyze", "score")
analysis_builder.add_edge("score", END)
analysis_subgraph = analysis_builder.compile()
# Parent node that invokes subgraph
def call_analysis(state: ParentState) -> dict:
"""Transform state at boundaries."""
# Map parent → subgraph state
subgraph_input = {"input_text": state["query"], "findings": [], "score": 0.0}
# Invoke subgraph
subgraph_output = analysis_subgraph.invoke(subgraph_input)
# Map subgraph → parent state
return {
"analysis_result": {
"findings": subgraph_output["findings"],
"score": subgraph_output["score"]
}
}
# Add to parent graph
parent_builder = StateGraph(ParentState)
parent_builder.add_node("analysis", call_analysis)
Pattern 2: Add as Node (Shared State)
Use when parent and subgraph share state keys.
from langgraph.graph.message import add_messages
# Shared state with messages channel
class SharedState(TypedDict):
messages: Annotated[list, add_messages]
context: dict
# Subgraph uses same state
agent_builder = StateGraph(SharedState)
agent_builder.add_node("think", think_node)
agent_builder.add_node("act", act_node)
agent_builder.add_edge(START, "think")
agent_builder.add_edge("think", "act")
agent_builder.add_edge("act", END)
agent_subgraph = agent_builder.compile()
# Add compiled subgraph directly as node
parent_builder = StateGraph(SharedState)
parent_builder.add_node("agent_team", agent_subgraph) # Direct embedding
parent_builder.add_edge(START, "agent_team")
parent_builder.add_edge("agent_team", END)
When to Use Each Pattern
| Pattern | Use When |
|---|---|
| Invoke | Different schemas, private message histories, multi-level nesting |
| Add as Node | Shared state keys, agent coordination, message passing |
Multi-Level Nesting
# Grandchild subgraph
grandchild = grandchild_builder.compile()
# Child subgraph (contains grandchild)
def call_grandchild(state: ChildState):
result = grandchild.invoke({"data": state["input"]})
return {"processed": result["output"]}
child_builder.add_node("processor", call_grandchild)
child = child_builder.compile()
# Parent (contains child)
def call_child(state: ParentState):
result = child.invoke({"input": state["query"]})
return {"result": result["processed"]}
parent_builder.add_node("child_workflow", call_child)
Checkpointing Strategies
Parent-Only (Recommended)
from langgraph.checkpoint.postgres import PostgresSaver
checkpointer = PostgresSaver.from_conn_string(DATABASE_URL)
# Checkpointer propagates to all subgraphs automatically
parent = parent_builder.compile(checkpointer=checkpointer)
Independent Subgraph Memory
# Subgraph maintains its own checkpoint history
# Useful for agent message histories that should persist independently
agent_subgraph = agent_builder.compile(checkpointer=True)
# Parent with its own checkpointer
parent = parent_builder.compile(checkpointer=PostgresSaver(...))
State Mapping Best Practices
def call_subgraph_with_mapping(state: ParentState) -> dict:
"""Explicit state transformation at boundaries."""
# 1. Extract relevant data from parent
subgraph_input = {
"query": state["user_query"],
"context": state.get("context", {}),
"history": [] # Subgraph has own history
}
# 2. Invoke with config propagation
config = get_runnable_config()
result = subgraph.invoke(subgraph_input, config)
# 3. Transform output back to parent schema
return {
"subgraph_result": result["output"],
"metadata": {
"subgraph": "analysis",
"steps": result.get("step_count", 0)
}
}
Streaming & Inspection
# Stream with subgraph visibility
for namespace, chunk in graph.stream(inputs, subgraphs=True, stream_mode="updates"):
depth = len(namespace)
prefix = " " * depth
print(f"{prefix}[{'/'.join(namespace) or 'root'}] {chunk}")
# Inspect subgraph state (only works when interrupted)
config = {"configurable": {"thread_id": "thread-1"}}
state = graph.get_state(config, subgraphs=True)
# Access nested state
for subgraph_state in state.tasks:
print(f"Subgraph: {subgraph_state.name}")
print(f"State: {subgraph_state.state}")
Key Decisions
| Decision | Recommendation |
|---|---|
| Schema design | Shared for coordination, isolated for encapsulation |
| Checkpointing | Parent-only unless agents need independent history |
| State mapping | Explicit transforms at boundaries for clarity |
| Team development | Each team owns their subgraph with defined interface |
Common Mistakes
- Not transforming state at boundaries (schema mismatch errors)
- Forgetting to propagate config for tracing/checkpointing
- Using shared state when isolation is needed
- Missing
subgraphs=Truewhen streaming nested graphs
Evaluations
See references/evaluations.md for test cases.
Related Skills
langgraph-streaming- Stream updates from subgraphslanggraph-supervisor- Subgraphs as workers in supervisor patternslanggraph-checkpoints- Cross-subgraph checkpointing strategieslanggraph-state- State schema mapping between graphslanggraph-parallel- Parallel subgraph executionlanggraph-functional- Subgraphs with Functional API
Capability Details
invoke-pattern
Keywords: invoke, different schema, isolated state, transform Solves:
- Embed graphs with different state schemas
- Isolate subgraph state from parent
- Transform data at graph boundaries
add-as-node-pattern
Keywords: add_node, shared state, messages, coordination Solves:
- Embed graphs with shared state
- Coordinate agents via message passing
- Build multi-agent systems
nested-graphs
Keywords: nested, multi-level, parent, child, grandchild Solves:
- Build deeply nested graph hierarchies
- Compose complex workflows from simple parts
- Implement recursive graph patterns
subgraph-checkpointing
Keywords: checkpoint, memory, independent, propagate Solves:
- Configure checkpointing for subgraphs
- Maintain independent agent histories
- Handle persistence in nested structures
Weekly Installs
6
Repository
yonatangross/orchestkitGitHub Stars
94
First Seen
Feb 6, 2026
Security Audits
Installed on
claude-code5
opencode4
github-copilot4
gemini-cli4
codex3
antigravity3