Почему вам нужно добавить LLM-as-a-Judge в пайплайн автоматического тестирования и как это сделать

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

Обложка: Почему вам нужно добавить LLM-as-a-Judge в пайплайн автоматического тестирования и как это сделать

Я расскажу, почему нужен автоматизированный гибридный пайплайн, включающий в себя сравнение векторов и LLM-as-a-Judge, в котором ручная разметка используется только на самом старте.

Тесты покрывают только часть функционала, а совпадение ответов изредка можно проверить посимвольно, потому что ответ может быть правильным, но написан в другой формулировке.

В целом подходов к тестированию LLM немного:

  1. ручная разметка,
  2. сравнение векторов,
  3. 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. Требования к заказчику должны включать бенчмарк, обсуждайте и добивайтесь того чтобы заказчик составлял или хотя бы помогал в составлении бенчмарка. Если есть бенчмарк, то мы можем вывести все остальные требования из него, если есть требования без бенчмарка, считай нет никаких требований.

На этом всё, надеюсь, что было полезно:)