Image

Три сказа о построении RAG: От выбора модели до форматирования базы знаний

0a9c15985619655cd729ceeed26bf2c6

Привет! Меня зовут Александр Золотых, уже два года я работаю во ВкусВилле разработчиком ИИ-решений. В этой статье хочу рассказать, как мы сделали карманного консультанта по клиентократии — и зачем вообще он понадобился.

ВкусВилл работает по клиентократии — модели управления, которую развивает и распространяет система управления  Beyond Taylor. Основная особенность клиентократии — фокус на клиенте, когда все процессы компании выстраиваются для удовлетворения его потребности. Модель инновационная: погружаешься, и возникает множество вопросов. Конечно, лучше спросить и узнать, чем не спросить и не узнать, но не всем и не всегда это просто. Значит, нужно снижать порог входа и сделать описание модели ближе к изучающему.

Именно из этого понимания у нашей команды и появилась идея карманного консультанта — инструмента, который готов отвечать на все «глупые» и каверзные вопросы. Мы поделились замыслом с коллегами из Beyond Taylor, получили их поддержку и приступили к реализации. Так родилась наша первая задача с тем, что сейчас называется RAG (Retrieval-Augmented Generation).

Конечно, есть готовые решения (Notebook LM, Нейроэксперт), но они имеют несколько минусов:

  1. Отсутствие интеграций (Базы знаний с Готовым решением и Готового решения с сайтом / интерфейсом заказчика)

  2. Низкое качество на узком домене знаний.

Сказ 1: О том как мы модель выбирали

80b7730f2c11f14ec359b2925df59290

С горящими глазами мы бросились решать эту задачу и первым делом взяли известный LangChain и поставили туда Qwen 32, как самую “умную” (лучшую по совокупности параметров) (если верить метрикам) из открытых и развернутых (на тот момент) на Hugging Face.

Далее нам предстояло разбить текст на такие куски, которые бы могли поместиться группой в промпте модели, предоставив ей необходимые знания, на основе которых будет отвечать модель. Разбив документ автоматически, мы столкнулись с первой проблемой – контекст.

Фраза: «Она была очень захватывающей и полезной».
Вопрос: «Кто она?»

Согласитесь, тут без контекста не получится ответить на вопрос, это может быть «Игра», а может быть «Книга» или «Проза», а может «Лекция»? Что же делать? Мы были зеленые, документ был маленький, поэтому долгим рабочим днем было принято волевое решение разбить файл вручную.

7a20c7aa332a6f3fd750b9b6f4303a07

Мы получили 150+ кусков текстов, теперь надо было выбирать из них те, которые подходят под конкретный вопрос пользователя, для этого мы воспользовались bm25.

Связав тексты таким алгоритмом, мы выяснили несколько новых проблем:

  1. Модель жестко проседает в некоторых моментах дня, предположительно, когда высокая нагрузка. Просадки отражаются на качестве. Это вам и зацикливание на паре символов, и банальная генерация без конца.

  2. К тому же, обнаружили нестабильность работы с HF API для Qwen-like моделей, которые по середине генерации могут скатиться в другой язык.

  3. LangChain не позволяет прокинуть параметры внутрь node. Допустим, у нас 10 node и они соединены в pipeline. И вот наша задача в десятую node передать параметр file_path, чтобы узел понимал, куда сохранить результаты. Решение, которое мы нашли, заставляет выдать этот параметр выходом для каждого узла ранее. На одном параметре не видно проблемы, но если у нас по одному параметру на каждый узел? У первого узла будет 9 параметров, проходящих через него транзитом и не использующихся. А если, о ужас, понадобится заменить последний узел и поменять в нем входные параметры?

  4. Документация! Мой любимый пункт. За время поиска решений на 1 и 2 пункт мы нашли 3 разных куска кода, которые решали одно и тоже разными частями библиотеки. Но сюр в том, что ни один из этих кусков не работал. Библиотека развивается и переписывается в разы быстрее, чем обновляется документация и гайды (в том числе и официальные).

Заменив LangChain на кастомную разработку (об этом, может быть, в следующей статье), мы перешли с китайской модели на GigaChat (здесь и далее мы приводим свои результаты, они могут отличаться от ваших из-за того, что модель всё время развивается, и из-за того, что мы могли допустить неточности в работе с данной моделью первый раз). Кроме LLM, мы взяли у них и Embedding-токены, и собрали поиск на основе FAISS (Векторное хранилище).
Это дало нам существенный прирост, но…

Сказ 2: О том как мы узлы общаться учили

1debd272400cbb9b61edb0205e34a8a6

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

—Расскажи про клиентократию?
— Что такое клиентократия?
— Есть ли клиентократия на Марсе?

Тогда мы решили сделать переводчика с человеческого на нормальный.
LLM принимает вопрос пользователя и контекст, который нашелся по этому вопросу, а дальше пытается предположить, а что имел в виду пользователь. Дополнительно еще и теги пытается написать, по которым можно было бы легче искать.
Всё звучит круто, но…
Фраза «пиши каждый вопрос с новой строки» заканчивалась провалом.

Если узел выдает неконтролируемый выход, это стопорит всё, что идет далее. Поэтому мы перешли на 2 вещи:

  1. JSON — делает разделение между сущностями более явными, даже при потере некоторого кол-ва символов (ошибки генерации модели).

  2. JSON Repeater — узел, который парсит JSON, а если находит ошибки, то переписывает его.

f4dd60b7413581907f30b27d302c4704

Теперь, решив все задачи, мы можем представить наш MVP заказчику.

Сказ 3: О том как мы форматировали базу знаний

