Чекпоинты для AI-агентов: как не терять часовые задачи
Длинные задачи агента падают на середине — из-за таймаута API, лимита токенов или сбоя сети. Разбираем, как чекпоинты и восстановление состояния спасают часы работы и деньги на токенах.

Агент разбирал репозиторий три часа, прошёл 40 шагов из 60 — и упал на 41-м, потому что провайдер вернул 529 (перегрузка). Без сохранённого состояния всё начинается заново: те же токены, те же деньги, то же время. Проблема не в качестве модели, а в том, что длинная задача выполнялась как один непрерывный процесс без точек сохранения. Чекпоинт — это способ разбить такую задачу на восстанавливаемые куски, чтобы после сбоя продолжить, а не начать сначала.
Почему длинные задачи падают
Чем дольше работает агент, тем выше шанс, что что-то оборвётся. Причины предсказуемы и повторяются:
- Таймауты API. У большинства провайдеров запрос к модели ограничен по времени — обычно в пределах нескольких минут на один ответ. Долгая генерация или медленный инструмент упираются в лимит.
- Переполнение контекстного окна. История диалога, результаты вызовов инструментов и промежуточные рассуждения накапливаются. Когда они не влезают в контекстное окно1, приходится обрезать или ужимать историю — и агент теряет часть контекста.
- Rate limit и перегрузка. Ошибки 429 (слишком много запросов) и 529/503 (сервис перегружен) прилетают в пик нагрузки. Retry помогает, но не всегда.
- Сбои инструментов и сети. Агент дёргает внешние API, базы, файловую систему. Любой из вызовов может отвалиться.
- Ручная остановка. Вы сами прерываете процесс, потому что агент пошёл не туда, а перезапускать всё с нуля не хочется.
Цена вопроса измеряется в токенах и минутах. Повторный прогон многошаговой задачи на большой модели — это реальные деньги на входных токенах, которые провайдер посчитает заново, плюс потерянное время.
Что такое чекпоинт в контексте агента
Чекпоинт — снимок состояния выполнения на определённом шаге, из которого можно продолжить. Минимально в него входит:
- история сообщений (или её сжатая версия);
- текущий шаг плана и что уже сделано;
- результаты вызванных инструментов, чтобы не дёргать их повторно;
- переменные состояния — счётчики, флаги, промежуточные артефакты;
- метаданные: версия модели, версия промпта, время.
Ключевая идея — сделать состояние сериализуемым и внешним по отношению к процессу. Пока состояние живёт только в оперативной памяти запущенного скрипта, любое падение процесса уничтожает его. Как только оно лежит в файле, базе или очереди, процесс можно перезапустить и подхватить работу.
Хороший агент проектируется так, будто его убьют в любой момент. Тогда восстановление после сбоя перестаёт быть аварийным сценарием и становится обычным ходом выполнения.
Идемпотентность шагов
Восстановление ломается, если шаг нельзя безопасно повторить. Представьте, что агент отправил письмо, а потом упал до записи чекпоинта. При восстановлении он отправит письмо ещё раз. Поэтому побочные действия — записи в базу, платежи, отправку сообщений — оборачивают ключами идемпотентности2 или проверкой «уже сделано?». Чтение данных повторять безопасно, изменение — нет.
Где хранить состояние: варианты
Инструментов для оркестрации длинных задач стало заметно больше. Ни один из них не «лучший» в вакууме — они закрывают разные сценарии.
| Подход | Где хранит состояние | Кому подходит | Ограничения |
|---|---|---|---|
| Свой код: JSON-файл или SQLite после каждого шага | Локальный диск | Прототипы, одиночные скрипты | Нет распределённости, легко получить гонки при параллельности |
| LangGraph с чекпойнтером | Память, SQLite, Postgres — на выбор | Графовые агенты с ветвлениями и циклами | Нужно описывать логику как граф, порог входа выше |
| Temporal / durable execution | Внешний движок воркфлоу | Продакшн, где важна надёжность и повторяемость | Отдельная инфраструктура, требует переписать логику под workflow |
| Очередь задач (Celery, очередь + БД) | Брокер + база | Пакетная обработка множества независимых задач | Состояние внутри одной задачи придётся вести вручную |
Точный набор чекпойнтеров и их зрелость сверяйте в актуальной документации соответствующего проекта — API этих библиотек меняется быстро.
Стратегии восстановления
Сохранить состояние — половина дела. Вторая половина — правильно продолжить.
- Продолжить с последнего шага. Самый частый случай: агент читает чекпоинт, восстанавливает историю и планирует следующий шаг. Работает, если шаги идемпотентны.
- Откат к безопасной точке. Если последний шаг оставил систему в непонятном состоянии, откатываемся к предыдущему валидному чекпоинту и переигрываем.
- Сжатие истории при восстановлении. Если контекст переполнен, при перезапуске историю суммаризируют: старые сообщения заменяют кратким резюме, оставляя факты и решения. Это отдельный вызов модели, но он дешевле повторного прогона всей задачи.
- Human-in-the-loop. Агент останавливается на развилке, сохраняет чекпоинт и ждёт решения человека. После ответа продолжает с того же места — состояние всё это время лежит во внешнем хранилище.
Как часто ставить чекпоинт
Слишком часто — накладные расходы на сериализацию и запись. Слишком редко — потеряете много при падении. Разумный ориентир: сохранять после каждого шага, который менял состояние или стоил дорого (вызов большой модели, тяжёлый инструмент). Дешёвые чтения можно не чекпоинтить отдельно.
Кому это пригодится и кому нет
Пригодится:
- Агентам, которые обрабатывают большие кодовые базы или документы за десятки шагов — там падение на середине особенно обидно.
- Пайплайнам, где агент ходит во внешние платные API: восстановление экономит на повторных вызовах.
- Задачам с человеком в цикле, где между шагами проходят часы или дни ожидания подтверждения.
- Продакшн-сервисам с SLA, где перезапуск с нуля недопустим.
Скорее не нужно:
- Коротким одноходовым запросам — вопрос к модели и ответ. Оркестрация тут только усложнит код.
- Чат-ассистентам, где «состояние» — это просто история диалога, и её потеря не критична.
- Одноразовым экспериментам, которые дешевле перезапустить, чем городить хранилище.
Что учесть на старте
- Сериализуйте состояние во внешнее хранилище, а не держите в памяти процесса.
- Разделяйте чтения (можно повторять) и записи (нужна идемпотентность).
- Кладите в чекпоинт версию модели и промпта — иначе восстановление на другой версии даст расхождения.
- Тестируйте восстановление намеренно: убивайте процесс на середине и проверяйте, что он корректно продолжает.
1 Контекстное окно — максимальный объём текста (в токенах), который модель обрабатывает за один запрос: и промпт, и история, и ответ должны в него уместиться.
2 Ключ идемпотентности — уникальный идентификатор операции, по которому система понимает, что действие уже выполнено, и не делает его повторно.
Prompt-инженер: Идеальные запросы для Midjourney, ChatGPT и других моделей.
Спросить за 15 ₽Источники: LangGraph: Persistence and checkpointers (документация), Temporal: What is a Workflow (документация)
Частые вопросы
Чем чекпоинт отличается от простого логирования истории диалога?
Обязательно ли брать LangGraph или Temporal, или можно обойтись своим кодом?
Как чекпоинты помогают с переполнением контекстного окна?
Что будет, если процесс упал сразу после действия, но до записи чекпоинта?
Как часто нужно сохранять состояние?
Можно ли восстановить состояние, если между запусками сменилась версия модели?
Материал носит информационный характер и подготовлен редакцией «Агентуры». Он не является офертой, рекламой или индивидуальной консультацией. Упомянутые продукты, компании и торговые знаки принадлежат их правообладателям. Перед принятием решений, влекущих юридические или финансовые последствия, обратитесь к профильному специалисту.