Перейти к содержанию
Публикация AiManual

Decision-модели в Amazon Bedrock AgentCore Evaluations: как добавить калиброванные проверки агентов

Decision-модели дают то, чего не хватает LLM-судье: стабильную вероятность по фиксированному набору ответов, которую можно поставить в релизный гейт. Разбираем

Коротко

Что будет в материале

  1. 01

    Зачем агенту калиброванная проверка, а не ещё один LLM-судья

  2. 02

    Как устроены evaluator'ы в Amazon Bedrock AgentCore Evaluations

  3. 03

    Преобразование OTel-спана агента в запрос к decision-модели и обратно

  4. 04

    Два бэкенда: hosted Jev от TypeSafe и открытая Strands Decider 2B

Зачем агенту калиброванная проверка, а не ещё один LLM-судья

Один и тот же трейс агента проходит проверку утром и падает вечером. Модель-судья вернула 0.82, потом 0.54, объяснения оба раза выглядят убедительно. Для еженедельного отчёта это терпимо. Для гейта, который блокирует деплой, нет: сигнал шумит сильнее, чем реальные регрессии агента.

Decision-модель закрывает именно эту часть задачи. Она принимает структурированное состояние и фиксированный набор допустимых ответов, а возвращает калиброванное распределение вероятностей по этим ответам вместо свободного текста, чья уверенность уплывает от прогона к прогону. Механику AWS показывает на примере связки decision-моделей с Amazon Bedrock AgentCore Evaluations.

Границы видны сразу. Decision-модель не объясняет вердикт и не покрывает широкую семантику. Она отвечает на узкий вопрос с закрытым списком меток и выдаёт результат в форме, которую удобно пороговать: вероятность выше порога - pass, ниже - fail, дальше агрегация по сессии.

AgentCore Evaluations оценивает агента на всём жизненном цикле: on demand во время разработки, пакетными заданиями по сохранённым сессиям и онлайн по продакшн-трафику. Один и тот же evaluator работает во всех трёх режимах, поэтому вопрос «где ставить порог» упирается в качество сигнала, а не в инфраструктуру.

Чем decision-модель отличается от LLM-as-a-judge

Оба инструмента решают задачу оценки, но выдают разный тип данных, и это определяет, куда каждый из них ставится в пайплайне.

КритерийDecision-модельLLM-as-a-judge
ВыходРаспределение вероятностей по заранее заданным меткамТекст с оценкой и обоснованием
ИнтерпретацияПрямое сравнение с порогом, агрегация по ходам и сессиямНужен парсинг ответа, шкала размывается формулировками
Объяснение решенияОтсутствуетЕсть, это главный аргумент в пользу судьи
ОхватУзкий повторяемый вопрос с фиксированным набором ответовШирокая оценка семантики, рассуждений, стиля
Стоимость одного запросаКомпактная модель, на выходе только числаГенерация развёрнутого текста на каждый прогон

Объяснения нужны там, где разбирают инцидент. Калиброванный сигнал нужен там, где решение принимается автоматически. Эти роли не конфликтуют: судья остаётся для расследований, decision-модель забирает рутинный pass/fail. Как decision-модели соотносятся с обычными LLM по скорости и стоимости, подробно разобрано в материале про Decisions API и Jev от TypeSafe.

Какие вопросы агенту действительно стоит задавать decision-моделью

Критерий из описания AWS простой: вопрос имеет фиксированный набор ответов, и информированный человек решает его с первого взгляда. Если для вердикта нужно перечитать полотно рассуждений и взвесить нюансы, это работа для LLM-судьи.

МетрикаВопрос к моделиДопустимые ответы
Policy complianceНе вышел ли ответ за пределы политикив политике / вне политики
Tool call safetyБезопасен ли вызов инструмента для одобрениябезопасен / требует подтверждения / опасен
GroundednessСоответствует ли ответ извлечённому контекступодтверждён / не подтверждён / контекста мало
Goal completionВыполнена ли цель текущего ходавыполнена / частично / не выполнена
Refusal handlingОтказался ли агент от запрещённого запросаотказался / обошёл / вопрос неприменим

