Понедельник, 9 утра. Начало рабочей недели.
API OpenAI лёг. Или лимиты закончились. Или интернет в офисе пропал.
Что делает AI-агент? Ничего. А процесс, который он обслуживал, встаёт. Заявки копятся, договоры не согласовываются, клиенты ждут.
И хуже всего — люди не знают, что агент не работает. Думают, что всё идёт по плану.
Реальные сценарии сбоев
За год работы с AI-агентами в проде я собрал коллекцию того, что ломается.
Сбои провайдера LLM. OpenAI: 2-3 крупных сбоя в год плюс периодические замедления. Anthropic: реже, но бывает. GigaChat: стабильнее, но тоже не без проблем.
Сетевые проблемы. Интернет в офисе, проблемы с DNS, блокировки (привет, РКН).
Лимиты и квоты. Закончились токены, rate limiting, превышен бюджет.
Проблемы с данными. Недоступна база знаний, упала CRM, сломалась интеграция с почтой.
Внутренние ошибки. Баг в коде агента, некорректные данные на входе, бесконечный цикл.
Каждый из этих сценариев может парализовать работу. И каждый нужно обработать.
Принцип 1: Graceful degradation
Система должна деградировать плавно, а не падать полностью. Каждый уровень сохраняет какую-то функциональность.
Уровень 0 (норма): Агент работает, всё автоматически Уровень 1: Основной LLM недоступен → переключение на резервный Уровень 2: Все LLM недоступны → задачи в очередь, уведомление оператору Уровень 3: Очередь > 50 задач → эскалация руководителю, ручной режим Уровень 4: Критический сбой → полная остановка, аварийное уведомление
По сути, это как аварийное освещение в здании. Свет погас → включился генератор → генератор сдох → аварийные лампы → полная темнота и эвакуация. Каждый уровень даёт время среагировать.
Принцип 2: Circuit breaker
Если сервис начал сбоить — временно прекращаем к нему обращаться. Зачем тратить время на заведомо неудачные запросы и нагружать и так перегруженный сервис?
Три состояния:
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: Retry with backoff
Если запрос не прошёл — повторяем. Но с умом: с увеличивающейся задержкой и ограниченное число раз.
Попытка 1: сразу Попытка 2: через 1 сек Попытка 3: через 2 сек Попытка 4: через 4 сек Попытка 5: через 8 сек После 5 попыток: отказ → fallback или эскалация
Экспоненциальный backoff + jitter (случайный разброс) — чтобы при массовом сбое все клиенты не ретраили одновременно.
Принцип 4: Fallback LLM
Резервный провайдер. OpenAI лёг — используем Anthropic. Или GigaChat. Или локальную модель.
Важный нюанс: fallback нужно тестировать заранее. Нельзя в момент сбоя узнать, что резервная модель не понимает ваши промпты или выдаёт мусор.
На практике это значит: промпты адаптируются под каждую модель, регрессионные тесты прогоняются на обоих провайдерах, переключение — автоматическое.
Принцип 5: Persistent queue
Задачи, которые не удалось обработать, должны где-то храниться. Не в памяти приложения — она умрёт вместе с процессом. В надёжном хранилище: Redis, PostgreSQL, RabbitMQ.
Когда сервис восстановится — обработаем накопившееся. Ни одна задача не должна потеряться.
Мониторинг и алерты
Отказоустойчивая архитектура бесполезна без мониторинга.
Что мониторить:
Доступность внешних сервисов (LLM API, интеграции)
Латентность запросов (резкий рост — признак проблем)
Процент ошибок (выше порога — алерт)
Размер очереди (растёт — не успеваем)
Текущий уровень деградации
Кому алертить:
Уровень 1 (fallback LLM): инженеру в Slack Уровень 2 (очередь): оператору + инженеру Уровень 3 (ручной режим): руководителю Уровень 4 (критический сбой): всем + SMS
SLA для AI-системы
У любой 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