Чуть ранее для оценки правильности ответов мы собрали пул из 30 вопросов, на которые нам эксперты благородно ответили. Далее мы прокинули документ через Notebook LM и получили ответы строго по контексту, без знаний экспертов, и на этапе второго Сказа мы уже «делали» Notebook LM в каверзных вопросах (экспертная оценка). Однако беда пришла оттуда, откуда не ждали:

  • (Заказчик): В данном вопросе должна быть ссылка на книгу (название).

  • (Мы): Хорошо, сейчас всё проверим.

(Проверяем логи и контекст)

  • (Мы): Так в контексте эта книга не упоминается.

  • (Заказчик): Да, мы знаем, но она есть!

Потянув далее за эту ниточку, мы поняли, что база знаний имеет несколько недочетов, и текущий формат не подходит для работы RAG-системы.

Определив новую проблему, мы решили не оставаться в стороне и помочь заказчику со структурированием информации. Мы взяли наш документ, добавили к нему транскрибирование видеолекций (чтобы нивелировать отсутствие информации) и передали это в LLM. На каждый блок мы задали вопросы, которые объединили в несколько кластеров. Из каждого кластера сделали статью, попросив LLM написать статью, которая бы отвечала на все вопросы и при этом была бы единая. Таким образом получили 20+ markdown файлов, которые передали экспертам для правок.

   

3862293853e9c6040d1d2f61ef718354

Пока эксперты превращали сгенерированные файлы в структурированную проверенную информацию, в контуре ВВ появилась и «своя» LLM (дистиллированный DeepSeek).

На этом этапе мы получили готовый продукт, который можно улучшать, а значит, нужны метрики, чтобы отслеживать прогресс. Тогда, подсмотрев метрику МЕРА, мы решили сделать свой датасет для оценки нашей RAG. На основе документов (внутренней документации, примерно 10 документов) было задано 85 вопросов тестового характера. Посчитав точность (ответ верен/неверен), мы поняли, что LLM ужасна (спойлер — мы ошиблись)!

41a4c57a86a3aaac9cdd8b024a15439b

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

464eb99dac9bbe7f66321101dcdcc4a6

Открыв для себя слабое место, мы бросили свои усилия на него, и после долгого кропотливого труда по выявлению плавающих ошибок мы пришли к:

 

dfb7b9e9f27af17f0df4e18fe6559c37

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

1) Построили поисковик;

2) Структурировали контекст;

3) Подружили это всё в едином продукте.

Мы были готовы выбрать её, святая святых: LLM. (Если быть менее пафосным, то просто хотели сравнить GigaChat с внутренним DeepSeek.)

aa631d826dcb50d1196453db5787aeaf

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

🔹 Улучшение поиска — эксперименты с эмбеддингами и векторными хранилищами

🔹 Масштабирование базы знаний — автоматизация обновления и дополнения документов

🔹 Автоматизация — внедрение «продовых» практик для разворачивания микросервисов

🔹 Развитие метрик — более глубокая оценка качества ответов

Мы прошли большой путь от идеи до работающего решения, но впереди еще много интересных задач!

С Вами была команда Центра Экспертизы ИИ компании ВкусВилл, до новых встреч.

P.S. Ждем ваших комментариев, как вы решали подобные задачи и с какими трудностями столкнулись.

Благодарим за помощь в написании материала @Andriljo.

Источник: habr.com

✅ Найденные теги: новости, Три
Каталог бесплатных опенсорс-решений, которые можно развернуть локально и забыть о подписках

галерея

Залитый солнцем лес с деревьями и болотистой водой, покрытой зелёной растительностью.
Пленка NeoFilm 100 на деревянном столе в окружении упаковок.
Деревянный минималистичный сундук с подсветкой в интерьере.
Обложка отчета о преодолении разрыва в операционном ИИ от MIT Technology Review.
Твит о разработке в 2026: выполнение сложных задач до пробуждения США, чтобы избежать проблем с ИИ.
Прозрачный раствор в бутылочке с черной крышкой, химическая формула на этикетке.
Диаграмма ложной идентичности: реальность и самозванец, высокие и низкие частоты.
Изображение крупным планом дрона с логотипом Anduril.
ideipro logotyp
Image Not Found
Пленка NeoFilm 100 на деревянном столе в окружении упаковок.

Цифровая камера OPT NeoFilm 100 в формате плёнки

Компактная камера OPT NeoFilm 100 выполнена в виде классической 35-мм плёнки, но внутри скрывается не аналоговый механизм, а цифровая «начинка», способная снимать фото и видео.  Камера оснащена 1-мегапиксельным сенсором, который позволяет получать изображения с разрешением до 3…

Мар 5, 2026
Деревянный минималистичный сундук с подсветкой в интерьере.

«Умная» кровать-трансформер Roll

Хорватский дизайнер Лука Булян разработал проект складной кровати Roll, которая по нажатию кнопки сворачивается в аккуратный деревянный шкаф. Главная идея строится на принципе ежедневного скручивания матраса без потери его свойств. Конструкция оснащена тихим электродвигателем и плавным механизмом…

Мар 5, 2026
Обложка отчета о преодолении разрыва в операционном ИИ от MIT Technology Review.

Преодоление разрыва в операционном применении ИИ

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

Мар 5, 2026
Прозрачный раствор в бутылочке с черной крышкой, химическая формула на этикетке.

Ученые усовершенствовали метод получения промышленного спирта

Полученный α-кумиловый спирт © Елена Редина. Ученые разработали новый метод получения α-кумилового спирта — ключевого продукта для производства полимеров, косметики и моющих средств. Этот спирт также служит основой для получения вещества, придающего пластикам прочность и устойчивость к…

Мар 5, 2026

Впишите свой почтовый адрес и мы будем присылать вам на почту самые свежие новости в числе самых первых