ESPN DeportesMonchi se disculpa por pedir Balón de Oro para LamineESPNHarbaugh offers rare critique of struggling QB Herbert: 'Be better'The Jerusalem PostWATCH: 'Don't mess with us': Netanyahu warns enemies may attack Israel ahead of electionBollywood HungamaJubin Nautiyal welcomes first child with wife after intimate wedding, shares update: “Mom and baby are back home”Daily MaverickTHE CONVERSATION: New world map makes Africa look bigger – What’s the fuss about? Cartographers explainRTP DesportoBrasil vence Austrália com Circati a marcar e Irankunda a cometer penáltiInquirerMost wanted person in Ilocos Sur town fallsBusiness AMRusland wil dit jaar nieuwe ballistische raket in dienst nemen met een bereik van 800 kmThe RegisterApple patches CoreGraphics zero-day already exploited in targeted attacksThe Hollywood ReporterHow a Microdramas Director Landed Her First Feature Film GigDeadlineLauren Cohan & Jake Epstein To Co-Star In Eric Stoltz Directed Rom-Com ‘Both Sides Now’The South AfricanPowerBall Xtra: R21 million up for grabs – plus guaranteed winner twist
The Daily Newsstand · Free, Always
Tuesday, September 29, 2026

Товарные рекомендации во ВКонтакте: как мы научили Ленту отличать интерес к контенту от намерения купить

Translate

Привет, Хабр. На связи Николай Карасов, ведущий разработчик отдела рекомендаций контентных сервисов в AI VK. Наша команда отвечает за рекомендации в Ленте ВКонтакте.

Перед нами стояла цель — развить внутри ВКонтакте новый пользовательский сценарий: человек приходит за контентом, видит у автора интересный ему товар и переходит к покупке прямо из социальной сети. Так в Ленте появился новый тип объекта — товарный пост. Первым партнёром в этом сценарии стал Ozon. Дальше речь пойдёт именно про товарные посты авторов в рамках реферальной программы Ozon, а не про любые публикации с товарами.

Было понятно, что обычный рекомендер для такого сценария не подходит. В итоге мы построили внутри Ленты отдельный товарный контур: со своими логированием, селекторами кандидатов, моделью ранжирования и выделенной квотой в финальной выдаче. Про это и расскажу.

Почему товар нельзя просто добавить в обычный рекомендер

Лента ВКонтакте много лет оптимизировалась под контентные действия: лайки, подписки, комментарии, вовлеченность, время в ленте. Ранкер хорошо предсказывает, что человек досмотрит ролик или поставит сердечко. Про покупку он не знает ничего — просто потому, что такого события в его обучающей выборке не было.

Разница тут не в количестве признаков, а в целевой функции. Для обычного поста цель рекомендации в том, чтобы человек его посмотрел, лайкнул или задержался в Ленте. Для товарного поста цель другая — покупка. 

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

Поэтому для нас товар — не ещё один тип контента, а объект рекомендации с другой целевой функцией. Отсюда два практических следствия:

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

2. Необходимы другие данные для обучения. История лайков не отвечает на вопрос, какие товары и товарные категории интересны конкретному человеку. У обычной ленты такой истории изначально просто нет.

Формально задача звучит так: из каталога товарных постов, которые могут попасть в рекомендации, нужно выбрать наиболее релевантные для конкретного пользователя. Для этого модель оценивает для каждой пары «пользователь — товар» вероятность того, что показ приведёт к заказу. Мы не пытаемся ответить на более общий вопрос «готов ли человек покупать вообще» — такая постановка слишком абстрактна и мало полезна для ранжирования. Сам каталог кандидатов сейчас насчитывает порядка 74 тысяч постов с товарами. 

Холодный старт: модель обучать не на чем

Сценарий покупки во ВКонтакте существовал и до запуска нового рекомендера, но в масштабе всей Ленты его доля оставалась небольшой. Для рекомендательной системы это означало ограниченное число товарных кандидатов и, соответственно, меньше данных для обучения. Но маленький каталог сам по себе не был главной сложностью. Задача оказалась циклической:

