Розробка системи резервування та відмовостійкості AI-агентів

Коли AI-агент раптово перестає відповідати через збій API або падіння сервера, бізнес-процес зупиняється. Ми розробляємо систему резервування та відмовостійкості, яка миттєво перемикає агента на резервних провайдерів і коректно деградує без втрати прогресу. Наша команда реалізує проєкт під ключ — від аудиту до впровадження та подальшої підтримки, забезпечуючи стабільну роботу ваших AI-рішень.

Розробка системи резервування та відмовостійкості AI-агентів

MLOps та інфраструктураСкладнийвід 1 тижня до 3 місяців
Часті запитання

Зазначимо: коли AI-агент раптово перестає відповідати через збій OpenAI API або падіння локального інференс-сервера, бізнес-процес зупиняється. Ми стикалися з цим не раз: у production-системах з SLA 99.9% недоступність LLM на 10 хвилин означає втрату тисяч замовлень. Нещодавно у клієнта з фінтеху GPT-4o впав на 15 хвилин через збій хмари — наші fallback-агенти переключилися на Claude 3.5 за 400 мс, і процес не перервався. Тому ми розробляємо архітектуру резервування LLM та всього стеку, яка тримає удар — fallback провайдери, circuit breaker'и, checkpoint'и та human escalation. Все під ключ, з гарантією та документацією.

Як забезпечити відмовостійкість AI-агентів?

Ключове завдання — щоб при відмові будь-якого компонента (LLM API, інструмент, оркестратор) агент або миттєво перемикався на резерв, або коректно деградував, не втрачаючи прогресу. Ми реалізуємо чотири рівні захисту: резервування LLM (fallback провайдери), circuit breaker для інструментів, checkpoint відновлення для тривалих задач, human escalation при нерозв'язних помилках. На практиці priority fallback з circuit breaker у 2-3 рази надійніший за round-robin при пікових навантаженнях. SLA AI-агентів при такому підході досягає 99.99%.

Чому priority fallback з circuit breaker надійніший?

Перший і найчастіший сценарій — основна модель (GPT-4o) недоступна через rate limit або аварію. Використовуємо fallback ланцюжок: OpenAI → Anthropic → локальна модель (LLaMA 3 8B через vLLM). Перемикання відбувається за <500 мс з використанням circuit breaker для кожного провайдера. Health checks дозволяють своєчасно виявляти збої.

Порівняємо популярні стратегії fallback:

Стратегія Час перемикання Надійність (p99) Складність реалізації
Round-robin <50 мс 99.9% низька
Priority з circuit breaker <500 мс 99.99% середня
Multi-head (всі одночасно) <100 мс 99.95% висока

Ми обираємо priority з circuit breaker: він дає найкращий баланс продуктивності та стійкості. MLOps відмовостійкість таких систем вимагає моніторингу та автоматичного відновлення.

Практична реалізація: код та конфіги

Розглянемо ключові компоненти на Python.

Fallback LLM Provider

from tenacity import retry, stop_after_attempt, wait_exponential, retry_if_exception_type
import anthropic
import openai

class ResilientLLMClient:
    def __init__(self):
        self.providers = [
            {"name": "openai", "client": openai.AsyncOpenAI(), "model": "gpt-4o"},
            {"name": "anthropic", "client": anthropic.AsyncAnthropic(), "model": "claude-3-5-sonnet-20241022"},
            {"name": "local_vllm", "client": openai.AsyncOpenAI(base_url="http://gpu1:8000/v1"), "model": "llama-3-8b"},
        ]
        self.circuit_breakers = {p["name"]: CircuitBreaker() for p in self.providers}

    async def generate(self, messages: list, **kwargs) -> str:
        last_error = None
        for provider in self.providers:
            cb = self.circuit_breakers[provider["name"]]
            if cb.is_open():
                continue  # провайдер відключений по circuit breaker
            try:
                result = await self._call_provider(provider, messages, **kwargs)
                cb.record_success()
                return result
            except Exception as e:
                cb.record_failure()
                last_error = e
                logger.warning(f"Provider {provider['name']} failed: {e}")
        raise RuntimeError(f"All LLM providers failed. Last error: {last_error}")

    @retry(
        stop=stop_after_attempt(3),
        wait=wait_exponential(multiplier=1, min=1, max=10),
        retry=retry_if_exception_type((openai.RateLimitError, openai.APIConnectionError))
    )
    async def _call_provider(self, provider: dict, messages: list, **kwargs) -> str:
        response = await provider["client"].chat.completions.create(
            model=provider["model"],
            messages=messages,
            **kwargs
        )
        return response.choices[0].message.content

