Стенд оценки, с которым я выкатываю ИИ-агентов без страха
Выкатывать агентов без страха помогает одна вещь: стенд оценки. Фиксированный набор размеченных тестовых случаев, оцениваемый автоматически (ассерции плюс LLM-судья), запускаемый перед каждым изменением промпта или модели. Если оценка держится — выкатывай. Тестовый набор строится из реальных продакшен-сбоев.
Каждую среду. 28 400+ читателей. Никакой воды.
✓ Проверьте почту — нажмите ссылку подтверждения, чтобы завершить подписку.
✓ Вы подписаны!
✓ Вы уже в списке.
Содержание
Обновлено в июне 2026 года.
Кратко: Причина, по которой я могу изменить промпт или поменять модель на работающем агенте, не затаив дыхание, — одна вещь: стенд оценки. Фиксированный набор размеченных тестовых случаев, оцениваемый автоматически — жёсткие ассерции там, где я могу их написать, LLM-судья там, где не могу, — запускаемый перед каждым изменением. Оценка держится — я выкатываю. Оценка падает — нет. Тестовый набор не синтетический; он строится из реальных продакшен-сбоев, так что каждый баг становится постоянным регрессионным тестом.
Взгляд оператора: На более чем 100 агентах разница между теми, к которым я прикасаюсь уверенно, и теми, которых я боюсь, — в том, есть ли у них оценки. Отсутствие стенда оценки означает, что каждая правка промпта — это азартная игра. Стенд оценки превращает «думаю, так лучше» в «это измеримо лучше на 4 балла и ничего не сломало». В этом вся разблокировка.
Вы не стали бы выкатывать код без тестов. Люди же постоянно выкатывают агентов без оценок, а потом недоумевают, почему «крошечная правка промпта» сломала продакшен. Стенд оценки — это набор тестов для недетерминированного ПО. Вот тот, который я действительно запускаю.
Начните с тестового набора, построенного из реальных сбоев
Стенд хорош ровно настолько, насколько хороши его тестовые случаи, а лучшие тестовые случаи приходят из продакшена, а не из вашего воображения. Каждый раз, когда агент даёт сбой в реальной работе, я фиксирую точный ввод (я логирую каждый прогон с трейс-идентификатором — см. как отлаживать агента в продакшене) и превращаю его в случай оценки:
interface EvalCase {
id: string;
input: AgentInput; // точный продакшен-ввод
expected?: string; // эталон, когда он есть
assertions: Assertion[]; // жёсткие проверки, которые должны пройти
rubric?: string; // для LLM-судьи, когда вывод открытый
}Здесь важны две практики. Берите из продакшена, чтобы ваши оценки проверяли то, что действительно ломается, а не то, что вы предположили. И охватывайте весь разброс — счастливый путь, краевые случаи, состязательные вводы и пустые/искажённые вводы, вызывающие тихие сбои. Тестовый набор из 30–50 хорошо подобранных случаев ловит куда больше, чем 500 ленивых. Я предпочту 40 случаев, каждый из которых представляет реальный режим отказа, тысяче, которые все проверяют один и тот же лёгкий путь.
Оценивайте сначала ассерциями, затем LLM-судьёй
Не каждому выводу нужна модель для оценки. Я тянусь к самому дешёвому оценщику, который работает.
Жёсткие ассерции для всего структурированного. Парсится ли вывод как валидный JSON? Содержит ли он обязательное поле? Попадает ли извлечённая дата в диапазон? Вызвал ли он правильный инструмент с правильными аргументами? Они детерминированы, бесплатны и однозначны — пишите их столько, сколько сможете.
const assertions: Assertion[] = [
(out) => isValidJSON(out),
(out) => parse(out).category in ALLOWED_CATEGORIES,
(out) => parse(out).confidence >= 0 && parse(out).confidence <= 1,
];LLM-судья для всего открытого остального — тон, полезность, «действительно ли это ответило на вопрос». Здесь вы даёте модели ввод, вывод и рубрику и просите её оценить. Два правила держат судью честным: сделайте рубрику конкретной (шкала от 1 до 5 с описанными опорными точками бьёт «оцените качество»), и используйте сильную модель в роли судьи — суждение есть задача рассуждения, поэтому это место, где я с радостью плачу за Sonnet, даже когда сам агент работает на Haiku согласно математике затрат. Размытая рубрика или слабый судья дают вам шум, похожий на сигнал.
Запускайте стенд перед каждым изменением
Стенд существует, чтобы ответить на один вопрос: сделало ли это изменение агента лучше или хуже? Поэтому я запускаю его перед каждой правкой промпта, заменой модели или изменением инструмента.
# базовая линия на main
npm run eval -- --suite=booking-agent > baseline.json
# внесите изменение, затем перезапустите
npm run eval -- --suite=booking-agent > candidate.json
# сравните
npm run eval:diff baseline.json candidate.jsonДифф показывает агрегированную оценку, прохождение/провал по каждому случаю и — что критично — какие именно случаи регрессировали. Агрегат, который ползёт вверх, пока три случая тихо ломаются, — это не улучшение; это компромисс, который я хочу видеть и одобрить, а не тот, что проскальзывает незаметно. Следить за диффом по случаям — вот как вы избегаете «починил одно, сломал два других», того режима отказа, из-за которого люди боятся собственных промптов.
Поставьте шлюз регрессии и дайте ему блокировать
Как только вы доверяете стенду, встройте его как шлюз в путь к продакшену. Моё правило прямолинейно: изменение, опускающее оценку ниже порога базовой линии, не выкатывается. Не «посмотрю позже» — оно заблокировано, как провалившийся CI-тест.
const PASS_THRESHOLD = 0.90; // 90% случаев должны пройти
if (candidate.passRate < PASS_THRESHOLD || candidate.passRate < baseline.passRate) {
throw new Error(`Eval regression: ${candidate.passRate} < ${baseline.passRate}`);
}Именно это превращает оценки из приятного дополнения в то, что позволяет двигаться быстро. Шлюз делает «выкатывать без страха» буквально истинным: худший случай для плохого изменения — красный прогон оценки, а не инцидент в продакшене. И поскольку тестовый набор растёт каждый раз, когда что-то ломается, шлюз сам со временем становится строже и защищённее.
Учитывайте недетерминизм при оценке
Тонкость, на которой спотыкаются: один и тот же ввод может получить разную оценку в разных прогонах, потому что модель сэмплирует по-разному. Если запускать каждый случай один раз, вы увидите фантомные регрессии — случай, который «сломался», на деле просто шум сэмплирования.
Два средства. Запускайте оценки при temperature: 0, чтобы сократить дисперсию (полностью её это не уберёт). А для случаев, которые мерцают, запускайте их N раз и берите долю прохождений, а не единичное прохождение/провал. Случай, проходящий 9 из 10, в лучшей форме, чем тот, что проходит 5 из 10, даже если оба могут показать зелёный единичный прогон. Это тот же принцип «объём важнее анекдота», который я применяю при отладке перемежающихся сбоев — один прогон — это мнение, пятьдесят прогонов — это данные.
Замкните цикл мониторингом продакшена
Стенд оценки проверяет против известных случаев. Продакшен подбрасывает новые. Поэтому цикл таков: мониторьте живое поведение, ловите новый режим отказа, превращайте его в случай оценки, чините — и теперь он под постоянной защитой. Сторона мониторинга — отслеживание доли успеха, валидности вывода и стоимости за прогон на живом трафике — это то, что я разбираю в как я измеряю, действительно ли ИИ-агент работает. Оценки и мониторинг — две половины одной системы: мониторинг находит баги, оценки следят за тем, чтобы они оставались мёртвыми.
Эта петля обратной связи и есть настоящий продукт. Любой отдельный набор оценок устаревает; а процесс, превращающий каждый продакшен-сбой в постоянный тест, крепнет с каждой неделей. Вот как агент переходит от «страшно трогать» к чему-то, что я буду рефакторить в пятницу днём, не моргнув глазом.
Часто задаваемые вопросы
Что входит в набор оценок для ИИ-агента?
Реальные продакшен-вводы, превращённые в размеченные случаи — счастливый путь, краевые случаи, состязательные и искажённые вводы — каждый с жёсткими ассерциями и, для открытых выводов, рубрикой LLM-судьи. От 30 до 50 случаев, взятых из реальных сбоев, бьют сотни синтетических, которые все проверяют лёгкий путь.
Стоит ли использовать LLM для оценки выводов агента?
Используйте жёсткие ассерции везде, где вывод структурирован (валидный JSON, верное поле, правильный вызов инструмента) — они бесплатны и детерминированы. Приберегите LLM-судью для открытых качеств вроде тона и полезности, с конкретной рубрикой и сильной моделью-судьёй, чтобы получать сигнал, а не шум.
Как не дать изменению промпта тихо сломать продакшен?
Запускайте стенд оценки перед каждым изменением и делайте дифф против базовой линии, следя за регрессиями по случаям, а не только за агрегированной оценкой. Затем привяжите деплои к результату, чтобы любое изменение, опускающееся ниже порога базовой линии, блокировалось как провалившийся тест.
Как справляться с недетерминизмом в оценках?
Запускайте при температуре 0, чтобы снизить дисперсию, а для мерцающих случаев запускайте их несколько раз и оценивайте долю прохождений вместо единичного прогона. Случай, проходящий 9 из 10 раз, здоровее того, что проходит 5 из 10, даже если единичный прогон показывает оба зелёными.
Каждую среду. 28 400+ читателей. Никакой воды.
✓ Проверьте почту — нажмите ссылку подтверждения, чтобы завершить подписку.
✓ Вы подписаны!
✓ Вы уже в списке.
Получайте ИИ-руководство на почту
Каждую среду. 28 400+ читателей. Никакой воды.
Проверьте почту.
Мы отправили письмо для подтверждения — нажмите на ссылку, чтобы завершить подписку. Проверьте папку «Спам», если не видите его в течение минуты.
Вы подписаны.
Добро пожаловать — следующий выпуск скоро придёт на вашу почту.
Вы уже в списке — ждите выпуск каждую среду.