- BrainTools - https://www.braintools.ru -
Понедельник, 9 утра. Начало рабочей недели.
API OpenAI лёг. Или лимиты закончились. Или интернет в офисе пропал.
Что делает AI-агент? Ничего. А процесс, который он обслуживал, встаёт. Заявки копятся, договоры не согласовываются, клиенты ждут.
И хуже всего — люди не знают, что агент не работает. Думают, что всё идёт по плану.
За год работы с AI-агентами в проде я собрал коллекцию того, что ломается.
Сбои провайдера LLM. OpenAI: 2-3 крупных сбоя в год плюс периодические замедления. Anthropic: реже, но бывает. GigaChat: стабильнее, но тоже не без проблем.
Сетевые проблемы. Интернет в офисе, проблемы с DNS, блокировки (привет, РКН).
Лимиты и квоты. Закончились токены, rate limiting, превышен бюджет.
Проблемы с данными. Недоступна база знаний, упала CRM, сломалась интеграция с почтой.
Внутренние ошибки [1]. Баг в коде агента, некорректные данные на входе, бесконечный цикл.
Каждый из этих сценариев может парализовать работу. И каждый нужно обработать.
Система должна деградировать плавно, а не падать полностью. Каждый уровень сохраняет какую-то функциональность.
Уровень 0 (норма): Агент работает, всё автоматически
Уровень 1: Основной LLM недоступен → переключение на резервный
Уровень 2: Все LLM недоступны → задачи в очередь, уведомление оператору
Уровень 3: Очередь > 50 задач → эскалация руководителю, ручной режим
Уровень 4: Критический сбой → полная остановка, аварийное уведомление
По сути, это как аварийное освещение в здании. Свет погас → включился генератор → генератор сдох → аварийные лампы → полная темнота и эвакуация. Каждый уровень даёт время среагировать.
Если сервис начал сбоить — временно прекращаем к нему обращаться. Зачем тратить время на заведомо неудачные запросы и нагружать и так перегруженный сервис?
Три состояния:
Closed (норма) → запросы идут как обычно
↓ 5 ошибок подряд
Open (сбой) → запросы не отправляются, сразу fallback
↓ через 60 секунд
Half-open (проверка) → пропускаем один тестовый запрос
↓ успех → Closed
↓ неудача → Open
Реализация на Python:
from datetime import datetime, timedelta
class CircuitBreaker:
"""
Circuit breaker для защиты от каскадных сбоев.
Отслеживает ошибки внешнего сервиса и временно
прекращает запросы, если сервис «лёг».
"""
def __init__(self, failure_threshold: int = 5, recovery_timeout: int = 60):
self.failure_threshold = failure_threshold
self.recovery_timeout = recovery_timeout
self.failures: dict[str, int] = {}
self.state: dict[str, str] = {} # closed / open / half-open
self.last_failure: dict[str, datetime] = {}
def can_execute(self, service: str) -> bool:
"""Можно ли отправлять запрос к сервису?"""
state = self.state.get(service, "closed")
if state == "closed":
return True
if state == "open":
# Проверяем, не пора ли попробовать снова
elapsed = datetime.now() - self.last_failure[service]
if elapsed > timedelta(seconds=self.recovery_timeout):
self.state[service] = "half-open"
return True # Один тестовый запрос
return False
# half-open — пропускаем запрос для проверки
return True
def record_success(self, service: str):
"""Запрос прошёл — сбрасываем счётчик."""
self.failures[service] = 0
self.state[service] = "closed"
def record_failure(self, service: str):
"""Запрос упал — считаем ошибки."""
self.failures[service] = self.failures.get(service, 0) + 1
self.last_failure[service] = datetime.now()
if self.failures[service] >= self.failure_threshold:
self.state[service] = "open"
Использование:
breaker = CircuitBreaker(failure_threshold=5, recovery_timeout=60)
async def call_llm(prompt: str) -> str:
if not breaker.can_execute("openai"):
# OpenAI «в отключке» — сразу идём на fallback
return await call_fallback_llm(prompt)
try:
result = await openai_client.complete(prompt)
breaker.record_success("openai")
return result
except Exception:
breaker.record_failure("openai")
return await call_fallback_llm(prompt)
Паттерн простой, но в проде спасает от каскадных сбоев. Без него один упавший сервис может повалить всю систему — запросы копятся, таймауты растут, ресурсы заканчиваются.
Если запрос не прошёл — повторяем [3]. Но с умом: с увеличивающейся задержкой и ограниченное число раз.
Попытка 1: сразу
Попытка 2: через 1 сек
Попытка 3: через 2 сек
Попытка 4: через 4 сек
Попытка 5: через 8 сек
После 5 попыток: отказ → fallback или эскалация
Экспоненциальный backoff + jitter (случайный разброс) — чтобы при массовом сбое все клиенты не ретраили одновременно.
Резервный провайдер. OpenAI лёг — используем Anthropic. Или GigaChat. Или локальную модель.
Важный нюанс: fallback нужно тестировать заранее. Нельзя в момент сбоя узнать, что резервная модель не понимает ваши промпты или выдаёт мусор.
На практике это значит: промпты адаптируются под каждую модель, регрессионные тесты прогоняются на обоих провайдерах, переключение — автоматическое.
Задачи, которые не удалось обработать, должны где-то храниться. Не в памяти [4] приложения — она умрёт вместе с процессом. В надёжном хранилище: Redis, PostgreSQL, RabbitMQ.
Когда сервис восстановится — обработаем накопившееся. Ни одна задача не должна потеряться.
Отказоустойчивая архитектура бесполезна без мониторинга.
Что мониторить:
Доступность внешних сервисов (LLM API, интеграции)
Латентность запросов (резкий рост — признак проблем)
Процент ошибок (выше порога — алерт)
Размер очереди (растёт — не успеваем)
Текущий уровень деградации
Кому алертить:
Уровень 1 (fallback LLM): инженеру в Slack
Уровень 2 (очередь): оператору + инженеру
Уровень 3 (ручной режим): руководителю
Уровень 4 (критический сбой): всем + SMS
У любой production-системы должен быть SLA. AI-агент — не исключение.
99.5% — не более 3.6 часов простоя в месяц. Базовый мониторинг, ручное переключение. Достаточно для большинства бизнес-процессов.
99.9% — 43 минуты в месяц. Нужен дежурный инженер, автоматическое переключение, резервирование.
99.99% — 4 минуты в месяц. Распределённая архитектура, мульти-регион, автоматическое восстановление. Для AI-агентов обычно overkill.
SLA определяет, сколько ресурсов вкладывать в отказоустойчивость. Зафиксируйте его явно.
Это дополнительные расходы, но считаются они просто.
Резервный LLM: +30-50% к стоимости inference (тестирование на двух моделях).
Мониторинг: 50-100к на настройку + 10-20к/месяц.
Очередь и хранилище: 5-10к/месяц.
Поддержка: 10-20% от времени разработки.
В сумме: +10-15% к бюджету проекта. Это не траты — это страховка. Стоимость одного серьёзного сбоя обычно кратно превышает эти расходы.
Если вам внедряют AI-агента — задайте эти вопросы:
Что произойдёт, если API провайдера LLM станет недоступен?
Есть ли резервный провайдер? Протестирован ли он?
Как система обрабатывает таймауты?
Где хранятся задачи, которые не удалось обработать?
Как я узнаю, что система деградировала?
Какой SLA вы гарантируете?
Что происходит при превышении лимитов?
Как выглядит процедура восстановления после сбоя?
Нет чётких ответов — получите систему, которая упадёт в самый неподходящий момент.
AI-агент в продакшене должен быть отказоустойчивым. Это не опция — это требование.
Graceful degradation, circuit breaker, fallback LLM, persistent queue, мониторинг — минимальный набор.
Если интегратор не может ответить на вопросы про отказоустойчивость — ищите другого.
Серия «Почему AI-проекты проваливаются»:
Что делать, когда AI-агент «упал» ← вы здесь
Анатолий Лапков. Telegram: @futex_ai [10]
Автор: a_lapkov
Источник [11]
Сайт-источник BrainTools: https://www.braintools.ru
Путь до страницы источника: https://www.braintools.ru/article/26808
URLs in this post:
[1] ошибки: http://www.braintools.ru/article/4192
[2] Image: https://sourcecraft.dev/
[3] повторяем: http://www.braintools.ru/article/4012
[4] памяти: http://www.braintools.ru/article/4140
[5] 6 проблем, о которых молчат интеграторы: https://habr.com/ru/articles/989086/
[6] Инструкция для человека vs инструкция для AI: https://habr.com/ru/articles/1005570/
[7] Кто отвечает за ошибки AI-агента: https://habr.com/ru/articles/1005574/
[8] Как передать агенту неявные знания: https://habr.com/ru/articles/1005578/
[9] Пошаговый план внедрения: https://habr.com/ru/articles/1005582/
[10] Telegram: @futex_ai: https://t.me/+Ak0d9WlUrCUwZTYy
[11] Источник: https://habr.com/ru/articles/1005576/?utm_source=habrahabr&utm_medium=rss&utm_campaign=1005576
Нажмите здесь для печати.