Alejandro Rioja.
AI Agents Operations

Как отлаживать ИИ-агента в продакшене (практическое руководство)

Alejandro Rioja
Alejandro Rioja
6 мин чтения
TL;DR

Отладка продакшен-агента ИИ — это в основном про изоляцию того, какой слой дал сбой: промпт, инструмент, модель или оркестрация. Я логирую каждый шаг с trace-ID, переигрываю те же самые входные данные и применяю бинарный поиск. В моих агентах ~70% 'багов ИИ' оказываются багами обвязки, а не модели.

Бесплатная рассылка

Каждую среду. 28 400+ читателей. Никакой воды.

Содержание

Обновлено в июне 2026 года.

TL;DR: Отладка продакшен-агента ИИ — это в основном про изоляцию того, какой слой дал сбой: промпт, вызов инструмента, вывод модели или оркестрация. Я логирую каждый шаг с trace-ID, переигрываю те же самые входные данные и применяю бинарный поиск, отталкиваясь от этого. В моих агентах примерно 70% того, что выглядит как «баг ИИ», оказывается обвязкой: некорректно сформированный результат инструмента, обрезанный ввод, молча проглоченное исключение.

Взгляд оператора: Я держу более 100 продакшен-агентов — потоки бронирования для Pickleland, контент-конвейеры, сортировщики входящих. Они ломаются так же, как ломается любое ПО, плюс несколькими новыми способами. Это то практическое руководство, которое я хотел бы иметь: как найти сбойный слой, не вглядываясь в стену из токенов.

Когда агент ведёт себя неправильно в продакшене, инстинкт — обвинить модель. «Claude нагаллюцинировал». Иногда правда. Обычно нет. Модель — это один слой в стеке из пяти-шести, и баг куда чаще сидит в том слое, который написали вы, чем в том, что выпустила Anthropic. Этот пост — систематический способ, которым я его нахожу.

Сделайте каждый запуск трассируемым прежде, чем что-либо отлаживать

Нельзя отладить то, чего не видишь. Самое рычаговое, что вы можете сделать, — ещё до появления какого-либо конкретного бага — это прикрепить trace-ID к каждому запуску агента и логировать каждый его шаг.

«Шаг» — это всё, что пересекает границу: входящий триггер, каждый вызов модели (с полным массивом сообщений), каждый вызов инструмента (с аргументами), каждый результат инструмента и финальный вывод. Логируйте их как структурированный JSON, ключом которого служит trace-ID.

typescript
function logStep(traceId: string, step: string, payload: unknown) {
  console.log(JSON.stringify({
    traceId,
    step,            // "trigger" | "model_call" | "tool_call" | "tool_result" | "output"
    ts: Date.now(),
    payload,
  }));
}

На Cloudflare Workers я отправляю их в очередь и в таблицу; локально они уходят в stdout. Правило абсолютно: если шаг не залогирован, то с точки зрения отладки его не было. Это отражает инструментирование, которое я описываю в стеке агентов, который я использую, — trace-ID это позвоночник, на котором держится всё остальное.

Изолируйте слой: промпт, инструмент, модель или оркестрация

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

1. Слой ввода (самый частый виновник)

Вытащите тот самый массив messages, который пошёл в сбойный вызов модели. Не реконструкцию — буквальный payload из лога. Затем прочтите его так, как прочёл бы посторонний. Половина моих багов «модель проигнорировала инструкции» на самом деле такие:

Если ввод неверный, модель безупречно сделала свою работу над мусором. Чините обвязку.

2. Слой инструментов

Если ввод выглядит чистым, проверьте, не вернул ли инструмент ошибку, которую агент воспринял как успех. Классика: API возвращает 200 с телом { "error": "rate limited" }, ваша обёртка инструмента не проверяет тело, и агент уверенно действует на основе сообщения об ошибке. Логируйте результаты инструментов в сыром виде и проверяйте их форму.

3. Слой модели

Только исключив 1 и 2, я начинаю подозревать модель. Даже тогда «баг модели» обычно означает «мой промпт неоднозначен». Возьмите тот самый сбойный ввод, закиньте его в одноразовый скрипт против той же модели и температуры и посмотрите, воспроизводится ли. Если да, то исправление — это работа над промптом или более строгий eval, а не паническая смена модели.

