Почему каталог не продаёт: разработка рекомендательной системы
Каталог на сотни тысяч позиций проигрывает не ассортименту, а выдаче. Новый гость и постоянный клиент видят одинаковый первый экран: те же категории, те же подборки, тот же порядок карточек. Конверсия карточек падает не из-за товара, а из-за того, что он показан не тому, кто готов купить.
Пока персонализация каталога держится на ручных правилах, её потолок задан их числом. Правила наслаиваются, конфликтуют между собой, и каждое изменение требует релиза. После полусотни условий уже никто не скажет, почему конкретная карточка оказалась первой, а проверка новой гипотезы растягивается на недели.
Параллельно в системе лежат неиспользованные данные о поведении: просмотры, поисковые запросы, добавления в избранное, время на карточке, отказы после перехода. Это готовый сигнал о намерении, но на выдачу он не влияет — максимум уходит в отчёт. Замкнутый круг: слабая выдача даёт мало кликов, а на слабых данных модель не учится.
Рабочая схема — двухбашенная модель (Two-Tower): одна часть считает вектор клиента по его истории, вторая — вектор товара по атрибутам и тексту. Оба вектора лежат в одном пространстве, поэтому выдача собирается не перебором каталога, а поиском ближайших позиций через FAISS.
Такой подбор укладывается в бюджет ответа страницы и пересчитывается на свежих событиях, а не раз в сутки. Ручные правила при этом остаются верхним слоем: промо, стоп-листы и остатки ограничивают выдачу модели, а не заменяют её.
Ниже разбираем, как это закрывается: от сбора сигнала и валидации модели до контроля качества и отката на предыдущую версию.
Что меняется после внедрения: эффект в измеримых метриках
Персонализация сдвигает метрики не за счёт косметики в интерфейсе, а за счёт смены логики ранжирования. Раньше порядок выдачи строился по популярности и свежести — его получали все одинаковый. После внедрения каждый пользователь видит последовательность, посчитанную под его историю, поэтому доля целевых действий растёт без роста трафика.
Технически работают две башни: одна считает представление пользователя, вторая — представление объекта. Близость ищется векторным поиском по индексу FAISS, оттуда берётся короткий список кандидатов, который затем переранжируется с учётом наличия, доставки и ограничений каталога.
Время ответа выдачи держится за счёт предрасчёта: представления обновляются по событиям, а не в момент запроса. Витрина отдаёт готовые блоки из кэша, поэтому нагрузка на неё падает — вместо тяжёлых выборок на каждый показ работают короткие чтения по ключу.
Отдельно снимается класс отказов, который раньше ломал выдачу: холодный старт нового пользователя, всплеск на распродаже, товар без истории. На такие случаи есть фолбэк — популярное в сегменте, ограничение пула кандидатов, постепенное дообучение. Эффект персонализации становится предсказуемым: доля целевых действий и глубина просмотра растут, время ответа выдачи остаётся ровным под нагрузкой, а витрина перестаёт быть узким местом.
Сравнение подходов к рекомендациям: правила, модели, гибрид
Каждая схема выдачи выигрывает на своём профиле данных и ломается на чужом. Ручные правила и блок популярного дают предсказуемый запуск, но не учитывают интерес конкретного пользователя; коллаборативная фильтрация опирается на поведение похожих пользователей и требует плотного потока событий; контентные признаки работают по описанию самого объекта и не зависят от истории. На практике выбор определяют три вещи: сколько взаимодействий накоплено, как быстро обновляется каталог и насколько критичен холодный старт.
| Подход | Когда подходит | Ограничения |
|---|---|---|
| Правила и блок популярного | Запуск с нуля, редкие события, нужна объяснимая выдача | Не персонализирует, быстро упирается в потолок вовлечённости |
| Коллаборативная фильтрация | Есть история взаимодействий и стабильный поток событий | Новые пользователи и новые объекты не получают выдачи, пока не накопят данные |
| Контентные признаки | Богатое описание каталога, частые изменения ассортимента | Показывает похожее на уже просмотренное, не выводит за пределы сложившегося вкуса |
| Гибридная схема | Боевой контур с разнородным трафиком и требованием к устойчивости | Дороже в поддержке: пересчёт признаков, разметка, контроль качества выдачи |
Гибрид обычно собирают не «на всё сразу», а послойно: коллаборативный сигнал отвечает за основную выдачу, контентный подстраховывает новые объекты, правила ограничивают нежелательные сочетания. Мы начинаем с аудита данных и метрики качества — только после этого фиксируем схему, иначе сравнение подходов остаётся теоретическим.
Этапы внедрения: от аудита данных до передачи модели
Разработка рекомендательной системы начинается не с модели, а с данных: каждый следующий шаг опирается на проверенный предыдущий. Сначала считаем, каких сигналов не хватает для персонализации, и только потом фиксируем схему. Такой порядок экономит недели на переделках.
Маршрут внедрения
- Аудит данных. Смотрим состав событий, глубину истории, долю анонимных сессий и разреженность взаимодействий по каталогу. Фиксируем, каких сигналов не хватает и что нужно достроить в сборе логов.
- Схема решения. Разделяем систему на два контура: быстрый отбор кандидатов из всего каталога и точное ранжирование отобранного по признакам пользователя и товара. Здесь же определяем перечень признаков и частоту их обновления.
- Настройка выдачи. Собираем обучающие пары из истории, балансируем популярное и новое, добавляем правила-исключения: уже купленное, ограничения по наличию, исключения по бренду.
- Проверка качества. Оцениваем на отложенном по времени отрезке, а не на случайной выборке, — иначе метрики завышены. Затем выводим часть трафика на новую выдачу и сравниваем с контрольной группой.
- Передача решения. Отдаём конфигурации контуров, схему признаков, регламент переобучения и порядок отката на предыдущую версию выдачи. Проводим обучение команды и остаёмся на связи на период самостоятельной эксплуатации.
Артефакты передачи: схемы, конфигурации, регламенты переобучения
Передаём не «работающий сервис под ключ», а комплект, по которому ваша команда сможет сопровождать систему без нас: запустить, переобучить, откатить, расширить признаки. Ниже — что физически остаётся в репозитории и в базе знаний после сдачи.
-
Схемы интеграции — куда рекомендательный сервис подключается: получение каталога и профиля пользователя, выдача списка на фронтенд и в рассылки, таймауты и поведение при недоступности источника данных.
-
Конфигурации обучения и выдачи — параметры модели, размерности представлений, правила отбора кандидатов и переранжирования. Всё в файлах конфигурации, а не в коде: смена настроек не требует релиза.
-
Регламент переобучения — триггеры (по расписанию, по притоку новых позиций, по падению метрик), порядок прогонки, критерии приёмки новой версии и процедура возврата к предыдущей.
-
Разграничение доступа — роли на обучающие данные, на сервис выдачи и на запуск переобучения, кто вправе выкатить модель, журналирование действий.
-
Документация решения — архитектура, словарь признаков, назначение компонентов, известные ограничения и обходные пути для каждого.
-
Набор проверок — офлайн-метрики качества, контрольные выборки, тесты на холодный старт и на просадку интереса к позиции.
-
Контроль в работе — какие показатели снимаются постоянно, пороги срабатывания, точки, где смотреть причину расхождения между обучением и выдачей.
-
Инструкции по эксплуатации — подъём с нуля, пересборка векторного индекса, восстановление после сбоя, типовые обращения и ответы на них.
Каждый пункт сверяем на приёмке: ваши инженеры проходят по нему руками и подтверждают, что схема читается, конфигурация запускается, регламент понятен без звонка нам.
Кейс: персонализация выдачи в каталоге маркетплейса
Каталог — сотни тысяч позиций, а выдача держалась на правилах: популярность, свежесть, наличие. Покупатель получал один и тот же порядок вне зависимости от того, что смотрел и покупал раньше, поэтому первые экраны занимали товары мимо его интереса. Переходы в целевое действие почти не росли вместе с трафиком — узкое место было не в ассортименте, а в том, как он подаётся.
Собрали двухбашенную модель: одна часть кодирует пользователя по истории просмотров и заказов, вторая — товар по атрибутам и текстам. Близость считается по векторному индексу FAISS, поэтому персональный порядок строится на лету, а не ночным пересчётом. Поверх скоринга оставили переранжирование: наличие, условия доставки и маржа по-прежнему решают, что попадёт в топ.
Что показали замеры
| Метрика | До | После |
|---|---|---|
| Порядок выдачи | единый, по правилам | персональный для авторизованных |
| Переходы в целевое действие из ленты | базовая линия | +27% на сопоставимом трафике |
| Глубина сессии | 4 карточки | 6,4 карточки |
| Отклик выдачи в часы пик | просадки | ровный, вчетверо быстрее |
| Новый товар в ленте | только по общим правилам | включается за минуты |
Отдельно проверили устойчивость: при недоступности модели выдача откатывается на прежние правила, и каталог не остаётся пустым. Повторные замеры через месяц держались на том же уровне — рост дала персонализация, а не сезонная волна.
Как быть, если данных для обучения почти нет: холодный старт
Когда данных мало, холодный старт — это не отсутствие логов вообще, а нехватка истории по конкретному пользователю или объекту. Новый посетитель приходит без профиля, новый товар — без показов, молодой проект — без накопленных взаимодействий. Матрица формально есть, но разрежена: почти все пары «пользователь–объект» пусты, и модель выучивает среднее по каталогу.
Первый контур строим не на поведении, а на содержимом: объекты и пользователи описываются признаками — категория, бренд, атрибуты, текст описания, состав текущей сессии. Из них собираются векторы, на которых обучается двухбашенная модель: одна башня кодирует пользователя, вторая — объект, близость ищется векторным поиском. Такой контур сходится уже на десятках тысяч событий.
Дальше — разогрев выдачи: не ждём полной истории, а постепенно подмешиваем поведение к контенту. Вес поведенческой части растёт вместе с числом взаимодействий пользователя и объекта, поэтому свежий профиль не перевешивает статистику по похожим. Часть показов отдаём под исследование — намеренно разнообразную выдачу для сбора обратной связи по неизученным позициям.
Слабые сигналы разводим по уровням уверенности: показ, клик, досмотр, добавление в список. Сваливать их в один счётчик нельзя — случайный показ начнёт считаться интересом, поэтому каждому уровню задаётся вес.
Холодный старт закрыт не тогда, когда модель обучилась, а когда доля персональных слотов в выдаче растёт, покрытие каталога расширяется, а новый пользователь получает релевантный показ за меньшее число шагов. Поэтому контентный контур мы оставляем постоянным слоем, а не заглушкой до накопления логов.
Разбор сомнений: качество данных, нагрузка, поддержка
Качество данных мы проверяем до обучения, а не после. Событийный лог фильтруем от дублей, ботов и аномальных всплесков, битые записи не удаляем, а помечаем: по ним видно, где теряется передача событий с фронта. На выходе — воспроизводимый набор, на котором метрики сопоставимы между запусками и не «плывут» от прогона к прогону.
Нагрузку считаем заранее: подбор рекомендаций отдаёт отдельный сервис, а пересчёт профилей и векторный поиск не конкурируют с основной базой за ресурсы. Поиск ближайших представлений на FAISS идёт в памяти, поэтому выдача укладывается в общий бюджет ответа страницы, а при росте каталога масштабируется добавлением узлов без переписывания логики.
Что делать, если данных на старте мало?
Первые недели система работает на признаках контента и правилах похожести — они дают осмысленную выдачу без истории пользователя. Дальше вес постепенно смещается на поведенческие сигналы по мере накопления событий, и холодный старт перестаёт быть узким местом.
Как вы замечаете деградацию качества?
На контрольном срезе считаем долю успешных взаимодействий и охват каталога; падение за порог поднимает оповещение. Модель при этом не «уезжает» незаметно: предыдущий снимок сохраняется, и откат на него занимает минуты, а не отдельный цикл обучения.
Сможем ли дообучать модель сами?
Мы передаём регламент переобучения, скрипты подготовки данных и проверку на теневом потоке перед выкаткой — дообучение становится штатной процедурой, а не разовой акцией. Сопровождение модели описываем в документации, чтобы этим занимался ваш инженер.
Обсудим задачу: какие данные и доступы нужны для оценки
Чтобы вернуться с оценкой, а не с уточняющими вопросами, нам нужен доступ к фактическим данным: по ним видно, хватит ли истории для обучения модели или её сначала придётся накапливать. Ниже минимальный набор, который закрывает этот этап.
- Выгрузку событий за 3–6 месяцев: просмотры, поисковые запросы, добавления в корзину, покупки — с идентификатором пользователя, идентификатором товара и меткой времени.
- Схему каталога: атрибуты, категории, остатки, доступность, связи между товарами.
- Тестовый доступ к API каталога и заказов в режиме чтения — проверим полноту истории и частоту событий.
- Описание инфраструктуры: где планируете считать рекомендации — в своём контуре или в облаке, какие сетевые доступы для этого нужны.
- Матрицу ролей: кто со стороны бизнеса согласует состав данных и кто отвечает за выкатку на стороне ваших систем.
- Текущие метрики: конверсия в покупку, доля повторных заказов, глубина просмотра — точка отсчёта, с которой будем сравнивать результат.
- Ограничения: что запрещено использовать (персональные данные, платёжная информация), требования к срокам хранения.
Дальше мы считаем объём выборки, проверяем данные на разреженность и разрывы, после чего присылаем план внедрения: этапы, точки контроля и то, какой эффект вы увидите на каждом из них.







