
Привет! Меня зовут Владимир Дробот, я SRE-лид и руководитель центра техподдержки кластера рекламных технологий компании МТС Web Services. Наша команда отвечает за вторую линию саппорта: мы разбираем сложные инциденты, ищем корни проблем и передаем разработчикам те баги, которые упираются в код или архитектуру.
Поиск нужной инструкции в заросшей документации Confluence и Jira — головная боль для многих команд техподдержки. Чтобы повысить эффективность работы, мы решили сделать собственного ИИ-помощника. Под катом расскажу, как нам удалось довести проект до прода, совмещая его с ежедневной рутиной, и что мы поняли после его реализации.
Сразу отмечу: я сосредоточусь на задачах, подходе и результатах. А техническими подробностями решения поделится в отдельном материале мой коллега, ведущий инженер Илья Парамошин, который непосредственно отвечал за реализацию ИИ-помощника.
Проблема
Основная задача техподдержки — решать инциденты в рамках SLA. Разумеется, это не единственная зона ответственности. В зависимости от процессов компании саппорт занимается мониторингом, эскалацией, взаимодействием с клиентами и другими командами, анализом инцидентов (postmortem), а также постановкой задач на устранение дефектов и доработку.
Однако в конечном счете о работе поддержки судят именно по времени и качеству решения инцидентов. Лучший способ обеспечить их — иметь четкие инструкции и сотрудников, которые умеют ими пользоваться. В идеале команда должна помнить самые важные кейсы, а документация — быть полной и оформленной.
На практике все иначе. Далеко не все специалисты знают кейсы, библиотека с документами неполная, а ее структура формировалась по мере написания, непоследовательно. Конечно, можно ее отрефакторить, но руки до этого не доходят.
Кроме того, даже хорошей инструкции часто мешает разнообразие симптомов. Если система еще и распределенная, то нужны навыки, чтобы связать очередь на входе с конкретным сервисом где-то в середине или на выходе.
Например, одна и та же проблема может проявляться как «увеличение времени обработки», «увеличение задержек доставки», «увеличение latency», «рост очереди сообщений» и так далее.
Задача для разработки
Решение проблемы с инструкциями мы нашли в русле основного тренда 2025 года — внедрения больших языковых моделей (LLM). Наша задача заключалась в том, чтобы сделать быстрый и точный поиск документации, и для этого мы перебрали несколько вариантов решений.
MWS GPT с загрузкой базы знаний файлом
Логично было начать с использования корпоративного сервиса MWS GPT, который предоставляет доступ к различным LLM — как развернутым локально на инфраструктуре компании, так и внешним. У сервиса имеется привычный для пользователей веб-интерфейс, позволяющий не только задавать вопросы выбранной модели, но и прикреплять текстовые файлы, которые учитываются при ответе. Этот вариант практически не требовал дополнительных усилий и подходил для первых шагов. Написав простой скрипт на Python, мы выгрузили пространство Confluence по REST API в виде json-файла следующего формата:
{
"id": "123456789",
"title": "Заголовок страницы на Confluence",
"body": "Содержимое страницы"
}
Нам было важно, чтобы мы не просто получали ответы от LLM на основе содержимого документации, а могли обратиться к источнику для уточнений и проверки.
Запросы пользователя дополнили примерно таким промптом:
Ты — ИИ-помощник, задача которого — анализировать приложенные JSON-файлы, содержащие множество статей. Каждая статья в JSON-файле имеет следующую структуру:
{
"id": "123456789",
"title": "Заголовок страницы на Confluence",
"body": "Содержимое страницы"
}Твоя задача:
Разобрать предоставленные JSON-файлы, чтобы извлечь информацию из статей.Формировать ответы, строго основываясь на содержимом поля body соответствующей статьи.Не добавлять в ответы информацию, которой нет в поле body. Не выдумывай и не галлюцинируй.В конце каждого ответа указывать URL статьи-источника в формате: https://<адрес confluence>/pages/viewpage.action?pageId=<id>.
Инструкции:Ориентируйся только на содержимое поля body статей.Если запрос относится к нескольким статьям, предоставь информацию из всех релевантных статей и укажи их URL.Если запрос не соответствует ни одной статье, отвечай: «Нет релевантной информации в предоставленных статьях».Не упоминай и не ссылайся на структуру JSON в ответах.Предполагай, что JSON-файлы корректны и содержат все необходимые поля.Твои ответы должны быть краткими и прямо отвечать на запрос пользователя на основе содержимого статей.