4. Слой оркестрации

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

Воспроизводите недетерминизм, а не боритесь с ним

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

Во-первых, зафиксируйте то, что можете. Установите temperature: 0 на время отладки. Это не сделает Claude полностью детерминированным, но резко сузит разброс, так что вы сможете отличить настоящий баг от шума сэмплирования.

Во-вторых, прогоните это N раз. Если сбой воспроизводится 1 раз из 20 запусков, прокрутите тот же самый ввод 50 раз и захватите каждый вывод. Теперь у вас есть выборка, а не байка. Баг, срабатывающий в 5% случаев, — настоящий баг; вам просто нужен объём, чтобы его увидеть.

bash
for i in $(seq 1 50); do
  node replay.mjs --trace=abc123 >> runs.jsonl
done
# затем подсчитайте сбои
grep -c '"status":"fail"' runs.jsonl

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

Постройте стенд воспроизведения, чтобы перестать отлаживать в продакшене

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

Стенд воспроизведения загружает залогированную трассу, реконструирует тот самый ввод для любого шага и заново прогоняет только этот шаг против модели. Поскольку вы залогировали полный массив messages, восходящая система вам вообще не нужна. Это превращает 10-минутный круг в продакшене в 2-секундный локальный цикл и является самым большим ускорением в моём рабочем процессе отладки.

Хороший стенд воспроизведения также позволяет мутировать и перезапускать: измените одну строку системного промпта, переиграйте те же 50 сбойных трасс и посмотрите, сколько теперь проходит. Это мост от отладки к eval — как только у вас есть корпус сбойных трасс, у вас есть начало набора регрессионных тестов.

Следите за метриками, которые действительно предсказывают поломки

Некоторые сбои никогда не выбрасывают исключение. Агент работает, возвращает нечто правдоподобное и тихо делает не то. Чтобы ловить такие, вы следите за поведенческими метриками, а не только за частотой ошибок:

Я отслеживаю их так же, как и всё остальное, — см. как я измеряю, действительно ли ИИ-агент работает. Метрика, ловящая тихий сбой, стоит десяти, ловящих громкие.

Чек-лист сортировки за 5 минут

Когда агент ломается, а время поджимает, я выполняю это по порядку:

  1. Получите trace-ID сбойного запуска.
  2. Прочтите тот самый ввод для сбойного шага. Хорошо ли он сформирован? (Решает здесь ~50% случаев.)
  3. Проверьте результаты инструментов в этой трассе на ошибки, замаскированные под успех.
  4. Переиграйте шаг офлайн при temperature: 0. Воспроизводится?
  5. Если воспроизводится, это проблема промпта/модели — исправьте и перепрогоните корпус трасс. Если нет, это недетерминизм или баг состояния/оркестрации — прокрутите его 50×, чтобы охарактеризовать.

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

Часто задаваемые вопросы

Как мне отладить ИИ-агента, который падает лишь иногда?

Захватите тот самый ввод из залогированной трассы и переиграйте его 50+ раз при температуре 0. Перемежающиеся сбои — это настоящие баги с низкой частотой срабатывания; объём превращает байку в воспроизводимую выборку, которую можно сравнить и починить.

Баг обычно в модели или в моём коде?

В моих продакшен-агентах примерно 70% видимых «багов ИИ» — это обвязка: некорректно сформированные результаты инструментов, обрезанные вводы, проглоченные исключения или потерянное между шагами состояние. Исключите слои ввода и инструментов прежде, чем подозревать модель.

Какой минимум логирования мне нужен, чтобы отлаживать агентов?

Trace-ID на каждом запуске, плюс структурированные логи триггера, каждого вызова модели (полный массив сообщений), каждого вызова инструмента и его сырого результата, и финального вывода. Если шаг не залогирован, отладить его нельзя.

Как перестать отлаживать против живого продакшена?

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

Читать дальше

Получайте ИИ-руководство на почту

Каждую среду. 28 400+ читателей. Никакой воды.

↵ — все результаты esc esc — закрыть