Покомпонентные evals: минимальный набор
Почему end-to-end метрики мало
Заголовок раздела «Почему end-to-end метрики мало»Success rate упал с 85% до 72%. Само число не объясняет, что случилось: сломался retrieval, модель хуже выбирает инструменты, контекст загрязняется после нескольких ходов или система упёрлась в возможности базовой модели. Команда начинает гадать, а с ростом проекта сбои складываются мультипликативно.
Покомпонентные evals дополняют end-to-end картину: показывают, какой слой работает, какой деградировал и где искать причину. Ниже — базовый набор, который внедряется минимальными затратами: для каждой проверки нужны задачи и способ оценки, а не платформа.
Семь проверок
Заголовок раздела «Семь проверок»1. Точность retrieval
Заголовок раздела «1. Точность retrieval»Что проверяет. Достаёт ли система нужные документы и чанки, нет ли мусора в топе.
Как собрать. 20–50 вопросов, для которых заранее известны релевантные источники в индексе. Для каждого запроса — top-k и три вопроса: попал ли правильный чанк в первые 3–5, сколько нерелевантного в топе, не вытеснил ли его похожий, но чужой документ.
Провал. Правильный источник отсутствует в top-k или присутствует ниже мусора. Дальше чинится не генерация, а поиск: Поиск и reranking.
2. Схема вызова инструментов
Заголовок раздела «2. Схема вызова инструментов»Что проверяет. Правильно ли модель вызывает инструменты.
Как собрать. Набор задач, где ожидается конкретный вызов. Проверяется не текст ответа, а сам вызов: имя инструмента, обязательные параметры, типы, отсутствие лишних полей, корректный формат значений.
Провал. Не тот инструмент, пропущенный обязательный аргумент, строка вместо числа, лишнее поле, ломающее строгую схему.
3. Консистентность состояния
Заголовок раздела «3. Консистентность состояния»Что проверяет. Не расходится ли представление модели о системе с фактическим состоянием.
Как собрать. Длинный сценарий на 10–20 действий. Периодически сравниваются три слоя: что агент считает сделанным, что реально произошло в системе, что должно было получиться по плану. Проверка особенно важна для stateful-доменов: документы, workflow, графы, корзины, заявки.
Провал. Агент ссылается на несуществующий объект, пересоздаёт уже созданное, объявляет готовым незавершённое. Это класс сбоев, разобранный в Сбоях обвязки.
4. Ретраи и распространение ошибок
Заголовок раздела «4. Ретраи и распространение ошибок»Что проверяет. Как система ведёт себя при сбоях.
Как собрать. Искусственно вернуть ошибки, свойственные системе: ошибку валидации, permission denied, not found, таймаут. Проверить три вещи: делается ли ретрай на временной ошибке, не делается ли он на неретраябельной, доходит ли ошибка до модели в понятном виде.
Провал. Тихий повтор, повтор запрещённой операции, ошибка, превращённая в пустой успешный результат.
5. Валидация структурированного вывода
Заголовок раздела «5. Валидация структурированного вывода»Что проверяет. Возвращает ли агент ответ в ожидаемой схеме.
Как собрать. Задачи с явно заданной схемой ответа; проверка парсером и валидатором. Отдельно проверяется поведение при невалидном ответе: ошибка должна быть видна агенту и содержать причину.
Провал. Битый JSON, отсутствующее обязательное поле, ошибка парсера, скрытая от агента. Успешная валидация схемы при этом доказывает только разбираемость ответа, а не его правильность.
6. «Не знаю»
Заголовок раздела «6. «Не знаю»»Что проверяет. Умеет ли агент отказаться, когда данных недостаточно, и не выдумывает ли при конфликте источников.
Как собрать. Вопросы без ответа в доступном контексте и вопросы с противоречивыми данными. Ожидаемое поведение: отказ с причиной или уточняющий вопрос, а не правдоподобная догадка.
Провал. Уверенный ответ по памяти модели, когда в контексте ответа нет, или выбор одного из конфликтующих источников без оговорки.
7. Сравнение моделей
Заголовок раздела «7. Сравнение моделей»Что проверяет. Является ли модель узким местом.
Как собрать. Один и тот же набор прогоняется на разных моделях без изменений в коде обвязки. Сравнивается не только общий результат, но и разбивка по компонентам.
Провал. Не сам провал, а вывод по нему: небольшой прирост при кратном росте стоимости означает, что чинить нужно обвязку, а не покупать модель. Подробнее — Модель или обвязка.
Как выглядит кейс
Заголовок раздела «Как выглядит кейс»Датасет — обычный JSONL: вход, ожидаемое поведение и тип проверки. Такой формат читается и кодом, и человеком, а новые кейсы добавляются одной строкой.
{"id": "refund-001", "input": "Верни деньги за заказ 4411", "expect": {"tool": "refund.create", "args": {"order_id": "4411", "amount": "full"}}, "check": "tool_call"}{"id": "unknown-014", "input": "Какая гарантия на товар из удалённого каталога?", "expect": {"behavior": "clarify"}, "check": "refusal"}{"id": "state-007", "input": "Создай заявку и приложи два файла", "expect": {"steps_max": 8, "final_state": "ticket_with_two_files"}, "check": "state_consistency"}Раннер прогоняет датасет и падает на конкретном кейсе с указанием компонента — это и есть диагностика:
import jsonimport pytest
from harness import run_case
CASES = [json.loads(line) for line in open("evals/agent-tasks.jsonl")]
@pytest.mark.parametrize("case", CASES, ids=lambda c: c["id"])def test_component(case): result = run_case(case["input"])
if case["check"] == "tool_call": assert result.tool_name == case["expect"]["tool"] assert result.tool_args.items() >= case["expect"]["args"].items() elif case["check"] == "refusal": assert result.behavior == "clarify" assert not result.hallucinated_answer elif case["check"] == "state_consistency": assert result.steps <= case["expect"]["steps_max"] assert result.final_state == case["expect"]["final_state"]Детерминированно, где возможно
Заголовок раздела «Детерминированно, где возможно»Все семь проверок выше можно закрыть программно: сравнение имени инструмента, наличие поля, состояние в базе, число шагов. Это предпочтительный путь — судья вносит смещение и стоимость.
LLM-судья остаётся там, где критерий нельзя выразить формально: полезность формулировки, уместность тона, полнота объяснения. Даже там лучше просить не оценку «1–10», а решение по пунктам рубрики.
Размер и каденция
Заголовок раздела «Размер и каденция»- Smoke на каждый pull request — 20–50 кейсов, быстрые проверки. Этого достаточно, чтобы увидеть регрессию до продукта.
- Полный набор ночью — все компоненты, длинные сценарии, сравнение моделей.
- Пополнение из production — каждый разобранный инцидент становится кейсом с конкретным типом проверки.
Набор растёт не по фантазии, а из реальных сбоев. Кейс, добавленный после инцидента, защищает именно от повторения этого инцидента.
Таблица диагностики
Заголовок раздела «Таблица диагностики»| Сигнал | Вероятный компонент | Что смотреть |
|---|---|---|
| Ответ уверенный, но не по тем источникам | Retrieval | top-k, чанки, реранкинг |
| Неверный инструмент или аргументы | Описания инструментов, схема | Пересечение семантики, типы параметров |
| Задача «выполнена», но ничего не изменилось | Консистентность состояния | Терминальные условия, передача состояния |
| Ошибка исчезла, результат испорчен | Ретраи | Логи попыток, классификация ошибок |
| Пустой ответ без ошибки | Валидация вывода | Парсер, обработка исключений |
| Правдоподобная выдумка при нехватке данных | Отказ | Наличие ветки «не знаю» |
| Смена модели почти не меняет результат | Обвязка | Все слои выше |
Что проверить в проекте
Заголовок раздела «Что проверить в проекте»- Покрыт ли retrieval отдельным набором. Иначе качество поиска оценивается через ответы генерации.
- Проверяются ли аргументы инструментов. Имя инструмента — только половина контракта.
- Есть ли длинные сценарии. Короткие кейсы не показывают дрейф состояния.
- Видна ли ошибка парсера агенту. Скрытая ошибка превращается в уверенный пустой ответ.
- Добавляются ли кейсы после инцидентов. Иначе набор не отражает вашу систему.
Материалы и источники
Заголовок раздела «Материалы и источники»- Evals для чайников. Как тестировать AI-агента, чтобы понимать, где именно он ломается — Артем Тарасов, минимальный набор evals
- Почему ломается ваш AI-агент — и почему смена модели обычно его не чинит — Артем Тарасов, state-drift и контракты инструментов
- Anthropic: Demystifying evals for AI agents