В нашем случае у данного подхода были очевидные недостатки:
Каждый пользователь должен сам загружать файл при создании запроса.
Требуется обновлять файл по мере появления новой информации на Confluence.
Нужно учитывать ограничение на размер файла.
Управлять форматом вывода можно только через промпт.
Такой подход легко применять, например, для запросов с небольшим дополнительным расширением (составить SQL-запрос по описанию схемы базы данных, проанализировать часть лога и так далее).
Реализация RAG-архитектуры с использованием API MWS GPT
После того как мы попробовали работать через web-интерфейс и результаты нас устроили, мы решили использовать MWS GPT через OpenAI API-интерфейс для создания универсального решения. Мы выбрали очень популярный сейчас подход RAG (Retrieval-Augmented Generation), или генерацию с дополненной выборкой. Этот подход мы в итоге и использовали в работе.
Суть подхода
О RAG уже много писали на Хабре, но для целостности картины и я опишу его в общих чертах. Этот подход позволяет обогатить запрос к большой языковой модели (LLM) специфической информацией, которая не использовалась при ее обучении. В нашем случае это инструкции и данные о решении инцидентов, доступные только внутри команды.
Иными словами, в RAG запрос расширяется и дополняется, а затем LLM формирует ответ, опираясь не только на собственные знания, но и на предоставленную в промпте информацию:

Ключевым компонентом RAG-системы выступает векторная база данных. В ней хранятся эмбеддинги — представления текста в виде числовых векторов в многомерном пространстве. Расстояние между ними отражает семантическую близость текстов.
Проще говоря, чем больше фрагменты похожи по смыслу, тем ближе друг к другу располагаются их векторы. Для измерения расстояния могут использоваться разные методы — например, величина косинуса угла между векторами или евклидово расстояние. Об этом недавно писал мой коллега.
Документы из базы знаний переводятся в эмбеддинги и сохраняются в векторной базе данных. При этом они разбиваются на части (чанки), что дает большую гибкость поиска. Чанки размером 2000-3000 символов с overlap 150-200, текст очищен от HTML-тегов. В базе храним следующие метаданные: id страницы, название пространства для Confluence или проекта для Jira, URL, текст чанка, embedding, время последнего обновления. Обновление запускается по расписанию раз в 30 минут — после выгрузки из API пересчитываем только измененные чанки. Для простоты мы не отслеживаем изменения частей документов и при обновлении пересчитываем весь документ.
Когда пользователь отправляет запрос через RAG-систему, он также преобразуется в эмбеддинг. По нему в базе находятся наиболее близкие по смыслу документы. Затем они добавляются к исходному запросу, который отправляется в LLM. Полученный от модели ответ возвращается пользователю вместе с учетом предоставленной информации.
Итоговая схема работы системы
Векторная база данных хранит документы из нескольких пространств Confluence и проектов Jira, с которыми мы работаем ежедневно. Эти источники регулярно сканируются: новые страницы и тикеты преобразуются в векторы и записываются в базу. Confluence и Jira сканируем инкрементально раз в 30 минут, обновляем только изменённые страницы, удалённые помечаем is_deleted. Для создания эмбеддингов используется специализированная нейросеть (embedding model):

Логику обработки запросов и представления ответов мы вынесли в отдельное веб-приложение:

В итоге, получив на вход запрос пользователя и список источников (Confluence или Jira), ИИ-помощник:
переводит запрос в эмбеддинг;
ищет наиболее близкие документы в векторной базе;
добавляет их к исходному запросу и в текстовом виде отправляет в LLM;
возвращает пользователю полученный ответ вместе со списком документов и их релевантностью.
Отдельно подниму вопрос безопасности: бизнес всегда переживает за утечки данных, когда документы передаются во внешние модели. Несмотря на то, что мы не храним в Confluence и Jira секретные сведения или персональные данные, ИИ-помощника решили строить внутри контура МТС.
Мы использовали внутрикорпоративные функции сервиса MWS GPT: через него любая продуктовая команда может получить доступ по интерфейсу OpenAI API к эмбеддинг-моделям и LLM, развернутым во внутренней сети.
Настройка и тестирование
Единственным надежным способом проверки качества работы ИИ-помощника в нашем случае является экспертное мнение. Мы составили список запросов и эталонных ответов на эти запросы. В ответы включили ссылки на статьи или тикеты в Jira, а получившийся список использовали в качестве тест-кейсов для проверки работы системы.
Пока мы не были уверены в результатах работы ИИ-помощника, мы попросили сотрудников обращаться к нему параллельно с обычным поиском и при обнаружении некачественных ответов создавать задачи на доработку.
Кроме того, мы экспериментировали с дополнительными настройками. Поиск был не всегда точным, потому что модель эмбеддингов не учитывала некоторые жаргонные фразы, транслитерацию терминов, а также специфичные для нашей команды сокращения. Например, поиски по запросам «как провести постмортем» и «как провести postmortem» выдавали разные страницы.
Мы сформировали словарь взаимозаменяемых слов и аббревиатур, который использовали для обогащения запросов. Например, запрос «как провести постмортем» после обогащения обрабатывался в виде «как провести постмортем postmortem».

