Lesson 4 / 29

State Reducers: Replace or Accumulate

Control how node updates merge into the state.

Last-write-wins versus append

By default a node's returned value overwrites that state key. For keys that should accumulate (a message list, a log, collected results) you attach a reducer with Annotated[list, operator.add]: updates are combined with the reducer instead of replacing. LangGraph's own add_messages reducer does this for chat messages and also merges by message ID. Reducers matter most with parallel branches: several nodes writing the same key in one step need a reducer to define how to merge, otherwise you get an error. Decide per key whether it is "latest value" or "append".

Reducer versus overwrite, run

I ran this offline with langgraph 1.2.12 and langchain-core 1.6.6 in a Python virtual environment. No API key or model is needed because plain Python functions stand in for the model, so the output is repeatable. Both nodes return a log entry and a score. The log key has an operator.add reducer, so it accumulates both entries; score has none, so the last write (2) wins.

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

class State(TypedDict):
    log: Annotated[list, operator.add]     # reducer: updates are appended, not replaced
    score: int                              # no reducer: last write wins

def a(state): return {"log": ["a ran"], "score": 1}
def b(state): return {"log": ["b ran"], "score": 2}

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({"log": [], "score": 0}))

Output:

{'log': ['a ran', 'b ran'], 'score': 2}

Use add_messages for chat

For conversation history, Annotated[list, add_messages] appends new messages and updates existing ones by ID.

Quick check: What does a reducer on a state key do?

  • Deletes the key
  • Defines how new updates combine with the existing value
  • Compiles the graph
  • Speeds up the GPU
Answer

Defines how new updates combine with the existing value — Without a reducer the latest write replaces the old value.