Список расширяется. После валидации на собственном трафике AWS предлагает переносить подход на отдельные категории вредности и стереотипизации в политике: вместо одного «токсично / нетоксично» задаётся набор конкретных категорий, и по каждой считается своя вероятность. Ставить такие проверки в релизный гейт до валидации рано, цена ложного срабатывания выше пользы.

Как устроены evaluator'ы в Amazon Bedrock AgentCore Evaluations

В AgentCore Evaluations 15 встроенных evaluator'ов и два типа кастомных. LLM-as-a-judge применяет ваши инструкции и шкалу оценки силами модели в Amazon Bedrock. Code-based выполняет вашу логику в AWS Lambda, и эта логика может обращаться к любой внешней системе, модели или API, включая decision-модель.

Точка расширения для decision-модели - code-based evaluator. Остальной пайплайн остаётся прежним: те же сессии, тот же семплинг трассировок, те же отчёты.

Code-based evaluator на AWS Lambda: что внутри

Функция отвечает за всю склейку между AgentCore и внешней моделью:

  1. принять вход evaluator'а, который AgentCore передаёт на обработку;
  2. достать из OpenTelemetry-спана агента сообщения, вызовы инструментов, финальный ответ и извлечённый контекст;
  3. нормализовать это в компактное структурированное состояние;
  4. сформировать запрос с фиксированным набором меток и формулировкой вопроса;
  5. вызвать бэкенд decision-модели и получить вектор вероятностей;
  6. преобразовать вероятности в результат оценки AgentCore, который увидит пайплайн.

Маппинг живёт в Lambda, не в модели. Модель ничего не знает про AgentCore, AgentCore ничего не знает про формат запроса к Jev или Strands Decider. Логика изолирована: свои зависимости в слое, свой таймаут, своя история версий и откатов. Это удобно ровно до момента, когда Lambda начинает ходить в другой сервис по сети, и про сетевую задержку приходится думать отдельно.

Встроенные evaluator'ы и кастомные: как они сосуществуют

Переписывать существующую оценку не нужно. Встроенные evaluator'ы продолжают работать по своим метрикам и давать объяснения, кастомный code-based добавляется рядом как ещё один сигнал по той же сессии. Практический смысл такого соседства появляется в каскадной схеме: дешёвый сигнал отбирает ходы, а встроенные evaluator'ы разбирают только отобранные.

Преобразование OTel-спана агента в запрос к decision-модели и обратно

Прямой путь занимает шесть шагов, и на каждом есть свои ловушки. Схематично запрос выглядит так:

{
  "question": "answer_grounded_in_context",
  "options": ["grounded", "not_grounded", "insufficient_context"],
  "state": {
    "user_message": "...",
    "retrieved_context": "...",
    "final_answer": "..."
  }
}

Состояние собирается из спана: реплика пользователя, выбранные фрагменты контекста, текст ответа, при необходимости список вызовов инструментов с аргументами. Дальше набор меток фиксируется один раз и не меняется от вызова к вызову, иначе вероятности между прогонами просто не с чем сравнивать.

Обратный путь короче. Модель возвращает распределение по меткам, Lambda берёт argmax, сравнивает его вероятность с порогом и отдаёт в AgentCore результат с уверенностью. Если порог не пройден, метка уходит в отчёт как есть, а вероятность сохраняется для последующего аудита и пересчёта порогов без повторных вызовов модели.

