Top.Mail.Ru
РБК Компании
Заморозили скидки: делитесь новостями бизнеса и читайте эксклюзивы на РБК
Успеть до 14.12
Заморозили скидки:
делитесь новостями бизнеса
и читайте эксклюзивы на РБК
Успеть до 14.12

Как мы научили AI отвечать на вопросы сотрудников

Целью проекта было решение внутренней бизнес-проблемы: снижение количества отвлекающих факторов для разработчиков
IceRock Development
Источник изображения: Freepik.com
Задача и причина

Задача

В любой быстрорастущей IT-компании объем внутренней документации, регламентов и гайдов растет экспоненциально. В IceRock централизованным хранилищем таких знаний служит Confluence. Однако, как показывает практика, наличие базы знаний не гарантирует ее использования.

Мы столкнулись с классической проблемой:

  1. Повторяющиеся вопросы в Slack: Сотрудники, особенно новички, регулярно задавали в общих каналах одни и те же вопросы: «Как оформить отпуск?», «Где найти шаблон для отчета?», «Какой у нас регламент код-ревью?».
  2. Отвлечение команды: На эти вопросы приходилось отвечать другим сотрудникам, чаще всего — старшим разработчикам или тимлидам. Это вырывало их из состояния «потока», снижало продуктивность и приводило к потере ценного рабочего времени.
  3. Пассивность базы знаний: Информация в Confluence была, но людям было проще и быстрее спросить в чате, чем самостоятельно искать нужный документ.

Перед нами стояла двойная задача:

  • Бизнес-задача: Создать инструмент, который бы взял на себя рутинные ответы на вопросы, тем самым высвободив время разработчиков для приоритетных задач. Нужно было «оживить» нашу базу знаний, сделав ее проактивным участником коммуникации.

  • Техническая задача (R&D): Проект также стал нашей «песочницей» для изучения и практического применения RAG (Retrieval-Augmented Generation). Нам было важно на собственном опыте понять, как заставить большие языковые модели (LLM) отвечать, основываясь на приватных, непубличных данных, которых нет в их базовом наборе для обучения.

Решение

Мы разработали систему «IceRock Assistant GPT», состоящую из бэкенд-сервиса и интеграции со Slack.

Решение представляет собой чат-бота, которого можно «призвать» в любой тред (ветку) в Slack, просто упомянув его (@IceRock Assistant).

Ключевой сценарий работы для пользователя:

  1. У сотрудника возникает вопрос. Он создает тред в релевантном канале Slack, упоминает бота и задает свой вопрос.
  2. Бот мгновенно отвечает: «Погодите, ищу информацию...».
  3. Бэкенд-сервис получает вопрос, анализирует его, ищет релевантные документы в нашей базе знаний Confluence, а затем с помощью OpenAI GPT генерирует развернутый, человекопонятный ответ.
  4. Бот присылает готовый ответ в тред.

Важные особенности решения:

  • Контекстуальная «память»: Бот работает в рамках тредов Slack. Он «помнит» всю историю переписки в данной ветке и учитывает ее при генерации последующих ответов. Это позволяет вести с ним диалог, задавать уточняющие вопросы (например: «А что, если я руководитель?»), и он будет понимать, о чем идет речь.
  • Гибридный режим ответов: Если бот находит релевантную информацию в Confluence, он отвечает строго на ее основе. Если же в нашей базе знаний ответа нет (например, на вопрос «Какая погода в Лиссабоне?»), бот отвечает, как стандартный ChatGPT, используя свою общую базу знаний.

Процесс разработки

Весь процесс строился вокруг архитектуры RAG (Retrieval-Augmented Generation), которая позволяет «дополнять» запросы к LLM релевантными данными из внешних источников. Процесс можно разделить на два независимых конвейера (pipeline): Индексацию и Обработку запроса.

Конвейер Индексации Базы Знаний

Чтобы бот мог что-то найти, информацию нужно было сначала подготовить и «скормить» ему. Этот процесс работает в фоновом режиме по расписанию (каждый час):

1. Поиск документов: Наш бэкенд-сервис на Kotlin обращается к API Confluence и ищет все страницы, помеченные специальным лейблом ira (IceRock Assistant). Это позволяет нам гибко контролировать, к каким именно знаниям бот будет иметь доступ.

2. Проверка версии: Система проверяет, изменилась ли страница с момента последней индексации.

3. Чанкинг (Chunking): Если страница новая или обновилась, ее содержимое скачивается и «нарезается» на небольшие логические куски — «чанки». Это необходимо для эффективного векторного поиска.

4. Создание Эмбеддингов (Embeddings): Каждый чанк текста отправляется в API OpenAI (модель text-embedding), которое возвращает его векторное представление — «эмбеддинг». Эмбеддинг — это, по сути, длинный массив чисел, который математически описывает смысл данного куска текста.

5. Сохранение в Базы Данных:

  • Полученный вектор (массив чисел) сохраняется в специализированную векторную базу данных Qdrant.
  • Сам исходный текст чанка, вместе с метаданными (ID документа, номер версии), сохраняется в традиционную реляционную базу PostgreSQL.

Конвейер Обработки Сообщения (Ответ пользователю)

Этот процесс запускается каждый раз, когда пользователь упоминает бота в Slack:

1. Получение запроса: Slack отправляет webhook на наш Kotlin-бэкенд с текстом сообщения и историей треда.

