Как проектировать fallback-цепи (агент А → агент Б → человек)?

Краткий тезис

Fallback-цепь — это последовательность исполнителей (агентов или людей), в которой каждый следующий обрабатывает запрос, если предыдущий не справился. Проектирование такой цепи требует чётких критериев переключения (таймаут, ошибка, confidence|низкая уверенность), сохранения контекста между шагами и определения, когда передавать управление человеку. Правильная fallback-цепь повышает robustness (устойчивость) системы и снижает нагрузку на операторов.


1. Термин: Fallback (запасной вариант) и Fallback-цепь

Fallback — механизм, при котором, если основной компонент не может корректно выполнить задачу, управление передаётся следующему по приоритету компоненту. Fallback-цепь — упорядоченный список таких компонентов.

Пример: agent|специализированный агент → общий агент → оператор-человек. Если специалист (агент А) не справился, запрос идёт к общему агенту (агент Б), а если и тот не может ответить — запрос эскалируется человеку.

Ключевая идея: чем дальше по цепи, тем выше ресурсоёмкость (стоимость LLM-вызова, время человека), но тем шире охват решаемых задач. Fallback-цепь балансирует между скоростью автономной обработки и качеством человеческого внимания.


2. Зачем нужны fallback-цепи в Agentic RAG

В сложных Agentic RAG системах (вопросы 760-762) один агент не может покрыть все сценарии. Варианты использования:

  • Специализация агентов агент А обучен отвечать на вопросы по финансам, агент Б — по техподдержке. Если А не знает, передаёт Б.
  • Обработка неопределённости агент обнаружил, что его уверенность в ответе ниже порога → переключается на более надёжного.
  • Соблюдение SLA при превышении времени ответа агента (таймаут) запрос эскалируется на другой сервис или человеку.
  • Контроль безопасности агент может запросить подтверждение у человека при опасных действиях.

Без fallback-цепей система либо жестко отказывает (user experience падает), либо зацикливается на ошибках.


3. Ключевые параметры проектирования

3.1 Критерии переключения (switch triggers)

Определяют, когда запрос передаётся по цепи. Основные варианты:

КритерийОписаниеПример реализации
Таймаут (timeout)Агент не уложился в лимит времениif elapsed > 5s: fallback()
Код ошибки (error code)Агент вернул ошибку (парсинг, валидация)if response.error in ["not_found","unsupported"]
Низкая уверенность (confidence score)Агент вычислил метрику уверенности ниже порогаif confidence < 0.7: fallback()
Отсутствие результата (null/empty)Агент не сгенерировал ответif response.text is None or response.text == ""
Флаг эскалации (escalation flag)Агент сам решил передать задачу (например, если запрос требует человеческого суждения)if response.requires_human: fallback_to_human()

3.2 Порядок агентов в цепи

Типичная цепь: Специализированный агент → Генеральный агент → Человек.

  • Агент А (специалист): дешёвый, быстрый, обучен на узкий домен. Покрывает 70-80% запросов.
  • Агент Б (универсал): более мощная модель (GPT-4, Claude), более широкие знания, но дороже и медленнее. Покрывает ещё 15-20%.
  • Человек (оператор): максимально качественный, но медленный и дорогой. Только самые сложные или сомнительные случаи.

3.3 Сохранение контекста между переходами

При передаче задачи следующий исполнитель должен получить всю историю: исходный запрос, действия предыдущего агента, частичные результаты, ошибки.

Без контекста агент Б начнёт с нуля — потеря времени и качества. Рекомендуется передавать структурированный объект:

class FallbackContext:
    request: str
    history: List[AgentResult]  # результаты каждого шага
    current_step: int
    metadata: dict  # тайминги, версии моделей

Паттерн «chain of responsibility» позволяет передавать контекст последовательно.


4. Архитектурные паттерны реализаций

4.1 Последовательная цепь (Sequential chain)

Проще всего: if A fails → B → C.

async def process_request(request: str) -> Response:
    context = FallbackContext(request=request)

    # Агент А
    result_a = await agent_a.process(context)
    if result_a.success:
        return result_a

    # Агент Б
    context.history.append(result_a)
    result_b = await agent_b.process(context)
    if result_b.success:
        return result_b

    # Человек
    context.history.append(result_b)
    result_human = await human_operator.handle(context)
    return result_human

4.2 Параллельный fallback с таймаутом

Запустить несколько агентов параллельно, использовать первый успешный ответ (race-based). Подходит для SLA.

