Реализовать 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 (связанные тесты) |
Если нет реального инструмента — симулируем:
- Создать синтетический датасет из 100 примеров: для каждого примера задать вопрос, два ответа (от «хорошей» и «плохой» модели) и сгенерировать human label с помощью «идеального» промпта на той же judge-модели (имитация человека).
- Реализовать функцию simulate_human_label(prompt, models_answers), которая возвращает балл
[1,2,3,4,5]с добавлением небольшого шума (нормальное распределение с σ=0.3). - Использовать этот синтетический датасет как ground truth для экспериментов.
3. Технологический стек
| Компонент | Инструменты | Назначение |
|---|---|---|
| Язык программирования | Python 3.10+ | Основной язык разработки |
| Работа с датасетами | datasets (Hugging Face) | Загрузка и предобработка данных |
| LLM API / inference | openai, anthropic, или transformers + vLLM | Запуск judge-модели |
| Управление промптами | langchain (PromptTemplate) | Шаблонизация и версионирование промптов |
| Метрики согласия | scikit-learn, scipy | Cohen’s Kappa, Weighted Kappa, точность |
| Логирование и отслеживание | mlflow или wandb | Логирование промптов и метрик (опционально) |
| Разработка | Jupyter Notebook + ipywidgets | Итеративная калибровка и визуализация |
4. Этапы выполнения
Этап 1: Подготовка данных и окружения (оценка времени: 1 час)
Действия
- Создать виртуальное окружение python -m venv judge_env && source judge_env/bin/activate.
- Установить зависимости:
pip install datasets scikit-learn scipy openai langchain jupyter matplotlib - Загрузить датасет lmsys/chatbot_arena_conversations:
from datasets import load_dataset dataset = load_dataset("lmsys/chatbot_arena_conversations", split="train") - Выбрать 200 диалогов, где есть оценка
winner(model_a, model_b, tie) — это будет ground truth. - Преобразовать данные в формат:
question: первый пользовательский запросanswer_a: ответ model_aanswer_b: ответ model_bhuman_label: 0 (победа model_a), 1 (победа model_b), 2 (ничья)
- Разделить на train (100) и validation (100). Сохранить в data/arena_processed.json.
Ожидаемый результат этапа Файл data/arena_processed.json с 200 размеченными примерами; окружение готово к работе.
Этап 2: Реализация базового LLM-as-Judge (оценка времени: 1.5 часа)
Действия
- Написать класс
LLMJudgeс методами:- init(self, model_name="gpt-4", system_prompt="")
- evaluate(self, question, answer_a, answer_b) -> int (возвращает 0, 1 или 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". - Реализовать функцию
parse_judge_output(output: str) -> int, преобразующую строку в метку. - Протестировать на 5 примерах вручную, убедиться, что API отвечает корректно.
- Прогнать базовый промпт через валидационный набор, записать предсказания в predictions_baseline.csv.
Ожидаемый результат этапа Рабочий пайплайн, файл с предсказаниями базового judge.
Этап 3: Оценка согласия с human labels (оценка времени: 0.5 часа)
Действия
- Написать скрипт
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}") - Зафиксировать базовые метрики.
- Если Kappa < 0.8 (ожидаемо), переходим к калибровке.
Ожидаемый результат этапа Численные значения Kappa и Accuracy для baseline.
Этап 4: Итеративная калибровка промпта (оценка времени: 2.5 часа)
Действия
- Составить пул вариаций промпта (не менее 5). Примеры изменений:
- Добавить instruction о шкале (1-5 баллов вместо категорий)
- Включить рубрики: полезность, точность, безопасность
- Попросить модель объяснять свой выбор (chain-of-thought)
- Изменить температуру judge-модели
- Использовать weighted Kappa как целевую метрику
- Для каждой вариации запустить оценку на validation set, сохранить Kappa.
- Выбрать 3 лучших варианта и провести кросс‑валидацию на train split (если позволяет размер выборки) для оценки стабильности.
- Выполнить поиск по температуре (0.0, 0.2, 0.5, 1.0) для лучшего промпта.
- Документировать каждую итерацию в Jupyter Notebook: промпт, метрики, комментарии.
Ожидаемый результат этапа Набор промптов с измеренными Kappa; лучший кандидат с Kappa > 0.8.
Этап 5: Финальная оценка и документирование (оценка времени: 1 час)
Действия
- На финальном промпте прогнать полный validation set (и, опционально, тестовый холд-аут, если данные позволяют).
- Построить матрицу ошибок (confusion matrix) для визуализации расхождений.
- Написать отчет в README.md:
- Описание задачи, метода judge, параметры калибровки.
- Финальные метрики: Cohen's Kappa, Weighted Kappa, Accuracy.
- Примеры успешных и неуспешных случаев.
- Зафиксировать версии зависимостей и 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-Judge | 1.5 часа |
| Этап 3: Оценка согласия с human labels | 0.5 часа |
| Этап 4: Итеративная калибровка промпта | 2.5 часа |
| Этап 5: Финальная оценка и документирование | 1 час |
| Итого | 6.5 часов |
Примечание: Для первого выполнения задачи рекомендуется выделить 8 часов с учётом отладки и ознакомления с инструментами.
9. Связанные вопросы из базы знаний
| Вопрос | Тема |
|---|---|
| 42 | LLM-as-Judge: основные подходы и ограничения |
| 57 | Метрики согласия для оценки качества judge (Cohen's Kappa, Fleiss' Kappa) |
| 123 | Промпт-инжиниринг для оценочных моделей |
| 205 | Калибровка confidence judge-моделей |
| 316 | Weighted vs Unweighted Kappa: когда применять |
| 408 | Датасеты для бенчмаркинга judge (MT-Bench, Chatbot Arena) |
| 522 | Few-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, команды установки, последовательность запуска.
- Отчёт содержит анализ ошибок и примеры расхождений.
- Все файлы лежат в структурированном репозитории в соответствии с ожидаемым результатом.