LangGraph Core: Graphs, State & Control Flow: overview
- Source
- From the RAG & Agents Engineering course
- By
- Sourav Banerjee
- Last updated
- 8 Nov 2026
A LangGraph application is a state object and the functions that update it. Nodes read the state and return a partial update, a reducer per key decides how that update merges, and edges, fixed or conditional, decide which node runs next. Agentic RAG, memory and multi-agent systems later in the course are all built from these parts. The T4.3 notebooks build on four ideas: the graph and its state, the reducers that merge updates, conditional edges that route on state, and Command, which updates and routes in one return.
The running example is a Larkspur Cloud support graph over the same handbook as T5.1 to T5.3. A classify node reads the customer's question and writes a route; a conditional edge sends it to a billing, technical or human node; the handler answers from the handbook. The notebooks use their own small demos (weather, comic books, a temperature alarm), and they ship without saved outputs. Every figure and error message on these pages comes from running the notebooks' code, or small variations of it, against the installed LangGraph 1.2.18, or from the lab, which matches that version's graph on all 24 of its settings.
In short
- A
StateGraphis a schema, nodes that return partial updates, and edges fromSTARTtoEND.compile()turns it into a runnable;invokereturns the final state and starts from a fresh state every call. - Each state key can have a reducer. Without one, the last write wins. In the lab the support graph ends with 1 message and no question when nodes return only their new message, with 3 under
add_messages, and with 7 (four copies of the question) whenoperator.addmeets nodes that return the whole list. - A conditional edge calls a router after its source node and goes to the node name it returns. A name outside the destination list raises
KeyError, and the order of the router's rules decides close calls: Can I export my data after I cancel my plan? goes to billing. Command(update=..., goto=...)writes and routes in one return. ItsLiteralannotation only draws the graph; agototo a node that does not exist ends the run with a logged warning and no error.TypedDictstate is hints only, and Pydantic state validates the input atinvokebefore any node runs, though not what nodes write. Input and output schemas hide private keys; config and runtime context carry settings and dependencies that are not state.
Mental model
- The input puts “When will my refund appear on my statement?” into messages.
- The classify node reads the whole state and returns route and one new message.
- route has no reducer, so it is set; add_messages appends the message. The state holds 2 messages.
- The conditional edge reads route and names the next node, billing.
- The billing node answers from the handbook page refund-timing.
- Its answer key is set and its message appended: 3 messages, the question once.
- No edge leaves billing except the one to END, so the run returns the final state.
Every node gets the whole state and returns only the keys it changes. Between nodes the graph merges each returned key with that key's reducer, so a node never sees another node's raw return value, only the merged state. The three-way choice after classify is a conditional edge: a plain function reads route and names the next node.
Interactive lab
Reducers and the message list: open the file in a browser. Keep the refund question and set the reducer to None (overwrite): the question disappears after the first node and the billing node has nothing to answer. Switch to operator.add and let each node return the whole list: the state grows 1, 3, 7. Then pick add_messages with the same setting and watch it stay at 3. Last, try the export question and see the router send it to billing.
How it connects
- Before: T4.1 introduced chat models and message types, and T4.2 composed them into LCEL chains. A chain runs one fixed path; a
StateGraphadds shared state, branches and loops. - Next: T4.4 adds the runtime: checkpointers that save the state between steps,
interrupt()andCommand(resume=...)for human approval, and streaming. T7.1 builds the tool loop from a model node and a conditional edge, T7.3 builds its workflow patterns from reducers and routers, T9.3 routes questions between knowledge bases, and T11.1 hands work between agents withCommand.
Key Takeaways
- Decide the reducer for every key that more than one node writes. Use
add_messagesfor message lists and keep one convention for what nodes return. - Route with a plain function of state, list every destination, and give the router a fallback; the order of its rules decides the close calls.
- Use
Commandwhen a node must write and route together, and test that everygotonames a real node. - Validate input with a Pydantic state schema, narrow what callers send and receive with input and output schemas, and keep settings and dependencies out of state.