async def race_fallback(request, agents):
    tasks = [asyncio.wait_for(agent.process(request), timeout=5) for agent in agents]
    for coro in asyncio.as_completed(tasks):
        try:
            result = await coro
            if result.success:
                return result
        except asyncio.TimeoutError:
            continue
    return await human_operator(request)

4.3 Вложенные цепи (nested fallback)

Агент А может внутри своей обработки вызвать другой fallback перед полным отказом (например, повторный запрос с другим промптом).


5. Проектирование эскалации человеку

Человек-оператор — последнее звено. Важные аспекты:

  • Контекстная панель оператору нужно показать всю цепочку: запрос, действия каждого агента, причины fallback, частичные ответы.
  • Интерфейс для коррекции оператор может отредактировать ответ или дать фидбэк, который пойдёт на улучшение агентов (fine-tuning loop).
  • SLA на человека время ответа оператора может быть 5-30 минут. Система должна сообщить пользователю, что запрос передан человеку.

Пример интерфейса передачи

{
  "request": "Как оплатить счёт за май?",
  "agent_results": [
    {"agent": "finance_specialist", "success": false, "error": "не найдена инструкция для региона"},
    {"agent": "general_assistant", "success": true, "answer": "...", "confidence": 0.4, "reason": "confidence_below_threshold"}
  ],
  "reason": "confidence_low",
  "original_metadata": {"user_id": "u123", "timestamp": "...", "channel": "chat"}
}

6. Валидация и тестирование fallback-цепей

  • Юнит-тесты проверить, что при каждом типе ошибки срабатывает нужный fallback.
  • Интеграционные тесты имитировать реальные запросы, проверять, что цепь доходит до человека в сложных случаях.
  • Мониторинг метрик
    • Процент запросов, обработанных каждым звеном.
    • Среднее время ответа с учётом fallback-задержек.
    • Количество эскалаций человеку (должно быть небольшим, <5%).
    • Отзыв человека о корректности предыдущих агентов.

7. Ошибки при проектировании

  • Отсутствие критериев выхода если агент А никогда не выдаёт ошибку, fallback не сработает.
  • Потеря контекста каждый следующий агент не видит, что делал предыдущий.
  • Бесконечные циклы агент Б передаёт обратно агенту А. Нужен строгий счётчик шагов.
  • Слишком строгие таймауты агент часто не успевает, но мог бы ответить → лишние эскалации.

8. Сравнение с другими подходами

ПодходПреимуществаНедостатки
Fallback-цепь (chain of responsibility)Простота, прозрачность, контрольЗадержки от последовательных вызовов
Параллельный запуск (race)Минимальная задержкаИзбыточные вызовы моделей
Агент-оркестратор (supervisor agent)Гибкость, адаптивностьСложность, риск единой точки отказа
Human-in-the-loop (только человек)Максимальное качествоВысокая стоимость, низкая масштабируемость

9. Пет-проект для закрепления

Задача Реализовать fallback-цепь для чат-бота службы поддержки интернет-провайдера.

Инструменты Python 3.10+, asyncio, OpenAI API (gpt-3.5-turbo для агента А, gpt-4 для агента Б), простой UI (Streamlit/FastAPI) для отображения оператору.

Шаги:

  1. Создать класс FallbackContext с полями: request, history, current_step.
  2. Реализовать агента А — специалист по тарифам и подключению. Если не может ответить (низкая уверенность или определённые ключевые слова) — возвращает fallback=True.
  3. Реализовать агента Б — универсальный LLM с доступом к базе знаний. При ошибке или низкой уверенности — эскалация человеку.
  4. Написать оркестратор, который проверяет результат каждого агента и передаёт контекст дальше.
  5. Создать страницу оператора, на которой отображается вся цепочка и есть кнопка «Ответить».
  6. Добавить мониторинг — логи с метриками (шаги, причина fallback, время).

Ожидаемый результат Система, которая на 70-80% запросов отвечает через агента А, на 15-20% через агента Б, и лишь 5% идёт к человеку. Вы сможете увидеть в логах, какие запросы эскалируются и почему.


10. Связь с другими вопросами

ВопросТема
760Проектирование multi-agent систем
761Оркестрация агентов (supervisor vs swarm)
762Мониторинг и логирование в агентных системах
764Human-in-the-loop: когда и как внедрять
768Оценка качества работы агентов (метрики)

Навигация