LLM-as-judge: pointwise (1-5 rubric) vs pairwise (A vs B with position swap) vs calibration vs human (Cohen's kappa). Failure modes: self-preference, length bias, position bias, rubric drift. Includes 3 ADRs covering when LLM-as-judge is the right primitive vs ground truth, pointwise/pairwise selection, and human calibration thresholds.
LLM-as-judge — это автоматический quality reviewer на масштабе. Цена ниже человека в 100×, скорость — минуты вместо недель, точность — 70-85% от человеческой при правильном rubric.
Тысячу outputs Haiku оценить вручную: ~$5000, 2 недели, два senior-инженера. Тот же batch отдать судье-Sonnet с rubric: ~$6, 5 минут, один JSON-валидатор. Это разница между «evals существуют где-то в Notion» и «evals блокируют merge в CI».
Но судья — не серебряная пуля. У него специфические failure modes (length bias, sycophancy, self-preference, position bias, factual blind spots), и он молча деградирует, когда candidate-модель улучшается за порог его discrimination. Без периодической калибровки против человека (Cohen's kappa) ты узнаешь о проблеме от пользователей, а не от метрик.
Судья — это узкоспециализированный property tester, не universal eval primitive.
Он отвечает на вопросы вида «выглядит ли это helpful, faithful, concise, on-tone?» — то есть на свойства, для которых нет closed-form проверки. Для всего, что можно проверить детерминированно (код, математика, JSON-схема, classification labels), судья — это медленнее, дороже и менее надёжно, чем ground truth.
Два режима работы:
И тот, и другой — это LLM-вызовы, которые сами могут ошибаться, и нуждаются в собственных evals. Cohen's kappa против человека на 50-100 stratified samples — обязательная калибровка раз в 4 недели.
Три группы вокруг eval pipeline:
Eval pipeline — dataset (1000 prompts + ground truth, где он есть), runner (Promptfoo/Braintrust), rubric store с критериями и few-shot anchors, и два кандидата candidate-a (prompt v3) / candidate-b (prompt v4) на Haiku.
Judge layer — два судьи разной формы (judge-point для pointwise 1-5, judge-pair для pairwise A/B с обязательным position swap) плюс validator, который парсит JSON судьи, проверяет schema и режектит ответы, где reasoning противоречит score.
Calibration loop — results DB со scores и reasoning, sampler (stratified 5% per bucket, не random!), human reviewer вслепую, kappa калькулятор и alert на drift. Loop замкнут обратно на rubric: алёрт триггерит rebuild.
Сценариев четыре: pointwise scoring, pairwise с position swap, calibration cycle, и failure modes (self-preference / length bias / drift). Три ADR прикреплены к ключевым нодам: на runner (когда судья — wrong tool), на judge-point (pointwise vs pairwise), на human (Cohen's kappa методология).
Pointwise — judge оценивает каждый output по rubric 1-5 с anchor descriptions для каждого числа и chain-of-thought reasoning перед score. Sonnet судит Haiku, JSON структурирован ({reasoning, score, criteria:{accuracy, clarity, completeness}}), validator режектит несоответствия (reasoning «плохо» + score 5 → отказ). Хорошая дистрибуция: {5:18%, 4:42%, 3:28%, 2:9%, 1:3%} — rubric калиброван. Плохая дистрибуция: {5:65%, 4:30%, rest:5%} — score saturation, anchors слишком мягкие, чинить до того, как доверять CI.
Pairwise — судья выбирает «лучше A или B?» для пары outputs. Сразу появляется position bias: в ordering (A=v3, B=v4) судья выбирает A в 68% случаев. Mitigation — обязательный position swap: тот же пар, но (A=v4, B=v3). Засчитывается победа только если кандидат выигрывает в обеих orderings; flips становятся ties. После dедупликации истинный win-rate v4=53%, v3=47%, p=0.04 — marginal, но реальный. Для RLHF training data pairwise масштабируется лучше pointwise, для «достаточно ли хорошо чтобы зашипить» pointwise интерпретируемее.
Calibration — каждые 4 недели берём stratified sample (5% per score bucket плюс oversampling edge cases: длинные, multilingual, adversarial). Random sampling здесь неправилен — недосэмплируешь редкие bucket'ы, которые критичны. Senior рейтит вслепую (без судейской метки) 50 outputs, ~2 часа, ~$300. Считаем weighted Cohen's kappa: 0.72 → «substantial agreement» (0.61-0.80) → судья usable на CI. Также test-retest reliability: судья оценивает те же 50 outputs дважды, consistency >=85% (иначе temperature/seed leak). Тренд kappa во времени — leading indicator of rubric drift.
Четыре способа, которыми судья молча врёт: self-preference (судья = same model family → scores инфляция ~12% на собственных outputs; фикс — Sonnet over Haiku, или GPT-4o judging Claude), length bias (длинному verbose ставит 5, короткому correct 4; фикс — anchor «короткий+правильный = 5» в few-shot), position bias (первый вариант 60% baseline; фикс — dual-order eval), drift (через 8 недель kappa с 0.72 падает до 0.41 — новые failure modes, которых rubric не предвидел; фикс — alert замораживает CI gate, rebuild rubric с anti-pattern примерами, re-калибровка до возобновления).
ADR-001 — судья vs ground truth. Default к ground truth везде, где у ответа есть verifiable structure: код → execute и assert (HumanEval, SWE-bench); математика → symbolic verify (sympy); structured extraction (JSON, dates, IDs) → exact match или schema validation; classification → F1/precision/recall против labels; compliance → regex + rules + human review. К LLM-judge тянутся только для свойств без closed-form проверки: helpfulness, faithfulness to context (RAG), conciseness, tone, instruction-following. Цена ошибки выбора: купить judge на $6/run для задачи, где assert решает за 0 секунд бесплатно.
ADR-002 — pointwise vs pairwise. Pointwise отвечает на «достаточно ли хорошо чтобы зашипить» — нужны anchored rubric levels, few-shot examples per anchor, mandatory chain-of-thought, JSON validation, и monitoring score distribution (если всё 4-5, rubric сломан). Pairwise отвечает на «v4 лучше v3» — обязательный position swap, win-rate как primary метрика (не Elo до >10K judgments), O(N²) для полного ранжирования. Для RLHF training data → pairwise масштабируется лучше. Для CI gate → pointwise интерпретируемее.
ADR-003 — калибровка против человека. Каждые 4 недели или после major rubric/judge-model изменения: stratified sample 50-100, человек рейтит blind, Cohen's kappa с порогами <0.4 = unusable / 0.4-0.6 = usable только с mandatory spot-check / 0.6-0.8 = substantial agreement, на CI / >0.8 = почти perfect, на autopilot. Также test-retest reliability >=85%. Tracking kappa over time как time series — downward trend = leading indicator rubric drift. Production failures sampled at 1-5% feed back в eval set, замыкая loop с offline gates.
ignoreBuildErrors для rubric drift — kappa упал ниже 0.6, gate замолчал, релизы пошли. Alert должен блокировать, не warning'овать.