Airflow retry повторяет упавшую задачу DAG, но безопасный повтор LLM-шага требует классификации ошибки и защиты внешнего вызова от дублей. Временный сетевой сбой допускает следующую попытку, а неверный запрос и отказ в доступе требуют исправления причины. После исчерпания попыток задача переходит в разбор человеку вместе с журналом вызовов и статусом внешней операции.
Состояние задачи
В документации Apache Airflow состояние up_for_retry означает сбой задачи при оставшихся попытках. Политика повторов управляет следующим запуском, а безопасность внешнего LLM-вызова проектируют отдельно.
Представьте DAG, который получает документ, вызывает языковую модель для черновика классификации и записывает результат в рабочую систему. Сетевой ответ может оборваться после обработки запроса внешней стороной. Airflow увидит ошибку задачи и запустит её снова, хотя первый вызов уже создал ответ. Поэтому статус задачи описывает исполнение внутри оркестратора, но состояние внешнего сервиса требует отдельной проверки.
Нарисуйте границы операции до выбора параметров. Входом служат идентификатор документа, версия содержимого, утверждённый шаблон запроса и версия модели из собственной конфигурации. Выходом служат текст ответа, признак успешной проверки формата и ссылка на журнал. Если шаг ещё публикует документ или меняет карточку клиента, вынесите такое действие в отдельную задачу с собственным разрешением. Тогда повтор вызова модели и повтор публикации получают разные правила.
Тема отличается от сценариев n8n для компании: там важна сборка потока из узлов, здесь важны состояния экземпляра задачи DAG и последствия повторного внешнего вызова. Для LLM-шага особенно опасна уверенная интерпретация тайм-аута как отказа модели: ответ мог существовать, хотя клиент его уже перестал ждать.
Сразу определите владельца результата. Модель создаёт черновик, скрипт проверяет формат, сотрудник сверяет смысл с источником. Настройка Airflow связывает эти действия, но решение об использовании ответа остаётся за человеком.
Типы сбоя
Повтор нужен после ошибки, которая способна исчезнуть без правки входа: краткий сетевой обрыв, ограничение частоты вызовов либо временная недоступность сервиса. Ошибка схемы запроса, отсутствующее право доступа и недопустимый файл сохранятся при новом запуске. Их отправляют в разбор сразу. Если результат внешнего вызова неизвестен из-за разрыва соединения, сначала ищут запись по ключу операции и лишь затем принимают решение о следующем запросе.
| Сигнал | Решение задачи | Проверка перед действием |
|---|---|---|
| Временный отказ соединения | Допустить ограниченный повтор | Сверить ключ операции во внешнем журнале |
| Ограничение частоты | Повторить после допустимой задержки | Учесть правило ответа сервиса |
| Ошибка входной схемы | Остановить попытки | Исправить структуру запроса |
| Отказ в доступе | Передать ответственному | Проверить права вне текста промпта |
| Ответ получен, формат нарушен | Зафиксировать отдельный тип сбоя | Сверить исходный ответ и парсер |
Раздел Tasks Airflow описывает предел повторов и задержку между ними, а также специальные исключения для немедленного завершения. В актуальной стабильной документации есть политика по типу исключения; наличие соответствующего механизма в вашем развёртывании проверяйте по установленной версии. Раннее завершение полезно для постоянных ошибок, поскольку повтор того же запроса только раздувает журнал.
Классификацию поместите рядом с кодом вызова модели. Ловите конкретные ошибки клиента, сохраняйте код ответа и очищенное диагностическое сообщение. Секреты, токены и полный клиентский текст в лог ошибки класть нельзя. Понятная запись содержит идентификатор задачи, тип сбоя, ключ операции и принятое решение: новая попытка либо ручной разбор.
Ключ операции
Идемпотентность означает, что повтор того же логического запроса сохраняет один согласованный результат. Сформируйте ключ из устойчивого идентификатора входного документа, его версии, назначения шага и версии инструкции. Номер попытки Airflow в ключ включать нельзя: тогда каждая попытка выглядела бы новой операцией. Для изменившегося входа нужен новый ключ, иначе система могла бы вернуть старый ответ к новой версии документа.
- Вычислите ключ из версии входа и сохраните запись операции до внешнего вызова.
- Проверьте, поддерживает ли внешний интерфейс ключ идемпотентности или поиск результата по вашему идентификатору.
- При повторе сначала прочитайте статус ранее созданной операции, затем решите вопрос нового вызова.
- Записывайте ответ и метаданные в хранилище с уникальным ограничением по ключу.
- Передайте вниз по DAG ссылку на сохранённый результат; публикацию выполняйте отдельной задачей.
Если внешний сервис поддерживает идемпотентный ключ, передавайте один и тот же ключ на каждой попытке. Если такой возможности нет, локальная таблица предотвращает дубли записи у вас, но внешний вызов после неизвестного тайм-аута остаётся неопределённым. Отдельная сверка с сервисом либо ручное решение необходимы перед новым запросом, особенно когда вызов запускает действие за пределами генерации текста.
Уникальное ограничение в базе защищает от одновременной записи одинакового результата; проверка наличия строки перед вставкой без ограничения гонку пропускает. Сохраните также состояние операции: подготовлена, отправлена, подтверждена, требует разбора. Это помогает инженеру увидеть место остановки, а редактору — открыть исходный ответ без запуска новой генерации.
Логику внешнего действия полезно сопоставить с разбором вызова инструментов ИИ-агентом: текст модели предлагает действие, а контролируемый код проверяет аргументы и право его выполнить.
Проверка дублей
Проверяйте повтор на заранее подготовленном наборе сбоев. Отключите реальную отправку и публикацию, направьте результаты в тестовое хранилище. Нужны сценарии с обрывом до вызова, с обрывом после принятия запроса сервисом, с ошибкой формата ответа и с одновременным запуском одинакового входа. Для каждого заранее запишите ожидаемый статус Airflow и число логических результатов в собственной базе.
- После временного сбоя Airflow запускает следующую попытку с прежним ключом операции.
- После постоянной ошибки DAG останавливает шаг и сохраняет причину разбора.
- При неизвестном исходе вызова запись остаётся помеченной до сверки с внешним сервисом.
- Повторная запись результата упирается в уникальное ограничение и попадает в журнал диагностики.
- Задача публикации получает только проверенный результат с отдельным подтверждением.
Число вызовов и число результатов различаются. Внешний сервис мог принять один запрос и вернуть клиенту тайм-аут; новая попытка тогда создаст ещё один вызов при отсутствии поддержки идемпотентности. Метрику качества берите по логическим входам: доля входов с одним принятым результатом и понятным статусом. Неизвестный исход выделяйте отдельной группой, поскольку пустой журнал Airflow оставляет исход внешнего действия неизвестным.
Сводку ошибок и записи о попытках обрабатывайте скриптом или парсером. Языковая модель может объяснить обнаруженные группы и предложить гипотезы причин; инженер сверяет выборку, ключи и журнал. Такой процесс подробнее раскрыт в статье о тестировании ИИ-агентов.
Команде полезно заранее выбрать владельца спорного исхода: человеку нужен доступ и к записи Airflow, и к подтверждению внешнего сервиса.
Где ваш LLM-шаг сейчас создаёт дубли после повтора?
Передача человеку
Когда попытки исчерпаны, задача должна оставлять ответственному запись с контекстом сбоя. Красного индикатора в интерфейсе для разбора мало. Передайте идентификатор входа, ключ операции, класс последней ошибки, историю статусов и ссылку на безопасный фрагмент журнала. Отдельно укажите, мог ли внешний сервис уже выполнить запрос. Эта отметка определяет следующий шаг: сверка результата, исправление входа либо разрешённый повтор.
Ручной запуск после исправления тоже проходит через идемпотентный слой. Человек проверяет, какая версия документа была входом и существует ли принятый результат для соответствующего ключа. Если версия изменилась, создаётся новая логическая операция; если ошибка касалась только доставки ответа, сначала ищут прежний результат. Удалять историю старых попыток ради чистого графика нельзя: по ней восстанавливают причинную цепочку.
Возьмите один LLM-шаг с временными сбоями. Нарисуйте исходы «ответ принят», «ответ отклонён» и «исход неизвестен», затем назначьте правило повторов и ключ операции для каждого исхода. На тестовом входе проверьте журнал и путь передачи человеку.
В рабочем контуре настройте проверку прав на повторный запуск и подтверждение результата. Промпт лишь описывает порядок работы. Ограничьте доступ к ручному действию, сохраните автора решения и причину. Языковая модель может предложить объяснение сбоя, но допуск к операции определяет система прав, а качество ответа проверяет специалист. Такая граница особенно важна, если следующий шаг DAG меняет документ, заявку или письмо.
Для внедрения проверьте стоимость поддержки журнала, внешнего хранения статусов, тестовых сценариев и интеграции с системой согласования. В обсуждении автоматизации бизнес-процессов можно разобрать этот контур под вашу задачу. Напишите нам, посчитаем для вашего процесса после карты ошибок, ключей и ответственных.