Привет! Меня зовут Владимир Дробот, я 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-файлы корректны и содержат все необходимые поля.Твои ответы должны быть краткими и прямо отвечать на запрос пользователя на основе содержимого статей.

Web-интерфейс MWS GPT
Web-интерфейс MWS GPT

В нашем случае у данного подхода были очевидные недостатки:

  • Каждый пользователь должен сам загружать файл при создании запроса.

  • Требуется обновлять файл по мере появления новой информации на 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. 

Если есть статьи с противоречивой информацией (например, с устаревшей и актуальной), то и результат запроса будет сбивать с толку. Соответственно, работа с ИИ-помощником, особенно в первое время, помогает выявлять неактуальную информацию и мотивирует улучшать документацию.

Планы на будущее

В перспективе мы планируем расширять использование помощника внутри команды, а также продвигаться к обработке с помощью ИИ оригинальных запросов пользователя для получения рекомендаций к решению без первоначального анализа со стороны человека.

Комментарии (0)