Привет! Я — Андрей Богомолов, сооснователь и технический директор GenAI Lab. Мы помогаем компаниям из разных сфер внедрять генеративный искусственный интеллект для автоматизации и повышения качества работы.

Сегодня я расскажу, как мы превратили поддержку клиентов одного интернет-магазина в «умного» помощника. Это не просто бот, а инструмент, который понимает запросы пользователей, отвечает естественно и, самое главное, всегда знает актуальную информацию. Начнём с проблем, с которыми столкнулся наш клиент.

О клиенте и его задаче

Наш клиент — крупный игрок в сфере электротехники на российском и европейском рынках. Успех, как это часто бывает, принёс свои трудности: с ростом заказов увеличивался и поток обращений в поддержку.

Чат-боты с заскриптованными сценариями — это прошлое. Они могут справляться с простыми задачами, но терпят фиаско, когда речь идёт о сложных вопросах. Например, пользователь спрашивает: «Какой товар лучше подходит для работы при температуре -20 градусов?». Такой запрос требует глубокого анализа характеристик товаров.

Представьте такую ситуацию: клиент ищет сложный товар, а на сайте указана ограниченная информация. Он пишет в поддержку, чтобы уточнить характеристики. Или ему нужен статус заказа: прибыл ли товар в пункт выдачи? С каждым днём таких запросов у клиента становилось всё больше, а поддержка не успевала отвечать вовремя. Люди злились, теряли время и уходили к конкурентам.

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

  • Работал с большими объёмами данных — товарами, заказами, статусами;

  • Отвечал быстро и естественно, как живой человек;

  • Интегрировался с CRM, чтобы использовать актуальную информацию.

Такую задачу мы и взяли на себя.

Что такое RAG и почему он стал таким популярным?

С появлением LLM (модели вроде ChatGPT), стало популярным обращаться к ним, как ко всезнающим оракулам для ответа на любой вопрос, потому что LLM может подстраиваться под контекст и очень точно отвечать на вопрос. Проблема тут возникает, когда мы пытаемся добиться от них ответов на вопросы из узкоспециализированных областей. LLM не видела эти знания при обучении и она начинает отвечать уверенно, но совершенно неверно (галлюцинировать).

Но что же нам делать, если мы хотим использовать всю мощь LLM для ответов на вопросы по нашей базе знаний? Один из подходов - это вместе с вопросом подавать всю нашу базу знаний в промпт (инструкцию с нашей задачей для LLM). Тут начинаются еще проблемы — стоимость использования LLM прямо пропорциональная размеру промпта, соответственно, ответ на любой вопрос при таком способе становится очень дорогим. 

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

И как же нам тогда подключить нашу базу знаний к LLM? Для ответа на этот вопросы был изобретён подход, который называется RAG (Retrieval-Augmented Generation). Его идея состоит в том, чтобы искать релевантные кусочки из базы знаний и для ответа на вопрос добавлять в промпт нейросети только их, а не всю базу знаний целиком. 

А чтобы мы могли быстро подбирать куски из базы знаний, релевантные вопросу, появляется еще 2 обязательных компонента RAG:

  • Первый — модель эмбеддингов — специальная нейронка, которая превращает любой текст в вектор (набор чисел) с уникальным свойством. У похожих по смыслу текстов эти вектора похожи между собой. 

  • Второй компонент — это векторная база данных — специальная база данных, которая хранит эти вектора и позволяет быстро искать ближайшие. 

Как мы разрабатывали решение

Создание бота потребовало нескольких шагов. Расскажу, как мы работали над каждым из них.

Сначала подготовили данные

При работе с RAG, как впрочем и с любыми AI/ML решениями, первоочередную роль всегда играют данные. Зная правило «мусор на входе — мусор на выходе», мы начали с аккуратной работы с данными. 

Известно, что базовый RAG плохо работает с большими таблицами: при переводе pdf-файлов в текст едет вёрстка, и LLM перестаёт понимать, как сопоставлять текст в данной ячейке, строке и столбце. Модель начинает ошибаться. На помощь тут приходят такие сервисы, как Unstructured.io и LlamaParse. Они решают задачу приведения файлов в вид удобный для чтения LLM. 

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

Предварительно, мы пропускаем эти логи через специальный промпт в ChatGPT, где просим его выделить все вопросы, которые задавал клиент и указать, что отвечал на это оператор. Такую отдельную задачу ChatGPT решает достаточно хорошо. И на выходе вместо чата диалога с кучей нерелевантных сообщений, мы получаем структурированный FAQ, на котором RAG система уже работает хорошо.