Опциональные параметры
Настройки по оптимизации запроса мы вынесли в пользовательский интерфейс. Как потом показало тестирование, оптимизации с помощью LLM не давали ощутимого результата, но мы оставили возможность их включать для возможных проверок в сложных случаев, когда базовые настройки работают неоптимально:

Например, оптимизация первоначального запроса с помощью LLM — добавление синонимов, очистка от малозначимых слов — не сильно прибавила качества ответам, но замедлила обработку запроса из-за дополнительного вызова модели.
Другая оптимизация — ранжирование найденных документов с помощью LLM. Документы, найденные после векторного поиска, отправляются в LLM для более точного ранжирования, и затем из них выбираются только самые релевантные. Такая оптимизация тоже по умолчанию не используется, так как замедляет запрос, а прирост качества оказывается несущественным.
Эти две настройки мы добавили в UI ИИ-помощника. Пользователь при желании может выбрать рабочую LLM, редактировать промпт, изменить опциональные настройки и так далее, но по умолчанию достаточно просто ввести запрос и дождаться ответа.
Автоматическое тестирование
Когда мы справились с основными проблемами — применили созданные в процессе разработки тест-кейсы для автоматического тестирования. В качестве метрики использовали нормализованное векторное расстояние между эмбеддингами запроса и полученного ответа.
Оно принимает значение от 0 до 1, где 0 — полное совпадение, 1 — полное несовпадение. Чем ближе расстояние к 0, тем лучше, но мы не знаем в точности, какое значение приемлемо, поэтому посчитали расстояние между запросом и ответом для эталонных запросов, написали на их основе автоматические тест-кейсы и следили за изменением метрики. Если она падает — надо идти разбираться, почему это происходит.
Тесты выполняются как с параметрами по умолчанию, так и с расширенными, что дает возможность лучше оценивать вклад каждой оптимизации.
Что мы в итоге поняли
Наш опыт показал, что современные LLM и инструменты разработки позволяют создать ИИ-помощника даже специалистам без профильных навыков в работе с ИИ. За несколько месяцев активного использования системы мы получили несколько ключевых инсайтов:
Качественное улучшение работы команды
Наша система поиска учитывает семантику запросов при поиске по Jira и Confluence, — это ускоряет работу, позволяя быстрее находить все относящиеся к запросу материалы. Качественно мы получаем хорошие отзывы от сотрудников, что мотивирует еще шире использовать ИИ-помощника. Сотрудники также могут оценить качество ответа и оставить комментарий сразу после получения результата в том же окне - это упрощает как оптимизацию поиска, так и улучшение документации.
Изменение подходов к документированию
Также уже можно сказать, что реализация этого проекта изменило отношение к документации. Теперь м�� все чаще формируем базу знаний так, чтобы с ней было удобнее работать именно через ИИ, а не через ручной поиск или вопросы коллегам. И мы меньше обращаем внимание на сложную иерархию для документации, которая хороша для визуального поиска. Зато в приоритете короткие инструкции и заметки, которые легко можно найти через ИИ-помощника. Такой подход дает больше свободы: сотрудникам не нужно запоминать структуру документации и быть к ней привязанными.
Реальные ограничение и их преодоление
ИИ-помощник — это дополнительный инструмент команды техподдержки, а не панацея. Его внедрение продолжается и пока сложно измерить количественные метрики вроде сокращения времени поиска или ответа. Это связано с тем, что SLA решения инцидентов в целом редко нарушается, а поиск решения не всегда необходим для решения стандартных задач.
Надо также помнить, что RAG-помощник для поиска — это инструмент в руках, а не замена сотрудника. Если документации по интересующей теме мало или нет вообще, то и ответ будет соответствующим: либо неполным, либо состоящим из общих рассуждений LLM.
Если есть статьи с противоречивой информацией (например, с устаревшей и актуальной), то и результат запроса будет сбивать с толку. Соответственно, работа с ИИ-помощником, особенно в первое время, помогает выявлять неактуальную информацию и мотивирует улучшать документацию.
Планы на будущее
В перспективе мы планируем расширять использование помощника внутри команды, а также продвигаться к обработке с помощью ИИ оригинальных запросов пользователя для получения рекомендаций к решению без первоначального анализа со стороны человека.