Agent Observability

Наблюдаемость агента — это трейсинг каждого шага, а не графики CPU/RAM. Классический мониторинг видит, что сервис «жив», но не отвечает на вопросы «почему агент принял это решение, какой tool вызвал, что отправил в LLM, где именно сломался». Без неё агент — black box: расходы растут, ошибки невоспроизводимы, отладка занимает часы вместо минут.

Суть

Для обычного сервиса хватает метрик инфраструктуры (инстансы, память, HTTP-коды). Агент недетерминирован и многошагов, поэтому нужен трейс — запись всей траектории выполнения: request → план → tool_call → tool_result → … → финальный ответ. Трейс превращает «гадание, почему агент упал» в наблюдаемый факт.

Зачем это нужно

Главные боли прода, которые ловит именно трейсинг:

  • Отказы — агент молча падает или зависает, данных о поведении нет.
  • Невизуальность — не видно, где он «тыкается» и деградирует на живом трафике.
  • Косты — дорогие/ненужные вызовы LLM не видны без пошагового учёта токенов.
  • Каскадные ошибки — трейс работает как «детектор лжи»: вскрывает, что модель не вызвала инструмент, а выдумала данные (например, котировку биткоина), и передала их дальше.

Как работает

  • Что логировать в span'е шага: вход/выход, какой tool вызван и с какими аргументами, latency, ошибки и ретраи. Это минимум, по которому можно отличить «не тот документ принесли» от «модель проигнорировала верный контекст».
  • Трейс как поле state — на уровне графа удобно вести журнал «размышлений» прямо в состоянии (поле trace), помимо внешнего инструмента (см. LangGraph Observability).
  • Лучшие практики эксплуатации: версионирование кода (каждый релиз агента — новая версия, хронология в git); раздельные конфиги для dev/staging/prod; горизонтальное масштабирование (k8s); прогон на тестовых экспериментах до прода.
  • Аннотации экспертом — UI, где доменный эксперт (не разработчик) накликивает оценки ответов; быстро строится, если инфраструктура данных уже есть.
  • Уровни наблюдаемости: на уровне агента/графа — трейсинг шагов и tools; на уровне retrieval — отдельный слой (RAG Observability: какие чанки пришли, версия индекса). Наблюдаемость — вход для оценки качества (Agent Evals) и алертинга при деградации метрик.

Метрики, которых нет в классическом мониторинге

Разница между APM и наблюдаемостью агента нагляднее всего видна в том, что каждый из них показывает на дашборде. Классический APM: латентность 250 мс, 12 000 запросов в минуту, доля пятисоток 0.01%, пропускная способность канала. Наблюдаемость агента показывает вместо этого граф выполнения и другой набор чисел:

  • TTFT (time to first token) — время до первого токена. Промышленный ориентир SLA — менее 800 мс, иначе интерфейс воспринимается как зависший.
  • Tokens per second — пропускная способность генерации. Её падение сигнализирует о деградации GPU или нехватке видеопамяти раньше, чем это станет заметно по ошибкам.
  • Атрибуция стоимости — перевод каждого взаимодействия в деньги, вплоть до микро-транзакции: например, $0.0245 за взаимодействие. Это то, что делает разговор о расширении контекстного окна предметным: видно, сколько стоит лишняя тысяча токенов на масштабе.

Главный тезис: успешный ответ с кодом 200 может стоить бизнесу полдоллара, вернуть галлюцинацию и увести клиента. APM слеп к ветвлению графа — он видит транспорт, но не смысл. Разбор конкретных режимов отказа — в Agent Failure Modes.

Технический фундамент под этими метриками — два стандарта: W3C Trace Context для сквозного проброса идентификатора между сервисами и OpenInference для типизации спанов внутри трейса.

Оценки живут на трейсе, а не в отдельном отчёте

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

