Агент с human-in-the-loop — эскалация человеку при low confidence
ТЕХНИЧЕСКОЕ ЗАДАНИЕ: Агент с human-in-the-loop — эскалация человеку при low confidence
1. Цель задачи
Разработать агента (чат-бота или ассистента), который способен самостоятельно обрабатывать запросы, но при низкой уверенности в правильности ответа или невозможности однозначно интерпретировать запрос передаёт управление человеку-оператору. Реализовать механизм оценки уверенности (confidence score) и порог эскалации, при котором 10% всех сессий переводятся на человека. Задача имитирует реальный production-сценарий, где автономность агента сочетается с контролем качества.
Ключевой результат Работающий прототип агента, который эскалирует ровно 10% сессий (допустимое отклонение ±2%), а в остальных даёт ответ с качеством не ниже 0.8 по метрике ROUGE-L на тестовом наборе.
2. Исходные данные
Перед началом необходимо подготовить:
| Что нужно | Откуда взять |
|---|---|
| LLM (API или локальная модель) | OpenAI API / Ollama (Llama 3 8B) / Hugging Face |
| Дашборд с историями диалогов | Любая база данных (SQLite, PostgreSQL) или CSV-файл |
| Эталонные ответы для оценки уверенности | Сгенерировать синтетически или взять готовые датасеты (например, DIALOGUE_SUMMARY) |
| Инструмент для расчёта confidence | Python + библиотека (см. стек) |
| Интерфейс для оператора | Telegram бот / Flask веб-интерфейс / Streamlit |
Если нет реальной LLM — симулируем:
- Использовать модель Ollama с локальным запуском ollama pull llama3.2:1b (минимальные требования)
- Для метрики уверенности использовать logprobs (если API поддерживает) или эмбеддинг-расстояние до ближайшего эталона
- Вместо реального оператора — написать скрипт, который принимает эскалацию и выводит запрос в консоль
3. Технологический стек
| Компонент | Инструменты | Назначение |
|---|---|---|
| LLM | Ollama (Llama 3.2 1B), OpenAI GPT-4o-mini | Генерация ответов |
| Оценка уверенности | Logprobs (OpenAI), semantic similarity (sentence-transformers), dropout Monte Carlo | Расчёт confidence score |
| Оркестрация | LangGraph / LangChain | Построение графа с условием эскалации |
| Интерфейс оператора | Telegram Bot (python-telegram-bot) / FastAPI + HTML | Приём эскалированных запросов |
| Хранилище сессий | SQLite + SQLAlchemy / Pandas | Логирование диалогов |
| Метрики | evaluate (Hugging Face) / ROUGE | Оценка качества ответов |
| CI / тесты | PyTest | Проверка эскалации и качества |
4. Этапы выполнения
Этап 1: Проектирование архитектуры и подготовка окружения (1.5 часа)
Действия
-
Определить схему диалога
Составить граф состояний:
user_input→ classify_intent →generate_response→compute_confidence→ если confidence < порога →escalate_to_human→ иначе →respond_to_user
В качестве графа использовать LangGraph (или простой if/else, если стек упрощён).
-
Настроить окружение
conda create -n hital python=3.11 pip install langchain langgraph openai ollama sentence-transformers evaluate rouge-score python-telegram-bot fastapi uvicorn sqlalchemy pandas -
Подготовить базу данных сессий
Модель SQLAlchemy:
class Session(Base): __tablename__ = 'sessions' id = Column(Integer, primary_key=True) user_id = Column(String) messages = Column(JSON) confidence = Column(Float) escalated = Column(Boolean, default=False) human_response = Column(Text, nullable=True)
Ожидаемый результат этапа Запущенное окружение, готовая схема, доступная LLM (локальная или через API).
Этап 2: Реализация агента с оценкой уверенности (3 часа)
Действия
-
Написать класс агента
class Agent: def __init__(self, llm, confidence_threshold: float): self.llm = llm self.threshold = confidence_threshold def compute_confidence(self, query: str, response: str) -> float: # Метод 1: logprobs (если есть) # Метод 2: cosine similarity между эмбеддингами query и эталонных пар # Метод 3: Monte Carlo dropout — несколько прогонов, std аномалий # Здесь используем комбинацию: max(logprobs) + 0.3 * similarity_score pass def decide(self, query: str) -> tuple[str, bool]: response = self.llm.invoke(query) conf = self.compute_confidence(query, response) if conf < self.threshold: return response, True # эскалация return response, False -
Реализовать метрику confidence
Для локальной модели Ollama через ollama.generate получим logprobs. Если модель не выдаёт — используем sentence-transformers: вычисляем эмбеддинг ответа, сравниваем с эмбеддингами эталонных ответов (косинусное расстояние). Чем ближе, тем увереннее.
В качестве дефолта: порог confidence = 0.8.
-
Протестировать на 50 случайных запросах
Запустить агента, собрать распределение confidence. Отрегулировать порог так, чтобы ровно ~10% попадало ниже порога.
Ожидаемый результат этапа Работающий агент, который эскалирует примерно 10% запросов.
Этап 3: Интеграция интерфейса оператора (2 часа)
Действия
-
Создать Telegram-бота
from telegram import Update, InlineKeyboardButton, InlineKeyboardMarkup from telegram.ext import Application, CommandHandler, CallbackQueryHandler async def handle_escalation(update: Update, context): # Принимаем запрос, отправляем оператору keyboard = [[InlineKeyboardButton("Ответить", callback_data='reply')]] await update.message.reply_text( f"Эскалировано: {context.user_data['escalated_query']}", reply_markup=InlineKeyboardMarkup(keyboard) ) -
Интегрировать бота с агентом
- Когда confidence < порога, агент отправляет запрос оператору через очередь (redis / просто хранит в БД)
- Оператор видит сообщение и может ввести ответ
- Ответ возвращается пользователю
-
Реализовать fallback на случай отсутствия оператора
Если оператор не ответил за 5 минут, агент возвращает автоматический ответ: «Ваш запрос передан специалисту, ожидайте ответа в ближайшее время».
Ожидаемый результат этапа Рабочий прототип, в котором эскалированные запросы уходят реальному человеку.
Этап 4: Тестирование, калибровка порога и измерение метрик (2 часа)
Действия
-
Собрать тестовый набор из 200–500 запросов
- Взять из открытых датасетов (например, DSTC, MultiWOZ) или сгенерировать синтетически с помощью LLM
- Для каждого запроса подготовить эталонный ответ
-
Прогнать все запросы через агента
Записать: запрос, ответ агента, confidence, эскалирован ли.
-
Посчитать метрики
- Доля эскалаций
escalated / total(цель 10%) - ROUGE-L для неэскалированных ответов (сравнение с эталоном)
- Время ответа среднее и 95-й перцентиль
- F1 оператора — если есть ответы от человека, сравнить их с эталонными
- Доля эскалаций
-
Настроить порог
Используя бинарный поиск по порогу, добиться ровно 10% эскалаций. Например:
Порог % эскалаций ROUGE-L 0.70 4% 0.85 0.80 9% 0.83 0.90 18% 0.78 0.85 10% 0.82 Выбрать порог 0.85.
Ожидаемый результат этапа Откалиброванный агент с заданной долей эскалаций, подтверждёнными метриками качества.
Этап 5: Документация и демонстрация (1 час)
Действия
-
Написать README для репозитория:
- Архитектура (диаграмма Mermaid)
- Инструкция по запуску
- Как настраивать порог
- Результаты тестирования
-
Подготовить демо-скрипт (10 запусков, 1 эскалация)
-
Сохранить метрики в лог-файл (
metrics.json)
Ожидаемый результат этапа Полный пакет артефактов: код, README, метрики, демо.
5. Критерии приемки (Definition of Done)
- Агент запускается локально или через контейнер (Docker)
- Реализован механизм оценки уверенности (confidence) с документацией метода
- На тестовом наборе ≥200 запросов доля эскалаций равна 10% (±2%)
- Для неэскалированных запросов ROUGE-L ≥ 0.8
- Интерфейс оператора (Telegram или веб) позволяет просматривать и отвечать на эскалированные запросы
- Реализован fallback при отсутствии оператора (автоответ через 5 мин)
- Все сессии логируются в SQLite с полем
escalated - Возможность менять порог конфигурацией (env-переменная)
- Написаны unit-тесты для функции
decide(минимум 3 теста) - README содержит инструкцию по развёртыванию и калибровке
6. Ожидаемый результат
Основной артефакт Репозиторий с кодом агента.
Структура репозитория:
hital-agent/
├── src/
│ ├── agent.py # класс Agent
│ ├── confidence.py # функции оценки уверенности
│ ├── db.py # работа с SQLite
│ ├── telegram_bot.py # бот-оператор
│ └── config.py # конфиги (порог, модель)
├── tests/
│ ├── test_agent.py
│ └── test_confidence.py
├── data/
│ ├── test_queries.json
│ └── metrics.json
├── README.md
└── requirements.txt
Содержимое метрик (metrics.json):
{
"total_queries": 250,
"escalated": 25,
"escalation_rate": 0.10,
"average_rouge_l": 0.82,
"average_confidence": 0.87,
"threshold": 0.85,
"human_response_time_avg_sec": 45,
"fallback_used": 2
}
Дополнительные артефакты (опционально):
- Dockerfile для развёртывания
- Скрипт калибровки порога (
calibrate.py) - Экспорт дашборда Grafana для визуализации эскалаций в реальном времени
7. Возможные сложности и их решение
| Сложность | Решение |
|---|---|
| LLM не возвращает logprobs (Ollama не даёт для всех моделей) | Использовать semantic similarity (sentence-transformers) + Monte Carlo dropout (зашумление embeddings) |
| Интерфейс оператора неудобен для постоянного мониторинга | Использовать Telegram-бота с уведомлениями; добавить кнопку «Ответить» |
| 10% эскалаций — слишком шумная метрика для малой выборки | Увеличить тестовый набор до 500+ запросов; использовать Bootstrap (CI) |
| Ручная калибровка порога отнимает время | Написать скрипт calibrate.py, который бинарным поиском находит порог под заданный % эскалаций |
| Оператор может быть недоступен | Реализовать автоответ после таймаута; можно добавить queue с приоритетами |
| Качество ответов падает после эскалации (оператор медленный) | Логировать время ответа оператора; в метриках учитывать только время до fallback |
8. Бюджет времени (оценка)
| Этап | Время (часы) |
|---|---|
| Этап 1: Проектирование и окружение | 1.5 |
| Этап 2: Реализация агента | 3.0 |
| Этап 3: Интерфейс оператора | 2.0 |
| Этап 4: Тестирование и калибровка | 2.0 |
| Этап 5: Документация и демо | 1.0 |
| Буфер на ошибки | 0.5 |
| Итого | 10.0 |
Примечание Для первого раза рекомендуется выделить 12 часов с учётом настройки LLM (скачивание модели, отладка logprobs).
9. Связанные вопросы из базы знаний
| Вопрос | Тема |
|---|---|
| 5 | Что такое confidence score и как его измерить? |
| 18 | Как работают logprobs в LLM? |
| 42 | Human-in-the-loop: архитектурные паттерны |
| 77 | Оценка качества RAG-систем (метрики ROUGE, BLEU) |
| 101 | Графы LangGraph: conditional edges |
| 143 | Обработка исключений и fallback в LLM-агентах |
| 211 | CI для AI-систем: тестирование порогов и метрик |
| 289 | Оценка неопределённости через Monte Carlo dropout |
| 301 | Сбор датасетов для тестирования чат-ботов |
| 405 | Docker-контейнеризация LLM-приложений |
10. Чек-лист самопроверки
- Я разобрал схему агента и уверен, что понимаю, как confidence влияет на эскалацию
- Я выбрал метод оценки уверенности, подходящий для моей LLM (logprobs / similarity / dropout)
- Я написал скрипт калибровки порога и добился 10% эскалаций на тестовом наборе
- Я протестировал интерфейс оператора (Telegram/FastAPI) с имитацией ответа
- Я задокументировал, как поменять порог и какие метрики считаются успешными
- Я проверил, что при отсутствии оператора срабатывает fallback-автоответ
- Я сохранил все артефакты (логи, метрики, config) в репозиторий