1. Товарных постов мало. На фоне всего объёма Ленты это доли процента кандидатов. 

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

3. Взаимодействий почти не набирается. Нет показов — нет кликов, переходов и тем более заказов.

4. Данных для обучения нет. А без данных модель не научится поднимать товарные посты.

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

Стопроцентное логирование для одного типа кандидатов

Первое решение было инфраструктурным. В обычной ленте мы логируем около 2% событий. Это осознанный компромисс: собирать 100% активности многомиллионной аудитории слишком дорого и по объёму данных, и по инфраструктуре, а для обучения контентных моделей двухпроцентной выборки хватает с запасом — событий всё равно очень много.

Для товарного контента арифметика ломается. Показы и так редкие, а 2% от редких показов — это статистический ноль. Обучающей выборки в таком режиме не появится никогда.

Очевидное решение — поднять процент логирования для всей Ленты — мы отбросили сразу: цена такого шага несопоставима с задачей. Вместо этого мы построили работу с Discovery-платформой так, чтобы процент логирования задавался отдельно для конкретного типа кандидатов. Для товарных постов подняли его до 100%.

Выглядит так: не хватало данных — не стали логировать всю Ленту целиком — сделали селективное стопроцентное логирование только нового домена. Товарных кандидатов относительно немного, поэтому дополнительная нагрузка несопоставима с полным логированием Ленты. А датасет по новому домену получается полный. В цифрах переход с двух процентов на сто дал рост обучающей выборки по товарному домену в 15 раз. 

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

Чем мы заменили заказы

Даже с полным логированием целевое событие остаётся редким. Заказ — это дно воронки, и на старте его частота близка к нулю. Мы использовали четыре приёма одновременно.

1. Похожие исторические сигналы

Мы посмотрели, как пользователи раньше взаимодействовали с коммерческим контентом: с товарными витринами сообществ в Маркете ВКонтакте и с товарными публикациями авторов. Такой контент во ВКонтакте существовал и до запуска нового сценария, а значит, по нему есть история. Она даёт первые сигналы о товарном интересе ещё до того, как появится история покупок. 

2. Простые топы по сегментам

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

3. Обучение на более частых таргетах

Сначала модель училась на доступных сигналах — прежде всего на позитивных реакциях. Когда данных стало больше, таргеты постепенно смещались ближе к целевому действию: к переходу и заказу. Это не разовая замена, а плановая миграция: по мере накопления событий нижние ступени воронки становятся статистически надёжными, и вес в обучении переходит к ним.

4. Expand как ранний proxy покупки

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

Логика простая: раскрыл текст — заинтересовался — вероятность перехода к партнёру выше. Expand заметно коррелировал с дальнейшим переходом и при этом случался в разы чаще, чем сам переход. На ранних этапах он стал одним из ключевых proxy-таргетов.

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

Какие сигналы собирает система

Сигналы делятся на две группы. Контентные — те же, что и для обычного поста:

  • просмотр;

  • время просмотра;

  • лайк;

  • комментарий;

  • открытие фотографии;

  • перелистывание карусели;

  • раскрытие текста поста (expand);

  • дизлайк;

  • скрытие и жалоба (hide/report).

И товарные — те, которых у обычной ленты нет:

  • переход на карточку товара в Маркете ВКонтакте;

  • переход к партнёру (click-out);

  • заказ.

У перехода к партнёру есть два разных пути, и это важно для атрибуции. Первый — напрямую по ссылке в тексте поста. Второй — через карточку товара в Маркете ВКонтакте; и кнопку покупки на ней. Пути дают разные по силе сигналы, поэтому мы их различаем.

Как мы ищем кандидатов

Источник 1. Товарное поведение на стороне партнёра

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

В VK моделирование признаков, счётчики и рекомендательные механики, работают на Discovery-платформе. На основе этих представлений работают селекторы, которые находят среди товарных постов товары, близкие к поведению человека у партнёра.

