API и разработка

Тестирование LLM-приложения: проверяйте ошибки продукта, а не впечатление

Как собрать регрессионный набор для LLM-функции: эталоны, опасные ошибки, отказ от ответа, сетевые состояния, расходы и заранее записанные критерии выпуска.

Редакция KvantoraТематический выпуск: Около 4 минут чтения
Обложка статьи «Тестирование LLM-приложения: проверяйте ошибки продукта, а не впечатление»

LLM-приложение тестируют на двух уровнях: протокол и продуктовый результат. Первый проверяет статусы, повторы и формат; второй: правильность ответа на заранее размеченных примерах, включая ситуации, когда модель должна отказаться от догадки.

Эталон нужен до запуска модели

Возьмите реальные по форме, но разрешённые или синтетические входы. Для заявки отметьте обязательные поля, допустимый пустой ответ и ошибки, которые нельзя пропустить. Для редакторской задачи задайте факты, которые нельзя менять. Не пишите ожидаемое после просмотра ответа: тогда тест станет оправданием кандидата, который вам уже понравился.

Эталон не всегда одна строка. У хорошего письма может быть несколько формулировок; проверяйте сохранённые факты, запрет на выдуманные обещания и удобство правки. Для JSON и арифметики лучше точная проверка кодом. Разведите машинный валидатор и мнение человека, чтобы не превращать субъективность в ложную точность.

Набор примеров и протокольные сбои

Положите рядом простой запрос, длинный документ, пустое поле, противоречие, неверный язык входа и попытку пользователя навязать системе действие вне её прав. Если продукт работает с поиском, добавьте вопрос без ответа в базе. Если с PDF: таблицу и сноску. Цель не поймать модель на экзотике, а увидеть ошибки, которые действительно попадут в рабочий поток.

Для каждого случая задайте тяжесть: косметический дефект, ручная правка, отказ задачи или опасная ошибка. Нельзя складывать их в один процент без контекста. Модель, которая красиво отвечает в девяти случаях и один раз выдумывает сумму платежа, может быть хуже скучного кандидата с десятью проверяемыми ответами.

Синтетический HTTP-сервер способен воспроизвести 200, 202, неверный JSON, 401, 429 и обрыв после приёма запроса. Проверьте, что клиент сохраняет тело и идентификатор до отправки, не создаёт новый ID при восстановлении и не объявляет незавершённый ответ готовым. Такой тест быстрый и воспроизводимый; он не зависит от поведения модели.

Для SSE добавьте разделение кириллического символа между байтами, несколько data-строк, отсутствие финального маркера и ошибку посреди ответа. Парсер должен отличать полный результат от черновика на экране. Если приложение выполняет инструменты или внешние действия, проверяйте полномочия и отсутствие эффектов при отказе отдельно.

Ручная оценка тоже нуждается в правилах

Когда два проверяющих называют один ответ «хорошим» и «плохим», попросите их отметить конкретную строку и вид ошибки. Возможно, один оценивает стиль, а другой: точность срока. Согласуйте рубрику до большого прогона. Не требуйте полного единодушия по вкусу текста; для опасных фактов и обязательных полей согласие должно быть намного строже.

Сохраняйте несколько обезличенных эталонных примеров для обучения новых проверяющих. Через месяц команда сможет повторить испытание после смены модели. Если правила оценки существуют только в голове одного разработчика, сравнение версий быстро превратится в спор о впечатлениях. Хорошая рубрика помогает и модели, и людям, которые принимают её результат.

Качество измеряют на одинаковых условиях

Сравнивайте модели с одинаковым набором входов, подсказкой, длиной и допустимыми параметрами. Записывайте публичный ID, дату, версию подсказки и результат каждого запуска. Если модель выдаёт нестабильный формат, повторите важные случаи несколько раз и покажите разброс. Официальные eval-инструменты OpenAI демонстрируют подход к измерению, но критерии вашего продукта всё равно надо определить вам.

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

Включите расход в критерий выпуска

Считайте стоимость не одного вызова, а пригодного завершённого результата. Если половина задач требует повторного запроса, число вызовов и работа оператора входят в оценку. Неизвестный исход и открытый резерв указывайте отдельно от подтверждённого расхода. Сравнение без этих состояний поощряет клиента, который теряет ответы и молча повторяет платную работу.

Установите лимит на один вызов и бюджет ключа. Во время теста сохраняйте расчёт и причину каждого отказа. Финальное решение может быть узким: модель подходит для черновика письма с проверкой человеком, но не для автоматического заполнения финансового поля. Это нормальный результат испытания.

После исправления найденной ошибки добавьте её вход в регрессионный набор с ожидаемым результатом и причиной. Не полагайтесь на память команды или скриншот чата. При следующей версии модели тот же случай должен запускаться автоматически там, где проверка детерминирована, либо попадать на повторную ручную оценку по явной рубрике.

Регрессия после каждого значимого изменения

Меняется и окружение модели. Новая подсказка, парсер, разбиение документов и даже шаблон пользовательской формы меняют вход. Перед выпуском запустите сохранённый набор и посмотрите, не вернулись ли старые ошибки. Отдельно проверяйте негативные сценарии протокола: сеть и бюджет не становятся надёжнее от улучшения качества текста.

Критерий выпуска должен быть записан заранее: какие ошибки недопустимы, какая доля случаев требует человека, какой расход укладывается в бюджет и как возвращаться к предыдущей конфигурации. После запуска собирайте реальные классы ошибок без публикации секретов или клиентских документов. Так тестовый набор постепенно отражает работу продукта, а не коллекцию эффектных примеров.

Источники