Настроить эскалацию человеку через 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-sdk | pip install slack-sdk |
| Confidence-модуль агента | Симулировать или использовать встроенный confidence (например, softmax logits LLM) |
| Тестовые запросы пользователей | Набор из 5–10 фраз разной сложности (часть – низкий confidence) |
Если нет реального Slack-воркспейса — симулируем:
- Установить ngrok для создания временного публичного эндпоинта.
- Создать простой HTTP-сервер на FastAPI, который принимает POST-запросы с сообщениями и выводит их в консоль (эмуляция Slack).
- Настроить агент так, чтобы при эскалации он отправлял запрос на
localhost:8000/slack-emulate. - Имитировать ответ оператора ручным возвратом фиксированного JSON-ответа.
3. Технологический стек
| Компонент | Инструменты | Назначение |
|---|---|---|
| AI-агент | LangChain / LlamaIndex / кастомный Python-класс | Основная логика и принятие решения об эскалации |
| Confidence-механизм | Softmax logits / логика падения confidence | Порог 0.6 |
| Slack API | slack-sdk (Python), Slack Events API | Отправка сообщений, получение ответов |
| Обработка вебхуков | FastAPI / Flask | Прием callback от Slack (если нужен интерактивный ответ) |
| Конфигурация | YAML / config.py | Параметры порога, токены, channel_id |
| Тестирование | pytest + requests | Проверка эскалации и ответа |
4. Этапы выполнения
Этап 1: Настройка Slack-интеграции (30–60 минут)
Действия
-
Создать Slack-приложение
- Зайти на https://api.[slack](/wiki/Slack).com/apps и нажать "Create New App".
- Выбрать "From scratch", задать имя (например, "Agent Escalation Bot").
- Добавить scope:
chat:write,commands, channels:join (для бота). - Установить приложение в свой тестовый воркспейс.
-
Получить токен и channel_id
-
Проверить отправку сообщения Написать простой 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"]) -
Настроить интерактивность (опционально, для приёма ответов от оператора)
Ожидаемый результат этапа Slack-бот отправляет тестовое сообщение в нужный канал.
Этап 2: Интеграция confidence в агента (45–90 минут)
Действия
-
Определить интерфейс confidence В классе агента добавить метод get_confidence(response, context) -> float. Для простоты реализовать симуляцию: случайное число от 0.1 до 0.9 на основе длины ответа или заранее заданной “сложности” вопроса.
-
Реализовать точку эскалации В основном цикле агента после генерации ответа:
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} -
Форматировать сообщение для 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"} ] } ] } -
Отправлять в Slack через SDK Использовать
client.chat_postMessageс блоками.
Ожидаемый результат этапа Агент перестаёт отвечать, когда confidence < 0.6, и отправляет красивый блок в Slack.
Этап 3: Обработка ответа оператора (45–60 минут)
Действия
-
Создать FastAPI-сервер для приёма интерактивных callback (если используются кнопки)
-
Реализовать модалку ответа
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отправить ответ в оригинальный канал (или вернуть пользователю через агента). -
Завершить цикл
- При получении ответа оператора отправить его пользователю через агента (например, сохранить в БД и уведомить пользователя).
- Записать в лог факт эскалации и ответа.
Ожидаемый результат этапа Оператор может написать ответ в Slack, и этот ответ передаётся пользователю (через агента или напрямую в UI).
Этап 4: Тестирование и доработка (30–60 минут)
Действия
-
Написать 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 -
Интеграционное тестирование с отправкой в Slack
- Запустить агента с тестовыми запросами, часть из которых имеет low confidence.
- Проверить, что в Slack приходят сообщения.
- Нажать кнопку "Принять ответ", написать ответ в модалке — проверить, что ответ появляется в логе агента.
-
Проверить пограничные случаи
- Агент с confidence == 0.6 — не эскалировать.
- Отсутствие интернета — агент логирует ошибку и не зависает.
- Дублирование эскалаций (один запрос эскалирован дважды) — добавить уникальный
idи проверку на dedup.
Ожидаемый результат этапа Все сценарии работают; эскалация происходит only при confidence < 0.6; оператор может ответить.
Этап 5: Документация и финализация (20–30 минут)
Действия
- Записать в README:
- Как установить зависимости, токены.
- Пример вызова агента с эскалацией.
- Скриншоты Slack-сообщения и модалки.
- Закоммитить код в Git с тегами.
- (Опционально) Развернуть агента на простом хостинге (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.py– FastAPI-приложение для приёма 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 |
| 218 | Unit-тестирование AI-агентов с mock LLM |
| 307 | De-dup эскалаций при повторных запросах |
| 412 | Передача контекста диалога между агентом и оператором |
| 558 | Анализ confidence на основе softmax logits |
10. Чек-лист самопроверки
- Я настроил Slack-приложение и получил рабочий токен.
- Мой агент умеет вычислять confidence и передавать его в функцию эскалации.
- При confidence < 0.6 в Slack приходит сообщение с нужными блоками.
- Я обработал случаи, когда Slack API возвращает ошибку (таймаут, invalid_token).
- Ответ оператора (из модального окна) приходит агенту и логируется.
- Я написал хотя бы один тест, который проверяет, что эскалация не происходит при confidence == 0.6.
- Весь код хранится в Git, в README есть инструкция по запуску.