Источник 2. Контентная близость

Второй источник интереснее, потому что он работает даже для человека без товарной истории. Отправной точкой становится обычный контентный интерес.

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

Сквозной пример

Разберём весь путь по шагам. По сути это item2item-рекомендации: якорь — обычный пост ВКонтакте, кандидат — пост с товаром. 

1. Человек смотрит пост с рецептом. Обычный контентный пост, никакого отношения к товарам он не имеет.

2. Лайкает или сохраняет его. Это явный позитивный сигнал.

3. Сигнал попадает в рекомендательную систему. Событие уходит в общий поток и становится доступно для построения следующей выдачи.

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

5. Отдельный селектор ищет среди товарных постов контентно похожие варианты. В случае с рецептом это условно посуда, ножи, книги рецептов и другие связанные товары.

6. Эти посты попадают в общий набор кандидатов. Никаких привилегий у них при этом нет.

7. Модель оценивает релевантность каждого кандидата для конкретного человека. Здесь и решается судьба товарного поста.

8. Если скор высокий, вероятность показа растёт. Человек видит товарный пост и потенциально переходит к покупке.

Мультитаргетное ранжирование: заказ важнее лайка

Ранжирование работает на градиентном бустинге, конкретно — на CatBoost. Целей у модели несколько одновременно, то есть это мультитаргетное ранжирование. Приоритет событий выстроен так: 

1. Заказ. Главная цель контура, максимальный вес.

2. Переход к партнёру, click-out. Следующая по силе ступень воронки.

3. Более лёгкие позитивные действия с контентом. Лайк, комментарий, время просмотра — они говорят об интересе, но не о покупке.

4. Внизу — нерелевантные показы, быстрые пролистывания и негатив. Такие исходы модель штрафует.

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

Продуктовая логика за этим такая: не максимизировать CTR любой ценой, а выстроить цепочку от интереса к товару до заказа. Если оптимизировать только верх воронки, легко получить красивую метрику кликов и ноль продаж.

Как товарный контур живёт внутри Ленты

Товарные рекомендации — это не отдельная независимая лента. Они существуют внутри общего рекомендательного механизма, но имеют собственную квоту. Такая схема даёт нам три вещи:

1. Контроль доли товарного контента. Явно задаём максимум, а не отдаём этот вопрос на откуп общему ранкеру.

2. Собственные фильтры релевантности. К товарным кандидатам применяются требования, которых нет у обычного контента.

3. Отдельная оптимизация переходов и заказов. Контур можно улучшать независимо от остальной ленты.

По порядку величины товарный контент подмешивается в выдачу с ограниченной вероятностью. Базово она составляет 1,5%. Но если для конкретного пользователя нашёлся пост с высококонверсионным товаром — по оценке модели, — квота в моменте увеличивается до 5%. Большая часть Ленты остаётся обычным контентом, и это принципиальная позиция: Лента не должна превращаться в витрину. 

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

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

Из выдачи товарный пост может выпасть и по другой причине — из-за стоков на стороне партнёра. Когда товар заканчивается, пост с ним уходит из рекомендаций и возвращается, как только стоки появляются снова.

Как не завалить Ленту одинаковыми товарами

По мере роста числа кандидатов появилась новая задача — категориальное разнообразие. Когда каталог маленький, вопроса нет: показать бы хоть что-то подходящее. Когда кандидатов становится много, у ранжирования возникает неприятное свойство: если человек проявил интерес к одной категории, топ по скору легко заполняется товарами именно из неё.

Сейчас мы тестируем механику, которая следит, чтобы в некотором окне выдачи не повторялись одинаковые категории — при условии, что доступны хорошие кандидаты из других категорий. Пробуем окна размером 2, 5 и 10 позиций. Категорию при этом берём из дерева тематик, а не от отдельного классификатора. Здесь важна оговорка: разнообразие не должно оплачиваться релевантностью. Если альтернатив достойного качества нет, механика не станет подставлять слабый кандидат ради формального разнообразия — сработает порог, и позиция останется за обычным контентом. 

