Добавить в корзинуПозвонить
Найти в Дзене
Цифровой Путь

Управление состоянием в LangGraph: ошибки, которые трудно найти

Когда всё зелёное, но данные испорчены
LangGraph — популярный инструмент для создания AI-агентов. Агент — это программа, где языковая модель выполняет задачи по шагам: получает запрос, ищет информацию, обрабатывает, выдаёт ответ.
Между шагами нужно передавать данные. Это называется «состояние» (state). И именно здесь прячутся баги, которые сложно заметить.
Что идёт не так
Проблема первая: нечёткая структура данных
Многие разработчики передают данные между шагами в виде обычного словаря — без строгого описания, какие поля там есть и какого они типа. Каждый шаг пишет туда что хочет. Каждый читает что ожидает. Если ожидания не совпадают — баг. Но модель не выбрасывает ошибку — она «догадывается» и идёт дальше. Проблема всплывает позже, когда ломается что-то внешне не связанное.
Решение: использовать TypedDict — специальный инструмент Python для строгого описания структуры. Каждое поле имеет имя и тип. Если шаг пытается записать что-то не то — это видно сразу.
Проблема вторая: перез

Когда всё зелёное, но данные испорчены

LangGraph — популярный инструмент для создания AI-агентов. Агент — это программа, где языковая модель выполняет задачи по шагам: получает запрос, ищет информацию, обрабатывает, выдаёт ответ.

Между шагами нужно передавать данные. Это называется «состояние» (state). И именно здесь прячутся баги, которые сложно заметить.

Что идёт не так

Проблема первая: нечёткая структура данных

Многие разработчики передают данные между шагами в виде обычного словаря — без строгого описания, какие поля там есть и какого они типа. Каждый шаг пишет туда что хочет. Каждый читает что ожидает. Если ожидания не совпадают — баг. Но модель не выбрасывает ошибку — она «догадывается» и идёт дальше. Проблема всплывает позже, когда ломается что-то внешне не связанное.

Решение: использовать TypedDict — специальный инструмент Python для строгого описания структуры. Каждое поле имеет имя и тип. Если шаг пытается записать что-то не то — это видно сразу.

Проблема вторая: перезапись вместо дополнения

Допустим, один шаг находит три документа, другой — ещё два. Если не задать правило объединения (редьюсер), второй шаг перезапишет результаты первого. Вместо пяти документов получим два. Без ошибки, без предупреждения.

Решение: для каждого поля-списка задавать функцию, которая объединяет старые и новые значения, а не заменяет.

Проблема третья: память как свалка

Когда агент работает долго, накапливается много истории. Если вся она лежит в одной куче, модель тратит ресурсы на поиск нужного фрагмента среди десятков нерелевантных. И часто находит не тот.

Решение: разделять память по типу. Отдельно — хронология событий (что произошло и когда). Отдельно — извлечённые факты и знания. Это упрощает и работу модели, и отладку.

Почему это важно

LangGraph умеет сохранять состояние после каждого шага. Если задача прерывается — можно продолжить с последней точки. Но это работает надёжно только когда структура данных предсказуемая. Словарь с произвольными ключами — непредсказуем.

Три правила для продакшна

1. Строгая структура — TypedDict с явными типами для каждого поля
2. Редьюсеры для списков — правила объединения данных, а не перезаписи
3. Разделение памяти — хронология отдельно, факты отдельно

Эти три паттерна не усложняют код. Они делают баги видимыми сразу, а не через три часа работы агента.