Май 2026 Кейс 8 мин

Один кейс, три процесса: как дефект LLM-классификатора превращается в ложный A/B-результат

Представьте: вы запустили A/B-тест нового алгоритма ранжирования на маркетплейсе. Через две недели — выручка на пользователя выросла на 20.9%, p-value практически нулевой, доверительный интервал далеко от нуля. Решение очевидно: выкатываем на всех. Но если посмотреть на этот же эксперимент через три процесса сразу — A/B-методологию, монетизацию и оценку качества ML-модели, — вывод меняется на противоположный. Прирост частично фальшивый, и чинить нужно не алгоритм ранжирования, а совсем другую вещь.

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

Кейс

Маркетплейс. Товары автоматически категоризирует LLM-классификатор. Категория влияет на ранжирование в выдаче. Команда выкатывает новый алгоритм ранжирования, который сильнее опирается на предсказанную категорию товара, и тестирует его через A/B: половина пользователей на старом ранжировании, половина на новом. Метрика успеха — выручка на пользователя.

В этом кейсе участвуют три процесса, и обычно за каждый отвечает свой человек или команда: аналитик эксперимента смотрит A/B, продуктовая аналитика следит за монетизацией и retention, ML-команда отвечает за качество классификатора. Когда они смотрят порознь, каждый видит свою правду. Сила — в том, чтобы посмотреть на все три сразу.

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

Процесс 1. A/B-эксперимент

Первый взгляд — на эффект. Выручка на пользователя: 11.16 в контроле, 13.49 в тесте, прирост +20.9%, Welch t-test даёт t≈11.2 при p<0.001. Сигнал сильный.

Здесь стоит применить CUPED — снижение дисперсии через предэкспериментальную ковариату (исторический ARPU пользователя). Идея простая: часть разброса выручки объясняется тем, что одни пользователи в принципе тратят больше других, и это видно ещё до теста. Вычитая предсказуемую часть, мы сужаем доверительный интервал, не сдвигая оценку эффекта.

theta = np.cov(Y, X)[0,1] / np.var(X)        # X — pre-period ARPU
Y_adj = Y - theta * (X - X.mean())            # скорректированная метрика

На этих данных CUPED снижает дисперсию на 14.4%: оценка эффекта та же, но t-статистика растёт с 11.2 до 12.1 — интервал уже, вывод увереннее.

