Автоматизировали 35% Tier-1 инцидентов через AIOps-агент: где прошли границы автономии
Перезапуск подов, очистка очередей, перераспределение дисков - агент делает это сам. Рассказываем, как мы определяли, что ему можно доверить, а что требует человека.
AIOps автоматизирует первый уровень реагирования на инциденты в зрелых NOC-командах
Примерно полгода назад мы собрали RCA-агент поверх Zabbix + Loki, который анализировал инциденты и писал дежурному в Mattermost: «вот что случилось, вот почему, вот где смотреть». Агент был read-only - никаких действий, только диагностика. Это был осознанный выбор: сначала понять, насколько он вообще прав.
Оказался прав достаточно часто, чтобы следующий вопрос стал неизбежным: а что если дать ему кнопки?
С марта этого года у нас в проде работает агент, который не только диагностирует, но и реагирует. Сейчас примерно треть Tier-1 инцидентов закрывается без участия дежурного - агент обнаружил, отработал, записал в тикет. Рассказываем, как мы дошли до такой конфигурации и где пришлось провести жёсткие границы.
Что такое Tier-1 в нашем контексте
Для начала - что мы называем Tier-1, чтобы не было иллюзий. Это не «простые» инциденты в смысле «не страшные». Это инциденты с понятным и повторяемым паттерном: симптом хорошо распознаётся, причина известна, действие стандартное. Накопленная база показала, что таких у нас около 40% от общего потока - и это неплохой материал для автоматизации.
Конкретные примеры из того, что сейчас делает агент:
- Перезапуск подов с OOMKill. Pod упал по OOM, это видно из событий Kubernetes. Агент проверяет, что это не системный под, не база данных, не stateful-компонент без graceful shutdown, и перезапускает. Если в течение 10 минут под падает снова - эскалирует.
- Очистка накопившихся очередей. Несколько сервисов у клиента генерируют «мусорные» сообщения при определённых условиях - это известная история, задокументированная в runbook. Агент сам чистит очереди по заданному паттерну.
- Перераспределение дискового пространства. Если заполнение раздела пересекает порог, агент проверяет стандартные места скопления мусора (logs, tmp, старые снапшоты) и чистит то, что помечено как безопасное для удаления. С явным лимитом: трогает только файлы старше 7 дней из заранее согласованного списка директорий.
Выглядит просто. На практике - без проработки граничных условий запускать не стоит.
Как мы определяли границы автономии
Самый сложный вопрос проекта - не технический. Технически несложно дать агенту kubectl exec или доступ к Kafka API. Сложно решить, для каких классов действий этот доступ допустим.
Мы пришли к трём критериям, которые определяют, идёт ли действие в автономный список или требует подтверждения:
Первый - обратимость. Действие должно быть обратимым без потери данных. Перезапуск пода - обратимо. Удаление файла логов - обратимо (файл воссоздаётся). Масштабирование деплоя вниз в прайм-тайм - нет, потому что пользователи уже получают деградацию и откат не мгновенный.
Второй - изолированность. Действие не должно затрагивать компоненты за пределами затронутого сервиса. Если проблема на одном поде - агент работает с этим подом. Если проблема выглядит как сетевая - агент ничего не трогает, потому что сетевые изменения каскадируют.
Третий - предсказуемость результата. Агент должен уметь сформулировать ожидаемый результат своего действия и проверить его через заданное время. Перезапустил под - через 3 минуты проверяет статус. Если не Ready - эскалирует. Это важно: без проверки результата автоматизация превращается в «выстрелил и забыл», что хуже ручной работы.
Всё, что не проходит хотя бы один критерий, идёт на подтверждение к дежурному. Агент присылает сообщение: «Вот что вижу, вот что предлагаю сделать, подтвердите.» Дежурный отвечает одной кнопкой. Или не отвечает - тогда через 5 минут агент отправляет повторный запрос и звонит.
Где потребовали человеческого подтверждения
Несколько случаев, которые казались автоматизируемыми, но оказались нет.
Деградация базы данных. Любое изменение, которое касается PostgreSQL или Redis в продуктиве, идёт только через подтверждение. Не потому что агент не может выполнить команду - потому что у баз данных слишком много состояния, которое агент не видит. Незафиксированные транзакции, репликационный лаг, блокировки - всё это влияет на то, что «безобидный» рестарт может сделать на практике.
Инциденты с внешними зависимостями. Если агент видит, что проблема с высокой вероятностью не на нашей стороне - сетевой провайдер, сторонний API, - он не делает ничего автоматически. Ни «лечебного» перезапуска сервиса, ни других действий, которые создают шум без пользы.
Паттерны с низким confidence. Есть пороговое значение уверенности диагноза. Если агент не может сопоставить симптом с известным паттерном выше порога - он сразу идёт к дежурному, не пытаясь применить «похожий» runbook.
Инженерная честность про 35%
Цифра 35% закрытых Tier-1 без участия человека звучит хорошо. Но важен контекст.
Первый месяц после запуска - примерно 20%, потому что список автономных действий был маленьким и агент часто перестраховывался. Мы итеративно разбирали каждый случай, где агент попросил подтверждение, и часть из них переносили в автономный режим - но только после явного обсуждения с клиентом. Сейчас 35%, и мы не торопимся поднимать эту цифру. Цель не максимизировать автономию, а держать её в зоне, где дежурный уверен, что агент не делает глупостей за его спиной.
Был один случай, который укрепил нас в консервативном подходе. Агент автономно почистил tmp-директорию на сервере приложений, потому что она соответствовала всем критериям безопасного удаления. Оказалось, что один из разработчиков положил туда временный файл с ручными миграционными данными, которые ждали применения. Файл был правильно назван, лежал в правильном месте, был достаточно старым. Данные потеряли. Восстановили из памяти разработчика за пару часов, но это была неприятная история.
После этого мы добавили четвёртый критерий к автономным действиям: файловые операции требуют явного согласованного списка - не директорий, а конкретных паттернов файлов. Это замедляет onboarding нового клиента, но убирает класс сюрпризов.
Где мы сейчас
Мониторинг трассировок дал нам метрику, которую сейчас смотрим отдельно: процент инцидентов, где агент эскалировал, но дежурный после разбора не применял никаких действий. Это «ложные эскалации» - агент перестраховался там, где мог справиться сам. Сейчас эта цифра около 15% от всех эскалаций. Работаем над тем, чтобы снизить её, но медленно и осторожно.
Следующий вопрос, который у нас открыт: как автоматизировать не отдельные действия, а цепочки. Сейчас агент делает одно атомарное действие и проверяет результат. Иногда нужно сделать несколько вещей подряд - например, почистить очередь, перезапустить воркер и проверить метрики. Это сложнее по логике подтверждений: если шаг 2 из 3 требует подтверждения, а шаг 1 уже выполнен - что делать? Такие сценарии в автономный режим не переводим. Накапливаем прецеденты.
Автономия агента - это не ползунок, который сдвигаешь вправо. Это набор решений о доверии, каждое из которых принимается медленно и на основе реального опыта.