А что с актуальностью?

Для интернет-магазина информация устаревает быстро. Утром товар есть на складе, а вечером его уже разобрали. Стандартный бот выдаёт устаревшие данные, что вызывает недовольство клиентов.

В лоб подгружать данные в RAG нецелесообразно, ведь при каждом обновлении статуса заказа пришлось бы индексировать всю базу заново. Поэтому необходимо научить бота получать информацию напрямую из CRM. 

Но как нам связать API CRM и RAG? Ведь всё, что умеют делать LLM, это генерировать текст. Тут нам на помощь пришёл подход разработки чатботов, основанный на интентах. Если вкратце, то интенты — это модель, на которой строилась разработка любых чатботов последние 8 лет. Суть подхода такова: к нам приходит запрос пользователя и мы классифицируем его в одну из категорий (интент). Далее следует фиксированная механика, которая помогает решить запрос пользователя, в нашем случае — отправляем запрос в API CRM и выдаём сообщение по шаблону с необходимыми пользователю данными.

У этого подхода есть один большой минус — при нём бот общается слишком механически и из-за этого пользователи часто не любят таких чатботов. Поэтому мы решили скрестить подход, основанный на интентах, с LLM.

Теперь, если мы классифицировали интент, то мы переключаем диалог на отдельного AI-ассистента, чтобы тот уточнил все необходимые для этого сценария детали, например, код товара или адрес. 

Когда все параметры собраны, то подключаем уже интеграцию с CRM для подготовки ответа. А в случае, если сообщение пользователя не распознано, как специфический интент, то мы направляем сообщение в RAG для того, чтобы AI ассистент уже ответил пользователю с учетом информации из базы знаний. 

Однако после решения этой проблемы появился ещё один нюанс: бот стал отвечать слишком «механически» — всё таки в основе всего лежала intent-модель, а не LLM, которая способна гибко подстраиваться под диалог с пользователем. 

Мы решили использовать LLM, как входящее и исходящее окно при ответе на любые сообщения пользователя. Чтобы этого добиться мы оставили механику с интентами, но на этот раз выдачу шаблонных сообщений из API CRM мы начали использовать, как контексты для RAG наравне с информацией из базы знаний.

Таким образом LLM теперь может агрегировать всю информацию самостоятельно и выдать точный ответ релевантный запросу пользователя и не перегружать его лишними данными.

Что в итоге

Гибридный подход, объединяющий RAG и CRM, позволил создать бота, который:

  • работает с динамическими данными и предоставляет актуальную информацию;

  • снижает вероятность «галлюцинаций» и даёт точные ответы;

  • использует логику интентов и RAG, что делает ответы понятными и удобными для клиентов;

  • применяет мультиагентную логику — главный агент направляет запросы к нужным агентам, повышая тем самым качество и точность взаимодействия.

Чтобы узнать подробности и понять, как всё это устроено, мы провели вебинар, где рассказали подробнее про этот проект и работу с RAG. Видео доступно в нашем Telegram-канале @genailab.

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


  1. nitro80
    06.12.2024 00:38

    Если бот не умеет сразу звать человека по запросу "сотрудник" - всё это лажа.

    Банки особенно этим грешат. Просишь позвать сотрудника - в ответ рассказывает про какие-нибудь акции.


    1. andrey_bogomolov Автор
      06.12.2024 00:38

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


  1. Ruslan123
    06.12.2024 00:38

    Спасибо, отличная статья. Мы на своем опыте пришли к похожим выводам!


  1. alexxxdevelop
    06.12.2024 00:38

    По какой логике вы определяете, что надо взять информацию из CRM, а не из RAG? По каким-то ключевым словам в вопросе? Ведь LLM может бесконечно отвечать на любые вопросы


    1. andrey_bogomolov Автор
      06.12.2024 00:38

      За это отвечает отдельный классификатор интентов на ML, который помечает сообщение пользователя в одну из категорий (что хочет получить пользователь). Дальше, когда LLM через диалог вытянула из пользователя все необходимые вводные, например код товара или город, то дальше уже включается прописанная логика, которая смотрит, что есть определенный интент, есть заполненные параметры, значит можно вызвать API CRM.

      Сам этот классификатор можно разными способами организовывать, можно делать его на ключевых словах, но скорее всего плохо будет работать. Можно обучать ML под эту узкую задачу, а можно даже прописать отдельный промпт, у которого будет только одна задача выполнить классификацию. У каждого подхода есть свои плюсы и минусы.