Суть
Когда узел возвращает {"field": value}, движок должен решить: заменить старое значение или объединить. Это решение и есть reducer. Без reducer'а — перезапись. С reducer'ом — произвольная логика слияния (добавление в список, суммирование, дедупликация).
Зачем это нужно
Самый частый случай — история сообщений. Чат-бот не должен перезаписывать прошлые сообщения новым; их надо накапливать. Перезапись здесь потеряла бы весь диалог. Reducer add (или специальный add_messages) дописывает новое в конец списка вместо замены.
Как работает
- Синтаксис:
Annotated[<тип поля>, <reducer-функция>]. Reducer получает старое и новое значение, возвращает объединённое. - Готовые reducer'ы:
operator.add(конкатенация списков/сложение чисел),langgraph.graph.message.add_messages(умное слияние сообщений с учётом id). - Можно задать кастомную логику — обычную функцию или лямбду.
- Поле без
Annotated→ поведение по умолчанию: перезапись.
Пример
from typing import TypedDict, Annotated
from operator import add
from langgraph.graph.message import add_messages
class State(TypedDict):
simple_value: str # перезапись
numbers: Annotated[list, add] # накопление списка
total: Annotated[int, lambda x, y: x+y] # кастомная логика
messages: Annotated[list, add_messages] # история диалога
Связано с
- LangGraph State — reducer'ы — это правила обновления полей State
- LangGraph — часть базового механизма State Machine
- Context Window — накопление
messages↔ рост контекста, требует управления
Открытые вопросы
-
addvsadd_messages— когда важно умное слияние по id (дедуп, обновление сообщений)