AI Hints
Home›Agentic AI Tutorial›LangGraph Agents
Agentic AI · Lesson 40 of 100

State and Reducers

How updates combine.

⏱ 2 min read▶ Video at 1:09:57🎓 Free
Watch this lesson in the Agentic AI courseWatch on YouTube ↗Full Agentic AI course

Here's a bug that catches everyone. You return a new message from a node, and your whole conversation disappears. That's because, by default, a new value replaces the old one. You've got to tell LangGraph when to combine things instead.

State and Reducers
From the video: State and Reducers
  • Your conversation disappears
  • New values replace old ones
  • Tell it when to combine

Replace or add

This state has two fields. Latest is a plain string. Log has a reducer, which is operator dot add, meaning, add new items to the list. Both nodes write to both fields. Run it. Latest was overwritten, so only b survives. But the log kept both entries. That's all a reducer is. A rule for combining updates.

reducers.pypython
import operator
from typing import Annotated, TypedDict
from langgraph.graph import StateGraph, START, END

class State(TypedDict):
    latest: str
    log: Annotated[list, operator.add]

def a(state):
    return {"latest": "from a", "log": ["a ran"]}

def b(state):
    return {"latest": "from b", "log": ["b ran"]}

g = StateGraph(State)
g.add_node("a", a)
g.add_node("b", b)
g.add_edge(START, "a")
g.add_edge("a", "b")
g.add_edge("b", END)

print(g.compile().invoke({"latest": "", "log": []}))
Output
{'latest': 'from b', 'log': ['a ran', 'b ran']}

The recursion limit

Graphs protect you from endless loops. Here, a node keeps pointing to itself, forever. We set a recursion limit of ten. Run it. It stopped with a clear error. Think of this as a seat belt. It's not a substitute for the budgets and stop rules that you learned earlier, but it means that one bad edge can't run forever.

limit.pypython
from typing import TypedDict
from langgraph.errors import GraphRecursionError
from langgraph.graph import StateGraph, START

class State(TypedDict):
    n: int

g = StateGraph(State)
g.add_node("spin", lambda s: {"n": s["n"] + 1})
g.add_edge(START, "spin")
g.add_edge("spin", "spin")
app = g.compile()

try:
    app.invoke({"n": 0}, {"recursion_limit": 10})
except GraphRecursionError:
    print("Stopped by the recursion limit after ten steps")
Output
Stopped by the recursion limit after ten steps

Designing state

Good state design makes everything easier. Keep state small, and store big files elsewhere, with only a reference in the state. Use clear types. Separate messages from business data, such as the order number and the refund amount. Then your code can read real fields, instead of parsing chat text.

Keep it smallreferences to big files
Clear typesfuture you says thanks
Business fieldsnot buried in chat
Reducersfor lists that grow

Summary

Replace by default, and combine with a reducer. Next, the feature that makes graphs worthwhile. Checkpoints.

Key takeaways
  • Default: replace
  • Reducers combine
  • Separate business data
Next up: Checkpoints — saving every step