LLM-as-Judge: position bias и mirror-judging
Маркетплейс хочет автоматизировать сравнение двух LLM-моделей для саппорт-бота. Вместо тысяч человеческих оценок — сгенерировать N ответов от каждой модели на одни и те же запросы клиентов, отдать пары ответов LLM-судье (GPT-4 в роли оценщика), попросить выбрать лучший. Цель — win rate новой модели B против текущей A.
План выглядит идеально: дёшево, быстро, масштабируемо. На 1000 пар $20 в API-вызовах вместо $5000 в зарплате разметчикам. Команда уже планирует выкатить новую модель на основе результатов pairwise judgment.
Но в этой методологии есть систематическая ошибка, которую не видно при простом запуске. LLM-судьи имеют position bias — они склонны предпочитать ответ, показанный первым, независимо от качества. Это measured number из академической литературы: для GPT-4 как судьи bias составляет 15–25 п.п. Если всегда показывать ответы в порядке (A, B) — оценка win rate B будет смещена.
Эта страница про то, как position bias работает, как его обнаружить, и как методологически правильно с ним бороться (mirror-judging). Симулятор посередине показывает, как смещена оценка при naive подходе и насколько mirror-стратегия исправляет результат.
Position bias — что это и почему серьёзно
Главная тема этого кейса.
Что такое position bias
LLM-судья получает промпт вида: «Вот два ответа на запрос клиента. Какой лучше?». В промпте ответы идут друг за другом — один первый, второй второй. По данным академических работ (Zheng et al. 2023, MT-Bench; Li et al., AlpacaFarm), GPT-4-class судьи систематически предпочитают ответ показанный первым — даже когда явно сказано «не учитывайте порядок».
Численно: если истинная вероятность что A лучше — 50%, то при «A первый» judge выберет A примерно в 60–65% случаев. Это не случайный шум, это systematic shift. Bias меняется от 15 до 25 процентных пунктов в зависимости от модели-судьи, типа задачи и формулировки промпта.
Почему это серьёзно
В типичном A/B-pipeline команда генерирует пары и оценивает их в фиксированном порядке (обычно «текущая модель первая, новая вторая» или наоборот — кому как удобнее). Результат — win rate смещён в сторону той модели, которая всегда первая.
Конкретно: если в эксперименте всегда A первый, и judge имеет bias +20 п.п. в сторону первого:
- Истинный win rate B = 50% (модели эквивалентны)
- Измеренный win rate B = 50% − 20% = 30%
- Вывод команды: «B сильно хуже»
- Реальность: B такая же
Это не academic curiosity. Это реальные продакшен-ошибки, которые приводят к неправильным решениям о замене моделей. В одну сторону, если порядок (A, B) — недооцениваем B. В другую, если (B, A) — переоцениваем. Случайный порядок смещения не убирает, потому что bias всё равно работает в каждой паре — он просто маскируется в среднем.
Как обнаружить
Простой sanity check: рандомизировать порядок и сравнить с обратным. Если win rate B при «A первый» равен 30%, а при «B первый» равен 70% — есть position bias. Если bias есть, эти две оценки расходятся на 2× bias_strength. Если порядок был всегда фиксирован — расхождение не видно, и команда «не знает» что есть проблема.
Как лечить — mirror-judging
Стандартная методология устранения position bias — mirror-judging. Каждую пару судить дважды:
- Первый раз: порядок (A, B)
- Второй раз: порядок (B, A)
Дальше засчитываем «B выиграл» только если B победил в обоих ордерах. Если B победил в одном, а A в другом — это tie (значит судья выбирал по позиции, не по содержанию).
Стоимость: 2× больше API-вызовов. Точность: позиционное смещение полностью устраняется (если оно симметрично). Это стандарт в академической литературе и продакшен-RLHF pipelines больших AI-лабораторий.
Численно: при истинном win rate 55% и bias 20 п.п.:
- Naive (всегда A first): измеряем 35%
- Mirror: измеряем 55%, без смещения
Симулятор ниже показывает эту разницу на разных параметрах.
Симулятор: position bias и стратегии judgment
Naive vs Mirror: оценка win rate
Зелёный — истинный win rate. Синий — оценка при текущей стратегии. Серый — tie rate (только для mirror). Красная линия — ±5 п.п. допустимое смещение.
Сравнение всех стратегий
Оценка win rate B при разных стратегиях при текущих параметрах. Горизонтальная линия — истинный win rate.
Что показывает симулятор
- Always A first / Always B first — naive. Систематически смещают оценку в сторону или против B на 2× bias_strength.
- Random order — снимает «направление» смещения, но добавляет шум. На большой выборке среднее правильное, но variance больше.
- Mirror (оба порядка) — единственная стратегия, которая действительно устраняет position bias. Стоимость — 2× API-вызовов на пару.
Главный takeaway: если ваш eval — naive (всегда один порядок), и bias 20 п.п., вы можете легко спутать «equivalent» с «50% хуже» или «50% лучше». Mirror — это не optional, это база.
Полный judgment pipeline
Практическое — как настроить LLM-as-judge pipeline без position bias.
Что генерировать
На N запросов клиентов получаем N пар (response_A, response_B). Это твой dataset для сравнения моделей. Запросы должны быть representative — взять реальные запросы из логов саппорта, не synthetic. Минимум 200–500 пар для статистически значимого вывода.
Что отправлять в judge
Каждую пару отправляем дважды в LLM-судью:
judgment_1 = judge(prompt, response_A, response_B)
judgment_2 = judge(prompt, response_B, response_A)
Логируем оба результата вместе с порядком:
pair_id — ID пары
order — "AB" или "BA"
judge_choice — "first" или "second"
judge_confidence — если judge даёт rationale, тоже логируем
Псевдокод:
for pair in pairs:
# Order 1: A first
verdict_1 = call_judge(pair.prompt,
first=pair.response_A,
second=pair.response_B)
log(pair_id=pair.id, order="AB", verdict=verdict_1)
# Order 2: B first
verdict_2 = call_judge(pair.prompt,
first=pair.response_B,
second=pair.response_A)
log(pair_id=pair.id, order="BA", verdict=verdict_2)
Что считать на уровне эксперимента
SQL-агрегация по логам:
WITH paired AS (
SELECT
pair_id,
MAX(CASE WHEN order = 'AB' THEN judge_choice END) AS verdict_AB,
MAX(CASE WHEN order = 'BA' THEN judge_choice END) AS verdict_BA
FROM judgments
WHERE experiment_id = 'llm_judge_q2'
GROUP BY pair_id
)
SELECT
COUNT(*) AS total_pairs,
-- B wins только если выиграл в обоих ордерах
AVG(CASE
WHEN verdict_AB = 'second' AND verdict_BA = 'first'
THEN 1 ELSE 0
END) AS mirror_winrate_B,
-- A wins только если выиграл в обоих ордерах
AVG(CASE
WHEN verdict_AB = 'first' AND verdict_BA = 'second'
THEN 1 ELSE 0
END) AS mirror_winrate_A,
-- Tie если расходятся
AVG(CASE
WHEN (verdict_AB = 'second' AND verdict_BA = 'second')
OR (verdict_AB = 'first' AND verdict_BA = 'first')
THEN 1 ELSE 0
END) AS tie_rate
FROM paired;
Что писать в финальный отчёт
В отчёте для команды:
- Mirror-corrected win rate B vs A с CI
- Tie rate (это сигнал силы position bias)
- Naive win rate (для сравнения) — показать разницу
- Decision threshold: было ли B статистически лучше A?
Не писать просто «win rate B = 55%». Правильная форма: «Mirror-corrected win rate B = 55% (CI 48–62%), tie rate = 18%. Naive win rate без mirror коррекции дал бы 38% из-за position bias. Решение: B equivalent или slightly better; рекомендуется второй раунд с увеличенной выборкой».
Что делать дальше
Минимальный checklist для аналитика, который собирается делать LLM-as-judge сравнение:
- Никогда не использовать фиксированный порядок. Mirror каждую пару (отправлять оба ордера) — это удвоит API-cost, но не делает что-то ещё дороже: вы всё равно используете judge.
- Если уже сделал eval без mirror — измерить bias ретроспективно. Случайная выборка 50–100 пар, реран в обратном порядке. Если расхождение существенное — оригинальные результаты ненадёжны, нужен полный mirror.
- Договориться о tie-handling до запуска. Когда B победил в одном ордере, A в другом — это tie или «B чуть лучше»? Стандартная практика — tie. Tie rate сам по себе полезный сигнал: высокий tie rate = модели близки или judge слабый.
- Логировать оба ордера всегда. Даже если в этом раунде считаете только naive — следующий раунд может потребовать mirror, а данные у вас будут.
- Для high-stakes решений (продакшен миграция, billion-dollar questions) добавить human spot-check на subsample. Mirror устраняет position bias, но не другие LLM-judge biases (self-preference, length, style). На 50 случайных парах попросить человека пересудить как ground truth.
- Подумать про choice of judge. GPT-4-class judges имеют более слабый bias чем меньшие модели. Использование своей же модели как judge — отдельная угроза (self-preference bias).
Связь с курсом и другими симуляторами
Этот кейс опирается на понятия из курса квазиэкспериментов и дополняет первый AI-evals симулятор:
- LLM A/B Test Simulator — планирование выборки для продакшен A/B с учётом stochasticity модели
- Модуль 1: causal inference — selection bias и почему рандомизация важна
- Модуль 7: валидность — проверки эксперимента
- Модуль 8: narrative — структура финального отчёта