Как мы научили AI отвечать на вопросы сотрудников
Целью проекта было решение внутренней бизнес-проблемы: снижение количества отвлекающих факторов для разработчиков
Задача
В любой быстрорастущей IT-компании объем внутренней документации, регламентов и гайдов растет экспоненциально. В IceRock централизованным хранилищем таких знаний служит Confluence. Однако, как показывает практика, наличие базы знаний не гарантирует ее использования.
Мы столкнулись с классической проблемой:
- Повторяющиеся вопросы в Slack: Сотрудники, особенно новички, регулярно задавали в общих каналах одни и те же вопросы: «Как оформить отпуск?», «Где найти шаблон для отчета?», «Какой у нас регламент код-ревью?».
- Отвлечение команды: На эти вопросы приходилось отвечать другим сотрудникам, чаще всего — старшим разработчикам или тимлидам. Это вырывало их из состояния «потока», снижало продуктивность и приводило к потере ценного рабочего времени.
- Пассивность базы знаний: Информация в Confluence была, но людям было проще и быстрее спросить в чате, чем самостоятельно искать нужный документ.
Перед нами стояла двойная задача:
Бизнес-задача: Создать инструмент, который бы взял на себя рутинные ответы на вопросы, тем самым высвободив время разработчиков для приоритетных задач. Нужно было «оживить» нашу базу знаний, сделав ее проактивным участником коммуникации.
Техническая задача (R&D): Проект также стал нашей «песочницей» для изучения и практического применения RAG (Retrieval-Augmented Generation). Нам было важно на собственном опыте понять, как заставить большие языковые модели (LLM) отвечать, основываясь на приватных, непубличных данных, которых нет в их базовом наборе для обучения.
Решение
Мы разработали систему «IceRock Assistant GPT», состоящую из бэкенд-сервиса и интеграции со Slack.
Решение представляет собой чат-бота, которого можно «призвать» в любой тред (ветку) в Slack, просто упомянув его (@IceRock Assistant).
Ключевой сценарий работы для пользователя:
- У сотрудника возникает вопрос. Он создает тред в релевантном канале Slack, упоминает бота и задает свой вопрос.
- Бот мгновенно отвечает: «Погодите, ищу информацию...».
- Бэкенд-сервис получает вопрос, анализирует его, ищет релевантные документы в нашей базе знаний Confluence, а затем с помощью OpenAI GPT генерирует развернутый, человекопонятный ответ.
- Бот присылает готовый ответ в тред.
Важные особенности решения:
- Контекстуальная «память»: Бот работает в рамках тредов 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
Результат
- Создан рабочий внутренний продукт: «IceRock Assistant GPT» успешно внедрен и используется сотрудниками.
- Снижена нагрузка на команду: Бот взял на себя ответы на большинство типовых вопросов, позволяя разработчикам не отвлекаться от основных задач.
- «Оживлена» база знаний: Наша документация в Confluence из пассивного хранилища превратилась в активный инструмент, интегрированный напрямую в рабочий процесс коммуникации.
- Получен бесценный R&D-опыт: Команда IceRock на практике освоила одну из самых востребованных сегодня технологий в области AI — RAG. Мы детально разобрались в работе с векторными базами данных (Qdrant), API OpenAI и логикой построения сложных AI-ассистентов.
- Создан фундамент для будущих продуктов: Этот внутренний проект стал основой для будущих коммерческих предложений, связанных с созданием кастомных GPT-ассистентов для наших клиентов, обученных на их собственных корпоративных данных.
Рубрики
Интересное:
Новости отрасли:
Все новости:
Публикация компании
Контакты
Социальные сети
Рубрики


