Nodes
Nodes are the units of computation in LangGraph. This article covers every node type — function, ToolNode, Command, deferred — plus node-level caching, pre/post model hooks, failure modes, and how to test nodes in isolation.
Quick Reference
- →Function node: any (state) -> dict function added via graph.add_node()
- →ToolNode: pre-built node that executes AIMessage tool_calls — from langgraph.prebuilt
- →Command node: return Command(goto='name', update={...}) to route from inside a node
- →Deferred node: waits for all upstream parallel branches before running — @defer decorator
- →Node caching: add_node('name', fn, cache_policy=CachePolicy(ttl=120)) — from langgraph.types
- →Pre/post hooks: pre_model_hook and post_model_hook on create_react_agent for context control
- →Nodes return partial state — only changed keys, merged into full state by reducers
What Is a Node
START → Agent → Tools → Agent (loop) → END
A node is any callable — sync or async — that receives the current graph state and returns a partial state update. LangGraph calls it, takes the returned dict, and merges it into the full state via reducers. That is the entire contract. Everything else — routing, caching, tool execution — is built on top of this.
Node lifecycle: full state in → cache check → node fn (with pre/post hooks) → partial dict → reducer merge
Before a node runs, LangGraph checks whether a cache hit exists (if you configured CachePolicy). If the node runs, any pre_model_hook fires first, then the node function, then any post_model_hook. The node returns a partial dict. Reducers merge it into the full state. If the node throws an unhandled exception, the graph fails — there is no automatic retry at the node level.