И сразу — методологическая дисциплина. Соблазн «подглядывать» в результат каждый день и остановиться, как только увидел значимость, ломает тест. Я прогнал A/A-проверку: взял контрольную группу, случайно разбил её надвое (истинного эффекта нет), и десять раз «подглядывал» по мере накопления данных. Наивный тест хотя бы раз пересекал p<0.05 в 18% случаев — вместо номинальных 5%. Подглядывание раздувает ложные срабатывания почти вчетверо. Лечится это либо фиксированным размером выборки, либо последовательными границами (например, O'Brien–Fleming).

Пока всё выглядит хорошо: значимый прирост, корректная методология. Аналитик A/B готов писать «выкатываем».

Процесс 2. Монетизация

Теперь — продуктовый взгляд. Выручка выросла, но за счёт чего?

метрика control treatment дельта
ARPU 11.16 13.49 +20.9%
показы рекламы 30.0 36.0 +20.1%
retention D7 0.726 0.686 −5.6%

Картина проясняется. Прирост выручки идёт в основном из роста показов рекламы (+20%). А retention седьмого дня упал на 5.6% — и это статистически значимо (p<0.001). Это классический конфликт «выручка против удержания»: можно показать больше рекламы и заработать сегодня, заплатив оттоком завтра. Продуктовая аналитика бьёт тревогу там, где A/B-аналитик видел успех.

Но почему новый алгоритм вообще роняет retention? Здесь нужен третий взгляд.

Процесс 3. AI-evals

Качество LLM-классификатора, который категоризирует товары. Наивная оценка — средняя точность по всем товарам: 86.4%. Выглядит достойно, «модель готова к проду».

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

категория точность доля товаров
electronics (частая) 0.937 21.8%
clothing 0.915 18.7%
crafts (редкая) 0.630 1.4%
vintage (редкая) 0.653 0.8%
График точности классификатора по категориям: высокая на частых, падает в длинном хвосте
Точность по категориям: высокая на частых, падает в длинном хвосте. Средняя 86% маскирует провал до 63%.

Классификатор отлично работает на частых категориях и проваливается в «длинном хвосте»: на пяти самых редких категориях средняя точность 67.7%. Разрыв между micro-точностью (взвешенной по частоте, 86.4%) и macro-F1 (где все категории равны, 81.1%) — пять пунктов, и именно micro прячет провал в хвосте. На бенчмарке со сбалансированными классами этот дефект не виден; он проявляется только на реальном распределении трафика.

# наивно — одна цифра прячет всё:
accuracy_score(y_true, y_pred)                # 0.864
# стратифицированно — виден провал в хвосте:
products.groupby("true_category")["correct"].mean()

Три взгляда дали три разные правды: A/B — «успех», монетизация — «retention падает», evals — «классификатор врёт в хвосте». По отдельности они не объясняют друг друга. Вместе — складываются в одну цепочку.

Связка

Соединим. Новый алгоритм ранжирования сильнее доверяет предсказанной категории. Там, где классификатор надёжен (частые категории), это работает хорошо. Там, где он врёт (хвост), новый алгоритм показывает нерелевантную выдачу — пользователь дольше скроллит в поисках нужного, видит больше рекламы (выручка растёт!), но уходит недовольным (retention падает).

Разрез treatment-группы по сегменту пользователя подтверждает:

сегмент ARPU retention D7
head-категории 13.76 0.692
tail-категории 10.00 0.603

В хвосте, где классификатор ошибается, retention заметно ниже. Вред сконцентрирован ровно там, где врёт eval-модель.

Финальная проверка — контрфактуал. Каким был бы эффект, если бы классификатор не ошибался? Оценим эффект только на head-сегментах, где он надёжен:

выручка retention
все сегменты (наблюдаемое) +20.9% −5.6%
только head (классиф. надёжен) +27.4% −3.8%
Контрфактуал: наблюдаемый эффект vs эффект без дефекта классификатора
Без дефекта классификатора прирост выручки выше, а retention почти не страдает — вред оплачен мисматчем категорий.

Вот разгадка. На сегментах, где классификатор не врёт, прирост выручки даже выше (+27%), а retention почти не страдает. Значит вред от нового алгоритма — это не его собственное свойство, а артефакт мисматча категорий. Алгоритм ранжирования хорош; плох классификатор в хвосте.

Схема причинной цепочки: дефект классификатора → искажение A/B → ложный сигнал монетизации
Один дефект порождает и ложный прирост выручки, и скрытый отток. Наивный взгляд видит только верхнюю ветку.

Что показывает этот кейс

Наивный путь: A/B-аналитик видит +20.9% выручки и выкатывает. Через квартал команда обнаруживает просевший retention и начинает откатывать или чинить алгоритм ранжирования — то есть лечит не ту болезнь.

Сквозной путь: связав три процесса, мы видим, что корень — в классификаторе. Правильное действие — не трогать алгоритм ранжирования (он работает), а дообучить классификатор на хвосте категорий. После этого новый алгоритм даст свой честный +27% без потери retention.

Этот вывод невозможно получить, глядя на один процесс. A/B-методология ловит, что эффект значим, но не объясняет цену. Монетизация ловит конфликт «выручка против retention», но не видит причину. Evals ловит дефект классификатора, но не связывает его с выручкой. Ценность — в том, чтобы держать три процесса в голове одновременно и увидеть причинную цепочку: дефект оценки модели → искажение эксперимента → ложный сигнал монетизации.

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

Если интересно обсудить — напишите в Telegram.

По теме: как A/B-тест ломается в рекламном аукционе и симуляторы AI-evals с category-matching дефектом.

← Все кейсы