Настроить эскалацию человеку через Slack при низком confidence агента

ТЕХНИЧЕСКОЕ ЗАДАНИЕ: Настроить эскалацию человеку через Slack при низком confidence агента

1. Цель задачи

Реализовать механизм эскалации от AI-агента к человеку-оператору, когда уверенность агента]] в правильности ответа падает ниже заданного порога (confidence < 0.6). Агент должен остановить автономное выполнение и передать всю необходимую информацию (контекст диалога, причину эскалации, запрос пользователя) в канал Slack, где оператор может принять решение или ответить пользователю напрямую. Задача развивает навыки интеграции AI-систем с коммуникационными инструментами, проектирования надежных пайплайнов hand-off и обработки пограничных состояний.

Ключевой результат Рабочий прототип агента, который при confidence < 0.6 отправляет структурированное уведомление в Slack-канал со всем контекстом и позволяет оператору ответить через Slack (например, через модальное окно или reply).

2. Исходные данные

Перед началом необходимо иметь:

Что нужноОткуда взять
Рабочая AI-агентская система (на Python)Собственный пет-проект, фреймворк LangChain/LlamaIndex или любой агент с функцией predict() и confidence score
Slack workspace (можно тестовый)Бесплатный Slack-аккаунт или существующий воркспейс
Slack-приложение с правами на отправку сообщений и создание модальных оконСоздать в api.slack.com (или использовать готовый Slack App с webhook)
Python-библиотека slack-sdkpip install slack-sdk
Confidence-модуль агентаСимулировать или использовать встроенный confidence (например, softmax logits LLM)
Тестовые запросы пользователейНабор из 5–10 фраз разной сложности (часть – низкий confidence)

Если нет реального Slack-воркспейса — симулируем:

  1. Установить ngrok для создания временного публичного эндпоинта.
  2. Создать простой HTTP-сервер на FastAPI, который принимает POST-запросы с сообщениями и выводит их в консоль (эмуляция Slack).
  3. Настроить агент так, чтобы при эскалации он отправлял запрос на localhost:8000/slack-emulate.
  4. Имитировать ответ оператора ручным возвратом фиксированного JSON-ответа.

3. Технологический стек

КомпонентИнструментыНазначение
AI-агентLangChain / LlamaIndex / кастомный Python-классОсновная логика и принятие решения об эскалации
Confidence-механизмSoftmax logits / логика падения confidenceПорог 0.6
Slack APIslack-sdk (Python), Slack Events APIОтправка сообщений, получение ответов
Обработка вебхуковFastAPI / FlaskПрием callback от Slack (если нужен интерактивный ответ)
КонфигурацияYAML / config.pyПараметры порога, токены, channel_id
Тестированиеpytest + requestsПроверка эскалации и ответа

4. Этапы выполнения

Этап 1: Настройка Slack-интеграции (30–60 минут)

Действия

  1. Создать Slack-приложение

    • Зайти на https://api.[slack](/wiki/Slack).com/apps и нажать "Create New App".
    • Выбрать "From scratch", задать имя (например, "Agent Escalation Bot").
    • Добавить scope: chat:write, commands, channels:join (для бота).
    • Установить приложение в свой тестовый воркспейс.
  2. Получить токен и channel_id

    • Скопировать Bot User OAuth Token (начинается с xoxb-...).
    • Создать публичный канал #agent-escalations и пригласить бота (если не входит при установке).
    • Узнать ID канала через веб-интерфейс (последний сегмент URL) или через Slack API.
  3. Проверить отправку сообщения Написать простой Python-скрипт:

    from slack_sdk import WebClient
    import os
    client = WebClient(token=os.getenv("SLACK_BOT_TOKEN"))
    response = client.chat_postMessage(channel="C1234567", text="Test escalation")
    print(response["ok"])
    
  4. Настроить интерактивность (опционально, для приёма ответов от оператора)

    • В настройках Slack-приложения включить Interactivity & Shortcuts.
    • Указать Request URL: опубликовать FastAPI-эндпоинт (например, через ngrok).
    • Создать модальное окно с полем "Ответ пользователю".

Ожидаемый результат этапа Slack-бот отправляет тестовое сообщение в нужный канал.

Этап 2: Интеграция confidence в агента (45–90 минут)

