Реализовать LLM-as-Judge с калибровкой

ТЕХНИЧЕСКОЕ ЗАДАНИЕ: Реализовать LLM-as-Judge с калибровкой

1. Цель задачи

Разработать и откалибровать систему на основе LLM, выступающую в роли судьи (LLM-as-Judge) для оценки качества ответов двух других LLM на заданные вопросы. Требуется подобрать промпт judge-модели таким образом, чтобы её оценки максимально совпадали с оценками человека (human labels). Калибровка осуществляется итеративно: сравниваются метрики согласия с человеческими метками, и промпт уточняется до достижения Cohen's Kappa > 0.8.

Ключевой результат Рабочий пайплайн LLM-as-Judge с документированным промптом, воспроизводимыми метриками и значением Cohen's Kappa ≥ 0.8 на валидационном наборе.

2. Исходные данные

Что нужноОткуда взять
Датасет с парами ответов двух LLM и человеческими оценками предпочтений (или баллами)Открытый датасет: lmsys/chatbot_arena_conversations (Hugging Face) или openbmb/UltraFeedback
Список промптных стратегий для judge-моделиСоставить на основе статей (например, "Judging LLM-as-a-Judge") и собственных экспериментов
API‑доступ к judge-модели (например, GPT‑4, Claude, или локальная модель через vLLM)Учётная запись OpenAI / Anthropic / локальный сервер
Инструментарий для расчёта метрик согласияscikit-learn (Cohen's Kappa), scipy (связанные тесты)

Если нет реального инструмента — симулируем:

  1. Создать синтетический датасет из 100 примеров: для каждого примера задать вопрос, два ответа (от «хорошей» и «плохой» модели) и сгенерировать human label с помощью «идеального» промпта на той же judge-модели (имитация человека).
  2. Реализовать функцию simulate_human_label(prompt, models_answers), которая возвращает балл [1,2,3,4,5] с добавлением небольшого шума (нормальное распределение с σ=0.3).
  3. Использовать этот синтетический датасет как ground truth для экспериментов.

3. Технологический стек

КомпонентИнструментыНазначение
Язык программированияPython 3.10+Основной язык разработки
Работа с датасетамиdatasets (Hugging Face)Загрузка и предобработка данных
LLM API / inferenceopenai, anthropic, или transformers + vLLMЗапуск judge-модели
Управление промптамиlangchain (PromptTemplate)Шаблонизация и версионирование промптов
Метрики согласияscikit-learn, scipyCohen’s Kappa, Weighted Kappa, точность
Логирование и отслеживаниеmlflow или wandbЛогирование промптов и метрик (опционально)
РазработкаJupyter Notebook + ipywidgetsИтеративная калибровка и визуализация

4. Этапы выполнения

Этап 1: Подготовка данных и окружения (оценка времени: 1 час)

Действия

  1. Создать виртуальное окружение python -m venv judge_env && source judge_env/bin/activate.
  2. Установить зависимости:
    pip install datasets scikit-learn scipy openai langchain jupyter matplotlib
    
  3. Загрузить датасет lmsys/chatbot_arena_conversations:
    from datasets import load_dataset
    dataset = load_dataset("lmsys/chatbot_arena_conversations", split="train")
    
  4. Выбрать 200 диалогов, где есть оценка winner (model_a, model_b, tie) — это будет ground truth.
  5. Преобразовать данные в формат:
    • question: первый пользовательский запрос
    • answer_a: ответ model_a
    • answer_b: ответ model_b
    • human_label: 0 (победа model_a), 1 (победа model_b), 2 (ничья)
  6. Разделить на train (100) и validation (100). Сохранить в data/arena_processed.json.

Ожидаемый результат этапа Файл data/arena_processed.json с 200 размеченными примерами; окружение готово к работе.

Этап 2: Реализация базового LLM-as-Judge (оценка времени: 1.5 часа)

Действия

  1. Написать класс LLMJudge с методами:
    • init(self, model_name="gpt-4", system_prompt="")
    • evaluate(self, question, answer_a, answer_b) -> int (возвращает 0, 1 или 2)
  2. Использовать LangChain для шаблона промпта. Базовый промпт:
    System: You are a fair judge. Compare the two answers and decide which one is better.
    User: Question: {question}
    Answer A: {answer_a}
    Answer B: {answer_b}
    Output exactly one of: "A", "B", "TIE".
    
  3. Реализовать функцию parse_judge_output(output: str) -> int, преобразующую строку в метку.
  4. Протестировать на 5 примерах вручную, убедиться, что API отвечает корректно.
  5. Прогнать базовый промпт через валидационный набор, записать предсказания в predictions_baseline.csv.

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

Этап 3: Оценка согласия с human labels (оценка времени: 0.5 часа)

Действия

  1. Написать скрипт compute_metrics.py:
    from sklearn.metrics import cohen_kappa_score, accuracy_score
    import json
    with open("predictions_baseline.csv") as f:
        # читаем предсказания и true labels
        ...
    kappa = cohen_kappa_score(true, pred)
    acc = accuracy_score(true, pred)
    print(f"Baseline Cohen's Kappa: {kappa:.3f}, Accuracy: {acc:.3f}")
    
  2. Зафиксировать базовые метрики.
  3. Если Kappa < 0.8 (ожидаемо), переходим к калибровке.

Ожидаемый результат этапа Численные значения Kappa и Accuracy для baseline.

Этап 4: Итеративная калибровка промпта (оценка времени: 2.5 часа)

Действия

  1. Составить пул вариаций промпта (не менее 5). Примеры изменений:
    • Добавить instruction о шкале (1-5 баллов вместо категорий)
    • Включить рубрики: полезность, точность, безопасность
    • Попросить модель объяснять свой выбор (chain-of-thought)
    • Изменить температуру judge-модели
    • Использовать weighted Kappa как целевую метрику
  2. Для каждой вариации запустить оценку на validation set, сохранить Kappa.
  3. Выбрать 3 лучших варианта и провести кросс‑валидацию на train split (если позволяет размер выборки) для оценки стабильности.
  4. Выполнить поиск по температуре (0.0, 0.2, 0.5, 1.0) для лучшего промпта.
  5. Документировать каждую итерацию в Jupyter Notebook: промпт, метрики, комментарии.

Ожидаемый результат этапа Набор промптов с измеренными Kappa; лучший кандидат с Kappa > 0.8.

Этап 5: Финальная оценка и документирование (оценка времени: 1 час)

Действия

  1. На финальном промпте прогнать полный validation set (и, опционально, тестовый холд-аут, если данные позволяют).
  2. Построить матрицу ошибок (confusion matrix) для визуализации расхождений.
  3. Написать отчет в README.md:
    • Описание задачи, метода judge, параметры калибровки.
    • Финальные метрики: Cohen's Kappa, Weighted Kappa, Accuracy.
    • Примеры успешных и неуспешных случаев.
  4. Зафиксировать версии зависимостей и seed для воспроизводимости.

Ожидаемый результат этапа Финальный промпт, полные метрики, README, воспроизводимый код.

5. Критерии приемки (Definition of Done)

  • Реализован Python-скрипт/ноутбук, воспроизводящий пайплайн «загрузка данных → judge → оценка → калибровка».
  • Cohen's Kappa на валидационном наборе ≥ 0.80.
  • Документированы все протестированные промпты и их метрики.
  • В репозитории есть файл final_prompt.txt с итоговым промптом.
  • Результаты воспроизводимы: указаны seed, версии библиотек, команды для запуска.
  • Код имеет комментарии и разбит на ячейки/функции с docstring.
  • Отчёт содержит анализ ошибок (confusion matrix, примеры рассогласования).
  • Использован как минимум один из открытых датасетов (или синтетический, если нет доступа).

6. Ожидаемый результат

Основной артефакт Репозиторий/папка со следующей структурой:

├── data/
│   ├── arena_processed.json         # предобработанный датасет
│   └── predictions_baseline.csv     # базовые предсказания
├── notebooks/
│   └── calibration.ipynb            # ноутбук со всеми итерациями
├── src/
│   ├── judge.py                     # класс LLMJudge
│   ├── metrics.py                   # функции расчёта метрик
│   └── run_pipeline.py              # скрипт для полного пайплайна
├── results/
│   ├── calibration_log.txt          # лог экспериментов
│   ├── final_metrics.json           # итоговые метрики
│   └── confusion_matrix.png         # матрица ошибок
├── final_prompt.txt                 # итоговый промпт
└── README.md                        # отчёт

Дополнительно (по желанию): Визуализация зависимости Kappa от температуры, таблица сравнения разных моделей judge (если используется несколько LLM).

7. Возможные сложности и их решение

СложностьРешение
Judge-модель часто возвращает TIE или имеет систематическое смещениеДобавить в промпт принуждение к выбору (например, "if you have to choose, even if both are similar, pick one"). Включить few-shot примеры с известными метками.
Human labels могут быть шумнымиИспользовать Weighted Kappa (который учитывает степень расхождения). При возможности агрегировать несколько человеческих оценок на один пример.
API дорогой (GPT-4)Использовать локальную модель (LLaMA-3 70B через vLLM) или взять дешёвый вариант (GPT-4o-mini); для калибровки можно использовать subset данных.
Разная шкала оценок (бинарные vs численные)Привести human labels к единой шкале (0/1/2). Если human labels — ранжирование, преобразовать в pairwise preference.
Нестабильность при повторных вызовахУстановить seed в промпте (например, "use deterministic reasoning") и зафиксировать температуру 0.0. Логировать каждый запрос для аудита.

8. Бюджет времени (оценка)

ЭтапВремя
Этап 1: Подготовка данных и окружения1 час
Этап 2: Реализация базового LLM-as-Judge1.5 часа
Этап 3: Оценка согласия с human labels0.5 часа
Этап 4: Итеративная калибровка промпта2.5 часа
Этап 5: Финальная оценка и документирование1 час
Итого6.5 часов

Примечание: Для первого выполнения задачи рекомендуется выделить 8 часов с учётом отладки и ознакомления с инструментами.

9. Связанные вопросы из базы знаний

ВопросТема
42LLM-as-Judge: основные подходы и ограничения
57Метрики согласия для оценки качества judge (Cohen's Kappa, Fleiss' Kappa)
123Промпт-инжиниринг для оценочных моделей
205Калибровка confidence judge-моделей
316Weighted vs Unweighted Kappa: когда применять
408Датасеты для бенчмаркинга judge (MT-Bench, Chatbot Arena)
522Few-shot промпты для снижения bias
634Влияние температуры на стабильность judge
745Оценка согласия между разными LLM-judge
888Воспроизводимость экспериментов с LLM (seed, детерминизм)

10. Чек-лист самопроверки

  • Я скачал и предобработал датасет, убедился в корректности human labels.
  • Базовый judge работает без ошибок и возвращает валидные метки (A/B/TIE).
  • Я посчитал Cohen's Kappa для baseline и сравнил с целью.
  • Проведено минимум 5 итераций изменения промпта с фиксацией метрик.
  • Финальный промпт даёт Kappa ≥ 0.8 на validation set.
  • Код полностью воспроизводим: указаны random seed, команды установки, последовательность запуска.
  • Отчёт содержит анализ ошибок и примеры расхождений.
  • Все файлы лежат в структурированном репозитории в соответствии с ожидаемым результатом.