Новое:Talanto осенью: поиск с цифрами, вакансия по шагам и каталог компаний

+717новых вакансий за сутки·60 871вакансия открыта сейчас·Новое:Talanto осенью: поиск с цифрами, вакансия по шагам и каталог компаний

Новые вакансии в TelegramРаботодателям
Talanto
Вакансии
Компании5 951
РезюмеAIПодготовкаСтатьи
ТарифыТарифы
Войти

Не нашли подходящее?

Пусть нужная вакансия найдёт вас сама.

  1. Подборка в TelegramНовые вакансии по вашему фильтру — сразу в бота.Подключить
  2. Мэтчи по резюмеЗагрузите резюме — покажем, где вы подходите лучше всего.Загрузить
  3. Сохранить фильтрНастройте поиск один раз и возвращайтесь к новым вакансиям.Настроить
Что нового на TalantoTalanto осенью: поиск с цифрами, вакансия по шагам и каталог компаний

Для работодателей

Опубликуйте вакансию — отклики придут в ваш кабинет.

  1. Вакансиябесплатно
  2. Откликиконтакты бесплатно
  3. Наймэтапы и интервью

40 компаний публикуют вакансии напрямую · 4 391 кандидат открыт к предложениям

Разместить вакансию

Популярные направления

Все подборки
  • Python9 224
  • Облачные технологии4 076
  • QA вакансии1 588
  • Android1 322
  • Инженер данных805
  • Продакт-менеджер368

Разработка

  • Backend вакансии1 317
  • iOS1 239
  • AI вакансии608
  • Fullstack вакансии523
  • Frontend вакансии456
  • Mobile вакансии28

По стеку

  • Go5 445
  • Java3 175
  • Kotlin1 119
  • Node.js1 026
  • Rust949
  • .NET666
  • PHP311
  • C#210
  • C++204

DevOps и инфраструктура

  • DevOps вакансии2 713
  • Kubernetes2 308
  • Linux-инфраструктура1 890
  • Terraform / IaC1 406
  • CI/CD842
  • Мониторинг и Observability645
  • SRE226
  • Кибербезопасность84

Аналитика и данные

  • Аналитик данных483
  • Data Scientist469
  • Бизнес-аналитик349
  • Системный аналитик48

Другие направления

  • Проджект-менеджер139
  • UI/UX дизайн71
  • Ручное тестирование14

По регионам

  • Вакансии в США24 791
  • Вакансии в Европе9 439
  • Работа в России2 924
  • Вакансии в Канаде2 178

По формату

  • Удалённые вакансии43 505
  • Релокация в США24 791
  • Гибридная работа3 370
  • Офисная работа2 525

По уровню

  • Senior вакансии20 898
  • Middle вакансии12 438
  • Junior вакансии3 864

Сейчас нанимают

Все компании
  • Wise191 вакансия
  • Rakuten188 вакансий
  • ASML163 вакансии
  • Grab134 вакансии
  • Celonis48 вакансий
  • Spotify37 вакансий
  • Adyen28 вакансий
  • Infobip28 вакансий
  • Monzo20 вакансий
  • Darktrace17 вакансий

Вакансии из 344 источников: карьерные страницы компаний и джоб-борды.

КомпанииО насНовостиПубличная офертаУсловия использованияПолитика конфиденциальностиПоддержка
←К теме LangGraphВсе вопросы
LangGraphMiddleКодинг

Что такое функция-редуктор add_messages и как она обрабатывает обновления состояния для списков сообщений?

В закладки
Сначала попробуйте ответить сами30 секунд
Сравнить с ответом ↓

add_messages — это редуктор LangGraph для поля состояния типа list[BaseMessage]. При обновлении он дописывает новые сообщения в конец, а не заменяет весь список. Дублирование по id предотвращается автоматически.

Как подключить

Редуктор указывается через аннотацию Annotated прямо в TypedDict-схеме состояния:

from typing import Annotated
from typing_extensions import TypedDict
from langchain_core.messages import BaseMessage, HumanMessage, AIMessage
from langgraph.graph import StateGraph, START, END
from langgraph.graph.message import add_messages

class State(TypedDict):
    # add_messages будет вызываться при каждом обновлении этого поля
    messages: Annotated[list[BaseMessage], add_messages]

def chat_node(state: State) -> dict:
    last = state["messages"][-1]
    reply = AIMessage(content=f"Вы написали: {last.content}")
    # Возвращаем только новое сообщение — редуктор сам допишет его в список
    return {"messages": [reply]}

builder = StateGraph(State)
builder.add_node("chat", chat_node)
builder.add_edge(START, "chat")
builder.add_edge("chat", END)
graph = builder.compile()