Оценка, привязанная к трейсу, отвечает на вопрос «почему упало качество» одним переходом: видно не только что completeness просела до 0.6, но и какие именно шаги дали этот прогон — какой инструмент вернул пустоту, что ушло в модель, сколько это стоило. Отчёт рядом с трейсом такой связи не даёт, и разбор превращается в сопоставление таймстемпов.

Технически это score на трейсе — именованное число с комментарием:

log_score("completeness", ev1["score"], trace_id)
log_score("translation_quality", ev2["avg_overall"] / 10, trace_id, comment=f"n={ev2['n']}")
log_score("tool_correctness", ev3["correctness"], trace_id)

Две детали, которые делают такие оценки сравнимыми между собой.

Единая шкала. Судья по своей природе отвечает по шкале 1–10, детерминированные проверки — долей от 0 до 1. Если писать как есть, метрики нельзя ни сложить в одну панель, ни поставить на них общий порог: девятка судьи и 0.9 полноты выглядят как разные вселенные. Судейская оценка нормируется делением на 10 при записи, и дальше все скоры живут в одном диапазоне. Отдельно стоит помнить, что нормировка не превращает шкалу судьи в измерение — про её ненадёжность и переход к бинарным вердиктам см. LLM as Judge.

Комментарий несёт основание. n=5 рядом со средним баллом отличает устойчивую оценку от случайной: то же число, посчитанное на пяти случаях и на двухстах, требует разной реакции.

Из этого же механизма получается регрессионный тест защиты. Прогон атак записывается таким же скором — «ноль, если всё поймано, единица, если что-то утекло», — и деградация guardrails становится видна в той же панели, что и деградация качества, вместо того чтобы ждать инцидента (см. Guardrails).

Альтернативный взгляд: наблюдаемость как инженерный blueprint

В основной интерпретации выше трейсинг — прежде всего диагностический инструмент: способ поймать агента на лжи, увидеть, что он не вызвал инструмент, а выдумал данные. Наблюдаемость здесь ближе к отладке, и её ценность в том, что она вскрывает конкретные инциденты.

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

Смена оптики даёт побочный эффект, которого нет в «диагностической» рамке. Когда промпт версионируется в системе трейсов, его нельзя вытащить из кода — потому что в коде его нет. Наблюдаемость перестаёт быть только средством смотреть и становится способом устранить целый класс уязвимостей.

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

Откуда берутся пороги алертов

Абсолютные пороги для агентных метрик не работают: «дороже 10 центов за запрос» одинаково срабатывает и на дорогом deep search, и на сломавшейся классификации интента. Порог считается относительно baseline своей операции — p95 за прошлую неделю скользящим окном, отдельно на каждый тип операции (Agent CostControl).

Множитель к baseline подбирается по цене ложного срабатывания: чем дороже разбудить дежурного, тем выше множитель, и стартовое значение калибруется на своей истории, а не берётся готовым (Cost Anomaly Alerting). Пока недели данных нет, порог ставится от бюджета и заменяется на статистику, как только окно набралось.

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

Связано с

  • Agent Audit Log — след для расследования и доказательств, а не для отладки качества
  • AI Observability Stack — инфраструктурный срез: пять контуров, панели дашборда, инструмент на каждый слой
  • AgentOps — observability как первый пиллар дисциплины
  • LangSmith vs Langfuse — инструменты, которые собирают трейсы
  • Agent Evals — трейс → метрики → оценка качества
  • RAG Observability — наблюдаемость на уровне retrieval (дополняет шаговый трейсинг)
  • LangGraph Observability — трейсинг шагов графа + поле trace в state
  • W3C Trace Context — сквозной идентификатор через границы сервисов
  • OpenInference — типы спанов и атрибуты, которыми описывается шаг
  • Agent Failure Modes — что именно ищем в трейсе: каталог режимов отказа
  • LLM as Judge — откуда берётся судейская оценка, которую нормируют перед записью
  • Guardrails — защитный контур, регрессию которого удобно писать тем же скором