Р. Аллахвердиев

Можно ли доверять LLM-судье: перекосы, калибровка на ручной разметке и kappa

Три известных смещения судьи (позиция, длина, самопредпочтение), как проверить каждое экспериментом, как посчитать согласие с людьми через accuracy и Cohen's kappa и какие решения принимать по результату.

опубликовано · 10 мин740c6f3
Обложка: Можно ли доверять LLM-судье: перекосы, калибровка на ручной разметке и kappa
Содержание

Коротко

  • LLM-судья — это ещё одна система, которую нужно тестировать. Прежде чем использовать его оценки в quality gate, сверьте их с ручной разметкой.
  • Три типичных перекоса: позиция (предпочитает первый вариант), длина (любит развёрнутые ответы), самопредпочтение (благосклонен к тексту своей модели).
  • Калибровка — это 50–100 ответов, размеченных людьми, и расчёт согласия: доля совпадений и Cohen’s kappa. Доля совпадений одна обманчива, kappa учитывает случайные совпадения.
  • Если согласие низкое, улучшайте критерии и промпт судьи, меняйте модель-судью или ограничьте использование метрики.
  • Фиксируйте версию судьи и промпт. Смена судьи — это смена измерительного прибора.

Почему судью нельзя принимать на веру

Метрики вроде Faithfulness или G-Eval вычисляет языковая модель. Она читает ответ и контекст и выносит вердикт. В разборе четырёх метрик RAG я описывал, как фреймворки снижают шум декомпозицией на бинарные решения. Но даже так остаются системные ошибки. Исследователи описывали такие смещения давно: например, в работе «Judging LLM-as-a-Judge with MT-Bench and Chatbot Arena» (Zheng и соавторы, 2023) обсуждаются позиционное смещение, склонность к длинным ответам и предпочтение ответов собственной модели. Конкретные величины зависят от модели и задачи, поэтому на чужие цифры я не опираюсь: мерьте на своих данных.

Три смещения и как их проверить

Позиционное смещение

При попарном сравнении («какой ответ лучше: A или B») судья может чаще выбирать вариант на первой позиции. Проверка простая: подавайте каждую пару дважды, меняя порядок.

def judge_pair(question: str, a: str, b: str) -> str:
    """Возвращает 'A' или 'B'. Реализация вызывает вашу модель-судью."""
    ...

def position_consistency(pairs: list[tuple[str, str, str]]) -> float:
    consistent = 0
    for q, x, y in pairs:
        first = judge_pair(q, x, y)    # x на позиции A
        second = judge_pair(q, y, x)   # x на позиции B
        winner_first = x if first == "A" else y
        winner_second = y if second == "A" else x
        consistent += winner_first == winner_second
    return consistent / len(pairs)

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

Смещение по длине

Судья склонен ставить выше более длинные и подробные ответы, даже когда лишние слова не добавляют фактов. Проверка: возьмите хорошие короткие ответы и искусственно «раздуйте» их водой без новой информации, затем сравните оценки. Если оценка выросла, критерий нужно уточнить: «оценивай только фактическую полноту, длина не является преимуществом». Дополнительно следите за корреляцией оценки судьи с длиной ответа на всём датасете: высокая корреляция — повод насторожиться.

Самопредпочтение

Модель может благоволить текстам, похожим на её собственные. Практические меры: по возможности берите судью из другого семейства, чем оцениваемая модель; для важных решений используйте двух судей и смотрите на расхождения. Это не гарантия, но снижает риск оптимизировать систему под вкус одной модели.

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

Калибровка: сверяем судью с людьми

Схема в пять шагов:

  1. Выборка. Возьмите 50–100 пар «вопрос, ответ (и контекст)». Включите хорошие, плохие и пограничные случаи, а не только лёгкие.
  2. Ручная разметка. Разметчик по чёткому критерию ставит бинарную метку: «ответ приемлем / неприемлем». Бинарная шкала надёжнее балльной. Лучше, если размечают двое, а спорные случаи обсуждаются.
  3. Прогон судьи. Судья оценивает те же пары, оценку переводим в метку по порогу.
  4. Согласие. Считаем долю совпадений и Cohen’s kappa.
  5. Разбор расхождений. Читаем случаи, где судья и люди не согласны: именно там видно, что чинить.