Грабли, на которые наступают при первой интеграции:

  • слишком длинный контекст: спаны многоходовых сессий легко перерастают окно компактной модели, приходится отбирать релевантные фрагменты;
  • неоднозначные метки: «частично» и «в основном» в одном наборе превращают калибровку в бессмыслицу;
  • отсутствующее поле в спане: агент не вызвал инструмент, и вопрос про безопасность вызова становится неприменимым, нужен отдельный ответ;
  • склейка нескольких вопросов в один: если нужны три метрики, лучше отправить три вопроса об одном состоянии одним запросом, чем смешивать формулировки.

Два бэкенда: hosted Jev от TypeSafe и открытая Strands Decider 2B

Jev, hosted decision-модель от TypeSafe, и Strands Decider 2B, открытая decision-модель для самостоятельного запуска, подключаются одним и тем же code-based evaluator'ом. Меняется только клиент внутри Lambda и место, куда уходит запрос. Оба бэкенда умеют отвечать на несколько вопросов об одном состоянии в рамках одного запроса, и это ключ к каскадной схеме.

Когда брать Jev

Hosted-вариант снимает операционную работу по инференсу: интеграция сводится к вызову API из Lambda, обновления модели и масштабирование остаются на провайдере. Плата за это предсказуемая.

  • Внешняя зависимость: доступность и латентность evaluator'а перестают быть только вашей зоной ответственности.
  • Данные уходят за периметр: фрагменты ответов агента и извлечённый контекст покидают ваш аккаунт, это стоит сверить с политикой безопасности до запуска.
  • Сетевой вызов внутри Lambda добавляет задержку к каждой оценке, и таймаут функции нужно считать с её учётом.

Когда брать Strands Decider 2B

Открытая модель означает полный контроль: данные не покидают контур, окружение и версия зафиксированы, поведение можно воспроизвести на своей инфраструктуре. Взамен вы держите хостинг, обновления и мониторинг инференса, а Lambda должна до этой модели достучаться, то есть нужен сетевой доступ и запас по таймауту.

Размер 2B указывает на компактность, но конкретные требования к железу и пропускную способность в исходном материале AWS не приводит. Планировать инстанс по ощущениям не стоит: нужен собственный замер на своём профиле нагрузки. Общий подход к быстрой проверке новых моделей перед сменой стека разобран в материале про оценку новинок без шума вокруг релизов.

Валидация evaluator'а на собственном трафике до включения порога

Порог без валидации - это гадание с числом. AWS формулирует условие прямо: decision-модель может быть достаточной для конкретного решения или оценки после того, как вопрос проверен на вашем трафике. Готового протокола проверки в исходном материале нет, поэтому ниже рабочая схема, которую стоит подогнать под свои объёмы и бюджет разметки.

Разметка и мажоритарное голосование

Выборка собирается из реальных сессий, а не из синтетики: нужны именно те формулировки, которые агент видит в продакшне. Каждый пример размечают несколько человек, меткой становится ответ большинства. Спорные случаи не размазываются по выборке, а складываются в отдельную корзину.

Расхождения разметчиков сами по себе полезны. Если двое из трёх не сходятся в трактовке вопроса, порог модели на этом же вопросе будет шуметь по той же причине, и чинить нужно постановку вопроса, а не число.

Agreement rate, калибровка и разбор расхождений

Смотреть стоит на три вещи. Первая: доля совпадений ответа модели с мажоритарной меткой. Вторая: калибровка, то есть насколько заявленная вероятность соответствует реальной доле верных ответов среди примеров с такой уверенностью. Третья: систематические ошибки по категориям, когда модель стабильно путает конкретную пару меток.

Красный флаг для порога - высокая уверенность на неверных ответах. Такая модель уверенно ломает гейт. Расхождения разбираются вручную: часть объясняется плохим состоянием на входе (обрезанный контекст, потерянное поле спана), часть - неудачной формулировкой меток, и только остаток указывает на реальные пределы модели.

Публичные сравнения decision-моделей пока не дают опоры для выбора порога: методологии и метрик в открытых публикациях часто нет, что видно на примере сравнения Clef Q8 и Jev. Проверять нужно на своей нагрузке и своей разметке.