2. Обратная связь: Бэкенд немедленно отвечает в Slack сообщением «Погодите...», чтобы пользователь видел, что его запрос принят в работу.

3. Векторизация запроса: Бэкенд берет текст вопроса пользователя (а также историю переписки в треде для контекста) и отправляет его в API OpenAI для получения «вектора запроса».

4. Векторный поиск (Retrieval): Этот вектор запроса используется для поиска в базе Qdrant. Qdrant быстро находит в своей коллекции наиболее семантически близкие векторы документов. То есть, если пользователь спросил «Как пойти в отпуск?», Qdrant найдет векторы, которые соответствуют чанкам текста про «оформление отпуска», «заявление на отдых» и т.д.

5. Извлечение контекста: Qdrant возвращает ID наиболее релевантных векторов. Используя эти ID, наш бэкенд обращается к PostgreSQL и забирает оттуда соответствующие им исходные куски текста.

6. Дополнение промпта (Augmentation): Бэкенд формирует финальный, большой промпт для основной LLM (GPT). Этот промпт содержит:

  • Системную инструкцию («Ты — помощник...»).
  • Историю переписки из треда Slack (для «памяти»).
  • Найденные куски текста из PostgreSQL (тот самый «дополненный» контекст).
  • Оригинальный вопрос пользователя.

7. Генерация ответа (Generation): Этот промпт отправляется в API OpenAI (модель GPT). Модель генерирует ответ, основываясь в первую очередь на предоставленном ей контексте из нашей базы знаний.

8. Отправка ответа: Готовый ответ отправляется в тред Slack, заменяя собой сообщение «Погодите...».

Что было самым сложным

Как и в любом R&D-проекте, основные сложности были не в коде, а в концепциях.

Сложность 1: Обеспечение актуальности данных. База знаний — это живой организм, документы постоянно обновляются. Если бот будет отвечать устаревшей информацией, он принесет больше вреда, чем пользы.

Как мы решили эту задачу: Мы реализовали автоматический фоновый индексатор. Наш бэкенд на Kotlin по расписанию (раз в час) опрашивает Confluence. Он не просто скачивает все подряд, а умнó проверяет номера версий документов, которые он уже индексировал. Если версия в Confluence новее, чем в нашей базе, бэкенд автоматически скачивает новую версию, заново создает эмбеддинги и обновляет их в векторной базе. Это гарантирует, что бот отвечает на основе самой свежей информации с минимальной задержкой.

Сложность 2: Контекстуальная «амнезия». Первая версия бота отвечала только на одиночные запросы. Но пользователи так не общаются. Они задают уточняющие вопросы: «А если я тимлид?», «А для Android-отдела так же?». Без истории диалога бот не понимал, к чему относятся эти вопросы.

Как мы решили эту задачу: Мы полностью завязали логику работы бота на треды (ветки) в Slack. При каждом новом запросе наш бэкенд запрашивает у Slack API всю историю сообщений в текущем треде. Эта история передается в LLM как часть промпта, что позволяет модели сохранять контекст диалога и давать релевантные ответы на уточняющие вопросы.

Сложность 3: Визуализация архитектуры. Система получилась многокомпонентной (Slack, Бэкенд, Confluence, Qdrant, PostgreSQL, OpenAI). Объяснить, как все это связано, было непросто.

Как мы решили эту задачу: В процессе разработки мы активно использовали Mermaid — инструмент для описания диаграмм в виде кода. Это позволило нам прямо в README-файле проекта в GitLab описать и поддерживать в актуальном состоянии две ключевые диаграммы: «Индексация Базы Знаний» и «Обработка Сообщений». Это упростило как саму разработку, так и последующую передачу знаний о проекте.

Технологический стек

  • Платформа: Slack (для пользовательского интерфейса)
  • Бэкенд: Kotlin (для всей бизнес-логики, индексации и оркестрации запросов)
  • Источник данных (База знаний): Confluence
  • LLM и Эмбеддинги: OpenAI (модели GPT и text-embedding)
  • Векторная База Данных: Qdrant (для хранения векторов и семантического поиска)
  • Реляционная База Данных: PostgreSQL (для хранения текстовых чанков и метаданных)
  • Документация и Диаграммы: Mermaid
Результат

Результат

  1. Создан рабочий внутренний продукт: «IceRock Assistant GPT» успешно внедрен и используется сотрудниками.
  2. Снижена нагрузка на команду: Бот взял на себя ответы на большинство типовых вопросов, позволяя разработчикам не отвлекаться от основных задач.
  3. «Оживлена» база знаний: Наша документация в Confluence из пассивного хранилища превратилась в активный инструмент, интегрированный напрямую в рабочий процесс коммуникации.
  4. Получен бесценный R&D-опыт: Команда IceRock на практике освоила одну из самых востребованных сегодня технологий в области AI — RAG. Мы детально разобрались в работе с векторными базами данных (Qdrant), API OpenAI и логикой построения сложных AI-ассистентов.
  5. Создан фундамент для будущих продуктов: Этот внутренний проект стал основой для будущих коммерческих предложений, связанных с созданием кастомных GPT-ассистентов для наших клиентов, обученных на их собственных корпоративных данных.

Интересное:

Новости отрасли:

Все новости:

Контакты

Адрес
Россия, г. Новосибирск, ул. Ядринцевская, д. 68/1
Телефон

Социальные сети

ГлавноеЭкспертыДобавить
новость
КейсыМероприятия