Действия

  1. Определить интерфейс confidence В классе агента добавить метод get_confidence(response, context) -> float. Для простоты реализовать симуляцию: случайное число от 0.1 до 0.9 на основе длины ответа или заранее заданной “сложности” вопроса.

  2. Реализовать точку эскалации В основном цикле агента после генерации ответа:

    confidence = agent.get_confidence(response, context)
    if confidence < 0.6:
        escalate_to_slack(conversation_id, user_query, agent_context, confidence)
        return {"status": "escalated", "confidence": confidence}
    else:
        return {"status": "success", "answer": response}
    
  3. Форматировать сообщение для Slack Создать функцию, формирующую блок сообщения:

    {
        "blocks": [
            {
                "type": "section",
                "text": {"type": "mrkdwn", "text": "*🚨 Эскалация* от агента\n> *Вопрос пользователя:* {user_query}\n> *Причина:* confidence = {confidence}\n> *ID диалога:* {conv_id}"}
            },
            {
                "type": "section",
                "text": {"type": "mrkdwn", "text": "*Контекст:*\n{context_preview}"}
            },
            {
                "type": "actions",
                "elements": [
                    {"type": "button", "text": "Принять ответ", "value": "accept"},
                    {"type": "button", "text": "Отклонить", "value": "reject"}
                ]
            }
        ]
    }
    
  4. Отправлять в Slack через SDK Использовать client.chat_postMessage с блоками.

Ожидаемый результат этапа Агент перестаёт отвечать, когда confidence < 0.6, и отправляет красивый блок в Slack.

Этап 3: Обработка ответа оператора (45–60 минут)

Действия

  1. Создать FastAPI-сервер для приёма интерактивных callback (если используются кнопки)

    • Эндпоинт POST /slack/actions с проверкой подписи.
    • При получении payload["actions"][0]["value"]:
      • Если "accept" — открыть модальное окно с полем для текста ответа.
      • Если "reject" — отправить пользователю уведомление "Агент эскалировал, оператор пока не ответил".
  2. Реализовать модалку ответа

    def open_modal(trigger_id, response_url):
        view = {
            "type": "modal",
            "title": {"type": "plain_text", "text": "Ответ пользователю"},
            "blocks": [
                {
                    "type": "input",
                    "block_id": "answer_block",
                    "element": {"type": "plain_text_input", "action_id": "answer"},
                    "label": {"type": "plain_text", "text": "Ваш ответ"}
                }
            ],
            "private_metadata": conversation_id,
        }
        client.views_open(trigger_id=trigger_id, view=view)
    

    После отправки модального окна по view_submission отправить ответ в оригинальный канал (или вернуть пользователю через агента).

  3. Завершить цикл

    • При получении ответа оператора отправить его пользователю через агента (например, сохранить в БД и уведомить пользователя).
    • Записать в лог факт эскалации и ответа.

Ожидаемый результат этапа Оператор может написать ответ в Slack, и этот ответ передаётся пользователю (через агента или напрямую в UI).

Этап 4: Тестирование и доработка (30–60 минут)

Действия

  1. Написать unit-тесты на логику confidence

    def test_confidence_below_threshold():
        agent = Agent(threshold=0.6)
        # mock контекст
        assert agent.should_escalate(0.5) == True
        assert agent.should_escalate(0.7) == False
    
  2. Интеграционное тестирование с отправкой в Slack

    • Запустить агента с тестовыми запросами, часть из которых имеет low confidence.
    • Проверить, что в Slack приходят сообщения.
    • Нажать кнопку "Принять ответ", написать ответ в модалке — проверить, что ответ появляется в логе агента.
  3. Проверить пограничные случаи

    • Агент с confidence == 0.6 — не эскалировать.
    • Отсутствие интернета — агент логирует ошибку и не зависает.
    • Дублирование эскалаций (один запрос эскалирован дважды) — добавить уникальный id и проверку на dedup.

Ожидаемый результат этапа Все сценарии работают; эскалация происходит only при confidence < 0.6; оператор может ответить.

Этап 5: Документация и финализация (20–30 минут)

Действия

  1. Записать в README:
    • Как установить зависимости, токены.
    • Пример вызова агента с эскалацией.
    • Скриншоты Slack-сообщения и модалки.
  2. Закоммитить код в Git с тегами.
  3. (Опционально) Развернуть агента на простом хостинге (Render, Railway) для демонстрации.

