Разбор кейса: 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 тыс. в пользовательском запросе.
- Для редких товаров нужен не один “покажем популярное”, а каскад запасных сценариев: категория, похожие атрибуты, ручные дополнения, глобальные популярные.
Цель блока рекомендаций в корзине
Что спрашивали
- Интервьюер дал масштаб: 10 млн пользователей и 100 тыс. товаров, а поверхность - блок в корзине.
- Затем проверял метрики: почему клики не доказывают, что блок принес пользу заказу.
Что было хорошо
- Кандидат держал в голове масштаб каталога и не предлагал полный перебор всех товаров на каждый запрос.
- В ответе появились бизнес-метрики: заказ, сумма заказа и поведение после рекомендации.
Где просело
- Нужно было раньше сказать, что цель блока отличается от главной ленты. В корзине пользователь уже выразил намерение, и блок должен дополнять заказ.
- CTR стоит назвать диагностикой, а не главной метрикой. Клик может быть любопытством, ошибкой или переходом без покупки.
Сильная структура ответа
- 1Сильнее было бы начать так: “Оптимизируем дополнительные добавления в корзину, заказ и средний чек, но контролируем жалобы, возвраты, повторы категорий, недоступные товары и задержку ответа”.
- 2Сразу задать первый запуск: заранее посчитанные товары, которые часто покупают вместе, плюс простые фильтры и запасной сценарий на популярное по категории.
Item-item baseline без лишней сложности
Что спрашивали
- Интервьюер ждал простой старт: взять историю заказов и понять, какие товары часто оказываются рядом в одной корзине.
- Дополнительно проверялись слабые места такого подхода: редкие товары, новые товары и перекос в сторону популярных позиций.
Что было хорошо
- Кандидат не начал с тяжелой персонализированной модели, а обсуждал item-item подход как первый рабочий вариант.
- Были затронуты случаи, когда рекомендаций не нашлось.
Где просело
- Нужно было конкретнее описать хранение: для каждого товара держим список лучших соседей, а не строим плотную матрицу 100 тыс. на 100 тыс. в пользовательском запросе.
- Для редких товаров нужен не один “покажем популярное”, а каскад запасных сценариев: категория, похожие атрибуты, ручные дополнения, глобальные популярные.
Сильная структура ответа
- 1Сильнее было бы сказать: заранее считаем совместные покупки, нормализуем не только по числу совпадений, храним список лучших соседей на товар и обновляем его по расписанию.
- 2На запросе берем товары из корзины, объединяем их соседей, суммируем оценки, удаляем дубли и включаем запасной сценарий, если после фильтров осталось мало кандидатов.
Фильтры до ранжирования
Что спрашивали
- Интервьюер подвел к самому базовому правилу: нельзя рекомендовать товар, который уже лежит в корзине.
- По сути проверялось, понимает ли кандидат, что качество системы - это не только модель, но и правила допустимости.
Что было хорошо
- Кандидат понял необходимость фильтровать уже добавленные товары.
- Дальше в обсуждении появились доступность и бизнес-ограничения.
Где просело
- Фильтры нужно было разложить на жесткие и мягкие. Жесткие нельзя пробивать модельным скором: нет в наличии, уже в корзине, запрещено в регионе, несовместимая категория.
- Не хватило счетчиков качества: сколько кандидатов выкинул каждый фильтр и как часто блок остается пустым.
Сильная структура ответа
- 1Сильнее было бы описать порядок: сначала достали кандидатов, затем удалили уже добавленное, недоступное, запрещенное и дубли вариантов, только потом ранжируем.
- 2Мягкие ограничения - разнообразие категорий, цена относительно корзины, маржинальность - можно учитывать в ранжировании, но они не должны отменять жесткие правила.
Дополнения против заменителей
Что спрашивали
- Интервьюер специально разобрал пример “кольцо к кольцу”, чтобы проверить доменное мышление.
- Вопрос был не про красивую векторную близость, а про то, понимает ли кандидат разницу между похожими товарами и товарами, которые хорошо покупаются вместе.
Что было хорошо
- Кандидат дошел до идеи категорий и совместимости товаров.
- В ответе появилась мысль, что простая похожесть не всегда равна полезности в корзине.
Где просело
- Нужно было резче сформулировать: в корзине похожий товар может конкурировать с уже выбранным, а дополнение увеличивает ценность заказа.
- Не хватило примеров признаков совместимости: категории товаров в корзине, категория кандидата, цена, материал, стиль, повод покупки.
Сильная структура ответа
- 1Сильнее было бы сказать: “Для кольца я сначала ищу комплементарные категории - серьги, подвески, браслеты, уход, упаковку - и только потом похожие кольца, если продукт этого хочет”.
- 2Сделать матрицу совместимости категорий: какие категории можно показывать вместе, какие нельзя, где нужен лимит на повторы и где нужен ручной контроль мерчандайзинга.
Ограничения категорий поверх поиска кандидатов
Что спрашивали
- После первого варианта интервьюер вел к тому, как встроить категории и признаки каталога в поиск кандидатов и ранжирование.
- Проверялось, не смешивает ли кандидат item-to-item задачу с персональным рекомендателем без объяснения границы.
Что было хорошо
- Кандидат обсуждал признаки товаров, категорий и возможный переход к более сложной модели.
- Была попытка связать текущую корзину с признаками пользователя.
Где просело
- Поиск ближайших векторов сам по себе возвращает похожие товары, но не гарантирует комплементарность и допустимые категории.
- Нужно было четче сказать, что признаки пользователя могут быть вторым слоем ранжирования, но текущая корзина остается главным контекстом запроса.
Сильная структура ответа
- 1Сильнее было бы предложить три уровня: отдельные списки кандидатов по категориям, фильтр после поиска с увеличенным списком кандидатов и ранжирование с признаком совместимости категории кандидата с корзиной.
- 2Для модели ранжирования строка - это кандидат в контексте корзины: признаки кандидата, агрегаты корзины, совместимость категорий, история пользователя и бизнес-ограничения.
Как сервис отвечает при изменении корзины
Что спрашивали
- Финальный блок был про запуск в продукте: где считаются кандидаты, как быстро ответить и как учитывать текущую корзину, которая меняется в сессии.
- Интервьюер проверял, не будет ли кандидат считать тяжелые признаки прямо в запросе пользователя.
Что было хорошо
- Кандидат отделял заранее подготовленные данные от онлайн-части ответа.
- Появились идеи кеша и обновления при изменениях корзины.
Где просело
- Нужно было назвать конкретные события пересчета: добавление товара, удаление товара, смена адреса, магазина, региона или промо.
- Не хватило деградации: что показываем, если сервис не успел, каталог устарел или после фильтров нет кандидатов.
Сильная структура ответа
- 1Сильнее было бы описать сервис так: при добавлении или удалении товара строим подпись корзины, достаем заранее посчитанных кандидатов, применяем фильтры, быстро ранжируем короткий список и возвращаем несколько лучших товаров.
- 2Контролируем задержку ответа сервиса на 95-м и 99-м процентилях, долю пустых ответов, долю запасного сценария, устаревший каталог и случаи, когда в ответе оказался товар, уже лежащий в корзине.
Термины
- Item-item baseline
- Первый простой подход: для каждого товара заранее найти товары, которые часто покупали вместе с ним, и использовать этот список как кандидатов.
- Fallback
- Запасной сценарий, если кандидатов мало или сервис деградировал: популярное по категории, ручные дополнения или скрытие блока вместо плохих рекомендаций.
- Substitutes
- Заменители: похожие товары, которые могут конкурировать с уже выбранным. Например, еще одно похожее кольцо к кольцу в корзине.
- Complements
- Дополнения: товары, которые логично купить вместе с текущей корзиной. Например, серьги или подвеска к кольцу.
- Serving
- Как рекомендационный сервис отвечает в продукте: получает текущую корзину, достает кандидатов, фильтрует, ранжирует и возвращает список за ограниченное время.
- Latency
- Задержка ответа сервиса. Для корзины важна, потому что блок должен быстро обновляться после добавления или удаления товара.