LLM-агент на первой линии поддержки: архитектура, интеграция с helpdesk и грабли
Запустили пилот LLM-агента для первой линии: агент закрывает около 40% тикетов без оператора. Рассказываем архитектуру, интеграцию с helpdesk и что пошло не так.
LLM-агенты в ITSM: первые production-деплои в крупных российских компаниях - осень 2025
Несколько месяцев назад один из заказчиков - крупная сервисная компания с helpdesk на несколько тысяч тикетов в месяц - поставил задачу: посмотреть, реально ли научить LLM-агента закрывать хотя бы часть обращений первой линии без живого оператора. Не чат-бота с деревом диалогов, а именно агента, который умеет читать тикет, обращаться к внутренним системам и принимать решение. Сейчас пилот работает в production несколько недель, результаты есть - и хорошие, и неожиданные.
Контекст задачи
Первая линия поддержки у заказчика - классический зоопарк: пароли, права доступа, «не работает принтер», «как сделать отчёт в 1С», сброс MFA, перезапуск зависшего сервиса. Операторов достаточно, но рутина убивает мотивацию, и текучка первой линии - хроническая проблема. Идея не в том, чтобы уволить людей, а в том, чтобы агент брал простые повторяющиеся обращения, а операторы занимались нетривиальными случаями.
Helpdesk у заказчика - Naumen Service Desk. Есть REST API, есть база знаний в Confluence, есть AD, есть несколько внутренних систем с API. Это важно: агент без интеграций - это просто дорогой FAQ.
Архитектура, которую в итоге выбрали
Перебрали несколько вариантов. Остановились на следующей схеме:
Naumen SD (webhook) -> оркестратор (Python) -> LLM + tool calls -> действие
Оркестратор - небольшой Python-сервис, который принимает вебхук от Naumen при создании тикета, формирует начальный контекст (тип обращения, приоритет, приложенные файлы, история аналогичных тикетов из векторной базы) и передаёт агенту.
LLM - локальный инференс на GPU, модель Mistral с дообучением на корпоративных данных. Про локальный инференс писали отдельно. Облачные API рассматривали, но у заказчика данные внутри периметра, часть тикетов содержит персональные данные сотрудников - поэтому GigaChat и YandexGPT для этого сценария не подошли.
Tool calls - набор инструментов, которые агент может вызывать:
- reset_password - сброс пароля в AD через PowerShell-обёртку
- add_to_group - добавление в группу AD
- get_kb_article - поиск по базе знаний в Confluence
- close_ticket - закрытие тикета в Naumen с комментарием
- escalate_ticket - передача тикету статуса «второй линии» с пометкой причины
- send_user_message - отправка сообщения пользователю в тикете
Инструменты написаны с явным логированием каждого вызова и результата - это критично для аудита и для последующего анализа ошибок.
Что пошло не по плану
Честно: первые две недели пилота были довольно занимательными в смехотворном смысле.
Проблема первая - классификация. Агент несколько раз сбрасывал пароль пользователю, который в тикете жаловался не на «забытый пароль», а на «не могу войти, пишет неверный пароль». Разница? Во втором случае проблема могла быть в блокировке учётной записи, в истёкшем пароле или в том, что пользователь просто ошибается в раскладке. Сброс пароля - не всегда правильное действие. Потратили время на уточнение промпта и добавили промежуточный шаг: перед действием агент запрашивает статус учётки в AD и только потом решает, что делать.
Проблема вторая - галлюцинации в KB-поиске. Агент иногда формулировал ответ пользователю, уверенно смешивая реальную статью из базы знаний с тем, что «логично предположить». Например, в статье о порядке подключения к VPN была одна версия клиента, агент в ответе упоминал более новую версию, которой в базе знаний не было. Решение - явный промпт «отвечай только на основе текста статьи, не добавляй от себя», и дополнительная проверка: если агент не нашёл статью с уверенностью выше порога - эскалирует, не фантазирует.
Проблема третья - тикеты без чёткой структуры. Пользователи пишут как умеют: «всё сломалось», «помогите», «не работает с утра». Агент пытался что-то сделать, но в 15-20% случаев просто не мог определить тип обращения. Добавили шаг clarification request: агент задаёт уточняющий вопрос и ждёт ответа. Это немного увеличило time-to-resolution для таких тикетов, но зато снизило процент некорректных действий почти до нуля.
Что получилось
После трёх недель настройки и нескольких итераций:
- агент обрабатывает около 40% тикетов полностью - от получения до закрытия без вмешательства оператора
- из них 85% - это сброс паролей, разблокировка учёток, ответы на вопросы по инструкциям, перезапуск зависших сервисов через утверждённые скрипты
- среднее время закрытия тикета агентом - несколько минут против нескольких часов у живого оператора в рабочее время (в нерабочее - агент вообще вне конкуренции)
- операторы первой линии действительно разгрузились - это уже видно по субъективным отзывам
Оставшиеся 60% тикетов агент эскалирует с пометкой, что именно он попробовал, что выяснил и почему передаёт человеку. Это, кстати, оказалось неожиданно полезным: оператор получает тикет уже с частичной диагностикой, а не с голым «всё сломалось».
Что важно для интеграционного проекта такого типа
Несколько вещей, которые мы теперь говорим на старте подобных задач.
Список разрешённых действий - сначала узкий. Соблазн дать агенту широкие права велик: чем больше умеет, тем больше закроет. На практике - лучше начать с двух-трёх безопасных операций, отработать их до надёжности, потом расширять. Сброс пароля в AD - одна из самых безопасных точек входа, потому что она обратима и хорошо аудируется.
Логирование каждого tool call обязательно. Без этого невозможно разобраться, почему агент принял то или иное решение. Особенно когда что-то пошло не так и нужно объяснить заказчику.
Человек в петле - не слабость архитектуры. Эскалация - это нормальное завершение цикла, не ошибка. Агент, который эскалирует честно и с контекстом, полезнее агента, который пытается закрыть всё любой ценой.
Пилот продолжается. Следующий этап - подключить ещё несколько инструментов и посмотреть, как поведёт себя агент на более сложных обращениях. Пока осторожно, но направление выглядит рабочим.