# Запуск
result = graph.invoke({"messages": [HumanMessage(content="Привет!")]})
for msg in result["messages"]:
    print(type(msg).__name__, ":", msg.content)
# HumanMessage : Привет!
# AIMessage    : Вы написали: Привет!

Что такое add_messages

add_messages — встроенный редуктор (reducer) LangGraph, предназначенный для поля состояния, хранящего список сообщений (list[BaseMessage]). Вместо того чтобы перезаписывать список целиком, он добавляет новые сообщения в конец уже накопленного состояния. Если пришло сообщение с уже существующим id, редуктор заменяет старый элемент — это обеспечивает идемпотентность при повторных запусках.

Механика слияния

Внутри add_messages работает следующий алгоритм:

  1. Берётся текущий список сообщений из состояния.
  2. Для каждого нового сообщения проверяется его id.
  3. Если id уже есть — старое сообщение заменяется (upsert).
  4. Если id новый — сообщение добавляется в конец.

Это означает, что узел может исправить предыдущее сообщение, вернув объект с тем же id, но изменённым содержимым — удобно для streaming-обновлений.

Использование с MessagesState

LangGraph предоставляет готовый базовый класс MessagesState, в котором поле messages уже аннотировано редуктором:

from langgraph.graph import MessagesState

# Эквивалентно TypedDict с Annotated[list[BaseMessage], add_messages]
class MyState(MessagesState):
    summary: str  # можно добавлять свои поля

Подводные камни

  • Без аннотации — полная перезапись. Если написать просто messages: list[BaseMessage] без Annotated[..., add_messages], каждое обновление узла будет заменять весь список, а не дополнять его.
  • Возврат dict, а не полного состояния. Узел должен возвращать только изменившиеся поля ({"messages": [new_msg]}). Если вернуть state целиком с уже обновлённым полем, редуктор применится повторно и сообщения продублируются.
  • Коллизии id при ручном создании сообщений. LangChain автогенерирует уникальные id, но если создавать сообщения с явным id, легко случайно передать одинаковый id — и старое сообщение будет молча перезаписано.
  • Неожиданный рост истории. В долгих агентских петлях список сообщений растёт бесконечно. Необходимо реализовать обрезку (trim) или суммаризацию истории, иначе контекстное окно LLM переполнится.
  • Тип элемента имеет значение. Редуктор принимает как BaseMessage, так и dict-представления сообщений, однако смешивание типов может вызвать ошибки сериализации при использовании checkpointer.
  • Параллельные узлы и порядок слияния. В fan-out / fan-in топологиях несколько узлов могут одновременно возвращать сообщения. Порядок их добавления в список определяется порядком завершения узлов, что может быть недетерминированным.
  • Несовместимость с простыми типами. add_messages рассчитан только на list[BaseMessage]. Попытка применить его к list[str] или другим типам вызовет ошибку или непредсказуемое поведение.
  • Checkpointer сериализует весь список. При использовании MemorySaver или SqliteSaver в checkpoint сохраняется полная история. Большой список существенно увеличивает размер snapshot и замедляет персистентность.

Типичные ошибки

  • Объяснять add messages reducer только синтаксисом без shape, dtype, состояния или режима выполнения.
  • Игнорировать leakage, воспроизводимость, пустые входы и скрытые копии данных.
  • Не проверять production-симптомы: latency, память, ретраи, дрейф качества и несовпадение версий.

Что проверяет интервьюер

  • Может ли связать add messages reducer с реальным контрактом входов и выходов.
  • Упоминает ли тесты, метрики, reproducibility и диагностику ошибок.
  • Видит ли различие между demo-кодом в ноутбуке и production-пайплайном.

Как вы знаете этот вопрос?

Проверить себя по теме LangGraph →

Источники

  • https://docs.langchain.com/oss/python/langgraph/graph-api
←Предыдущий вопросКак LangGraph обрабатывает циклы и петли — как построить агента, который итерирует до выполнения условия?Следующий вопрос→Расскажите о случае, когда вы использовали LangGraph для pipeline, evaluation, optimization, deployment или debugging.

Связанные темы

LangGraphdata-ailanggraphllm-orchestrationtool-calling

Частые вопросы на собеседовании

  • Как LangGraph представляет состояние с помощью TypedDict и как оно передаётся между узлами?
  • Что является основной абстракцией в LangGraph — что такое nodes, edges и state?
  • Что такое LangGraph и как он расширяет LangChain для построения stateful агентских воркфлоу?
  • В каких data/AI-задачах LangGraph даёт реальный выигрыш, а где лучше выбрать другой инструмент или более простой pipeline?