IT · MAX
Как проверить качество LLM-функции: evals, LLM-as-judge и регрессии при смене модели
· 13 мин чтения · Редакция ultrathink
Качество LLM-функции проверяют не впечатлением от пары удачных ответов, а набором оценок (evals): фиксированными примерами с понятными критериями, которые прогоняются автоматически при каждом изменении. Часть критериев проверяется кодом, часть — моделью-судьёй (LLM-as-judge), а сам судья должен быть сверен с оценками людей. Без такого набора любая смена модели или промпта — это выкатка вслепую.
Почему «проверил в чате — работает» не считается
Языковая модель недетерминирована и чувствительна к формулировкам: функция, которая хорошо ответила на ваши пять вопросов, может провалиться на шестом, который задаст пользователь. Ручная проверка к тому же неповторяема: после правки промпта вы проверяете уже другие примеры и не замечаете, что сломалось старое. К тому же автор функции невольно задаёт вопросы так, как удобно ему, а пользователи формулируют их по-своему.
Evals превращают качество из ощущения в измерение. Это тот же принцип, что и автотесты в обычной разработке, только с поправкой на то, что правильный ответ часто не единственный и проверяется не простым сравнением строк. Как и тесты, evals ценны не в момент написания, а при каждом следующем изменении.
Что именно оценивать
«Качество» — слишком общее слово, чтобы его измерять. Прежде чем собирать примеры, разложите его на отдельные критерии, каждый из которых можно проверить. Набор критериев зависит от задачи, но обычно включает несколько из следующих.
- Правильность: ответ верен по существу или совпадает с эталоном.
- Верность источнику: для функций с документами — ответ опирается только на переданный материал и ничего не выдумывает.
- Полнота: в ответе есть все обязательные элементы.
- Формат: структура, длина, язык, валидность JSON, наличие обязательных полей.
- Следование инструкции: модель делает то, что просили, и не делает того, что запрещено.
- Корректный отказ: на вопросы вне рамок функция отвечает отказом или «не знаю», а не выдумкой.
- Тон и стиль: соответствие принятому в продукте.
- Эксплуатационные свойства: задержка, стоимость, доля ошибок и обрезанных ответов.
Критерии полезно ранжировать. Ошибка в правильности или выдуманный факт обычно хуже, чем слишком длинный ответ. Если это не зафиксировать, улучшение по второстепенному критерию может скрыть ухудшение по главному.
Как сформулировать критерий
Хороший критерий можно проверить, не споря. «Ответ полезный» — плохой критерий: два человека оценят его по-разному. «В ответе указан срок доставки из базы знаний для региона из вопроса» — хороший: его можно проверить по источнику. Если критерий не удаётся сформулировать так, разбейте его на несколько более узких или признайте, что для него нужна экспертная оценка людьми.
Как собрать набор оценок
Начинать стоит с небольшого набора, который вы в состоянии разметить и просмотреть вручную, и расширять его постепенно. Важнее разнообразие и честность примеров, чем их количество.
- Реальные запросы пользователей — обезличенные, из логов или пилота.
- Типичные сценарии, ради которых функция создавалась.
- Краевые случаи: пустой ввод, очень длинный текст, смешение языков, опечатки, неоднозначные формулировки.
- Вопросы, на которые правильный ответ — отказ или «не знаю».
- Попытки сломать функцию: просьбы игнорировать инструкции, выйти за рамки роли, раскрыть системный промпт.
- Каждая ошибка, найденная в продакшене: она становится новым примером, чтобы не повториться.
Для каждого примера записывается, что считается хорошим ответом: эталон, список обязательных фактов или набор правил. Если вы сами не можете сформулировать, чем хороший ответ отличается от плохого, никакая автоматика это за вас не решит.
Набор полезно делить на части: основную, которая отражает типичный трафик, и отдельные срезы — по языкам, типам запросов, сложным случаям. Тогда ухудшение в одном срезе не утонет в общем среднем. Отдельно держите небольшую часть примеров, на которой вы не настраиваете промпт, — иначе есть риск подогнать функцию под свой же набор.
Разметка эталонов
Эталоны должны размечать люди, которые понимают предметную область, по письменной инструкции. Инструкция нужна, даже если разметчик один: через время вы сами забудете, почему считали ответ правильным. Спорные примеры не стоит удалять — их полезно обсудить и записать решение в инструкцию, потому что именно на них потом ошибается и функция, и судья. Эталоны тоже устаревают: при изменении базы знаний или правил продукта их нужно пересматривать.
Условный пример
Допустим, функция отвечает клиентам на вопросы по условиям доставки на основе внутренней базы знаний. В набор попадут частые вопросы о сроках и стоимости, вопросы с опечатками и на двух языках, вопросы о том, чего в базе нет, — например, о доставке в регион, который не обслуживается, — и попытки заставить бота пообещать скидку. Для каждого записываются обязательные факты из базы знаний и правило: никаких обещаний, которых нет в источнике.
Виды проверок и когда какую выбирать
Проверки кодом
Всё, что можно проверить детерминированно, проверяйте кодом: валидный ли JSON и соответствует ли он схеме, есть ли обязательные поля, не превышена ли длина, совпадает ли извлечённое значение с эталоном, нет ли запрещённых слов, совпадает ли язык ответа с языком вопроса. Отдельно проверяйте, что ответ не обрезан: оборванный по лимиту ответ может прийти как успешный и тихо испортить результат.
Сравнение с эталоном
Для задач классификации и извлечения данных ответ можно прямо сравнить с правильным и посчитать долю совпадений. Для свободного текста сравнение строк не работает: два правильных ответа могут не иметь общих слов. Здесь нужен либо судья, либо человек.
Модель-судья
LLM-as-judge оценивает то, что сложно формализовать: полноту, верность фактам из источника, тон, следование инструкции. Это быстро и масштабируемо, но требует настройки и калибровки, о которых ниже.
Люди
Люди нужны для калибровки судьи, для самых ответственных решений и для разбора спорных случаев, а не для каждого прогона. Разметка людьми дорогая, поэтому её стоит тратить там, где без неё нельзя.
- Если критерий можно выразить правилом — используйте код, потому что он быстр, дёшев и стабилен.
- Если есть единственный правильный ответ — сравнивайте с эталоном, потому что судья здесь только добавит шума.
- Если критерий смысловой и ответов может быть много — используйте судью, но откалиброванного на людях.
- Если решение дорогое — например, переход на другую модель в ответственной функции, — добавьте ручную проверку выборки, потому что цена ошибки оправдывает затраты.
Многошаговые и агентные функции
Если функция не просто отвечает текстом, а выполняет цепочку действий — ищет, вызывает инструменты, заполняет поля в системе, — оценивать нужно и результат, и путь. Результат проверяется по итоговому состоянию: правильно ли заполнена карточка, создана ли нужная запись. Путь — по журналу шагов: не вызывались ли лишние или опасные инструменты, не было ли зацикливания, уложилась ли функция в разумное число шагов. Функция, которая приходит к верному результату через запрещённое действие, проваливает оценку.
Как настроить LLM-as-judge
Судья — это тоже LLM-функция со своим промптом, и его качество зависит от постановки так же, как качество любой другой функции. Несколько практик заметно повышают надёжность оценок.
- Один судья — один критерий. Узкий судья проще калибруется, а его ошибки легче понять. Общий судья «оцени качество ответа» смешивает всё сразу, и по его оценке невозможно понять, что именно стало хуже.
- Бинарные вопросы вместо шкал. «Опирается ли ответ только на переданный документ — да или нет» стабильнее, чем «оцени верность от 1 до 10».
- Чёткая рубрика. Опишите, что считается «да», а что «нет», с примерами пограничных случаев.
- Эталон или источник в запросе. Проверять верность фактам судья может, только если видит, с чем сравнивать.
- Сначала объяснение, потом оценка. Просите судью кратко обосновать решение и сохраняйте это обоснование: при разборе расхождений с людьми оно показывает, какой критерий судья понял не так.
- Фиксированная модель и параметры судьи. Смена судьи меняет шкалу, и результаты до и после нельзя сравнивать напрямую.
Ловушки LLM-as-judge
Модель-судья удобна, но у неё есть систематические искажения. Если о них не знать, вы будете уверенно измерять не то, что нужно.
- Смещение по позиции: при сравнении двух ответов судья может предпочитать первый или второй независимо от содержания. Лечится прогоном в обоих порядках и учётом только согласованных решений.
- Любовь к длинным ответам: развёрнутый ответ выглядит «лучше», даже если в нём больше воды или ошибок. Лечится явным критерием краткости и проверкой полноты по списку фактов.
- Предпочтение собственного стиля: судья может завышать оценки ответам, похожим на то, что написал бы сам. Это особенно важно, когда судья и оцениваемая функция работают на похожих моделях.
- Уверенный тон вместо правильности: ответ, сформулированный убедительно, может получить оценку выше, чем осторожный, но верный.
- Ошибки в фактах: без источника или эталона судья проверяет правдоподобие, а не правду.
- Нестабильность: один и тот же ответ при повторной оценке может получить разные оценки. Проверьте это на нескольких повторах до того, как доверять сравнению версий.
Отдельная ловушка — утечка эталона. Если примеры из набора оценок попали в промпт функции как образцы, функция будет хорошо проходить именно их, а на новых вопросах — хуже. То же происходит, когда промпт долго настраивают на одних и тех же примерах. Контрольная часть набора, которую не используют при настройке, защищает от этого самообмана.
Калибровка судьи по оценкам людей
- 01Отберите часть примеров из набора, включая пограничные и сложные случаи.
- 02Попросите людей, понимающих задачу, разметить их по тому же критерию и той же рубрике, что и судью. Если разметчиков несколько, сначала проверьте, согласны ли они между собой.
- 03Прогоните на этих примерах судью.
- 04Сравните ответы судьи и людей по каждому примеру и выпишите расхождения.
- 05Прочитайте обоснования судьи в случаях расхождения: часто проблема в неясной рубрике, а не в модели.
- 06Уточните рубрику, добавьте примеры пограничных случаев и повторите сравнение.
- 07Повторяйте калибровку при смене модели судьи и при существенном изменении функции.
Если люди между собой расходятся так же сильно, как с судьёй, проблема в самом критерии: он недостаточно определён. Сначала договоритесь о том, что считать хорошим ответом, и только потом автоматизируйте оценку.
Регрессии при смене модели или промпта
Новая версия модели или правка промпта может улучшить среднее и при этом сломать отдельные важные сценарии. Поэтому смотреть нужно не только на итоговую цифру, но и на список примеров, которые раньше проходили, а теперь нет.
- Фиксируйте версию модели, промпт и параметры вместе с результатами каждого прогона.
- Прогоняйте весь набор при любом изменении: модели, промпта, поиска, постобработки, версии библиотеки.
- Из-за недетерминизма делайте несколько прогонов на спорных примерах, а не один.
- Сравнивайте результаты по примерам и разбирайте каждое ухудшение вручную.
- Смотрите на срезы отдельно: ухудшение на одном языке или типе запросов может спрятаться в среднем.
- Проверяйте не только качество, но и задержку, стоимость, долю отказов и обрезанных ответов.
Отдельно стоит проверять устойчивость к перефразированию: один и тот же вопрос, заданный разными словами, должен давать сопоставимый ответ. Если качество резко меняется от формулировки, функция держится на удачном совпадении, а не на понимании задачи. Если же два прогона одной и той же версии заметно расходятся, сначала разберитесь с этим шумом, иначе сравнение версий ничего не покажет.
Как читать отчёт сравнения
Начинайте не с итоговой цифры, а со списка примеров, которые перешли из «прошёл» в «не прошёл» по главным критериям. Каждый такой пример стоит открыть и прочитать оба ответа: иногда ухудшение — это ошибка судьи, иногда — реальная потеря, иногда — устаревший эталон. Затем посмотрите на срезы и только потом — на среднее. Улучшения тоже стоит проверять выборочно: неожиданно большой рост часто означает ошибку в самой проверке.
Evals в процессе разработки
Набор оценок приносит пользу, только если его запускают регулярно и по правилам. Иначе он устаревает и превращается в разовую проверку, которую никто не повторяет.
- 01Храните набор в репозитории рядом с кодом функции, с версиями и историей изменений.
- 02Запускайте быстрые проверки кодом при каждом изменении, а полный прогон с судьёй — перед слиянием изменений в промпт, модель или поиск.
- 03Формируйте отчёт сравнения: итог по каждому критерию и срезу, список ухудшившихся и улучшившихся примеров.
- 04Договоритесь о правиле: изменение не сливается, если ухудшились примеры по главным критериям, пока ухудшения не разобраны.
- 05Пересматривайте набор: удаляйте устаревшие примеры, добавляйте новые сценарии и ошибки из продакшена.
Прогон с судьёй стоит денег и времени, поэтому его не обязательно запускать на каждый коммит. Разумно разделить набор на быстрый и полный: быстрый с проверками кодом и небольшим числом ключевых примеров — на каждое изменение, полный — перед слиянием значимых изменений и по расписанию. Ответы функции и оценки судьи можно кэшировать по версии промпта и модели, чтобы не платить за повторный прогон без изменений.
Условный пример сравнения
Команда меняет промпт функции ответов по доставке, чтобы ответы стали короче. Отчёт показывает, что средняя длина уменьшилась, верность источнику не изменилась, но в нескольких примерах исчезло обязательное упоминание о сроках для отдалённых регионов. Без сравнения по примерам это осталось бы незамеченным — среднее по полноте почти не изменилось.
После выкатки
После выкатки качество продолжают отслеживать на реальном трафике: собирают отзывы пользователей, выборочно проверяют ответы — кодом, судьёй и людьми, — следят за долей отказов и обрезанных ответов. Найденные провалы переносятся в набор оценок. Так набор растёт вместе с продуктом и отражает то, что действительно происходит у пользователей.
Чек-лист: evals для своей функции
- 01Разложите «качество» на отдельные критерии и расставьте их по важности.
- 02Соберите небольшой разнообразный набор примеров из реальных запросов и краевых случаев.
- 03Для каждого примера запишите, что считается хорошим ответом.
- 04Добавьте вопросы, на которые правильный ответ — отказ.
- 05Разделите набор на срезы и отложите контрольную часть.
- 06Всё формализуемое проверяйте кодом, включая формат и обрезанные ответы.
- 07Для остального настройте узких судей с бинарными критериями и рубрикой.
- 08Откалибруйте судей на ручной разметке и повторяйте калибровку при их смене.
- 09Проверьте стабильность оценок на повторных прогонах.
- 10Встройте прогон набора в процесс: ни одна смена модели или промпта без него.
- 11Храните результаты с версиями и сравнивайте по примерам и срезам.
- 12Отслеживайте задержку, стоимость и долю отказов вместе с качеством.
- 13Пополняйте набор каждой ошибкой из продакшена.
Короткий словарь терминов
- Evals — набор примеров с критериями, по которым оценивается LLM-функция.
- Эталон — заранее подготовленный правильный ответ или список обязательных элементов ответа.
- LLM-as-judge — использование языковой модели для оценки ответов по заданному критерию.
- Рубрика — описание того, какой ответ считается соответствующим критерию, с примерами.
- Калибровка — сверка оценок судьи с оценками людей и уточнение критериев.
- Регрессия — ухудшение на примерах, которые раньше проходили.
- Срез — часть набора, выделенная по признаку: языку, типу запроса, сложности.
Вывод
Оценка качества LLM — это инженерная практика, а не разовая проверка. Набор примеров с понятными критериями, проверки кодом там, где это возможно, откалиброванный судья там, где нет, и сравнение по примерам при каждом изменении — вот что позволяет менять модели и промпты без страха.
Чем раньше такой набор появится в проекте, тем дешевле обходится каждое следующее улучшение. Начните с малого — небольшого набора честных примеров и нескольких проверок кодом, — и наращивайте его вместе с продуктом.
Частые вопросы
Это набор фиксированных примеров с критериями хорошего ответа, который автоматически прогоняется через LLM-функцию. Он показывает, улучшилось или ухудшилось качество после изменения модели, промпта или окружения.
Только после сверки с оценками людей на части примеров. У судьи есть систематические смещения — по позиции, по длине, к собственному стилю, — и их нужно учитывать в постановке критериев.
Прогнать на обеих один и тот же набор оценок с одинаковыми критериями и сравнить результаты по каждому примеру и срезу, а не только средний балл. Отдельно сравните задержку, стоимость и долю отказов.
Универсального числа нет. Начните с набора, который можете разметить и проверить вручную, и расширяйте его за счёт реальных запросов и найденных ошибок.
Принцип тот же — фиксированные проверки при каждом изменении, — но правильный ответ часто не единственный, а результат модели недетерминирован. Поэтому вместо точного сравнения используют критерии, судей и несколько прогонов.
Быстрые проверки кодом — при каждом изменении, полный прогон с судьёй — перед любым изменением промпта, модели или поиска. После выкатки качество отслеживают на реальном трафике постоянно.