Что дала Discovery-платформа

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

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

Эффект на проекте выразился в скорости:

1. Быстрее проводили эксперименты. Меньше инфраструктурной работы на каждую гипотезу.

2. Поставили больше A/B-тестов за тот же срок. Пропускная способность команды по гипотезам выросла.

3. Быстрее дошли до рабочих вариантов. Больше проверенных гипотез — раньше находится удачная конфигурация.

4. Превысили изначально ожидаемый рост продуктовых метрик. План по конверсии перевыполнили вдвое, по показам — втрое. Конверсия и показы выросли одновременно, а значит, переходы к партнёру прибавили кратно. 

Что получилось в цифрах

Сравним два одинаковых окна: 1–30 марта и 1–30 августа. Между ними пять месяцев работы контура.

1. Сквозная конверсия «показ → созданный заказ» выросла на 53%. Это главная метрика проекта: она показывает, что отдельный контур под намерение купить работает лучше обычного ранжирования.

2. Созданные заказы — рост в 43,2 раза. Итоговое действие всей воронки.

3. Переходы к партнёру — рост в 55,3 раза. Ступень воронки прямо перед заказом.

4. Просмотры товарных постов — рост в 28,3 раза. Здесь сказались и квота, и то, что кандидатов в системе стало заметно больше.

5. CTR перехода к партнёру из поста вырос на 95,6%. Почти вдвое.

Эти числа стоит читать раздельно, потому что они про разное. Рост просмотров в 28 раз — это объём: товарных постов в системе стало больше, и квота начала их пропускать. А конверсия и CTR — это качество: при том же показе человек стал заметно чаще доходить до заказа. Рост заказов складывается из обоих эффектов сразу и раскладывается почти точно: 28,3 × 1,53 ≈ 43,2.

Разделение важно ещё и потому, что объём упирается в потолок. Квота ограничена, каталог растёт не бесконечно, и дальше выигрыш приходит в основном со стороны качества ранжирования. Именно поэтому конверсия для нас — главная метрика, а не число показов.

Побочный эффект: авторы принесли больше товарных постов

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

Получился положительный цикл: лучше рекомендации — больше аудитории у товарного поста — больше мотивации у авторов делать такой контент — больше кандидатов в системе — ещё лучше возможности для рекомендаций.

Для рекомендательной команды это важный момент. Качество рекомендаций в маркетплейс-сценарии — не только про удобство пользователя. Оно напрямую влияет на предложение: каталог кандидатов растёт сам, если авторам выгодно его наполнять. И наоборот: слабые рекомендации в новом домене душат предложение и загоняют проект обратно в холодный старт.

Что из этого стоит забрать себе

Главная мысль проекта в одну строку: мы не стали учить обычный рекомендер продавать. Мы построили внутри него отдельный контур, который постепенно научился отличать интерес к контенту от намерения купить.

Если вы запускаете рекомендации в новом домене поверх существующей системы, вот что мы бы советовали проверить в первую очередь:

1. Начните с данных, а не с модели. Сэмплирование, настроенное под старые задачи, способно полностью обнулить обучающую выборку нового домена. Проверьте это до того, как выберете архитектуру.

2. Ищите точечное решение вместо глобального. Поднять логирование для всей ленты дорого и не нужно. Поднять его для одного типа кандидатов — дёшево и достаточно.

3. Стройте лестницу таргетов. Начинайте с частых proxy-событий вроде expand, а по мере накопления данных переезжайте ближе к настоящей цели. И заранее решите, по какому критерию будете переезжать.

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

5. Держите контентные метрики в критериях приёмки. Иначе коммерческий контур рано или поздно оплатит свой рост качеством основного продукта.

View the original on Хабр →

KioskNews shows a cleaned-up reading view extracted from the publisher’s page — the original always lives on their site, not ours.