Circuit Breaker Pattern

Наш circuit breaker слідує класичному Circuit Breaker pattern.

from enum import Enum
import time

class CircuitState(Enum):
    CLOSED = "closed"  # нормальна робота
    OPEN = "open"  # провайдер відключений
    HALF_OPEN = "half_open"  # тестуємо відновлення

class CircuitBreaker:
    def __init__(self, failure_threshold=5, reset_timeout=60):
        self.failure_threshold = failure_threshold
        self.reset_timeout = reset_timeout
        self.failure_count = 0
        self.last_failure_time = 0
        self.state = CircuitState.CLOSED

    def is_open(self) -> bool:
        if self.state == CircuitState.OPEN:
            if time.time() - self.last_failure_time > self.reset_timeout:
                self.state = CircuitState.HALF_OPEN
                return False
            return True
        return False

    def record_failure(self):
        self.failure_count += 1
        self.last_failure_time = time.time()
        if self.failure_count >= self.failure_threshold:
            self.state = CircuitState.OPEN
            logger.error(f"Circuit breaker OPEN after {self.failure_count} failures")

    def record_success(self):
        if self.state == CircuitState.HALF_OPEN:
            self.state = CircuitState.CLOSED
            self.failure_count = 0
            logger.info("Circuit breaker CLOSED - provider recovered")
"}

Checkpoint та відновлення задачі

Для тривалих задач (>1 хв) зберігаємо прогрес у Redis:

@dataclass
class AgentCheckpoint:
    task_id: str
    step_index: int
    completed_steps: list[StepResult]
    state: dict  # довільний стан агента
    saved_at: datetime

class CheckpointManager:
    def __init__(self, storage: Redis):
        self.storage = storage

    async def save(self, checkpoint: AgentCheckpoint):
        key = f"checkpoint:{checkpoint.task_id}"
        await self.storage.setex(
            key,
            3600,  # 1 година TTL
            pickle.dumps(checkpoint)
        )

    async def load(self, task_id: str) -> AgentCheckpoint | None:
        key = f"checkpoint:{task_id}"
        data = await self.storage.get(key)
        return pickle.loads(data) if data else None

    async def resume_or_start(self, task: AgentTask) -> AgentCheckpoint:
        existing = await self.load(task.id)
        if existing:
            logger.info(f"Resuming task {task.id} from step {existing.step_index}")
            return existing
        return AgentCheckpoint(
            task_id=task.id,
            step_index=0,
            completed_steps=[],
            state={},
            saved_at=datetime.utcnow()
        )

Human escalation при нерозв'язних помилках

class EscalationPolicy:
    MAX_RETRIES = 3
    MAX_FALLBACK_ATTEMPTS = 2

    async def handle_failure(
        self, task: AgentTask, error: Exception, retry_count: int
    ) -> EscalationDecision:
        if retry_count < self.MAX_RETRIES and self._is_retriable(error):
            return EscalationDecision(action="retry", delay_seconds=2 ** retry_count)

        if isinstance(error, ToolUnavailableError):
            return EscalationDecision(action="use_fallback_tool", tool=self._get_fallback_tool(error.tool))

        # Ескалація до людини
        await self.notify_human(task, error, retry_count)
        return EscalationDecision(
            action="escalate",
            message=f"Task {task.id} requires human intervention after {retry_count} retries: {error}"
        )

