Находка, переформулированная точно
Четверть развёртываний агентов работает без мониторинга. Обычное прочтение — организационное: команды выпускали слишком быстро, надёжностью никто не владел, управление отставало. Это прочтение удобно и в основном неверно. Когда у системы нет стабильной границы шага, нет общего идентификатора корреляции и нет схемы спанов, мониторинг — не проблема дисциплины, а отсутствующий примитив. Нельзя выбраться дашбордами из архитектуры, которая никогда не испускала события, по которым вы хотите строить алерты.
Почему мониторинг пропускают
Фреймворки выдают логи, а не трейсы. Типичный цикл агента пишет удобочитаемые строки: промпт отправлен, инструмент выбран, ответ разобран. Строки логов дёшевы в производстве и почти бесполезны для агрегации. Нет отношения родитель-потомок, нет длительности, нет поля статуса, нет пространства имён атрибутов. Запрос «какие запуски вызывали инструмент возврата более трёх раз» превращается в упражнение с регулярными выражениями по неструктурированному тексту — поэтому никто не строит алерт.
Данные живут в разных системах. Вызовы модели находятся у провайдера инференса. Вызовы инструментов — в логах приложения. Извлечения — в векторном хранилище. Решения политики — в шлюзе. У каждой системы свой идентификатор для одной и той же логической операции, и ни один из них не согласуется с другими. Без correlation ID, созданного на границе запуска и распространяемого через каждый хоп, реконструкция одного шага агента требует соединения выгрузок четырёх вендоров по временной метке — подход, который рушится в тот момент, когда два вызова попадают в одну и ту же миллисекунду.
Инструментирование добавляют после запуска. К тому времени, когда команда решает, что ей нужны трейсы, агент уже дважды отрефакторен, инструменты обёрнуты в логику повторных попыток, а граница шага растворилась в цепочке асинхронных колбэков. Ретрофит спанов означает переопределение того, чем является шаг, — это изменение дизайна, а не изменение observability. Оно откладывается бесконечно, потому что конкурирует с работой над фичами и не имеет видимого влияния на пользователя до первого серьёзного инцидента.
Инструментирование как контракт времени сборки

Альтернатива — трактовать observability как часть интерфейса агента, обеспечиваемую так же, как сигнатура типа или миграция схемы.
Каждый шаг испускает спан. Шаг — это любая единица, которую система может повторить, отклонить или выставить в счёт независимо: один вызов модели, один вызов инструмента, одно извлечение, одна оценка политики. Спан несёт входы, выходы, стоимость, задержку и решение политики, которое разрешило действие. Стоимость — не производная метрика, вычисляемая позже из подсчёта токенов; это атрибут, записываемый при испускании, потому что цены меняются, а ретроактивный пересчёт по длинному окну хранения — это то место, где умирают аудиторские следы.
Correlation ID распространяются через границы. ID запуска создаётся один раз, затем протягивается через исходящие HTTP-заголовки, контекст сессии базы данных и метаданные очереди сообщений. Конкретный механизм — объект контекста, внедряемый рантаймом и читаемый каждым адаптером, так что инструменту, вызывающему внешний API, не нужно знать, что его трассируют: обёртка HTTP-клиента прикрепляет заголовок, драйвер базы данных устанавливает переменную сессии, публикатор очереди копирует поле. Когда нижестоящий сервис логирует тот же ID, трейс замыкается от начала до конца без ручной сшивки.
Сэмплирование объявляется заранее. Полноточное трассирование каждого запуска редко доступно по цене при большом объёме. Контракт времени сборки задаёт политику сэмплирования: какие запуски трассируются всегда (отклонённые действия, дорогие запуски, первые N на развёртывание), какие сэмплируются вероятностно и что отбрасывается. Решения о сэмплировании принимаются на корневом спане, чтобы исключённый из выборки запуск отсутствовал согласованно, а не присутствовал наполовину, — именно этот режим отказа делает данные трейсов недостоверными.
Минимальная схема спана выглядит так:
{
"trace_id": "run_8f2c...",
"span_id": "step_01",
"parent_span_id": null,
"kind": "model.invoke",
"started_at": "2025-01-01T10:00:00.000Z",
"duration_ms": 812,
"attributes": {
"model": "...",
"input_tokens": 1042,
"output_tokens": 233,
"cost_units": 0.0041,
"policy_decision": "allow",
"polic
Компромисс реален: каждый адаптер должен участвовать, и один неинструментированный инструмент разрывает цепочку. Средство смягчения — заставить рантайм отказываться выполнять инструмент, который не принимает объект контекста: проверка на этапе компиляции или запуска, а не надежда на этапе выполнения. Это ограничение непопулярно у команд, которые хотят быстро добавлять инструменты, и это цена трейса, который действительно полон.

## От трейсов к контролю
Трейсы полезны только тогда, когда отвечают на вопросы о конкретных действиях.
**Запрашиваемость — это тест на аудируемость.** Трейс, который нельзя отфильтровать по имени инструмента, хешу аргументов, правилу политики или действующему лицу, — это средство отладки, а не аудиторский след. Это значит, что схема должна включать поля, которые запрашивают регуляторы и те, кто разбирает инциденты, а не только поля, которые случайно испускает фреймворк. Если на вопрос «покажи каждый запуск, где агент вызвал инструмент оплаты без спана человеческого одобрения» нельзя ответить одним запросом, инструментирование неполно.
**Алерты на поведенческие инварианты.** Счётчики ошибок — самый слабый сигнал в системе агентов, потому что режим отказа обычно представляет собой успешный вызов, которого не должно было быть. Полезные инварианты структурны: частота вызовов инструментов на запуск относительно объявленного потолка, расход на запуск относительно атрибута бюджета, число отклонённых действий, отношение извлечений к вызовам модели и появление инструмента вне разрешённого набора политик. Они вычислимы из спанов и стабильны при обновлениях модели, в отличие от порогов задержки, которые дрейфуют при изменениях провайдера.
**Хранение и редактирование принадлежат схеме.** Решение задним числом о том, какие поля содержат персональные данные, означает переработку исторических трейсов, что дорого и часто невозможно, как только сырые полезные нагрузки исчезли. Вместо этого помечайте каждый атрибут во время определения как сохраняемый, хешируемый или редактируемый и позвольте конвейеру применять правило при записи. Компромисс — снижение точности отладки для редактируемых полей и схема, которую нужно версионировать по мере изменения правил классификации. Эта цена ниже, чем обнаружение во время запроса субъекта на доступ к данным того, что промпты и выходы инструментов лежат в хранилище вендора observability без политики на уровне полей.
## Что меняется, когда это требование времени сборки
Статистика о четверти агентов описывает популяцию, у которой никогда не было примитивов. Команды, которые определяют границу шага, создают ID запуска, распространяют его через каждый адаптер и объявляют сэмплирование и хранение до запуска, позже не сталкиваются с решением о мониторинге — они сталкиваются с миграцией схемы, а это хорошо понятная инженерная задача. Неудобная часть в том, что эта работа происходит до появления какой-либо видимой проблемы, оправдывающей её, и она ограничивает скорость добавления новых инструментов. Это честный компромисс: более медленная интеграция инструментов в обмен на систему, поведение которой можно реконструировать, запрашивать и контролировать. Альтернатива — парк агентов, которым доверяют именно потому, что никто не видит, что они делают.
