Почему линейные цепочки вызовов ломаются, а LangGraph — нет
Линейная цепочка вызовов выглядит надёжно, пока сценарий короткий: шаг, ещё шаг, ответ. Как только появляется ветвление — «если данных не хватает, уточни у пользователя» — код превращается в дерево условий, а состояние агента размазывается по локальным переменным и промежуточным словарям. Добавьте цикл вроде «переспросить и дождаться подтверждения», и отслеживание того, на каком шаге мы находимся, становится отдельной задачей.
Хуже всего ведёт себя сбой посреди сценария. Процесс упал на пятом шаге из десяти — и повторный запуск шага заново выполняет то, что уже прошло: письмо уходит второй раз, карточка в CRM создаётся дублем, внешний счётчик увеличивается повторно. Точки возврата нет, поэтому восстановление сводится к полному прогону с нуля.
LangGraph меняет модель исполнения: сценарий описывается как граф узлов и переходов, а состояние агента становится явной структурой, которую каждый узел читает и дописывает. Состояние фиксируется после каждого перехода — после сбоя сценарий продолжается с последнего успешного узла, а ветвления и циклы выражаются обычными рёбрами графа, а не вложенными условиями.
Дальше разбираем, как это закрывается на практике: где живёт состояние, как устроены точки сохранения и как выглядит повторный запуск шага после падения.
Что даёт LangGraph: измеримый эффект графовой оркестрации
Графовая оркестрация отличается от линейной цепочки тем, что каждый шаг — отдельный узел с явными входами и выходами, а состояние живёт вне модели. Сбой шага поэтому не рушит весь прогон: агент возвращается к последней сохранённой контрольной точке и повторяет только упавший узел — восстановление занимает секунды вместо перезапуска сценария с нуля.
Отсюда первый измеримый эффект — доля сценариев, доведённых до конца. Там, где одиночный вызов модели обрывался на недоступном сервисе или неполном ответе, граф доходит до финального шага в 90+% случаев: неудачный узел повторяется, а уже собранные данные не теряются. Резервная ветка описывается тем же способом, что и основная.
Второй эффект — переиспользование ветки. Новая логика (проверка входных данных, передача оператору, другой источник сведений) добавляется как узел и связь, а не как правка всего сценария: типовое расширение закрывается за один-два дня инженерной работы вместо переписывания половины логики и повторной отладки.
Третий — наблюдаемость агента, которая снимает главную боль поддержки: «ответ неверный, непонятно где». Каждый переход между узлами протоколируется, видно, на каком шаге потерялся контекст, сколько занял вызов и где сработал резервный путь. Инцидент разбирается по журналу прогона, а не воспроизведением вслепую.
Технически это даёт LangGraph — контрольные точки состояния, повтор шага и ветвление встроены, не нужно достраивать их вокруг вызовов модели.
Режимы исполнения графа: сравнение подходов
Режим исполнения определяет, где принимается решение о следующем шаге — внутри одного вызова модели, в жёстком сценарии или в узле графа. От этого зависит воспроизводимость ответа и то, насколько быстро локализуется сбой. Ниже — четыре варианта, между которыми выбирают на старте.
| Вариант оркестрации | Когда подходит | Что ограничивает |
|---|---|---|
| Один большой вызов модели | Короткий сценарий без ветвлений: разобрать запрос и вернуть структурированный ответ | Нет промежуточного контроля — ошибку в середине рассуждения видно только в финале |
| Жёсткая цепочка шагов | Регламент известен заранее и меняется редко | Отклонение от сценария ломает всю цепочку, ветвления приходится писать условиями в коде |
| Граф с общим состоянием | Многотуровые задачи: сбор данных, проверка, возврат на шаг назад | Нужна дисциплина в описании состояния, иначе граф читается хуже линейного сценария |
| Внешний диспетчер задач | Долгие процессы и параллельные ветки, переживающие перезапуск | Добавляется слой инфраструктуры, который надо сопровождать и синхронизировать с логикой |
Ключевое отличие графа — состояние живёт между шагами: узел получает накопленный контекст, а не только последнее сообщение. Это позволяет вернуть задачу на предыдущий шаг, если проверка не прошла, и не пересказывать модели всю историю заново. Так устроен LangGraph: маршрутизация между узлами описана явно, а не выводится моделью на ходу.
Чистые варианты встречаются реже гибрида: диспетчер держит очередь и повторные запуски, а решение о следующем шаге принимает граф. Схему фиксируем до разработки — сразу видно, где заканчивается логика агента и начинается инфраструктура.
Этапы внедрения LangGraph в работающий сервис
Внедрение графа не означает переписывание сервиса: мы расширяем существующую логику, оставляя рабочие маршруты как резервные. Каждый этап заканчивается артефактом, который можно проверить до перехода к следующему.
- Разбор текущих сценариев. Фиксируем, где сервис уже принимает решения: ветвления, обращения к внешним системам, места, где обязателен человек. На выходе — карта процессов с явными входами, выходами и точками отказа.
- Схема графа. Определяем узлы, переходы, условия остановки и состояние, которое переносится между шагами. Схему согласуем до кода — на ней сразу видны циклы, тупики и сценарии, где агент может зациклиться.
- Перенос логики. Существующие проверки, лимиты и вызовы сервисов становятся узлами графа; правила валидации сохраняются. Старый маршрут остаётся рабочим, чтобы переключение было обратимым.
- Проверка агента на реальных данных. Прогоняем исторические обращения с известным результатом и считаем долю верных решений. Расхождения разбираем по шагам: видно, какой именно узел или переход дал ошибку.
- Прогон под нагрузкой. Смотрим поведение на потоке, близком к боевому: время ответа, повторы, расход на дорогие вызовы. Здесь же настраиваем ограничители и правила отката к прежней логике.
- Передача в эксплуатацию. Отдаём схему графа, конфигурацию, журналы прогонов и инструкцию по правке узлов. Отдельно описываем, что видно в мониторинге и по каким признакам команда понимает, что агент отклонился от ожидаемого поведения.
Такой порядок даёт предсказуемый переход: сначала логика, потом проверка на реальных данных, и только затем нагрузка и эксплуатация.
Что передаём на руки: графы, политики, документация
Проект считается сданным не тогда, когда агент отвечает на подготовленном примере, а когда ваша команда может сама поменять поведение отдельного шага, не разбирая код заново. Поэтому в передачу входит комплект артефактов: от карты графа до регламента выпуска. Ниже — что именно остаётся у заказчика после интеграции LangGraph.
- Описание графа и карта состояний — схема узлов, переходов и условий ветвления, с пометками, какие данные накапливаются по ходу выполнения и на каком шаге агент останавливается.
- Контракты узлов — форматы входа и выхода каждого шага, обязательные поля, поведение при пустом или некорректном ответе модели, таймауты и число повторов.
- Правила доступа к внешним системам — какие учётные записи нужны, где хранятся ключи и как они обновляются, что агент только читает, а куда ему разрешено писать.
- Регламент выпуска изменений — как правка логики узла или инструкции для модели проходит проверку на наборе сценариев и попадает в рабочую версию.
- Мониторинг и разбор инцидентов — какие события фиксируются, как отличить сбой внешнего сервиса от ошибки маршрутизации и как вернуть граф к предыдущей версии.
- Документация агента для поддержки — инструкции простым языком: что делать при типовом сбое, куда смотреть в первую очередь, где границы ответственности команды.
- Набор проверочных сценариев — задачи с ожидаемым результатом, по которым прогоняют сборку после каждой правки.
Кейс: агент обработки заявок перестал падать
У заказчика — сервисная компания с несколькими тысячами обращений в неделю — агент на LangGraph разбирал входящие заявки: вытягивал реквизиты из письма, сверял их с базой клиентов, готовил ответ и передавал данные в учётную систему. Ломалось не качество ответов, а устойчивость сценария.
Отказ шага агента — недоступный внешний сервис, обрыв соединения, неожиданный формат поля — валил весь прогон. Заявка зависала в неопределённом состоянии, оператор разбирал её руками, а восстановление сценария после отказа занимало часы. Доля заявок, доведённых до конца без вмешательства, держалась около 60%.
Мы перевели обработку в явный граф состояний: у каждого шага появилась точка сохранения, ограниченное число повторов и признак невосстановимого отказа. Ошибка узла больше не откатывает весь прогон — агент возвращается к последнему сохранённому состоянию и продолжает с того же места либо передаёт заявку оператору вместе с уже собранным контекстом.
Метрики до и после
| Метрика | До | После |
|---|---|---|
| Заявки, доведённые до конца без оператора | ~60% | 94% |
| Возврат сценария после отказа шага | вручную, часы | автоматически, секунды |
| Ручные доработки логики обработки | каждую неделю | раз в квартал |
Побочный эффект оказался не менее важным: когда часть отказов закрывается повтором, а часть — корректной передачей оператору с контекстом, инженеры правят причину, а не следствие. Объём ручных доработок логики падает по той же причине — новые ветки добавляются в граф, не ломая уже работающие.
LangGraph или собственный оркестратор на функциях?
Короткий ответ: пока сценарий линеен, свой оркестратор из обычных функций дешевле и в разработке, и в поддержке. Графовая библиотека вроде LangGraph окупается там, где появляются ветвления, циклы и возобновление выполнения с середины.
Самописный диспетчер — это цепочка вызовов, где состояние лежит в одном словаре и передаётся от шага к шагу. Два-четыре шага, один внешний сервис, простая обработка ошибок: такой код читается целиком и не требует, чтобы команда знала чужую модель исполнения. Стоимость поддержки здесь близка к нулю — правка порядка шагов не ломает ничего вокруг.
Проигрывать самописное начинает, когда появляются развилки по результату шага, параллельные ветки, цикл уточнения и пауза до ответа пользователя. Тогда приходится самим реализовывать обход, хранить контрольные точки состояния, повторять упавшие шаги без дублей и ограничивать число итераций. Это уже небольшой движок — с его тестами, отладкой и документацией для новых разработчиков.
Критерий выбора простой: если схема помещается на один лист, состояний немного и возвратов назад нет — берите функции. Если есть циклы, развилки, длинные задачи с ожиданием внешнего события или участием оператора — граф даёт устойчивость, которую иначе пишут руками.
Стоимость поддержки расходится на горизонте: самописное дешевле на старте и дороже с каждым новым требованием, графовая схема — наоборот. Переход при этом не переписывает логику: узлы остаются обычными функциями, меняется только слой маршрутизации между ними.
Технические сомнения перед стартом интеграции
Инженеров, которые поведут интеграцию, редко интересует общая выгода — они спрашивают, что станет с уже работающим агентом. Ниже пять вопросов, которые звучат до старта переноса на LangGraph, и наши ответы на них — чтобы объём работ был понятен заранее.
Придётся ли переписывать логику текущего агента?
Нет. Вызовы модели, обращения к базе и внешним сервисам остаются прежними — меняется связь между шагами: вместо жёсткой цепочки появляются узлы и явные переходы.
Что происходит с состоянием при переходе между шагами?
Состояние — общий объект, который каждый шаг получает и дополняет. В любой момент видно, что агент знал и на что опирался в момент решения.
Можно ли продолжить прерванный запуск, а не начинать заново?
Да. Контрольные точки сохраняются после каждого узла, поэтому повторные запуски не перепроходят выполненные шаги и не дублируют обращения к внешним сервисам.
Как добавить новую ветку, не ломая живую систему?
Новый узел ставится рядом со старыми, прежний маршрут остаётся рабочим. Ветка включается флагом на части запросов, откат — переключением обратно.
Как разобрать, почему агент принял именно это решение?
Пошаговый журнал: какой узел вызван, что вошло в состояние и что вышло. Расхождение видно на конкретном шаге, а не в общем логе — разбор перестаёт быть гаданием.
Если сомнение осталось по конкретному пункту — разберём его на схеме вашего агента.Обсудим задачу: как начать интеграцию графа
Чтобы вернуться с оценкой и планом, а не с общими соображениями, нужны исходные данные по вашему сценарию. Присылать можно в свободной форме — заметки из трекера и схема на салфетке подойдут лучше, чем вылизанная документация.
- Текущий сценарий: кто и что делает сейчас, где ветвления, в какой момент подключается человек.
- Объём: сколько запусков в сутки, длина типового диалога или пакета документов, есть ли пики нагрузки.
- Ограничения: что нельзя выносить за периметр, что обезличивать, какая задержка ответа допустима.
- Точки интеграции: откуда граф получает запуск и куда возвращает результат — интерфейс, база, тикетница, CRM.
- Что уже пробовали: узлы, вызовы моделей, результаты — что не устроило по качеству или стабильности.
- Критерий приёмки: что считаем успехом в числах — доля обращений, закрытых без человека, ручные доработки, время ответа.
Этого достаточно, чтобы разложить сценарий на граф: определить состояние, ветвления, контрольные точки и откаты, показать, где узлы LangGraph заменяют разрозненные вызовы модели, и как измерять эффект на первом этапе.
Опишите задачу в том виде, в каком она есть, — вернёмся с оценкой и планом: состав работ, последовательность этапов, что делаем на первом шаге и в какой точке вы принимаете результат.