Етапи впровадження відмовостійкості

Ми працюємо за перевіреним процесом:

  1. Аналітика (1-2 дні): аудит поточної архітектури, виявлення єдиних точок відмови, збір вимог за RTO/RPO. Для багатоагентної резервації важливо визначити критичні сценарії.
  2. Проектування (3-5 днів): вибір патернів (retry, circuit breaker, checkpoint), прототипування інтеграції з провайдерами.
  3. Реалізація (2-4 тижні): написання коду, налаштування circuit breaker'ів, розгортання checkpoint storage, налаштування ескалації.
  4. Тестування (1 тиждень): chaos testing — емуляція відмов LLM API, падіння інструментів, перевантажень. Вимірюємо p99 latency та відсоток успішних відновлень.
  5. Деплой та документація (2-3 дні): канарейковий rollout, моніторинг усіх шарів, написання runbook'ів.

Додатково проводимо навантажувальне тестування з емуляцією збоїв у кожному шарі. Це дозволяє виявити приховані проблеми, наприклад, несиметричні таймаути між різними провайдерами.

Порівняння шарів відмовостійкості

Шар Компонент Патерн Час відновлення
LLM Провайдери Fallback + circuit breaker <500 мс
Інструменти API виклики Retry + exponential backoff <10 сек
Агент Логіка задачі Checkpoint + resume <100 мс
Оркестратор Розподіл Health check + reassign <1 сек

Строки та що входить

Орієнтовні строки: від 2 до 6 тижнів залежно від складності системи та кількості провайдерів. Вартість розраховується індивідуально після аудиту.

В результати роботи входить:

  • Впровадження fallback LLM клієнта з circuit breaker
  • Checkpoint система на Redis (або іншому сховищі)
  • Політика human escalation з інтеграцією в месенджер
  • Тестовий сценарій chaos testing
  • Документація (runbook, архітектурна схема)
  • Навчання команди (1 година)
  • Гарантія на реалізовані компоненти 3 місяці
Приклад конфігурації circuit breaker для production
circuit_breaker: failure_threshold: 5 reset_timeout: 60 half_open_max_requests: 1 monitor_interval: 10 

Налаштування підбирається під p99 latency провайдера. Для OpenAI з типовою затримкою 2-3 секунди використовуйте reset_timeout 60 секунд, для локальної моделі — 10-15 секунд.

Типові помилки при проектуванні

  • Однаковий timeout для всіх провайдерів. Різні LLM API мають різний p99 latency. Налаштовуйте індивідуальні таймаути.
  • Скидання circuit breaker при кожному успіху. Після відкриття ланцюга робіть лише один пробний запит через reset_timeout, інакше провайдер буде навантажуватися помилками.
  • Відсутність деградації. Якщо всі провайдери впали, агент має повідомити про це, а не висіти у нескінченному циклі.

Наш багаторічний досвід: ми реалізували відмовостійкі AI-агенти для 20+ проєктів — від чат-ботів e-commerce до систем автоматизації складів. Отримайте консультацію щодо вашої архітектури: зв'яжіться з нами для аудиту за 1 день. Замовте відмовостійкість, і ваші агенти перестануть боятися збоїв.

Напрямки AI-розробки

Останні роботи

  • Розробка сайту компанії B2B ADVANCE
    Розробка сайту компанії B2B ADVANCE
    1543
  • Розробка веб-додатків для компанії FEEDME
    Розробка веб-додатків для компанії FEEDME
    1394
  • Розробка веб-сайту для компанії БЕЛФІНГРУП
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    1081
  • Розробка інтернет магазину для компанії FURNORO
    Розробка інтернет магазину для компанії FURNORO
    1374
  • Розробка логотипу компанії B2B Advance
    Розробка логотипу компанії B2B Advance
    816
  • Розробка веб-додатків для компанії Enviok
    Розробка веб-додатків для компанії Enviok
    1142