Назад к подготовке
GRII RED2026-03-12

Разбор кейса: GRII RED: ML System Design

System design cart recommendations: item-item baseline, category complements, fallbacks и online serving.

Этапы

6

Вопросы

14

Практика

14

Кейс простыми словами

Это кейс про блок рекомендаций внутри корзины. Пользователь уже выбрал товары, поэтому система должна не просто показать “похожие” товары, а предложить то, что полезно добавить к текущему заказу.

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

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

Карта разбора

6

этапов с вопросами, просадками и сильной структурой ответа.

Быстро подтянуть

4

повторяющихся слабых мест вынесены наверх перед деталями.

Практика

14

связанных вопросов открываются прямо из этапов разбора.

Главные просадки

  • Нужно было раньше сказать, что цель блока отличается от главной ленты. В корзине пользователь уже выразил намерение, и блок должен дополнять заказ.
  • CTR стоит назвать диагностикой, а не главной метрикой. Клик может быть любопытством, ошибкой или переходом без покупки.
  • Нужно было конкретнее описать хранение: для каждого товара держим список лучших соседей, а не строим плотную матрицу 100 тыс. на 100 тыс. в пользовательском запросе.
  • Для редких товаров нужен не один “покажем популярное”, а каскад запасных сценариев: категория, похожие атрибуты, ручные дополнения, глобальные популярные.
Этап 1

Цель блока рекомендаций в корзине

00:02:07-00:13:41

Что спрашивали

  • Интервьюер дал масштаб: 10 млн пользователей и 100 тыс. товаров, а поверхность - блок в корзине.
  • Затем проверял метрики: почему клики не доказывают, что блок принес пользу заказу.

Что было хорошо

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

Где просело

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

Сильная структура ответа

  1. 1Сильнее было бы начать так: “Оптимизируем дополнительные добавления в корзину, заказ и средний чек, но контролируем жалобы, возвраты, повторы категорий, недоступные товары и задержку ответа”.
  2. 2Сразу задать первый запуск: заранее посчитанные товары, которые часто покупают вместе, плюс простые фильтры и запасной сценарий на популярное по категории.
Этап 2

Item-item baseline без лишней сложности

00:15:55-00:20:17

Что спрашивали

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

Что было хорошо

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

Где просело

  • Нужно было конкретнее описать хранение: для каждого товара держим список лучших соседей, а не строим плотную матрицу 100 тыс. на 100 тыс. в пользовательском запросе.
  • Для редких товаров нужен не один “покажем популярное”, а каскад запасных сценариев: категория, похожие атрибуты, ручные дополнения, глобальные популярные.

Сильная структура ответа

  1. 1Сильнее было бы сказать: заранее считаем совместные покупки, нормализуем не только по числу совпадений, храним список лучших соседей на товар и обновляем его по расписанию.
  2. 2На запросе берем товары из корзины, объединяем их соседей, суммируем оценки, удаляем дубли и включаем запасной сценарий, если после фильтров осталось мало кандидатов.
Этап 3

Фильтры до ранжирования

00:13:41-00:15:55

Что спрашивали

  • Интервьюер подвел к самому базовому правилу: нельзя рекомендовать товар, который уже лежит в корзине.
  • По сути проверялось, понимает ли кандидат, что качество системы - это не только модель, но и правила допустимости.

Что было хорошо

  • Кандидат понял необходимость фильтровать уже добавленные товары.
  • Дальше в обсуждении появились доступность и бизнес-ограничения.

Где просело

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

Сильная структура ответа

  1. 1Сильнее было бы описать порядок: сначала достали кандидатов, затем удалили уже добавленное, недоступное, запрещенное и дубли вариантов, только потом ранжируем.
  2. 2Мягкие ограничения - разнообразие категорий, цена относительно корзины, маржинальность - можно учитывать в ранжировании, но они не должны отменять жесткие правила.
Практика по просадкам
Этап 4

Дополнения против заменителей

00:25:08-00:40:02

Что спрашивали

  • Интервьюер специально разобрал пример “кольцо к кольцу”, чтобы проверить доменное мышление.
  • Вопрос был не про красивую векторную близость, а про то, понимает ли кандидат разницу между похожими товарами и товарами, которые хорошо покупаются вместе.

Что было хорошо

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

Где просело

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

Сильная структура ответа

  1. 1Сильнее было бы сказать: “Для кольца я сначала ищу комплементарные категории - серьги, подвески, браслеты, уход, упаковку - и только потом похожие кольца, если продукт этого хочет”.
  2. 2Сделать матрицу совместимости категорий: какие категории можно показывать вместе, какие нельзя, где нужен лимит на повторы и где нужен ручной контроль мерчандайзинга.
Этап 5

Ограничения категорий поверх поиска кандидатов

00:35:42-00:54:44

Что спрашивали

  • После первого варианта интервьюер вел к тому, как встроить категории и признаки каталога в поиск кандидатов и ранжирование.
  • Проверялось, не смешивает ли кандидат item-to-item задачу с персональным рекомендателем без объяснения границы.

Что было хорошо

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

Где просело

  • Поиск ближайших векторов сам по себе возвращает похожие товары, но не гарантирует комплементарность и допустимые категории.
  • Нужно было четче сказать, что признаки пользователя могут быть вторым слоем ранжирования, но текущая корзина остается главным контекстом запроса.

Сильная структура ответа

  1. 1Сильнее было бы предложить три уровня: отдельные списки кандидатов по категориям, фильтр после поиска с увеличенным списком кандидатов и ранжирование с признаком совместимости категории кандидата с корзиной.
  2. 2Для модели ранжирования строка - это кандидат в контексте корзины: признаки кандидата, агрегаты корзины, совместимость категорий, история пользователя и бизнес-ограничения.
Этап 6

Как сервис отвечает при изменении корзины

00:55:43-01:01:53

Что спрашивали

  • Финальный блок был про запуск в продукте: где считаются кандидаты, как быстро ответить и как учитывать текущую корзину, которая меняется в сессии.
  • Интервьюер проверял, не будет ли кандидат считать тяжелые признаки прямо в запросе пользователя.

Что было хорошо

  • Кандидат отделял заранее подготовленные данные от онлайн-части ответа.
  • Появились идеи кеша и обновления при изменениях корзины.

Где просело

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

Сильная структура ответа

  1. 1Сильнее было бы описать сервис так: при добавлении или удалении товара строим подпись корзины, достаем заранее посчитанных кандидатов, применяем фильтры, быстро ранжируем короткий список и возвращаем несколько лучших товаров.
  2. 2Контролируем задержку ответа сервиса на 95-м и 99-м процентилях, долю пустых ответов, долю запасного сценария, устаревший каталог и случаи, когда в ответе оказался товар, уже лежащий в корзине.

Термины

Item-item baseline
Первый простой подход: для каждого товара заранее найти товары, которые часто покупали вместе с ним, и использовать этот список как кандидатов.
Fallback
Запасной сценарий, если кандидатов мало или сервис деградировал: популярное по категории, ручные дополнения или скрытие блока вместо плохих рекомендаций.
Substitutes
Заменители: похожие товары, которые могут конкурировать с уже выбранным. Например, еще одно похожее кольцо к кольцу в корзине.
Complements
Дополнения: товары, которые логично купить вместе с текущей корзиной. Например, серьги или подвеска к кольцу.
Serving
Как рекомендационный сервис отвечает в продукте: получает текущую корзину, достает кандидатов, фильтрует, ранжирует и возвращает список за ограниченное время.
Latency
Задержка ответа сервиса. Для корзины важна, потому что блок должен быстро обновляться после добавления или удаления товара.