← Блог

Evals: автоматическая проверка качества AI-агентов

Сережа Рис · 10 February 2026

evalsclaude codeтестирование

Мой бот делает дайджесты чата вайбкодеров. 200+ сообщений в день, 5-7 тем, текст на 4000 символов со ссылками. Выглядит нормально. Читается хорошо.

Пока не проверишь ссылки.

Агент получает URL и придумывает название. Не идёт на страницу, не смотрит заголовок — генерирует правдоподобный текст. “YouTube-стрим Vibecoder” вместо реального “Как я собрал SaaS за выходные”. Ссылка рабочая. Название — галлюцинация.

Я это заметил когда подписчик спросил: “А почему ссылка про SaaS, а в тексте — стрим?” Бот работал неделю. Сколько таких ошибок проскочило — не знаю.

Корректура для AI

Eval (от evaluation) — автоматическая проверка того, что выдаёт LLM. Корректура, только не человеком, а скриптом.

Редактор проверяет текст: факты верны? Ссылки рабочие? Формат правильный? Eval делает то же самое, но после каждой генерации. Автоматически.

Без eval — “выглядит нормально”. С eval — “проверено, вот результат”.

Три уровня

Не все проверки одинаковые. Есть три уровня, от простого к сложному:

Уровень 1          Уровень 2           Уровень 3
ДЕТЕРМИНИРОВАННЫЕ   LLM-AS-JUDGE        LIVE GENERATION
─────────────────   ─────────────────   ─────────────────
Точные правила      AI проверяет AI     Реальные данные

• Формат верный?    • Текст связный?    • На новых входах
• Ссылки из входа?  • Тема раскрыта?    • Edge cases
• Нет запрещённых   • Нет повторов?     • A/B тесты
  слов?

Скорость: мс        Скорость: сек       Скорость: мин
Стоимость: 0        Стоимость: ~$0.01   Стоимость: ~$0.10

Уровень 1 — самый важный. Обычные assert-ы: текст заканчивается хештегом, нет @упоминаний, все URL из входных данных, нет markdown в HTML. Работает мгновенно и ловит большинство проблем.

У меня три таких теста. Первый проверяет что в дайджесте нет ни одного URL, которого не было во входных данных — ловит галлюцинации. Второй — что каждая тема ведёт на правильный тред. Третий — что текст ссылки похож на реальный заголовок страницы, а не на выдумку модели.

Уровень 2 — когда правила не формализуешь. “Текст должен быть интересным” — это не assert. Зато другая LLM может оценить по шкале 1-5.

Промпт для LLM-судьи: “Оцени дайджест от 1 до 5 по критериям: конкретность (цифры, названия, а не ‘обсудили проблемы’), связность (темы не повторяются), полезность (читатель узнал что-то новое). Верни JSON с оценками и объяснением.”

Уровень 3 — прогон на реальных данных. Не на фикстурах, а на свежих сообщениях из чата. Тут видно как модель справляется с необычным входом: пустой день, 500 сообщений, сплошные мемы без текста.

Как я начал

Никаких фреймворков. Обычный pytest.

Сначала я сохранил пару реальных входов-выходов. Вход — JSON с темами для генерации. Выход — что модель реально выдала. Это стали мои фикстуры.

Потом попросил агента написать три проверки на то, что точно не должно случиться:

Три стартовых eval-а для любого LLM-проекта: (1) выход не содержит данных, которых не было на входе — ловит галлюцинации; (2) формат соответствует ожиданиям — ловит сломанный вывод; (3) длина в допустимых пределах — ловит обрезание и раздувание.

Теперь после каждого изменения промпта я прогоняю eval-ы и вижу что сломалось.

Всё. Это уже eval-система.

Eval-Driven Development

Как TDD, только для промптов. Сначала определяешь что “правильно”. Потом пишешь промпт. Потом проверяешь.

1. Определи критерии       "Ссылки не должны быть выдуманными"
       │
2. Напиши eval             assert all_urls_from_input(output)
       │
3. Прогони                 FAIL — 3 галлюцинированных URL
       │
4. Поправь промпт          "Используй ТОЛЬКО ссылки из входных данных"
       │
5. Прогони снова           PASS

Без eval правишь промпт вслепую. С eval — видишь что конкретно сломалось и что починилось. По-моему, это единственный способ итерировать на промптах без потери рассудка.

Ловушка: исправлять за агентом вместо проверки

Когда я увидел что агент выдумывает названия ссылок, первая мысль была — добавить постобработку, которая автоматически подставляет правильные названия после генерации. Агент пишет что угодно, а пайплайн потом молча исправляет.

Я так и сделал. Все проверки сразу стали зелёными. Ноль ошибок. Идеально.

А потом дошло: я проверяю не агента, а свою заплатку. Это как если учитель проверяет домашку, но перед проверкой секретарь исправляет все ошибки. Оценка всегда пять, но ученик не стал лучше — и ты этого не видишь.

Eval должен видеть то, что агент выдал на самом деле — до любых автоисправлений. Иначе ты не узнаешь, стал ли промпт лучше или хуже.

Автоисправления — это страховка для публикации. Eval — для понимания, как работает агент. Одно не заменяет другое.

Почему это важно именно сейчас

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

В 2024 году Air Canada проиграла суд: их чатбот выдумал правила скидок на перелёт для родственников умерших. Пассажир поверил, купил билет, а потом ему отказали в возврате. Суд решил — авиакомпания отвечает за всё, что пишет её бот. CNET в том же духе: публиковали AI-статьи, в которых больше половины потребовали исправлений после ручной проверки.

У обоих одна причина: никто не проверял выход автоматически. Правила в CLAUDE.md предотвращают известные ошибки. Eval-ы ловят новые.

Что дальше

Я начал с уровня 1. Три детерминированных проверки — и сразу поймал галлюцинации в ссылках, которые пропускал глазами.

Следующий шаг — LLM-судья для качества текста. Потом прогон на реальных данных.

Одна проверка лучше нуля.

Источники

Подписаться на обновления — @sereja_tech