Zenaique

Fill in the LangGraph reducer choices for three classic state fields

Fill in blank·Medium·4.0 · 0·~1 min·Asked atKore AiSiemensYellow Ai
Attempt it
In a LangGraph parallel fan out, the messages field typically uses a(n) reducer so every worker's contribution is kept; the status field typically uses a(n) reducer so the latest write wins; and a search_hits field that may include duplicates across workers typically uses a custom reducer that combines and dedupes.
TL;DR

Append for messages so every worker's output survives, overwrite (last write wins) for status so the latest scalar wins, custom merge and dedup for hits that may duplicate across workers.

Memory aid
Sign in to see the mnemonic that makes this stick.
Easy to grasp

Think of a group homework assignment. Three students each work on a piece and email their work to the teacher. The teacher needs different rules for different things. For the actual essay paragraphs, the teacher staples every student's contribution into one document; nothing is dropped. For the cover sheet that says how far along the team is, the teacher only keeps the most recent version; the earlier cover sheets are outdated. For the bibliography, the teacher merges all three lists and removes duplicate sources, because two students may have cited the same paper. LangGraph's reducers are these three rules in code: append, overwrite, and custom merge with dedupe.

Concept explanation~2 min read

Everything you need to truly understand this topic: intuition, mechanics, step by step explanation, code, formulas, and worked example. Click to expand.

LangGraph's typed-state model is one of the cleaner abstractions in the agent-framework space, and reducers are the core primitive that makes parallel fan-out behave predictably. A reducer is a function that combines the previous value of a state field with a new write to produce the next value. When N workers write to the same field concurrently, the reducer runs once per write and the field ends up with the accumulated result.

Different fields need different reducers because their semantics differ. A messages list wants every contribution; a scalar status wants the most recent value; a deduped result set wants set union. Getting the reducer choice right per field is the difference between a graph that scales cleanly to more workers and a graph that loses contributions, leaks memory, or breaks replay.

This deep dive walks the three canonical reducer choices for the three semantic classes of state fields, the LangGraph annotation syntax that wires them in, the commutativity and idempotency requirements that make reducers safe under parallelism and replay, and the failure modes that hit graphs in production when the reducer choice is wrong.

The three semantic classes and their reducers

Accumulating fields are lists where every worker's contribution should survive. The canonical example is messages, a list of conversation messages that grows as workers contribute outputs. The reducer is append: take the previous list, take the new write (also a list), concatenate. The Python implementation is operator.add for plain lists. For LangChain message objects the preferred reducer is add_messages, which is smarter than plain addition because it matches messages by their id field: if a worker writes a message with the same ID as an existing one, the existing message is updated in place rather than duplicated. This ID-matching property is what saves the messages list from doubling under retry or LangGraph's replay model.

Scalar progress fields are single values where the most recent write should win. Examples include status ("in_progress" or "complete"), current_phase, error_code. The reducer is overwrite: take the new write, discard the old value. LangGraph's default behaviour on a state key without an explicit reducer annotation IS overwrite, so the canonical way to express this is to leave the field un-annotated in the TypedDict or Pydantic model. The trap is reflexive over-annotation: if you write Annotated[str, operator.add] on a status field out of habit, the field silently converts to a concatenated string and downstream consumers expecting state.status == 'complete' start failing in confusing ways.

Set-valued fields are collections where duplicate entries should be merged. Examples include search_hits (each item identified by URL), retrieved_documents (each item identified by doc ID), candidate_solutions (each identified by content hash). The reducer is custom merge and dedup: union the two collections and remove duplicates using a domain-specific identity key. LangGraph does not ship this reducer because the dedup key varies per field. You write the function and annotate the state field with it.

The LangGraph annotation syntax
Commutativity and idempotency: the contract reducers must honour
Production failure modes and how to avoid them
Sign in to unlock the full deep dive.

Situations where this technique stops working.

Sign in to see when this approach fails.

2–4 min · Everything important, quickly.

Sign in to see the quick scan of the deep dive.

Real products, models, and research that use this idea.

  • LangGraph's add_messages reducer matches message IDs to update messages in place, preventing duplicates under replay.
  • LangGraph's Send primitive fans out concurrent worker invocations, with the reducer running on the joined outputs.
Sign in to see more production examples.

What an interviewer would ask next. Try answering before peeking at the approach.

QWhy must a reducer be commutative in a parallel fan-out, and what is the concrete failure mode if it is not?
A

Parallel workers complete in non-deterministic order. A non-commutative reducer produces different state depending on which worker's output arrives first, which makes the same graph run produce different results on replay and breaks deterministic debugging. The concrete failure mode is a flaky test that passes locally and fails in CI because the worker arrival order changed.

2 more follow-ups an interviewer would ask next. Sign in to reveal them.

Red flags & common mistakes

The phrases that signal junior thinking. Click to expand.

Most common mistake

Defaulting every state field to append, which silently turns scalar status fields into ever-growing lists and breaks downstream consumers expecting a single value.

Sign in to see all red flags and common mistakes.

60 second bullets to scan on the way to the call.

  • Name the three semantic classes of state fields and the reducer each one wants

  • Explain why the default no-reducer behaviour on a scalar is overwrite

Sign in to unlock the revision sheet.

Primary sources. Browse if you want the original framing.

Similar questions

Same topic, related formats. Practice these next.

4 curated
Next question
Why AutoGen 0.4 makes TerminationCondition a first class primitive instead of leaving it to convention
Flashcard·Medium