Accuracy и Cohen’s kappa

Доля совпадений проста, но обманчива при дисбалансе классов. Если 90% ответов хорошие, судья, который всегда говорит «хорошо», получит 90% совпадений и будет бесполезен. Cohen’s kappa вычитает совпадения, ожидаемые случайно:

kappa = (p_o - p_e) / (1 - p_e)

где p_o — наблюдаемая доля совпадений, p_e — доля совпадений, ожидаемая случайно при тех же частотах меток. Значение 1 означает полное согласие, 0 — не лучше случайного.

# pip install scikit-learn
from sklearn.metrics import cohen_kappa_score, accuracy_score, confusion_matrix

human = [1, 1, 0, 1, 0, 0, 1, 1, 0, 1]   # метки людей: 1 = приемлемо
judge = [1, 1, 0, 1, 1, 0, 1, 0, 0, 1]   # метки судьи по порогу

print("accuracy:", accuracy_score(human, judge))
print("kappa:   ", round(cohen_kappa_score(human, judge), 2))
print(confusion_matrix(human, judge))     # строки: люди, столбцы: судья

Данные выше — игрушечные, чтобы показать вызовы; в реальной калибровке нужна выборка из десятков примеров. Как интерпретировать kappa, единого стандарта нет. Часто приводят шкалу Ландиса и Коха (0,61–0,80 — «существенное согласие»), но это условность, и пороги стоит выбирать по цене ошибки в вашей задаче.

Не забудьте посмотреть на матрицу ошибок. Судья, который чаще пропускает плохие ответы (ложно положительный), опаснее для quality gate, чем тот, что слишком строг. Два судьи с одинаковой kappa могут ошибаться в разные стороны.

Что делать с результатом

Что видите Действие
Высокое согласие, ошибки случайны Используйте метрику, периодически перепроверяйте
Судья завышает оценки Ужесточите критерий, добавьте примеры плохих ответов, поднимите порог
Согласие низкое Перепишите критерий, разбейте на более простые вопросы, смените модель-судью
Сильное смещение по длине Явно укажите, что длина не плюс, и проверьте снова
Разметчики сами расходятся Уточните инструкцию: проблема в критерии, а не в судье

Каждый шаг проверяйте повторной калибровкой. Результат калибровки — документ: версия судьи, промпт, дата, размер выборки, accuracy, kappa, матрица ошибок и выводы «для чего метрике можно доверять».

Стабильность и версии

Судья даёт разные оценки на одинаковом входе. Измерьте это: прогоните один и тот же набор 3–5 раз и посмотрите разброс. Если разброс сопоставим с эффектом, который вы хотите поймать, метрика бесполезна для сравнения версий.

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

Ограничения

  • Калибровка доказывает согласие с вашими разметчиками, а не истину. Если разметчики ошибаются или не эксперты в предметной области, судья «откалибруется» на их ошибки.
  • Выборка в 50–100 примеров даёт грубую оценку; доверительный интервал у kappa на такой выборке широкий. Не делайте выводов по разнице в несколько сотых.
  • Распределение реальных вопросов меняется, и калибровку нужно пополнять.
  • Ничто из этого не отменяет детерминированных проверок: всё, что можно проверить кодом (формат, наличие источников, запрещённые слова), проверяйте кодом.

Что дальше

  • Разметьте 50 ответов вручную и посчитайте kappa для вашей текущей метрики. Это можно сделать за вечер.
  • Включите калиброванную метрику в автоматический прогон: quality gate в CI на pytest и DeepEval.
  • Если вы только собираете датасет, начните с golden-датасета для RAG.