Почему вам нужно добавить LLM-as-a-Judge в пайплайн автоматического тестирования и как это сделать
Если вы читаете эту статью, значит, уже понимаете, зачем нужны автотесты и какое место они занимают в разработке LLM-ассистентов и агентов. В таких проектах тестирование важнее, чем в классической разработке: детерминированных ответов нет, а специфические задачи есть — сбор бенчмарков, сравнение сгенерированных ответов с эталонными.

Сергей Темченко
Промпт-инженер в Альфа-Банке
Я расскажу, почему нужен автоматизированный гибридный пайплайн, включающий в себя сравнение векторов и LLM-as-a-Judge, в котором ручная разметка используется только на самом старте.
Тесты покрывают только часть функционала, а совпадение ответов изредка можно проверить посимвольно, потому что ответ может быть правильным, но написан в другой формулировке.
В целом подходов к тестированию LLM немного:
- ручная разметка,
- сравнение векторов,
- LLM-as-a-Judge.
Это три основных способа оценить качество ответов модели: либо люди вручную размечают результаты, либо ответы сравниваются автоматически через эмбеддинги, либо одну LLM используют как «судью» для оценки другой.
Ручная разметка дорогой процесс и по времени, и по деньгам. Сравнение векторов условно бесплатное, но часто может давать сбои (об этом поговорим ниже). LLM-as-a-Judge дороже векторов и умеет ловить кейсы, которые не видят вектора, но и этот метод далеко не идеален.
Нам, конечно, хочется запускать тесты при каждом изменении промптов: добавил новый пример во few-shot - тут же проверил результат, это невозможно достичь с ручной разметкой.
Дальше я покажу, почему нужен автоматизированный гибридный пайплайн, включающий в себя вектора и LLM-as-a-Judge, в котором ручная разметка используется только на самом старте.
Примечание. Эта статья касается LLM ассистентов/агентов ответы которых мы не можем проверять посимвольно.
Ручная разметка: дорого
Ручная разметка — это часы людей, экспертов из бизнеса, методологов (вам повезло, если у вас есть доступ к операторам поддержки и они являются компетентными в вашем домене). Команду разметки нужно онбордить, объяснять схему оценок, определять и переделывать спорные кейсы. В итоге мы тратим недели, чтобы собрать один устойчивый golden dataset.
Ручная разметка — это инструмент для создания эталонного бенчмарка, а не метод регресс-тестов.
Почему тесты не совпадают с продом и что с этим делать?
Тут есть ловушка: тестовая среда и прод живут в разных реальностях. Эксперты сидят в Excel, просматривают десятки ответов подряд, привыкают к стилю и начинают шире трактовать норму. На прошлом месте работы у меня был случай, где в Excel ответы получают оценку «отлично, не нужно редактировать», а в проде такие же ответы получают дизлайк.
Почему так происходит?
Контекст размыт: разметчик не ощущает реальную боль пользователя, не видит его путь, не чувствует цену ошибки - и планка «отличного» ответа незаметно сползает вниз.
Чтобы тестовые условия были ближе к продовым, важно тщательно онбордить команду разметки и договариваться о единых критериях. Например, явно зафиксировать: считается ли «отличным» ответ, где нужно поправить одно слово, или любая правка — вплоть до удаления/добавления смайлика — уже снижает оценку.
Мы используем ручную разметку только на этапе создания бенчмарка. Дальше мы хотим сделать тесты автоматическими — откалибровать векторы и LLM-as-a-Judge так, чтобы это максимально совпадало с оценками экспертов.
Вектора не работают?
Современные модели хорошо следуют правилам Tone of Voice и могут правдоподобно дофантазировать структуру ответа. Это галлюцинирование создаёт ложное совпадение, повышая векторный скор. Векторное сравнение ловит общий смысл, но теряет критически важные факты.
Посмотрим на примере реального кейса LLM-ассистента по страхованию (стиль текста агента сохранён для наглядности). Пользователь спрашивает: «Хочу купить ОСАГО. Подскажи, как?»
LLM-ассистент отвечает:
«Для оформления ОСАГО вам потребуется выполнить несколько шагов:
Подготовьте документы:
— Паспорт
— Водительское удостоверение
— Свидетельство о регистрации транспортного средства (СТС)
— Паспорт транспортного средства (ПТС)
— если система не найдёт документы автоматически по номеру авто, вам потребуется загрузить их вручную.
Выберите способ оформления:
— Онлайн на сайте
— В мобильном приложении
— В офисе
Заполните заявку:
— Укажите данные автомобиля и водителей
— Укажите срок страхования и дополнительные опции
Оплатите полис:
— Оплата картой или через интернет-банк
Получите полис:
— Электронный полис придёт на e-mail
— Его можно распечатать или сохранить на телефоне
Оформление занимает несколько минут. Хотите оформить ОСАГО прямо сейчас?»
Автоматически мы разметили этот ответ и эталон как правильное совпадение, но эксперт подсветил, что на самом деле мы допустили ошибку. Дело в том, что:
«Для ОСАГО срок страхования сейчас выбирать нельзя — мы оформляем только на год».
Векторный скор не реагирует на изменение факта, даже если этот факт — главный. По сути, в векторном представлении нет разницы между отдельными тезисами: весь блок текста переводится в вектор, и если, например, 95% его — это болтовня и 5% — факт, векторное представление не может отбросить шелуху как лишнюю. Чем ответы длиннее, тем меньший вес имеют различие или сходство отдельно взятого факта.
В результате:
- неправильный ответ с похожими структурой и формулировками → высокий скор,
- правильный ответ, но перефразированный → низкий скор.
Вы можете убедиться сами: в одних примерах абсолютно разные по фактам ответы оказываются близкими по векторам; в других — одинаковые ответы отлетают далеко друг от друга.
А LLM-as-a-Judge работает?
Противоположно векторам LLM-as-a-Judge может быть слишком чувствительным к фактам. Модель честно замечает любое расхождение — даже там, где для бизнеса это вообще неважно. Например, мы сравниваем два приветственных сообщения от LLM-ассистента, в которых как будто не может быть никаких фактов, и эта пара внезапно получает 0. Размышления модели:
«Оба сообщения предлагают помощь, используя слово "помочь". Темы пересекаются — готовность предоставить поддержку. Однако первое сообщение более подробное, обращается по имени и предлагает обратиться при необходимости. Второе сообщение краткое и общее. В ответах разные факты, необходимо поставить 0».
Формально модель права, но для качества ассистента это не критично — наш ответ окей.
Поэтому нам нужна не одна метрика, а их связка: векторное сходство + LLM-as-a-Judge. Всё, что прошло оба порога (вектор выше 0.8 и LLM-as-a-Judge говорит «факты совпадают»), считаем корректным. Всё, что провалилось по обеим метрикам, считаем некорректным.
А вот пограничные случаи, где метрики не расходятся (например, вектор даёт 0.6 при пороге 0.8, а LLM-as-a-Judge ставит 1, или наоборот), мы обязаны пересматривать вручную.
Опять же в идеале использовать эти кейсы для итеративного улучшения пайплайна и вести всю систему в сторону полной автоматичности.
Можно ли тестировать LLM без golden dataset?
Автотесты строятся на golden dataset — фиксированном наборе пар «запрос пользователя → эталонный ответ».
Исполнителю часто не хватает доменной экспертизы, поэтому он просит заказчика помочь собрать такой датасет. Но заказчики обычно не хотят тратить на это время: присылают синтетические вопросы или просто дают документацию («тут всё есть, разберитесь»).
Возникает соблазн вообще отказаться от эталонных ответов и тестировать только по цепочке:
- какой запрос пришёл,
- какие функции или инструменты вызвались,
- какие документы подтянулись из векторной базы,
- что в итоге ответила модель.
Но так делать нельзя.
1. Нам нужно измерять регрессию
Регрессия — это ухудшение качества после изменений.
Без фиксированного датасета мы не можем сравнить: было → стало.
Частый случай, что мы починили одну часть и у при этом у нас отвалилась другая.
Golden dataset даёт нам неподвижную точку, относительно которой мы измеряем любые изменения в поведении модели.
2. Проверки внутренних шагов полезны — но вторичны
Мы действительно можем проверять. Но это дополнение, а не замена эталонному бенчмарку.
3. Единственный способ понять, что ответ исчерпывающий, — сравнить его с эталоном
Даже если цепочка вызовов функций выглядит идеально, итоговый ответ может быть неполным, ошибочным или излишним. Это видно только при сравнении с эталоном.
4. Бенчмарки с эталонами устойчивы к изменениям системы
Вы можете менять:
— промпты,
— цепочку рассуждений,
— инструменты,
— векторный поиск.
Но тест «эталон → сгенерированный ответ» остаётся валидным в любом случае. Проверять же полноту ответа, просто передавая вопрос пользователя и ответ системы — очень плохая идея. По своей природе LLM продолжают диалог, поэтому даже при галлюцинациях ответ выглядит полным. По сути, неполным ответ будет только в тех случаях, когда LLM явно уходит в отказ. Но для такого сценария лучше сделать заглушку и при необходимости искать эти кейсы по ней.
Как собрать бенчмарк?
Надеюсь, я убедил вас, что нужно собирать бенчмарк и вместе с векторами использовать LLM-as-a-Judge? Теперь обсудим, как это сделать.
Сколько должно быть кейсов в бенчмарке? Конечно, чем больше, тем лучше. Если вопросы подобраны репрезентативно, то 1000 примеров — уже потолок. Не стоит забывать, что каждый прогон LLM-as-a-Judge стоит денег.
Бенчмарк — это обычно Excel-файл с ≈100 примерами.
По хорошему нам надо собрать репрезентативный набор реальных запросов, который отражает распределение тем. Например, если 20% обращений связаны с темой X, то из 100 вопросов 20 должны быть про X. Это важно, чтобы не попасть в локальный минимум. Не собирая репрезентативный набор запросов может получится так, что вопросы будут одной природы, модель покажет хорошие результаты на тесте, но провалиться в проде.
Где взять вопросы для бенчмарка:
- У поддержки. Узнайте, ведут ли они статистику по тегам. Обычно да, поддержка — хороший источник. Можно также с помощью LLM сократить переписку до «вопроса и ответа», а эксперта попросить только проверить, насколько корректно мы собрали бенчмарк.
- Из продакшена. Если уже есть реальные запросы, их можно сгруппировать в кластеры и передать эксперту для проверки получившихся категорий.
Где взять ответы
Мы собрали репрезентативный набор вопросов, теперь нужно подготовить ответы. Эталонные ответы должен писать доменный эксперт.
Важно:
- ответы должны соответствовать актуальной политике компании, содержать правильные суммы и описания процессов;
- если процессы изменились, такие пары нужно обновлять или удалять из бенчмарка, чтобы он оставался актуальным.
Какая должна быть оценка для LLM-as-a-Judge
Помните спор Шелдона Купера и Стюарта Блума в «Теории большого взрыва»? Шелдон настаивал, что «ошибаться — абсолютное состояние и степени ошибки не бывает». На что Стюарт возразил: «Сказать, что помидор — это овощ, — это немного неверно, а назвать помидор подвесным мостом — очень неверно».
Так вот, Шелдон был прав.
Градиентные оценки нам не подходят: ответ считается верным, только если все факты совпадают с эталоном. Совпало 3 из 4 фактов — это так же неприемлемо для бизнеса, как 2 из 4.
Если ввести градиентную оценку, может получиться, что оценка выросла на 10%, а новых корректных ответов не прибавилось.
Бинарная система удобнее: группируем ответы, получившие 0, категоризируем ошибки вручную, итеративно исправляем, начиная работу с самой большой группы.
Оценка LLM-as-a-Judge не должна включать ToF. Тестировать ToF лучше отдельно: без бенчмарка, передавая ответ и правила редакционной политики компании и проверяя совпадение.
Как понять, что оценки судьи стабильны и близки к ручной разметке
После того как один эксперт дал/проверил ответы на все вопросы бенчмарка, нам понадобится ещё двое. Они должны разметить бенчмарк по нашей шкале (0 или 1) и коротко написать, почему поставили такую оценку. Дальше их объяснениями мы сможем дополнить наш промпт, если это понадобиться.
Далее считаем модульную разницу их оценок и берём среднее — это человеческая погрешность.
Наша цель — чтобы LLM-судья на A/A-тестах показывал сопоставимую погрешность.
Почему A/A-тесты важны: LLM — вероятностная система, нам нужна проверка стабильности. Сегодня мы можем попасть в «коридор» оценок экспертов, а завтра — выйти за его пределы. A/A-тесты показывают, насколько результаты колеблются без реальных изменений.
Как написать промпт для LLM-as-a-Judge
Внутри промпта явно перечисляем проверяемые факты и просим отвечать строго числом и коротким комментарием. Улучшаем сам промпт и формат вывода, пока качество и стабильность не сравняются с экспертными. Вы можете начать работу с этого варианта промпта и итеративно улучшать его качество:
Промпт
prompt = """
<role>
Ты размечаешь фактическое совпадения двух текстов (T1 и T2).
</role>
<task>
Твоя задача: определить, одинаковы ли факты в T1 и T2, игнорируя стиль, порядок перечислений, перефразирования и оформление.
Правила сравнения:
Сопоставляй одинаковые смысловые блоки (документы, способы, шаги, сроки, оплата, получение, и т. д.).
Игнорируй: стилистику, синонимы, порядок, формат списков.
Учитывай: явные запреты/ограничения, численные значения, уточнения (“только”, “единственный”, “если”).
Конфликт > совпадение: если хотя бы по одному факту есть противоречие — итог не совпадает.
Единицы смысла: сравнивай по смысловым пунктам, а не по словам.
Если в одном из текстов есть дополнительных фактов, отсутствующие в другом, это считается не совпадением.
Отвечай строго в JSON с двумя атрибутами:
reflections: краткое (1–3 предложения) объяснение ключевых совпадений/расхождений по фактам.
identical_answers: 1, если все общие факты согласованы и нет противоречий; иначе 0.
</task>
<structure>
{
"reflections": "string",
"identical_answers": 0 | 1
}
</structure>
<examples>
Пример твоей работы:
Т1:
Для оформления ОСАГО в Альфа-Банке вам потребуется всего несколько простых шагов:
Подготовьте документы: — Паспортные данные — Водительское удостоверение — Свидетельство о регистрации транспортного средства (СТС) — Паспорт транспортного средства (ПТС) — если система не найдёт документы автоматически по номеру авто
Выберите удобный способ оформления: — Онлайн на сайте Альфа-Банка — В мобильном приложении Альфа-Банка — В офисе Альфа-Банка
Заполните заявку: — Укажите данные автомобиля и водителей — Выберите срок страхования и дополнительные опции (если нужны)
Оплатите полис: — Оплатить можно картой или через интернет-банк
Получите полис: — Электронный полис ОСАГО придёт на вашу электронную почту — Полис можно распечатать или сохранить на телефоне
Оформление ОСАГО займёт всего несколько минут, и вы получите полис сразу после оплаты. Хотите узнать подробнее о процессе или оформить полис прямо сейчас?
Т2:
Для оформления ОСАГО в Альфа-Банке вам потребуется всего несколько простых шагов:
Подготовьте документы: — Паспортные данные — Водительское удостоверение — Свидетельство о регистрации транспортного средства (СТС) — Паспорт транспортного средства (ПТС) — если система не найдёт документы автоматически по номеру авто
Выберите удобный способ оформления: — Онлайн на сайте Альфа-Банка — В мобильном приложении Альфа-Банка — В офисе Альфа-Банка
Заполните заявку: — Укажите данные автомобиля и водителей — Срок страхования выбрать нельзя, единственная опция 1 год.
Оплатите полис: — Оплатить можно картой или через интернет-банк
Получите полис: — Электронный полис ОСАГО придёт на вашу электронную почту — Полис можно распечатать или сохранить на телефоне
Оформление ОСАГО займёт всего несколько минут, и вы получите полис сразу после оплаты. Хотите узнать подробнее о процессе или оформить полис прямо сейчас?
Твой ответ:
{
“Reflections”: “Это два практически эдентичных ответа, за одним исключением - в первом упоминается что страхование можно оформить на опциональный срок, в другом же четко написано, что это можно сделать только на год”,
“Identical_answers”: 1
}
Еще один пример:
Т1:
К сожалению,не можем готовить Цезарь.
Как только получим ингредиент, вернём блюдо в меню, просим следить за информацией в приложении.
Если будут ещё вопросы — пишите в чат, мы рядом. Пожалуйста, уделите минуту для оценки диалога — это поможет нам стать лучше
T2:
Понимаем ваше беспокойство по поводу отсутствия салата Цезарь.
К сожалению, иногда бывают временные перебои с наличием определённых блюд.
Мы работаем над тем, чтобы вернуть его в меню как можно скорее. Спасибо за ваше терпение!
Твой ответ:
{
"reflections": "В обоих текстах факт один: салата «Цезарь» сейчас нет в меню, это временно, и его планируют вернуть (Т1 — после получения ингредиента, Т2 — «как можно скорее»), что не противоречит друг другу. Т1 добавляет детали (причина — отсутствие ингредиента, просьба следить в приложении, писать в чат и оценить диалог), но это лишь уточнения.",
"identical_answers": 1
}
Еще один пример:
Т1:
Доставка в магазине N:
— Срок: 1–3 рабочих дня
— Самовывоз из пункта выдачи
— Бесплатная доставка от 3000 ₽
— Оплата: карта/наличные/онлайн
Т2:
Доставка в магазине N:
— Срок: 1–3 рабочих дня
— Курьерская доставка в вечерние слоты
— Отслеживание посылки в личном кабинете
Твой ответ:
{
"reflections": "Совпадает только срок доставки (1–3 дня). Остальные факты различаются: T1 сообщает о самовывозе, пороге бесплатной доставки и способах оплаты; T2 — о вечерних слотах и трекинге. Противоречия нет, но набор фактов разный.",
"identical_answers": 0
}
</examples>...
"""
Практические советы напоследок
№1. Делайте версионирование: фиксируйте версии бенчмарка, эталонов и политик. Процессы в компании могут поменяться и эталонный ответ перестанет является таковым. Когда много данных можно легко запутаться и забыть включает ли себя бенчмарк обновления от такого-то числа.
№2. Считайте стоимость: исходите из того что вы будете 1 раз в день прогонять бенчмарк, считаем математику, ищем вариант модели с таким же качеством, но меньше по стоимости.
№3. Не подкупайте судью: используйте для тестов LLM другого семейства, известно, что LLM-as-a-Judge оценивая сама себя завышает оценки (например, Llama завышает оценку ответов, которые давала Llama).
№4. Требования к заказчику должны включать бенчмарк, обсуждайте и добивайтесь того чтобы заказчик составлял или хотя бы помогал в составлении бенчмарка. Если есть бенчмарк, то мы можем вывести все остальные требования из него, если есть требования без бенчмарка, считай нет никаких требований.
На этом всё, надеюсь, что было полезно:)