Всё началось с, казалось бы, простой идеи, а закончилось пачкой выводов, которые, переносятся на любую систему, где тоже есть трейдофф между релевантностью и выручкой.
Идея была следующая. В рекомендациях платные объявления продвигались несколькими независимыми механиками, каждая со своей логикой и своими костылями. Мы решили сделать одинаково для всех: коллеги из команды Рекомендаций строят органическую выдачу и не думают о деньгах.
Все платные объявления складываются в один список по денежному критерию, а на каждой позиции независимо решаем, платное туда встанет или органическое. По офлайн-оценке тест был зелёным, все довольны.
Угадайте, что могло пойти не так (спойлер: всё).Первый же большой тест прожил считанные дни. Платные объявления, которые новый алгоритм поднимал выше всех, оказались теми, по которым много кликают, но редко пишут и звонят.
Продавцы платили за клики и не получали результата, и жалобы пришли раньше, чем мы успели посмотреть на дашборды. Мы знали заранее, что конверсия у этого сегмента чувствительная, но всё равно решили попробовать. Что ж, эффект оказался такой, что тест пришлось выключать на второй день.
Отсюда первый вывод: guardrail закладывается в дизайн первой итерации, а не добавляется после жалоб.
Защиту мы, конечно, добавили: порог по предсказанной конверсии, ниже которого объявление в выдачу не попадает. Качество выровнялось, и мы пошли в большой тест с разделением продавцов на группы, чтобы понять, что новый алгоритм делает с их бюджетами.
И там тестовые продавцы стали продвигаться меньше контрольных даже в той группе, где алгоритм был один на всех.
Месяц гипотез, и механизм нашёлся в самом пороге: механика давала тестовым объявлениям больше показов, показы портили их поведенческие счётчики, модель конверсии честно занижала предикт, и тестовые объявления выпадали на пороге, который мы ввели ради качества. Модель права, счётчики правы, но всё ломает общий порог.
Второй вывод: каждый защитный механизм возвращается в фичах с задержкой в несколько недель, и подумать об этом надо до теста, а не после.
Раздельные пороги починили группу, где наш новый алгоритм работал для всех. А группу, где на одной выдаче одни продавцы шли через новую механику, а другие через старую, не починило ничего. Смешанная выдача просто не даёт тестовым объявлениям такой ликвидности, как полная раскатка.
Третий вывод: эффект на продавцов не измеряется интерливингом, его нужно измерять раскаткой и обратным тестом.
А параллельно нас догнало то, чего в плане не было. Мы крутили параметры ранжирования ради одних категорий, а сильнее всех отреагировали другие.
Для них каждый наш тест был всплеском трафика, а каждое выключение — падением ниже, чем было до, потому что смещение в счётчиках вымывается неделями.
В итоге, получилось так, что одна вертикаль требовала ленту не раскатывать, другая — раскатить обратно.
Четвёртый вывод: тест, который нельзя оставить включённым, лучше не запускать, а о размене между категориями договариваться заранее.
В конце концов, мы дошли до раскатки, и теперь продолжаем развивать механизм продвижения. Изначально стремились к немного другому сетапу, но именно эти четыре вещи я бы рассказал себе год назад.
А теперь к вам: какие из ошибок уже испытали на своей шкуре?) Голосуйте реакциями:
🔥 — guardrail задним числом
🤯 — feedback loop через счётчики
😁 — тест, который не измеряет то, ради чего запущен
😭 — откат оказался хуже самого теста
И расскажите в комментариях, как ищете оптимальное соотношение между релевантностью для пользователя и выручкой компании — интересно сравнить)