Глава 5 — Оценка LLM-приложений
Пятый пост поглавного разбора LLM Primer V: Building Real-World LLM Applications. Глава, признающая, что assertEqual для LLM-выходов мёртв, и перестраивающая дисциплину тестирования вокруг заякоренных судей, RAG-триады и trajectory-тестов.
Почему существует эта глава
Классическое тестирование опирается на предположение, что корректный выход — это конкретный выход: функция возвращает 42, строка равна «Hello, world», JSON совпадает с фикстурой. LLM-системы производят парафразы, эквивалентные по смыслу, но различные посимвольно, и exact-match-ассерт, полсотни лет державший тестирование, разваливается на первом же перегенерировании. Команды тянутся к BLEU, ROUGE или косинусной близости эмбеддингов и обнаруживают, что эти метрики слабо коррелируют с человеческим суждением на том, что важно: правилен ли ответ, обоснован ли он, отвечает ли он на вопрос. Глава 5 перестраивает дисциплину тестирования вокруг того, что реально работает: заякоренных рубрик LLM-as-a-judge, RAG-триады, trajectory-тестов для агентов и непрерывного цикла, где продакшен-трейсы кормят eval-набор, гейтирующий следующий релиз.
5.1 Оценочный разрыв и LLM-as-a-judge
Оценочный разрыв — это расстояние между тем, что может измерить классический тест, и тем, что реально нужно измерять в LLM-выходе. Exact-match и метрики по эталонной строке не ловят ни одной интересной ошибки на задачах, тяжёлых парафразом. LLM-as-a-judge — рабочая лошадь, закрывающая разрыв, с двумя дисциплинами, отделяющими её от фокуса. Первая: рубрика судьи заякорена — каждое значение шкалы имеет письменное определение, желательно с примером, чтобы судья не сочинял число по вольной ассоциации. Вторая: судья пишет рассуждение до оценки, потому что судья, вынужденный проговорить рассуждение, — это судья, дающий более согласованные оценки. Программные проверки дополняют судью там, где что-то проверяется детерминированно: JSON парсится, обязательные поля на месте, запрещённых строк нет, длина ответа в рамках. Судья не универсален; он покрывает то, что не берут детерминированные проверки.
5.2 RAG-триада — релевантность контекста, обоснованность, релевантность ответа
Для retrieval-систем закристаллизовался паттерн независимой оценки трёх вершин. Релевантность контекста спрашивает, действительно ли найденные чанки релевантны запросу, и изолирует отказы retrieval от отказов генерации. Обоснованность спрашивает, следует ли сгенерированный ответ из найденного контекста, и ловит галлюцинации, прошедшие валидацию формы. Релевантность ответа спрашивает, отвечает ли ответ на тот вопрос, что пользователь на самом деле задал. Оценённые независимо, три вершины локализуют отказы: низкая релевантность контекста указывает на retrieval, низкая обоснованность — на генератор, низкая релевантность ответа — либо на роутер, либо на систему, отвечающую на смежный вопрос. RAGAS оперирует триадой как батч-конвейером; качество судьи-модели доминирует над качеством оценок, поэтому сам судья — компонент, который команда оценивает.
5.3 Ниши фреймворков и регрессия агентов
Три фреймворка занимают разные ниши. RAGAS прогоняет RAG-триаду батчем против набора пар вопрос–ответ и правильный инструмент для периодических dataset-оценок. TruLens цепляет feedback-функции к живому продакшен-трафику и считает триаду прямо на трейсах, замыкая петлю между продакшеном и оценкой. DeepEval запускает LLM-тесты как CI-гейты так же, как pytest запускает юнит-тесты, с порогами на каждую метрику. Агенты расширяют всё это в трёх направлениях: trajectory-snapshot-тесты фиксируют форму последовательности вызовов инструментов на фиксированный вход, ловя структурный дрейф; инвариант-ассерты проверяют, что агент не вызвал запрещённый инструмент и не пропустил обязательное подтверждение; рубрик-тесты оценивают саму траекторию по критерию «был ли путь разумным». Агент, дающий правильный ответ неправильным путём, — это один твик промпта до неправильного ответа тем же путём, и trajectory-тест — дисциплина, ловящая это.
Что подготавливает глава 5
Оценкам нужны продакшен-трейсы для сэмплинга. CI-гейтам нужны реальные регрессии, от которых защищать. Цикл непрерывного улучшения работает, только если есть слой наблюдаемости, ловящий каждый шаг каждого вызова: модельные вызовы, вызовы инструментов, результаты retrieval, хопы субагентов, стоимость, задержку, отзыв пользователя. Глава 6 — это слой. Она проходит OpenTelemetry с семантическими соглашениями GenAI, метрики, которые действительно важны для LLM-систем, выбор платформы и — самое главное — экспортный конвейер, направляющий низкоскоринговые трейсы обратно в eval-набор, гейтирующий следующий релиз.
Дальше — Глава 6: Наблюдаемость и трассировка ИИ. Субстрат, делающий и оценку, и отладку возможными, — один вложенный трейс на вызов, со стоимостью и качеством в качестве атрибутов первого класса.