5.4 Оценка качества ИИ-систем (evals)
Зачем это аналитику
«Работает хорошо» — не критерий приёмки. ИИ-система недетерминирована, и без набора оценок невозможно ни принять её, ни сменить модель, ни заметить деградацию. Требования к качеству ИИ-функции и способ их проверки — прямая работа аналитика.
Готовность к модулю
Модуль опирается на темы ниже. Если какая-то из них незнакома или её вопросы для самопроверки даются с трудом, начните с неё.
Что понять
- Почему обычное тестирование не подходит: нет единственного правильного ответа, недетерминированность, зависимость от данных.
- Уровни оценки: компоненты (поиск, классификатор, извлечение) и система целиком (ответ пользователю).
- Эталонный набор (golden set): как собрать, сколько примеров нужно, как покрыть сложные и граничные случаи, как поддерживать.
- Метрики: точные совпадения и классические (precision, recall, F1) там, где можно; для текстов — верность источнику, полнота, релевантность, соблюдение формата.
- LLM как судья: когда допустим, как калибровать по человеческой разметке, типичные искажения.
- Регрессия: прогон набора при каждой смене модели, промпта или данных; пороги приёмки.
- Оценка в эксплуатации: обратная связь пользователей, выборочная разметка, мониторинг дрейфа, A/B-сравнение.
- Precision и recall на пальцах и компромисс между ними в бизнес-терминах.
Урок
Почему тест-кейсы не работают
Классический тест-кейс устроен просто: вход, ожидаемый выход, сравнение на равенство. Для ИИ-функции ломается каждая из трёх частей.
Во-первых, у большинства запросов нет единственного правильного ответа. На вопрос «какой срок возврата товара надлежащего качества» корректно ответить десятком формулировок, и все они будут верны. Сравнение строк отбракует хорошие ответы и пропустит плохие, если плохой случайно совпал с эталоном по словам.
Во-вторых, система недетерминирована. Даже при нулевой температуре провайдер может менять инфраструктуру, порядок вычислений или саму модель под тем же именем. Один прогон теста ничего не доказывает: ответ, прошедший проверку утром, вечером может выйти другим.
В-третьих, поведение зависит от данных, которых нет в тесте. RAG-ассистент отвечает по базе знаний; когда в базу добавили новый регламент, ответы на старые вопросы изменились, хотя код не менялся. Классификатор обращений деградирует, когда клиенты начинают писать о новом продукте.
Отсюда смена подхода. Вместо «прошёл / не прошёл» на одном примере — статистическая оценка на наборе: доля ответов, удовлетворяющих критериям, с порогом приёмки. Вместо равенства строк — набор критериев качества и способ проверки каждого. Вместо однократной приёмки — постоянный контур: прогон при каждом изменении и наблюдение в эксплуатации. Этот набор проверок и называют оценками (evals).
Два уровня оценки
Составная ИИ-система — это цепочка: разбор запроса, поиск, переранжирование, генерация, постобработка. Оценивать только итоговый ответ недостаточно: при плохом результате непонятно, где сломалось.
Оценка компонентов проверяет каждое звено отдельно, и там, как правило, есть проверяемая истина:
- поиск (retrieval): попал ли нужный документ в первые k результатов (recall@k), какая доля выданных документов релевантна (precision@k);
- классификатор намерений или тематики: обычные precision, recall, F1 по классам, матрица ошибок;
- извлечение полей (из договора, платёжного поручения, накладной): точное совпадение по каждому полю после нормализации (даты, суммы, ИНН).
Оценка системы целиком смотрит на то, что получил пользователь: ответ верен, опирается на источники, полон, в нужном формате, не содержит запрещённого.
Эти уровни дополняют друг друга. Системная метрика говорит, есть ли проблема; компонентные — где она. Если доля верных ответов упала, а recall@5 поиска остался прежним, искать надо в промпте или модели генерации. Если упал recall поиска — в индексации или разбиении документов на фрагменты.
flowchart TD
Q["Запрос"] --> R["Поиск фрагментов"]
R --> G["Генерация ответа"]
G --> A["Ответ пользователю"]
R -.->|"recall@k, precision@k"| E1["Оценка поиска"]
G -.->|"верность источнику"| E2["Оценка генерации"]
A -.->|"корректность, полнота, формат"| E3["Системная оценка"]
Эталонный набор
Эталонный набор (golden set) — это зафиксированные примеры входов с тем, что считать хорошим результатом. Для извлечения полей это точные значения. Для открытых ответов — не готовый текст, а ключевые факты, которые ответ обязан содержать, ссылки на правильные источники и то, чего в ответе быть не должно.
Откуда брать примеры
Лучший источник — реальные запросы: логи пилота, обращения в поддержку, вопросы из чатов сотрудников. Синтетические примеры, сгенерированные моделью, полезны для расширения покрытия, но их распределение отличается от реального: они грамотнее, короче и «удобнее» настоящих вопросов.
Набор должен покрывать не только типичное, но и трудное:
- частые запросы — чтобы метрика отражала массовый опыт;
- граничные случаи: неоднозначные формулировки, опечатки, смешение языков, очень длинные вопросы;
- вопросы, ответа на которые в базе нет, — правильное поведение здесь «не знаю», а не выдумка;
- вопросы с противоречивыми источниками (старая и новая редакция регламента);
- вредоносные и нецелевые запросы — попытки вытащить системный промпт, вопросы не по теме;
- известные прошлые провалы — каждый найденный в эксплуатации дефект превращается в пример набора.
Полезно размечать примеры по срезам (тип вопроса, продукт, сложность) и считать метрики по каждому срезу. Среднее может не измениться, пока в одном срезе качество падает вдвое.
Сколько примеров нужно
Точного числа нет, но есть логика. Метрика на наборе — это оценка доли, и у неё есть погрешность. Для доли p на n примерах стандартная ошибка примерно равна корню из p(1−p)/n. При p около 0,8 и n = 100 это около 4 процентных пунктов, то есть 95-процентный интервал — примерно ±8 п. п. При n = 400 — около ±4 п. п.
Практический вывод: несколько десятков примеров хватает, чтобы на ранней стадии ловить грубые поломки и итерировать промпт. Чтобы уверенно различать версии, отличающиеся на несколько пунктов, нужны сотни. Если срезы важны по отдельности, требование к объёму относится к каждому срезу.
Поддержка
Эталонный набор — живой артефакт, у него есть владелец и версия. Регламенты меняются, и эталонный ответ устаревает. Раз в период набор пересматривают: убирают устаревшее, добавляют новые темы и дефекты из эксплуатации. Важно не «подгонять» систему под набор: если промпт годами шлифуют на одних и тех же 200 примерах, метрика растёт, а реальное качество — нет. Помогает отложенная часть набора, на которой не итерируют, а только принимают версии.
Метрики
Там, где есть правильный ответ
Если задачу можно свести к классификации или извлечению — это стоит сделать, потому что такие метрики дешёвые, объективные и стабильные. Точное совпадение (exact match) после нормализации подходит для полей и кодов. Для классов — precision, recall и F1.
Precision и recall на пальцах. Пусть система помечает обращения клиентов банка как «подозрение на мошенничество».
- Precision (точность): из всех помеченных — какая доля действительно мошенничество. Низкая точность — много ложных тревог.
- Recall (полнота): из всех реальных случаев мошенничества — какую долю система поймала. Низкая полнота — пропуски.
- F1 — гармоническое среднее двух, удобно как одна цифра, но скрывает, чем именно вы жертвуете.
Почти всегда можно поднять одно за счёт другого, сдвинув порог уверенности. Пометить всё подряд — полнота 100%, точность мизерная. Помечать только очевидное — точность высокая, половина случаев пропущена.
Выбор — бизнес-решение, и его надо проговаривать в стоимости ошибок:
| Ситуация | Что дороже | Что приоритетнее |
|---|---|---|
| Антифрод по платёжным поручениям | Пропущенный мошеннический платёж | Recall, ложные тревоги разбирает оператор |
| Автоматическая блокировка счёта клиента | Блокировка честного клиента | Precision |
| Поиск документов для ответа ассистента | Пропущенный нужный регламент | Recall поиска, лишнее отсеет переранжирование |
| Автоответ клиенту без проверки человеком | Неверный ответ от имени компании | Precision: лучше «передаю специалисту» |
Хорошая формулировка требования звучит так: «при полноте не ниже X точность не ниже Y», плюс указание, что происходит с сомнительными случаями.
Там, где ответ — свободный текст
Для генерации используют критерии, которые проверяют отдельно:
- верность источнику (faithfulness, groundedness) — каждое утверждение ответа подтверждается найденными фрагментами; это главный критерий против выдумки;
- корректность — ответ совпадает по смыслу с ключевыми фактами эталона;
- полнота — перечислены все обязательные условия, а не только первое;
- релевантность — ответ отвечает на заданный вопрос, а не на соседний;
- соблюдение формата — JSON валиден по схеме, есть ссылки на источники, длина в пределах.
Формат, наличие ссылок, запрещённые слова, валидность JSON проверяются кодом детерминированно. Остальное требует суждения — человека или модели-судьи. Шкала должна быть простой. Бинарная оценка «соответствует / не соответствует» с чётким определением воспроизводится лучше, чем шкала 1–10, где никто не может объяснить разницу между 6 и 7.
Метрики лексического пересечения с эталоном (BLEU, ROUGE) для ответов ассистента подходят плохо: верный ответ другими словами получает низкий балл.
LLM как судья
Модель-судья (LLM-as-a-judge) получает вопрос, ответ, иногда источники и эталон, и выносит оценку по критерию. Это масштабирует оценку до тысяч ответов, но судья — тоже недетерминированная модель со своими ошибками.
Когда допустимо
Судья хорошо работает на узких вопросах с явным определением: «содержит ли ответ утверждения, которых нет в приведённых фрагментах», «упомянут ли срок и условие о сохранении чека». Плохо — на размытых: «насколько ответ хорош по шкале от 1 до 10». Судья не заменяет экспертизу там, где сам вопрос требует знаний предметной области, которых нет в контексте.
Калибровка
Судью принимают так же, как любую ИИ-функцию, — по разметке:
- Эксперт вручную размечает выборку ответов по критерию, фиксируя обоснование.
- Судья оценивает те же ответы.
- Считают согласие: долю совпадений, а для несбалансированных классов — отдельно, насколько судья находит плохие ответы (его recall по классу «плохо») и насколько ему можно верить, когда он говорит «плохо».
- Разбирают расхождения. Часто виноват не судья, а нечёткий критерий: два эксперта тоже разошлись бы.
- Уточняют промпт судьи, добавляют примеры, повторяют на новой выборке, чтобы не подогнать судью под старую.
Полезно сравнить согласие судьи с человеком с согласием двух людей между собой: требовать от судьи большего, чем достижимо для людей, бессмысленно.
Типичные искажения
- Позиционное смещение: при сравнении двух ответов предпочтение первому или второму. Лечится прогоном в обоих порядках.
- Предпочтение длинных ответов: развёрнутый ответ кажется полнее, даже если содержит лишнее.
- Предпочтение «своего»: модель склонна выше оценивать тексты своей же модели или семейства.
- Уверенный тон: уверенно написанная ошибка оценивается выше неуверенной правды.
- Снисходительность: судьи склонны ставить «хорошо», если критерий не требует явно найти изъян.
Судья версионируется вместе с промптом: смена модели судьи меняет шкалу, и старые и новые цифры становятся несравнимы.
Регрессия и пороги приёмки
Любое изменение — модели, промпта, параметров поиска, правил разбиения документов, самой базы знаний — может ухудшить качество. Поэтому прогон эталонного набора встраивают в процесс изменений так же, как регрессионные автотесты.
flowchart TD
C["Изменение: модель, промпт, данные"] --> Run["Прогон эталонного набора"]
Run --> Det["Детерминированные проверки:<br/>формат, схема, запреты"]
Run --> Judge["Модель-судья по критериям"]
Det --> Cmp["Сравнение с текущей версией<br/>по срезам"]
Judge --> Cmp
Cmp -->|"пороги выполнены"| Ok["Выкладка, затем<br/>наблюдение в эксплуатации"]
Cmp -->|"пороги нарушены"| Fix["Разбор регрессий"]
Fix --> C
Пороги бывают двух видов. Абсолютные: «верность источнику не ниже заданного уровня», «ноль случаев раскрытия системного промпта на наборе атак». Относительные: «новая версия не хуже текущей более чем на N п. п. ни в одном срезе». Жёсткие требования безопасности формулируют как абсолютный запрет, качество — как не-ухудшение.
Разобранный пример: переход на более дешёвую модель
Интернет-магазин использует ассистента для ответов покупателям о доставке, оплате и возвратах. Предлагают заменить модель генерации на более дешёвую. Как принять решение.
- Критерии и пороги. Заранее, до прогона, фиксируют: верность источнику, корректность по ключевым фактам, полнота условий, корректный отказ на вопросы без ответа в базе, формат со ссылкой на статью. Порог: не хуже текущей версии более чем на 2 п. п. по каждому критерию, отказ на вопросы без ответа — не хуже, чем сейчас.
- Набор. 400 вопросов из реальных логов, размеченных по темам (доставка, оплата, возврат, акции) и сложности, плюс 50 вопросов без ответа в базе и 30 провокационных.
- Прогон. Обе модели отвечают на весь набор, каждый вопрос — несколько раз, чтобы оценить разброс. Поиск общий, меняется только генерация — так различия относятся именно к модели.
- Оценка. Формат и ссылки — кодом. Верность и корректность — откалиброванным судьёй. Спорные ответы и все случаи, где версии расходятся, — выборочно человеком.
- Результат. Допустим, средняя корректность отличается на 1 п. п. — в пределах погрешности. Но в срезе «возвраты» дешёвая модель чаще теряет второе условие (сроки и состояние товара), полнота там ниже на 9 п. п. На среднем это почти не видно, потому что возвраты — около шестой части набора.
- Решение. Варианты: оставить дорогую модель только для темы возвратов (маршрутизация), доработать промпт и повторить прогон, либо принять с записью риска. Решение фиксируется вместе с цифрами.
Главный урок примера — смотреть на срезы и на разброс, а не на одно среднее.
Оценка в эксплуатации
После запуска эталонных ответов для реальных запросов нет. Качество приходится оценивать косвенно и выборочно.
- Явная обратная связь: оценки «полезно / нет», жалобы. Сигнал смещённый — голосует малая и недовольная доля, — но годится для поиска проблемных тем.
- Неявные сигналы: пользователь переформулировал вопрос, ушёл в поддержку к человеку, скопировал ответ, завершил сценарий. Для каждой функции набор своих.
- Выборочная разметка: регулярно отбирают случайную выборку диалогов и размечают её людьми или откалиброванным судьёй по тем же критериям, что и на эталонном наборе. Это даёт метрику качества на реальном трафике.
- Онлайн-проверки без эталона: верность источнику можно проверять судьёй на каждом ответе, сравнивая с найденными фрагментами, — эталон для этого не нужен.
- Мониторинг дрейфа: меняется ли распределение тем и длины запросов, доля вопросов, на которые поиск ничего не находит, доля отказов. Рост вопросов о новом продукте, которого нет в базе, — сигнал обновить базу и набор.
- A/B-сравнение: часть трафика получает новую версию, сравнивают бизнес-метрики — долю решённых без оператора обращений, повторные обращения, конверсию. Нужна заранее выбранная метрика и достаточный объём трафика.
Всё найденное в эксплуатации возвращается в эталонный набор. Так замыкается цикл: эксплуатация поставляет новые трудные примеры, набор защищает от их повторения.
Для этого нужна наблюдаемость: логирование запроса, найденных фрагментов, версии промпта и модели, ответа, оценок. Без версии в логе невозможно понять, какая конфигурация дала плохой ответ. Логирование персональных данных при этом должно подчиняться требованиям безопасности — об этом модуль 5.5.
Критерии приёмки как раздел постановки
Для аналитика итог всего сказанного — раздел требований, который отвечает на вопросы:
- какие критерии качества, с определениями и примерами «хорошо / плохо»;
- на каком наборе проверяем: источник, объём, срезы, владелец, порядок обновления;
- как проверяем каждый критерий: код, судья (с каким уровнем согласия с людьми), эксперт;
- пороги: абсолютные для безопасности, относительные для качества, по срезам;
- что запускает повторную проверку: смена модели, промпта, данных, параметров;
- как контролируем в эксплуатации: какие сигналы, какая выборка, кто размечает, какая реакция на падение.
Типичные ошибки
- Принимать ИИ-функцию по демонстрации на десятке удачных вопросов без набора и порогов.
- Смотреть только на итоговый ответ и не мерить поиск отдельно, из-за чего не понятно, что чинить.
- Использовать одну среднюю метрику и не видеть провала в отдельном срезе.
- Доверять модели-судье без калибровки по человеческой разметке и без проверки на смещения.
- Собирать эталонный набор только из синтетических или только из «удобных» вопросов, без вопросов без ответа и провокаций.
- Формулировать шкалу 1–10 без определений: оценки не воспроизводятся ни людьми, ни судьёй.
- Не версионировать набор, промпт и судью, после чего цифры разных месяцев несравнимы.
Как говорить об этом на собеседовании
Уровень senior виден по тому, что вы говорите о качестве как о требовании с проверяемым критерием, а не как об ощущении. Хорошая структура ответа: «разделяю оценку компонентов и системы; для поиска — recall@k, для ответа — верность источнику, корректность, полнота и формат; эталонный набор из реальных запросов со срезами и трудными случаями; судья откалиброван по разметке экспертов; пороги — не-ухудшение по каждому срезу и абсолютный запрет на утечки; в эксплуатации — выборочная разметка и обратная связь, дефекты возвращаются в набор».
Полезно показать, что вы понимаете статистику: назвать порядок погрешности на ста примерах и объяснить, почему для сравнения версий нужны сотни. Компромисс precision и recall переводите в деньги и риски конкретного бизнеса — например, «в антифроде пропуск дороже ложной тревоги, поэтому фиксируем минимальную полноту и уже при ней оптимизируем точность».
Коротко
- ИИ-функцию принимают статистически: доля успешных ответов на наборе с порогом, а не пример за примером.
- Оценивают два уровня: компоненты с проверяемой истиной и систему целиком по критериям качества.
- Эталонный набор строится из реальных запросов, покрывает трудные случаи и срезы, версионируется и пополняется дефектами из эксплуатации.
- Где задачу можно свести к классификации или извлечению — используйте точные метрики; для текста — верность, корректность, полноту, релевантность и формат.
- Precision и recall — выбор между ложными тревогами и пропусками; его делают по стоимости ошибок.
- Модель-судья допустима на узких критериях и только после калибровки по человеческой разметке.
- Любая смена модели, промпта или данных запускает регрессионный прогон с порогами по срезам.
- В эксплуатации качество оценивают по сигналам пользователей, выборочной разметке, мониторингу дрейфа и A/B-сравнениям.
Читать дальше
- Chip Huyen, AI Engineering — главы об оценке.
- Hamel Husain, статьи «Your AI Product Needs Evals» и «Creating a LLM-as-a-Judge» (hamel.dev).
На system-design.space:
- Оценивание и наблюдаемость для AI-систем
- Precision и recall на пальцах
- Человек в контуре, качество данных и операционный цикл AI
- Выпуск моделей, калибровка и контуры экспериментов
Практика
- Для RAG из модуля 5.2 определить 4–5 критериев качества ответа, шкалу оценки по каждому и пороги приёмки.
- Разметить вручную 20 ответов модели по этим критериям, затем попросить модель-судью оценить те же ответы. Посчитать долю совпадений и разобрать расхождения.
- Написать раздел «Критерии приёмки» для обезличенной ИИ-функции: метрики, эталонный набор, пороги, кто и как проверяет.
Вопросы для самопроверки
- Почему ИИ-функцию нельзя принять обычными тест-кейсами?
- Как собрать эталонный набор и сколько в нём должно быть примеров?
- Чем precision отличается от recall? Приведите бизнес-пример, где важнее одно, и пример, где важнее другое.
- Когда можно использовать LLM как судью и как проверить, что судья адекватен?
- Как убедиться, что смена модели на более дешёвую не ухудшила качество?
- Как отслеживать качество после запуска, если эталонного ответа для реальных запросов нет?