Эвалуация ИИ-агентов в продакшене: от трейсов к тестовым наборам
Автоматический перевод Эта статья была автоматически переведена с оригинальной английской версии.
Финальный ответ может утверждать, что возврат средств выполнен, хотя из трейса видно, что verify_identity ни разу не запускался, issue_refund повторился 17 раз или агент объявил об успехе до изменения базы данных. Грейдинг только по ответу скрывает такие сбои.
Для инженеров, которые эксплуатируют агентов с tool use в продакшене, решение — превращать воспроизводимые трейсы в ограниченные регрессионные кейсы: детерминированные проверки контролируют порядок вызовов инструментов, аргументы, циклы и инварианты; калиброванные джаджи обрабатывают решения, требующие интерпретации. В результате появляется версионируемый тестовый набор, который выявляет тот же сбой до следующего релиза.
Краткое сравнение инструментов см. в статье Лучшие инструменты для эвалуации ИИ-агентов.
Чем эвалуация агентов отличается
Традиционные эвалы LLM обычно оценивают одну пару «ввод-вывод»: релевантность, faithfulness, корректность, безопасность, иногда стиль. Агенты добавляют планирование, tool calls, ретраи и проверки завершения, поэтому каждый шаг становится новой точкой отказа.
Возьмём агента для возврата средств. Транскрипт может завершиться хорошо, а трейс при этом быть неправильным:
lookup_order -> issue_refund -> final_answer
Эвалуация вывода пройдёт. Эвалуация траектории должна завершиться ошибкой, потому что verify_identity не запускался до issue_refund. Для агентов с tool use эвалы только по ответу — это smoke-тесты: они выявляют полный отказ и пропускают почти всё остальное.
Есть и вторая проблема: ошибки накапливаются. Если в workflow есть 20 обязательных шагов, каждый выполняется независимо, а надёжность каждого составляет 95%, то сквозная вероятность успеха будет около 36%:
Таким образом, агент может хорошо выглядеть в изолированных проверках и при этом проваливать большинство полных запусков. Сбой обычно происходит где-то в середине, и найти его можно только при видимости на уровне компонентов, а не ещё одним просмотром ответа.
Две исследовательские команды выразили это в цифрах.
tau-bench даёт агенту задачи из авиаперевозок и розничного клиентского сервиса. Агент общается с симулированным пользователем, вызывает APIs и должен соблюдать доменную политику. После диалога грейдер проверяет, пришла ли база данных к размеченному целевому состоянию. Правдоподобный транскрипт с неправильными строками всё равно считается провалом.
При таком грейдинге GPT-4o решал только 35,2% задач авиаперевозок и немногим более 60% задач розничного сервиса. В статье также введён pass^k: запускать одну и ту же задачу k раз и засчитывать проход только в том случае, если агент успешно справился во всех k запусках.
В более простой категории — розничном сервисе — результат опускался ниже 25% при k = 8. Более чем в трёх четвертях этих задач один и тот же агент, получая одну и ту же задачу восемь раз, терпел неудачу хотя бы однажды. Эвалуация одного запуска не выявит такую нестабильность.
MAST исследует причины сбоев агентов. Авторы построили таксономию из 14 типов на основе 150 размеченных вручную трейсов, а затем применили её к более чем 1 600 трейсами из 7 популярных мультиагентных фреймворков. В таксономию входят расплывчатые определения ролей (системный дизайн), игнорирование одним агентом сообщения другого (межагентная рассогласованность) и объявление об успехе без проверки результата (отсутствие верификации). Эти сбои указывают на проблемы в промптах, логике оркестрации и отсутствии проверок в харнессе. Более сильная базовая модель не сможет выполнить шаг верификации, которого никто не добавил, поэтому объект эвалуации должен включать харнесс вокруг модели.
Разрыв между внедрением и эвалуацией
Опрос LangChain State of Agent Engineering (1 340 респондентов, проведён в конце 2025 года) показывает, что у многих команд уже есть исходные данные для более качественной эвалуации. Согласно опросу, у 89% была хотя бы какая-то observability, 52,4% запускали офлайн-эвалы, а 37,3% — онлайн-эвалы.
Опрос также сообщает, что 57,3% респондентов уже используют агентов в продакшене. На вопрос о препятствиях для выхода в продакшен 32% назвали качество, а 20% — латентность. Это опрос пользователей конкретного вендора, а не перепись всех команд, работающих с агентами, однако он хорошо показывает разрыв между сбором трейсов и систематической эвалуацией.
Команды оказываются в неудобном промежуточном состоянии: они могут постфактум изучить неудачный запуск, а затем дважды выпустить в продакшен тот же сбой.
Каждый диагностированный продакшен-сбой должен оставлять после себя трейс, метку, строку датасета и скорер. Воспроизводимый сбой должен попасть в регрессионный набор.
Выбирайте метрики по типу сбоя
Правильная метрика зависит от типа сбоя, а не от фреймворка. Полезно разделять эвалуацию на три уровня:
- Эвалы результата отвечают на вопрос, успешно ли выполнена задача.
- Эвалы траектории отвечают на вопрос, был ли путь корректным, эффективным и соответствующим политике.
- Эвалы компонентов показывают, какой инструмент, retrieval, субагент или шаг принятия решения сломался.
Каждый уровень можно запускать офлайн на фиксированных воспроизводимых кейсах до релиза или онлайн на выбранных продакшен-трейсах после формирования ответа. Раздел о гардрейлах ниже подробно описывает это различие. Для офлайн-эвала могут потребоваться goldens: сохранённые кейсы, где вход сопоставлен с результатом, инвариантами инструментов и аргументами, которые должен выдать корректный запуск. Онлайн-эвалы должны отдавать предпочтение инвариантам, распределениям и асинхронным проверкам, которые не блокируют обработку запроса.
| Вопрос | Семейство метрик | Контракт офлайн / онлайн | Детерминированная проверка или джадж? | На что обратить внимание |
|---|---|---|---|---|
| Вызвал ли агент правильные инструменты? | Корректность инструментов: точное совпадение, совпадение по порядку или в любом порядке | Точные goldens офлайн; инварианты обязательных инструментов и аномалии онлайн | Детерминированная | Точное совпадение наказывает допустимые альтернативные пути |
| Передал ли он правильные входные данные? | Корректность аргументов, валидация схемы, совпадение параметров | Ожидаемые аргументы офлайн; проверки схемы, диапазона и политики онлайн | Оба | Правильный инструмент с неправильными аргументами всё равно означает сбой |
| Не делал ли он лишних шагов? | Эффективность шагов, число ретраев, детекция циклов, стоимость и латентность | Бюджеты шагов и циклов офлайн; дрейф стоимости и латентности онлайн | В основном детерминированная | Высокий процент выполнения может скрывать дорогие блуждания |
| Действительно ли задача выполнена? | Завершение задачи, грейдинг результата, diff финального состояния | Симулятор или golden state офлайн; финальное состояние, сигнал пользователя или асинхронный джадж онлайн | Джадж или проверка состояния | По возможности оценивайте состояние среды |
| Сохранил ли он контекст между ходами? | Точность в многоходовом диалоге, соблюдение роли, полнота разговора | Сценарные долгие кейсы офлайн; выборочные длинные сессии онлайн | Джадж | Одноходовые тесты ничего не говорят о 14-м ходе |
| Остановился ли он вовремя? | Корректность завершения, преждевременный успех, бесконечная работа | Сценарные тесты офлайн; онлайн-мониторы циклов, таймаутов и ложного успеха | Оба | «Готово» может быть галлюцинированным состоянием |
| Правильно ли он интерпретировал результаты инструментов? | Понимание результатов инструментов, проверки состояния на следующих шагах | Адверсариальные результаты инструментов офлайн; проверки downstream-состояния и выборочная проверка онлайн | Оба | Оценивайте downstream-состояние, а не exit code инструмента |
Начинайте с детерминированных метрик. Они дешёвые, быстрые и не дрейфуют.
Корректность tool calls
Корректность инструментов сравнивает вызванные инструменты с ожидаемыми. Заранее выберите нужную строгость:
- Точное совпадение: последовательность должна совпасть полностью. Используйте этот вариант, когда порядок задан политикой, например
lookup_order -> verify_identity -> issue_refund. - Совпадение по порядку: обязательные инструменты должны встретиться в правильном относительном порядке, но дополнительные безвредные вызовы разрешены.
- Совпадение в любом порядке: обязательные инструменты должны встретиться, но их порядок может отличаться.
Для начала достаточно небольшого локального скорера:
from collections import Counter
def tool_correctness(called: list[str], expected: list[str], mode: str = "in_order") -> float:
if not expected:
return 1.0
if mode == "exact":
return float(called == expected)
if mode == "any_order":
matched = sum((Counter(called) & Counter(expected)).values())
return matched / len(expected)
rows = [[0] * (len(expected) + 1) for _ in range(len(called) + 1)]
for i, tool in enumerate(called):
for j, wanted in enumerate(expected):
if tool == wanted:
rows[i + 1][j + 1] = rows[i][j] + 1
else:
rows[i + 1][j + 1] = max(rows[i][j + 1], rows[i + 1][j])
return rows[-1][-1] / len(expected)
called = ["lookup_order", "check_refund_policy", "issue_refund"]
expected = ["lookup_order", "verify_identity", "issue_refund"]
print(round(tool_correctness(called, expected, "exact"), 3)) # 0.0
print(round(tool_correctness(called, expected, "in_order"), 3)) # 0.667
Метрика in_order — это recall по longest-common-subsequence: какая доля обязательной последовательности сохранилась в правильном порядке. Обратите внимание, чего она не учитывает. Лишние вызовы не снижают результат, поэтому агент может получить здесь 1,0, сделав вдвое больше вызовов, чем нужно. Если дополнительные вызовы стоят денег или изменяют состояние, отслеживайте также precision — долю совпавших обязательных вызовов от общего числа вызовов — и интерпретируйте эти две метрики вместе. Recall выявляет пропущенный шаг, а precision — блуждание.
Метрика Tool Correctness в DeepEval предоставляет те же настройки через should_consider_ordering и should_exact_match.
Корректность аргументов
Правильный инструмент с неправильными аргументами часто хуже неправильного инструмента, потому что такой трейс выглядит нормальным.
В простых случаях валидируйте JSON Schema и точные значения. Для семантических случаев сохраняйте ожидаемые аргументы и оценивайте отличия:
{
"trace_id": "tr_2417",
"input": "Reschedule order A-100 for next Friday.",
"expected_tools": ["lookup_order", "reschedule_delivery"],
"expected_arguments": {
"reschedule_delivery": {
"order_id": "A-100",
"date": "2026-06-19"
}
}
}
Метрика по имени инструмента не обнаружит 2026-06-17, если политика требует 2026-06-19. Датасет должен хранить и аргументы.
Связанная с этим датасетом метрика — совпадение параметров: доля ожидаемых троек (tool, key, value), которые агент передал правильно.
def argument_correctness(called_args: dict, expected_args: dict) -> float:
total = matched = 0
for tool, params in expected_args.items():
for key, want in params.items():
total += 1
if called_args.get(tool, {}).get(key) == want:
matched += 1
return matched / total if total else 1.0
Точное равенство подходит для ID, enum-значений и дат, уже нормализованных к одному формату. Оно не подходит для свободного текста, float-значений и дат в произвольном формате, где == пометит правильный ответ как неправильный. Для таких полей используйте соответствующий компаратор: сравнение нормализованных строк, парсинг дат или числовой допуск. Метрика остаётся той же, меняется только компаратор конкретного поля.
Эффективность, циклы и тупиковые пути
Агент, который выполняет задачу после пяти избыточных вызовов инструментов, всё равно указывает на проблему планирования и обходится дороже.
Начните со следующих дешёвых сигналов:
- Доля повторных вызовов: идентичные вызовы одного инструмента с одинаковыми аргументами, повторённые более двух раз.
- Аномалии формы трейса: резкие всплески глубины, числа tool calls, количества токенов, латентности или стоимости.
- Сходимость пути: насколько запуск близок к кратчайшему известному корректному пути для задачи.
- Корректность завершения: остановился ли агент слишком рано, продолжил ли работу после успеха или объявил об успехе без обязательного изменения состояния.
- Следование плану: если агент пишет план до начала действий, проверяйте, следовал ли ему трейс. Хороший план, которому не следуют, и плохой план, которому следуют идеально, одинаково означают провал, но по разным причинам; разница между планом и трейсом показывает, какая именно проблема произошла.
По возможности запускайте эти проверки до джаджа. Детектор циклов — это несколько строк кода над трейсом. Модель ему не нужна.
Завершение задачи и грейдинг результата
При оценке результата вопрос звучит так: «Получил ли пользователь то, что просил?»
Лучше всего работают два подхода:
- Грейдинг завершения задачи без референса: извлечь цель из входных данных и оценить, достигли ли её трейс вместе с финальным ответом. Этот подход подходит для онлайна, потому что в продакшен-трафике редко есть golden outputs.
- Грейдинг состояния среды: сравнить финальные строки базы данных, файлы, тикеты, бронирования или записи с размеченным целевым состоянием. Это надёжнее сопоставления транскриптов, потому что агент может найти допустимый путь, который вы не предусмотрели явно.
Второй вариант лучше, если его можно построить. Финальное состояние — это контракт. Транскрипт — лишь свидетельство.
Есть два ограничения. Аудит агентных бенчмарков за 2025 год показал, что tau-bench оценивает некоторые задачи исключительно по состоянию базы данных. В отдельных задачах размеченный результат не требует ни изменения состояния, ни конкретного текста. Тогда агент, который ничего не делает, может получить проход: 38% в категории авиаперевозок и 6,0% в розничном сервисе при любом k. Anthropic сообщила о запуске Opus 4.5, который «провалил» задачу бронирования в tau2-bench, следующем бенчмарке. Агент нашёл лазейку в политике, которая на деле давала пользователю лучший результат. Грейдинг состояния лучше сопоставления транскриптов, но целевое состояние всё равно является разметкой, а в разметке бывают ошибки. Аудируйте кейсы, которые проходят слишком легко, а не только те, что завершаются провалом.
Эвалы компонентов
Метрики результата и траектории показывают, что запуск провалился, и примерно указывают где. Эвалы компонентов оценивают один спан: релевантен ли найденный чанк, вернул ли субагент схему, которую ожидал вызывающий код, распарсился ли собственный ответ инструмента. Привязывайте оценку к спану, а не к запуску, чтобы вопрос «какой инструмент деградировал на этой неделе» решался запросом, а не повторным прогоном.
Большинство задач покрывают три проверки:
- Оценка каждого спана: запускайте метрику, подходящую типу спана. Retrieval-спаны получают recall и precision относительно размеченного чанка, спаны субагентов — валидацию схемы и собственную оценку корректности инструментов, спаны инструментов — error rate и латентность.
- Интерпретация результатов инструментов: передавайте агенту корректный, но неудобный вывод инструмента — пустой список, частичное совпадение или устаревший timestamp — и проверяйте его следующий шаг. Инструмент может работать правильно, а агент — неправильно читать его результат; такой сбой проявится через два шага.
- Атрибуция сбоя: видимый сбой обычно находится downstream от настоящей причины. Относите его к самому раннему спану, вывод которого уже был неправильным, а не к шагу, на котором возникла ошибка.
Здесь особенно полезна математика накопления ошибок из начала статьи. Даже если все 20 шагов выглядят хорошо по отдельности, запуск всё равно может чаще проваливаться, чем завершаться успешно. Pass rate по спанам показывает, какой шаг работает с надёжностью 95%, а какой — 70%.
Маховик «от трейса к эвалу»
Сначала извлекайте из продакшена реальные сбои, а уже потом придумывайте дополнительные кейсы.
Цикл:
- Собрать полный трейс.
- Разметить причину сбоя.
- Сгруппировать похожие сбои.
- Оставить по одному репрезентативному golden на кластер.
- Версионировать датасет.
- Запускать его в CI.
- Продолжать оценивать выбранные продакшен-трейсы онлайн.
Сопутствующий репозиторий trace2evals реализует полный цикл для неисправного саппорт-агента. Он собирает GenAI-спаны OpenTelemetry, обнаруживает сбои с помощью детерминированных правил, дедуплицирует кейсы в версионируемый golden-датасет и повторно прогоняет каждый golden в CI. Бэкенд по умолчанию заменяет модель детерминированными правилами, воспроизводящими решения неисправного агента, поэтому make demo воспроизводит весь цикл офлайн без API key. Выполните uv sync --extra live и задайте API key — те же команды начнут использовать реальную модель.
Ищите сбои с помощью error analysis
Hamel Husain и Shreya Shankar предлагают workflow error analysis именно для этого этапа; в практическом руководстве Hamel он разобран пошагово. Первые два шага заимствуют названия из качественных исследований, но сам метод прост: читайте трейсы, делайте заметки, называйте паттерны.
- Открытое кодирование: прочитайте 30–50 реальных трейсов и в свободной форме запишите, что пошло не так.
- Осевое кодирование: сгруппируйте заметки в 5–6 именованных категорий сбоев.
- Разметьте всё по этой таксономии.
- Постройте метрики для самых крупных категорий.
Не начинайте с меток вроде reasoning_issue или tool_problem. Они слишком расплывчаты для тестирования. Используйте метки вроде missing_identity_verification, date_argument_mismatch, retried_same_tool_after_429 или stopped_before_database_update. Настолько конкретная метка сразу подсказывает, что именно должен проверять регрессионный тест.
Дедуплицируйте до добавления в набор
У цикла извлечения кейсов из трейсов есть ловушка: можно бесконечно добавлять каждый плохой трейс. В результате датасет станет большим, дорогим и узким. Он будет проходить почти дубликаты из марта, но пропустит новую форму того же бага в июне.
Сначала группируйте. Добавляйте по одному репрезентативному golden на кластер. Сохраняйте ID связанных трейсов в метаданных, чтобы ревьюер позднее мог изучить продакшен-доказательства.
Если после исправления снова появляется кластер того же сбоя, регрессионный кейс не обобщился. Перекластеризуйте данные и расширьте golden вместо добавления 15 точечных примеров.
Версионируйте датасет
Версионируйте датасеты так же, как промпты и код. При любом существенном изменении — модели, промпта, схемы инструмента, промпта джаджа или поведения приложения — нужно запускать одну и ту же версию датасета до и после изменения.
CI-гейт должен фиксировать:
- версию датасета;
- версию приложения;
- версию промпта;
- модель джаджа;
- промпт джаджа;
- версию кода эвалуатора.
Если что-то из этого меняется, сравнение до и после становится нечётким. Небольшой файл goldens-v3.json в git вполне подходит на начальном этапе. Нативные снапшоты инструментов в Langfuse, Phoenix, Braintrust или LangSmith пригодятся, когда датасет станет совместным ресурсом.
Добавьте CI-гейт
Метрика со статусом fail должна превращаться в падение сборки, иначе набор эвaлов останется просто дашбордом, который никто не читает.
Тест должен заново запускать текущего агента на golden-входе. Он не должен просто воспроизводить старый упавший трейс (эскиз; рабочая версия находится в сопутствующем репозитории):
@pytest.mark.parametrize("golden", GOLDENS, ids=[item["id"] for item in GOLDENS])
def test_agent_regression(golden: dict) -> None:
answer, fresh_trace = run_agent_and_capture_trace(golden["input"])
refired = set(flag_failures(fresh_trace)) & set(golden["failure_modes"])
assert not refired, f"failure mode regressed: {sorted(refired)}"
assert tool_correctness(
called=[call["name"] for call in fresh_trace["tool_calls"]],
expected=golden["expected_tools"],
mode=golden.get("tool_match", "in_order"),
) >= golden.get("tool_threshold", 1.0)
Эту разницу легко упустить. Задача датасета — поймать следующую версию агента, которая повторяет старый сбой, а не архивировать сам сбой.
Калибруйте джаджа, прежде чем ему доверять
LLM-as-judge помогает. Но с ним легко обмануться самому.
G-Eval оценивает три бенчмарка мета-эвалуации. Это SummEval, построенный на суммаризации новостей CNN/DailyMail; Topical-Chat, бенчмарк диалогов с grounding по знаниям; и QAGS, проверяющий фактическую согласованность саммари CNN/DailyMail и XSum. Используя GPT-4 как backbone, G-Eval-4 достиг коэффициента корреляции Спирмена 0,514 с человеческими оценками на SummEval. Его функция оценки взвешивает уровни рейтинга по вероятности токенов ().
В статье вероятность токенов GPT-4 оценивалась 20-кратной выборкой, поскольку в эксперименте модель их не предоставляла. Hosted-модель может не давать пригодные logprobs, поэтому сохраняйте рубрику, но не создавайте впечатление, будто вы воспроизвели взвешивание вероятностей из статьи. Эти результаты сравнивают протокол статьи с её NLG-бейзлайнами на указанных бенчмарках. Они подтверждают необходимость тестировать джадж с явной рубрикой, но не доказывают, что он в целом заменяет автоматические метрики или бенчмарк траекторий агентов в продакшене.
MT-Bench показал, что GPT-4 соглашался с человеческими предпочтениями примерно так же часто, как люди соглашались друг с другом. Этот результат помог сделать LLM-грейдинг массовым. Последующие работы выявили смещения по позиции, длине и самопредпочтению. Оценки джаджа также могут меняться при изменении промпта или версии модели.
JudgeBench построил пары ответов, в которых один ответ объективно неверен в задачах на проверяемые знания, ризонинг, математику и код. С простым промптом джаджа GPT-4o набрал 50,9% — едва выше случайного угадывания; более сильный промпт Arena-Hard из статьи поднял результат той же модели лишь до 56,6%. Замена модели под этим сильным промптом важнее: Claude 3.5 Sonnet, лучший из протестированных джаджей общего назначения, достиг 64,3%, а o3-mini при высоком усилии ризонинга — 80,9%. Уверенные, но неправильные ответы по-прежнему трудно оценивать джаджу, который не выполняет ризонинг до выставления оценки.
Относитесь к джаджу как к измерительному прибору: сначала откалибруйте его по человеческой разметке, а затем перепроверяйте каждый раз при изменении модели или промпта джаджа.
Когда джадж необходим, делайте вердикт структурированным. Schema-Guided Reasoning (SGR) задаёт схему формы и проверяемости вывода. Structured Outputs или constrained decoding могут принудительно обеспечить форму объекта, обязательные поля и ограничения значений для таких полей, как evidence, passed_criteria, failed_criteria, failure_mode и score.
Если так запись легче проверять, размещайте поля с доказательствами перед оценкой. Порядок полей — это представление данных, а не гарантия процесса ризонинга. Вердикт, соответствующий схеме, всё ещё может содержать неподтверждённые доказательства или ненадёжную оценку. Проверяйте надёжность джаджа с помощью калибровки по человеческой разметке, детерминированных валидаторов и ревью транскрипта. CI может сравнивать стабильный JSON-объект, но это проверяет проверяемость и форму, а не доказывает соблюдение этапов рубрики.
Структурированный вердикт также может изменить кривую стоимости. Рассматривайте более дешёвую модель как кандидата, а не как автоматическую замену. Прогоните её на том же калибровочном наборе с человеческой разметкой. Сравните agreement, false-pass rate и false-fail rate с более крупным джаджем. Используйте её для рутинных кейсов только при прохождении порогов, заданных вашим приложением. Более крупного джаджа оставляйте для разногласий, рискованных кейсов или калибровочных прогонов.
Чек-лист гигиены джаджа по умолчанию:
- По возможности используйте бинарный pass/fail. Пятибалльные шкалы создают иллюзию точности.
- Разметьте вручную 30–50 траекторий до подготовки финальной рубрики.
- Измеряйте согласие джаджа с людьми с помощью каппы Коэна, confusion matrix и recall для положительного и отрицательного классов. Джадж, который всегда отвечает «pass», не умеет различать классы; каппа может быть равна нулю или не определена, если знаменатель ожидаемого согласия равен нулю. До использования метрики как гейта деплоя задайте явную политику для неопределённой каппы.
- Декомпозируйте общие критерии. «Проверил ли агент личность перед вызовом инструмента возврата средств?» лучше, чем «Была ли траектория хорошей?»
- Выдавайте вердикт через SGR-схему с доказательствами, невыполненными критериями, типом сбоя и оценкой.
- По возможности используйте джаджа из другого семейства моделей, чем генератор.
- Рандомизируйте порядок пар и усредняйте результаты в обоих направлениях.
- Штрафуйте неподкреплённую длину в рубрике. Более длинный ответ не обязательно лучше.
- Фиксируйте модель джаджа, промпт, датасет, схему и версию приложения.
- Повторно калибруйте джаджа после изменений модели, промпта, инструмента, политики или схемы.
Для high-stakes оценок используйте небольшое жюри вместо одного большого джаджа. PoLL протестировал панель небольших джаджей из непересекающихся семейств моделей и агрегировал их вердикты. На шести датасетах панель лучше соответствовала человеческим оценкам, чем один джадж GPT-4. Кроме того, она избегала bias самопредпочтения единственного джаджа и стоила более чем в семь раз дешевле. Сохраняйте human review для решений, влияющих на деньги, доступ, безопасность или compliance.
Если на вашей задаче джадж согласуется с людьми с каппой 0,55, не используйте его для блокировки деплоев. Применяйте его для сортировки очередей на ревью. Если значение близко к 0,75, а стоимость сбоя умеренная, CI-гейт значительно проще обосновать.
Гардрейлы блокируют запросы, онлайн-эвалы наблюдают после ответа
Люди путают эти механизмы, потому что оба выдают оценки. Разница в размещении: inline в пути запроса, до релиза или после ответа.
Гардрейлы работают inline. Они быстрые и заметны пользователю. Гардрейл может заблокировать вызов инструмента, замаскировать PII, отклонить промпт-инъекцию или инициировать ретрай до того, как ответ покинет систему. False positive — это продакшен-баг. False negative тише и опаснее, потому что путь запроса не сообщает о пропуске. Проверки схемы, диапазона и политики детерминированы. Детекция инъекций и PII выполняется классификаторами, поэтому промахи неизбежны; оставляйте асинхронный эвал, который отслеживает, что они пропустили.
Офлайн-эвалы запускаются до релиза. Они воспроизводимы и проверяют промпты, модели, инструменты, retriever-ы и политики на фиксированном датасете.
Онлайн-эвалы запускаются после ответа, обычно на выборочном трафике. Они могут использовать более медленные LLM-джаджи, поскольку не находятся на пути обработки запроса. Их задача — обнаруживать дрейф, находить новые кластеры сбоев и возвращать их в следующий офлайн-датасет.
Неправильное размещение вредит в обоих случаях:
- Джадж на пути запроса добавляет латентность и новый источник нестабильности.
- Гардрейл, переведённый в асинхронный режим, позволяет нарушениям политики дойти до пользователей.
В системах с большим объёмом трафика оценивайте небольшую выборку сильным джаджем, а более широкую — дешёвыми классификаторами. Подавайте алерты по кластерам и доверительным интервалам, а не по одной шумной точечной оценке.
Выбор инструментов
Ни один инструмент не закрывает весь цикл. Сравнивайте отдельно хранилище трейсов и датасетов и CI/eval-раннер; один продукт может покрывать обе задачи, но покупать оба у одного вендора необязательно.
Это авторский срез, проверенный 2026-08-16. Каждая ссылка ведёт на актуальную документацию, которую я использовал для подтверждения заявленной возможности. При этом по-прежнему действуют ограничения планов, лицензий, API keys, доступа к провайдерам и инфраструктурных требований.
| Инструмент | Выбирайте его, когда… | Проверенная возможность и условие |
|---|---|---|
| DeepEval | Python и pytest должны быть CI-гейтом. | deepeval test run выполняет eval-файлы, а упавшие метрики завершают сборку с ошибкой. Для обозначения официального baseline Confident AI требуется CONFIDENT_API_KEY. |
| Inspect AI | Нужны задачи по безопасности, frontier-моделям или агентам в сэндбоксах. | inspect eval и Python API запускают задачи; лимиты, агенты, сэндбоксы и доступ к провайдерам моделей настраиваются отдельно. Это eval-раннер, а не хранилище продакшен-трейсов. |
| Phoenix | Нужны self-hosted-трейсинг и эвалы с хранением данных в собственной инфраструктуре. | Phoenix документирует бесплатный self-hosting без функциональных ограничений, а также детерминированные и LLM-эвалы. Деплой эксплуатируете вы сами. |
| Langfuse | Нужен open-source workflow для трейсов, датасетов и экспериментов. | Ядро можно развернуть самостоятельно; Docker Compose для небольших объёмов не предоставляет high availability, масштабирование и резервные копии, а для некоторых add-on требуется лицензия. Его CI experiment action умеет фиксировать версию датасета и завершать сборку при регрессии. |
| LangSmith | Вы уже используете LangChain/LangGraph и принимаете границы платформы. | Доступны cloud-, hybrid- и self-hosted-режимы; hybrid- и self-hosted-деплой относятся к Enterprise. Создание датасетов и workflow эвалуации остаются привязанными к выбранному режиму деплоя. |
| Braintrust | Важнее managed feedback для PR и сопоставимые снапшоты экспериментов, чем self-hosting. | В документации CI/CD показан GitHub Action, публикующий результаты в pull request; CI требует BRAINTRUST_API_KEY и управляемый сервис. |
| Promptfoo | Регрессии промптов или red-team-проверки должны выполняться до деплоя. | Документация CI описывает CLI и GitHub Action; action требует конфигурацию, GitHub token и секреты провайдера, если выбранный провайдер их требует. Это не хранилище трейсов. |
Примечания о компромиссах описывают источники затрат, а не конкретные цены. Страницы с тарифами меняются, а вендоры считают разные сущности: трейсы, observations, спаны, оценки, пользователей, срок хранения или объём обработанных данных. Перед выбором перепроверьте актуальные цены.
Рекомендации по ограничениям:
- Выбирайте Phoenix, если self-hosting, приватность и OTel-совместимый трейсинг обязательны, а команда может эксплуатировать деплой.
- Выбирайте Langfuse, если нужны также версионирование датасетов и эксперименты, а команда готова поддерживать стек хранения или приобрести необходимые add-on.
- Выбирайте DeepEval, если основной контракт — pass/fail в CI на Python/pytest.
- Выбирайте Inspect AI, если основная работа — эвалуация безопасности или frontier-агентов в настраиваемых сэндбоксах.
- Выбирайте LangSmith, если интеграция с LangChain/LangGraph важнее требования Enterprise для hybrid- или self-hosted-деплоя.
- Выбирайте Braintrust, если управляемый feedback в pull request и сравнение экспериментов оправдывают сервис с API key.
- Выбирайте Promptfoo, если главная поверхность регрессий — промпты или red-team-проверки, а хранилище трейсов не требуется.
Выбор инструмента вторичен. Если продакшен-сбои не превращаются в тестовые кейсы, вы в основном платите за хранение трейсов.
Практический чек-лист внедрения
Сначала постройте пайплайн работы с доказательствами, а уже потом расширяйте стек метрик. Начните с решения, откуда будут поступать примеры.
-
Сначала соберите исторические запуски. Если агент уже существует, соберите трейсы, тикеты поддержки, баг-репорты, сессии с отрицательной оценкой, транскрипты ручного QA и заметки dogfooding до изменения реализации. Если агента ещё нет, логируйте каждый прототип и ручной тестовый запуск с первого дня.
-
Инструментируйте форму трейса. Собирайте сообщения, tool calls, аргументы, результаты инструментов, ошибки, количество токенов, латентность, стоимость, feedback пользователей, версию приложения, версию промпта, версию модели, версию схемы инструмента и финальное состояние среды. Используйте конвенции OpenTelemetry GenAI или спаны в стиле OpenInference, если нужна переносимость. Используйте Langfuse, LangSmith, Phoenix или Braintrust, если UI для трейсов и workflow датасетов нужен сразу.
-
Превращайте реальные сбои в стартовые кейсы. Прочитайте трейсы до того, как начнёте суммировать их с помощью модели. Для каждого полезного сбоя сохраняйте вход, ID исходного трейса, ожидаемое состояние, ожидаемые инварианты инструментов, тип сбоя, severity и заметку ревьюера. Langfuse умеет связывать элементы датасета с продакшен-трейсами; LangSmith умеет создавать датасеты из протрассированных запусков. Сохраняйте исходную ссылку, чтобы кейс оставался аудируемым.
-
Если истории нет, создайте cold-start кейсы. Попросите LLM составить задачи на основе продуктовых требований, политик, схем инструментов, машин состояний и саппорт-макросов. Покройте happy path и сбои: неверные разрешения, отсутствие проверки личности, устаревшие результаты инструментов, неоднозначные даты, ретраи после rate limit и противоречивые результаты инструментов.
-
Не доверяйте синтетическим кейсам без human review. Синтетические примеры полезны для покрытия, но не являются источником истины. Помечайте их как
source: syntheticи требуйте от ревьюера подтвердить ожидаемый результат. По возможности запускайте эталонный корректный путь и используйте разные семейства моделей для генерации кейса и оценки результата. -
Соберите небольшой сбалансированный датасет. Включите успешные и неуспешные запуски, отказы, граничные случаи, длинные диалоги, чувствительные к политике кейсы и допустимые альтернативные пути. Не делайте golden «точной копией старого транскрипта». Храните все перечисленные выше атрибуты golden и добавляйте тип сбоя, из-за которого кейс попал в набор.
-
Сначала добавьте детерминированные проверки. Проверяйте обязательный порядок инструментов там, где он задан политикой, обязательные аргументы, валидацию схемы, diff финального состояния, лимиты циклов, ограничения токенов и латентности, а также прикладные инварианты — до запуска любого джаджа.
-
Добавьте один SGR-ориентированный джадж. Используйте его только для части, требующей интерпретации. Откалибруйте его по человеческой разметке. Если он не различает хорошие и плохие примеры на калибровочном наборе, исправьте рубрику до интеграции в CI.
-
Соедините цикл. Запускайте небольшой офлайн-набор в CI, большой набор — перед релизом, оценивайте выбранный продакшен-трафик онлайн и возвращайте повторяющиеся кластеры онлайн-сбоев в офлайн-датасет.
Ваш первый eval-набор будет неправилен по скучным причинам. Всё равно выпускайте его. Набор, который запускается каждый день, проще исправить, чем идеальный дизайн-документ, который никогда не блокирует плохой PR.
Ссылки
- Сопутствующий demo-репозиторий trace2evals
- LangChain — State of Agent Engineering
- Anthropic — Demystifying Evals for AI Agents
- Hamel Husain — A Field Guide to Rapidly Improving AI Products
- Семантические конвенции OpenTelemetry для генеративных AI-систем
- DeepEval Tool Correctness
- DeepEval Task Completion
- DeepEval unit testing in CI/CD
- Запуск эвaлов в Inspect
- Структурированные Outputs моделей OpenAI
- Schema-Guided Reasoning: vLLM, xgrammar и Pydantic
- Self-hosting Phoenix
- Датасеты и версионирование в Langfuse
- Эксперименты Langfuse в CI/CD
- Настройка платформы LangSmith
- LangSmith — программное создание и управление датасетами
- Braintrust — создание экспериментов
- LLM-эвалы в Phoenix
- Интеграция Promptfoo с GitHub Action
- tau-bench: бенчмарк взаимодействия tool-agent-user в реальных доменах
- Почему мультиагентные LLM-системы дают сбои?
- Практики построения строгих agentic-бенчмарков
- G-Eval: оценка NLG с помощью GPT-4 с улучшенным соответствием человеческим оценкам
- Оценка LLM-as-a-Judge с помощью MT-Bench и Chatbot Arena
- Замена джаджей жюри: оценка генераций LLM панелью разнообразных моделей
- JudgeBench: бенчмарк для оценки джаджей на базе LLM
- Bias самопредпочтения в LLM-as-a-Judge