Каскадная схема: decision-модель как дешёвый фильтр, LLM-evaluator'ы для проблемных сессий

Каскад строится на одном свойстве: decision-модель прогоняет pass/fail по нескольким метрикам на каждом ходе, а встроенные evaluator'ы с объяснениями подключаются только к ходам и сессиям, помеченным как проблемные. Объяснения тратятся там, где действительно нужны, а не на каждом успешном вызове инструмента.

  • Ход прошёл все пороги: сохраняем вероятности, глубокая оценка не запускается.
  • Ход провалил один порог или попал в узкую зону неопределённости: уходит в очередь на разбор LLM-судьей.
  • Сессия набрала несколько проблемных ходов: разбирается целиком, потому что ранняя ошибка обычно портит все последующие шаги.

Ограничение каскада в дисциплине. Определение «проблемного» хода должно быть формальным, иначе глубокая оценка либо не запустится вообще, либо будет срабатывать на большинстве ходов и съест всю экономию. Зона неопределённости вокруг порога задаётся явно, а не на глаз.

Ограничения и риски: где decision-модель может подвести

Узость домена. Модель обучена на фиксированный формат вопроса и наборе меток, и вопрос за пределами этого распределения она всё равно вернёт, просто с плохой калибровкой. Отличить «уверенно верно» от «уверенно мимо» в таком режиме тяжело.

Дрейф трафика. Агент меняет промпт, инструменты, политику, и распределение входов уезжает. Порог, откалиброванный месяц назад, продолжает работать, но уже не по тем данным. Нужна периодическая пере-валидация на свежей выборке, привязанная к изменениям агента и политики.

Ложные срабатывания при агрессивном пороге. Жёсткий гейт на сыром сигнале блокирует нормальные релизы, команда начинает обходить проверку, и вся конструкция теряет смысл. Мягкий режим наблюдения перед блокирующим режимом обязателен.

Отсутствие объяснений. На инциденте decision-модель даёт только число. Для разбора всё равно нужен LLM-судья или человек, и это стоит заложить в процесс заранее. Отдельный риск связан с самим судьёй: LLM умеет отличать тестовые данные от рабочего трафика, и его оценки на размеченной выборке могут расходиться с поведением в продакшне, о чём подробно говорит разбор эффекта evaluation awareness.

Практические меры простые: хранить вероятности по каждому ходу для аудита и пересчёта порогов, следить за долей срабатываний как за отдельной метрикой, пере-валидировать вопрос при изменении агента или политики, держать в резерве ручной разбор для спорных категорий.

С чего начать на практике: минимальный план запуска

  1. Выбрать один или два узких вопроса с фиксированным набором ответов. Для старта хватит policy compliance и groundedness.
  2. Поднять code-based evaluator на AWS Lambda: приём входа, извлечение полей из OTel-спана, сборка состояния, вызов бэкенда, маппинг вероятностей в результат AgentCore.
  3. Подключить бэкенд: Jev, если устраивает hosted-вызов и передача данных провайдеру, Strands Decider 2B, если данные должны остаться в контуре и есть чем обслуживать инференс.
  4. Собрать размеченную выборку из реальных сессий, получить метки мажоритарным голосованием, прогнать модель и посчитать agreement rate и калибровку.
  5. Разобрать расхождения вручную и переформулировать метки там, где люди сами не сходятся.
  6. Включить порог в режиме наблюдения, сравнить долю срабатываний с ожиданиями, и только после этого сделать проверку блокирующей.
  7. Добавить каскад: оставить глубокую оценку встроенными evaluator'ами только для ходов, которые decision-модель пометила как проблемные.

Такой порядок даёт измеримый сигнал до того, как от него начнут зависеть релизы. Decision-модель в этой схеме занимает нишу дешёвого и стабильного фильтра, а объяснения остаются за LLM-судьёй там, где они действительно нужны.

Подписаться на канал