Ожидаемый результат этапа Публичный репозиторий с рабочим кодом и документацией.

5. Критерии приемки (Definition of Done)

  • Slack-бот отправляет сообщение с контекстом при confidence < 0.6.
  • Сообщение включает: текст запроса пользователя, значение confidence, предысторию диалога (последние 3–5 сообщений).
  • Оператор может нажать кнопку "Принять ответ" и через модальное окно отправить ответ пользователю.
  • Ответ оператора доставляется пользователю (через агента или напрямую) в течение 5 секунд.
  • Агент не эскалирует один и тот же запрос повторно (предотвращение зацикливания).
  • При confidence >= 0.6 агент отвечает самостоятельно, без эскалации.
  • Весь процесс логируется (файл logs/escations.log).
  • Код покрыт минимум 3 unit-тестами и 1 интеграционным тестом (с использованием mock Slack).
  • При ошибке Slack API агент корректно обрабатывает её (логирует, но не впадает в бесконечный цикл).
  • Порог confidence настраивается через конфигурацию (файл config.yaml или переменная окружения).

6. Ожидаемый результат

  • Файл/артефакт
    • agent.py – основной класс агента с логикой эскалации.
    • slack_integration.py – функции отправки сообщений и обработки callback.
    • server.pyFastAPI-приложение для приёма Slack Actions.
    • config.yaml – файл с настройками (SLACK_TOKEN, CHANNEL_ID, THRESHOLD).
    • tests/ – папка с тестами.
    • README.md – документация с инструкцией по запуску.
  • Содержание агент, способный работать в двух режимах (автономно и с эскалацией). При эскалации создаётся структурированное сообщение в Slack, оператор может дать ответ, который обратно передаётся пользователю.
  • Опционально дашборд Grafana с метриками количества эскалаций (если подключена БД метрик).

7. Возможные сложности и их решение

СложностьРешение
Нет реального Slack-воркспейсаИспользовать эмулятор (локальный FastAPI + имитация токена, печать в консоль).
Confidence-модуль не реализованСоздать заглушку: random() или на основе длины ответа (короткий ответ = lower confidence).
Slack API не принимает блоки из-за неверного форматаИспользовать Slack Block Kit Builder для валидации. Включить blocks вместо attachments.
Ответ оператора не доходит до пользователя (нет real-time UI)Сохранять ответ в локальную БД (SQLite) и показывать в логах агента. Для полноценной передачи можно завести WebSocket.
Агент эскалирует слишком часто (низкий threshold)Сделать порог настраиваемым, по умолчанию 0.6. Проанализировать метрики confidence на реальных данных.
Сложность с дедупликацией эскалацийИспользовать хэш от user_query + timestamp. Хранить отправленные conversation_id в set.

8. Бюджет времени (оценка)

ЭтапВремя
Этап 1: Настройка Slack-интеграции30–60 мин
Этап 2: Интеграция confidence в агента45–90 мин
Этап 3: Обработка ответа оператора45–60 мин
Этап 4: Тестирование и доработка30–60 мин
Этап 5: Документация и финализация20–30 мин
Итого~4–5 часов

Примечание для первого раза: возможно увеличение на 1–1.5 часа из-за отладки Slack API и форматирования блоков.

9. Связанные вопросы из базы знаний

ВопросТема
12Как спроектировать hand-off от AI к человеку в production
42Как выбирать порог confidence для эскалации
58Интеграция Slack-бота с Python: Best practices
71Логирование и мониторинг эскалаций
93Обработка rate limits Slack API
104Проектирование модальных окон Slack: View Submission
218Unit-тестирование AI-агентов с mock LLM
307De-dup эскалаций при повторных запросах
412Передача контекста диалога между агентом и оператором
558Анализ confidence на основе softmax logits

10. Чек-лист самопроверки

  • Я настроил Slack-приложение и получил рабочий токен.
  • Мой агент умеет вычислять confidence и передавать его в функцию эскалации.
  • При confidence < 0.6 в Slack приходит сообщение с нужными блоками.
  • Я обработал случаи, когда Slack API возвращает ошибку (таймаут, invalid_token).
  • Ответ оператора (из модального окна) приходит агенту и логируется.
  • Я написал хотя бы один тест, который проверяет, что эскалация не происходит при confidence == 0.6.
  • Весь код хранится в Git, в README есть инструкция по запуску.