Трассировка AI-запросов: как быстро найти сбой
Следующий шаг
Открой бота или продолжай маршрут внутри раздела.
Статья -> план в ИИ
Отправь ссылку на эту статью в любой ИИ и получи план внедрения под свой проект.
Прочитай эту статью: https://vibecode.morecil.ru/ru/dannye-i-khranenie/trassirovka-ai-zaprosov-kak-bystro-naiti-sboi-v-prode/
Работай в контексте моего текущего проекта.
Сделай план внедрения под мой стек:
1) что изменить
2) в каких файлах
3) риски и типичные ошибки
4) как проверить, что всё работает
Если есть варианты, дай "быстрый" и "production-ready". Как использовать
- Скопируй этот промпт и отправь в чат с ИИ.
- Прикрепи проект или открой папку репозитория в ИИ-инструменте.
- Попроси изменения по файлам, риски и короткий чеклист проверки.
Введение
Простыми словами
Когда AI-функция ломается в проде, обычно видно только итог: пользователь получил ошибку, бот завис, задача не дошла до конца. Но непонятно, где именно всё сломалось: в API, в очереди, в модели, в базе данных или в вашем коде.
Эта статья для новичка, который уже запустил первый AI-сценарий и теперь хочет перестать чинить сбои вслепую. На выходе у вас будет рабочий минимальный шаблон: что логировать, как добавить trace_id, как связать шаги одного запроса и как быстро найти корень проблемы.
Как сделать на практике
Сразу запомните главный принцип: один пользовательский запрос = один идентификатор трассы (trace_id) на всех шагах. Если этого нет, вы не можете уверенно сказать, где произошел сбой.
Мини-лестница сложности:
- База: пишем структурированные логи в JSON.
- Рабочий минимум: добавляем
trace_idи прокидываем его через все вызовы. - Усиление: подключаем OpenTelemetry и смотрим трассы в UI.
Что сделать прямо сейчас:
- Выберите один критичный сценарий (например, "создать ответ ассистента").
- Проверьте, есть ли сейчас единый
trace_idв каждом шаге. - Если нет, внесите это в ближайшую задачу как обязательное требование.
Коротко: суть в 5 пунктах
Простыми словами
Если упростить до минимума, наблюдаемость AI-сценария строится не вокруг "красивых дашбордов", а вокруг ответа на вопрос: "почему этот запрос сломался или стал медленным".
Как сделать на практике
- Логи без структуры почти бесполезны в момент инцидента.
- Без
trace_idнельзя связать шаги одного запроса. - Сначала покройте только 3 точки: вход, вызов модели, запись результата.
- Настройте 3 алерта: рост ошибок, рост задержки, рост таймаутов.
- Регулярно проверяйте 5-10 реальных трасс после релиза.
Мини-лестница сложности:
- База: читаемые логи с едиными полями.
- Рабочий минимум: трассировка и базовые алерты.
- Усиление: sampling, дешборды по версиям промптов, контроль стоимости.
Что сделать прямо сейчас:
- Добавьте в тикет шаблон полей лога (
trace_id,span,status,duration_ms). - Назначьте ответственного за качество трассировки.
Словарь терминов
Простыми словами
Ниже короткий словарь, чтобы дальше не путаться в терминах.
Как сделать на практике
Observability(наблюдаемость): способность понять состояние системы по логам, метрикам и трассам.Trace(трасса): полная цепочка шагов одного запроса от входа до результата.Span(спан): один отдельный шаг внутри трассы, например вызов LLM или запись в БД.Trace ID: уникальный номер трассы, который связывает все шаги одного запроса.Structured logs(структурированные логи): логи в формате JSON с одинаковыми полями.Latency(задержка): сколько времени занял шаг или весь запрос.Sampling: выбор только части трасс, чтобы снизить нагрузку и стоимость хранения.Alert(алерт): автоматическое уведомление, когда метрика вышла за порог.SLO(целевой уровень сервиса): заранее согласованная цель качества, например "95% запросов до 3 секунд".
Что сделать прямо сейчас:
- Убедитесь, что вся команда одинаково понимает термины
traceиspan. - Добавьте словарь в README сервиса.
База и контекст: почему AI-сценарии трудно отлаживать
Простыми словами
В обычном веб-сервисе запрос часто проходит 1-2 шага. В AI-сценарии шагов больше: получение контекста, вызов модели, вызов инструмента, пост-обработка, запись результата. На любом участке может быть задержка или ошибка.
Проблема новичка в том, что логи есть, но они разбросаны. Один сервис пишет в файл, другой в stdout, третий вообще молчит. Из-за этого даже простая ошибка выглядит как детектив.
Как сделать на практике
Разделите путь запроса на блоки и назначьте каждому имя спана:
request.in— вход HTTP/webhook запроса;context.load— чтение данных из БД/кэша;llm.call— запрос к модели;tool.call— внешний API или внутренний инструмент;response.save— запись результата;request.out— возврат ответа.
Мини-лестница сложности:
- База: пишете логи на каждом блоке.
- Рабочий минимум: в каждом блоке есть
trace_idиduration_ms. - Усиление: добавляете
model_name,prompt_version,retry_count,token_usage.
Что сделать прямо сейчас:
- Нарисуйте текущий путь запроса в 5-7 шагах.
- Для каждого шага выпишите, где сейчас теряется контекст.
- Определите 3 шага, которые нужно покрыть первыми.
Практическая часть по шагам
Шаг 1. Введите единый формат логов
Простыми словами
Если каждый разработчик пишет логи как хочет, вы не сможете быстро искать и фильтровать события. Единый формат убирает хаос.
Как сделать на практике
Минимальные поля JSON-лога:
timestamplevelservicetrace_idspanmessagestatusduration_ms
Пример на инструменте: Node.js + pino
npm i pino pino-http
import pino from "pino";
const logger = pino({ level: process.env.LOG_LEVEL || "info" });
export function logStep(data) {
logger.info({
timestamp: new Date().toISOString(),
service: "ai-gateway",
...data,
});
}
Мини-лестница сложности:
- База: единый JSON-формат.
- Рабочий минимум: обязательные поля валидируются в коде.
- Усиление: схема логов проверяется в CI.
Что сделать прямо сейчас:
- Зафиксируйте обязательные поля логов в
docs/logging.md. - Добавьте проверку, что
trace_idне пустой.
Шаг 2. Прокиньте trace_id через весь сценарий
Простыми словами
trace_id должен создаваться один раз на входе и идти дальше в каждый вызов. Тогда вы всегда сможете собрать полную картину.
Как сделать на практике
- На входе HTTP берите
traceparentиз заголовка или генерируйте новыйtrace_id. - Передавайте его в функции, фоновые задачи и внешние API.
- Возвращайте
trace_idв ошибке, чтобы саппорт быстро находил трассу.
Пример на инструменте: Express middleware
import { randomUUID } from "node:crypto";
export function traceMiddleware(req, res, next) {
const incoming = req.headers["x-trace-id"];
const traceId = typeof incoming === "string" && incoming ? incoming : randomUUID();
req.traceId = traceId;
res.setHeader("x-trace-id", traceId);
next();
}
Мини-лестница сложности:
- База:
trace_idв HTTP-слое. - Рабочий минимум:
trace_idв очередях и воркерах. - Усиление: поддержка стандарта W3C
traceparent.
Что сделать прямо сейчас:
- Проверьте, что
trace_idдоходит в фоновые задачи. - Добавьте
x-trace-idв ответы API.
Шаг 3. Добавьте трассировку LLM-вызова и инструментов
Простыми словами
Обычно самая большая задержка и ошибки сидят в вызове модели и внешних инструментов. Эти шаги должны иметь отдельные спаны.
Как сделать на практике
Что записывать в спан llm.call:
provider(кто отвечает: OpenAI, Anthropic и т.д.);model(модель);prompt_version(версия шаблона);duration_ms;status(ok,timeout,error);token_usage(если доступно).
Что записывать в tool.call:
tool_name;http_status;retry_count;duration_ms;- краткую причину ошибки без чувствительных данных.
Важно: не логируйте секреты, токены и персональные данные. Если нужно, делайте маскирование.
Мини-лестница сложности:
- База: отдельные спаны для
llm.callиtool.call. - Рабочий минимум: фиксируете длительность и статус каждого спана.
- Усиление: добавляете версии промптов и агентов.
Что сделать прямо сейчас:
- Добавьте 2 спана:
llm.callиtool.call. - Убедитесь, что в логах нет токенов и паролей.
Шаг 4. Подключите OpenTelemetry и просмотр трасс
Простыми словами
OpenTelemetry — это открытый стандарт и набор библиотек для сбора телеметрии: логов, метрик и трасс. Он нужен, чтобы не собирать всё вручную и не привязываться к одному вендору.
Как сделать на практике
Базовый запуск в Node.js:
npm i @opentelemetry/sdk-node @opentelemetry/auto-instrumentations-node
import { NodeSDK } from "@opentelemetry/sdk-node";
import { getNodeAutoInstrumentations } from "@opentelemetry/auto-instrumentations-node";
const sdk = new NodeSDK({
instrumentations: [getNodeAutoInstrumentations()],
});
sdk.start();
Дальше отправляйте трассы в удобный backend (например, Tempo, Jaeger или Sentry) и проверяйте, что цепочка запроса отображается целиком.
Мини-лестница сложности:
- База: автосбор базовых спанов.
- Рабочий минимум: ручные спаны на критичных шагах.
- Усиление: кастомные атрибуты (версия релиза, промпта, клиента).
Что сделать прямо сейчас:
- Поднимите локально один backend для трасс.
- Проверьте, что один реальный запрос виден целиком.
Шаг 5. Настройте алерты, которые реально полезны
Простыми словами
Без алертов вы узнаете о проблеме от пользователей. Но слишком много алертов тоже плохо: команда перестает реагировать. Нужен рабочий минимум.
Как сделать на практике
Стартовый набор алертов:
- Ошибки: доля
status=errorвыше порога за 5 минут. - Задержка:
p95времени ответа выше порога. - Таймауты внешнего провайдера: рост
timeoutвllm.call.
Пример стартовых порогов:
- error rate > 3% за 5 минут;
- p95 > 6 секунд за 10 минут;
- timeout на LLM > 2% за 10 минут.
Мини-лестница сложности:
- База: 1 алерт на ошибки.
- Рабочий минимум: 3 алерта (ошибки, задержка, таймауты).
- Усиление: отдельные пороги по моделям и типам запросов.
Что сделать прямо сейчас:
- Настройте хотя бы один алерт на рост ошибок.
- Проверьте, кто и как получает уведомление.
Реальные сценарии использования
Простыми словами
Ниже три типовых случая, где трассировка экономит часы ручного разбора.
Как сделать на практике
- Ошибка "500" только у части пользователей. По трассе видно: падает один инструмент
crm.lookupпри редком формате входного поля. - Резкий рост задержки. По спанам видно: не LLM, а медленная запись в БД после ответа модели.
- Плавающий дубль сообщений. По
trace_idвидно повторную доставку задачи из очереди и отсутствие проверки ключа операции.
Мини-лестница сложности:
- База: ищете проблему по одной трассе.
- Рабочий минимум: группируете похожие трассы по ошибке.
- Усиление: строите дешборд по классам инцидентов.
Что сделать прямо сейчас:
- Разберите последний продовый сбой через одну трассу.
- Зафиксируйте, какого поля не хватило для быстрого анализа.
Инструменты и технологии
Простыми словами
Не нужно ставить "всё и сразу". Для старта достаточно одного логгера, одного сборщика трасс и одного интерфейса для просмотра.
Как сделать на практике
Рабочий набор для новичка:
pinoилиwinstonдля структурированных логов в Node.js.- OpenTelemetry SDK для сбора спанов.
- Jaeger/Tempo/Sentry для просмотра трасс.
- PostgreSQL или ClickHouse для хранения агрегированных логов.
Как выбрать просто:
- Если нужен быстрый старт на локалке: Jaeger.
- Если уже есть Grafana: Tempo.
- Если нужен продукт с готовыми алертами и issue workflow: Sentry.
Мини-лестница сложности:
- База: один инструмент визуализации трасс.
- Рабочий минимум: логи + трассы + 3 алерта.
- Усиление: единый дешборд качества AI-сценариев.
Что сделать прямо сейчас:
- Выберите один backend трасс и зафиксируйте его как стандарт команды.
- Не меняйте стек, пока не пройдете 2-3 реальных инцидента.
Сравнительная таблица подходов
Простыми словами
Таблица помогает выбрать подход по зрелости команды, а не по моде.
Как сделать на практике
| Подход | Что видно | Что не видно | Когда подходит |
|---|---|---|---|
| Только текстовые логи | Отдельные ошибки и сообщения | Полный путь запроса | Первый день, очень маленький проект |
| Логи + trace_id | Связь шагов одного запроса | Подробная визуализация задержек | Рабочий минимум для большинства команд |
| OpenTelemetry + backend трасс | Полный путь, узкие места, проблемные спаны | Бизнес-контекст без ваших полей | Прод и регулярные релизы |
| Полный observability-стек (логи + трассы + метрики + алерты) | Состояние системы в реальном времени | Ничего критичного, если верно настроен | Команда с постоянной нагрузкой и SLA |
Что сделать прямо сейчас:
- Честно отметьте, где вы сейчас по таблице.
- Следующим шагом перейдите минимум на уровень "Логи + trace_id".
Чеклист внедрения
Простыми словами
Чеклист нужен, чтобы не пропустить базовые вещи и не застрять в теории.
Как сделать на практике
- Есть единый формат JSON-логов.
- На входе создается или принимается
trace_id. -
trace_idпроходит через API, очередь и воркер. - Для
llm.callпишутсяstatusиduration_ms. - Для
tool.callпишутсяhttp_statusиretry_count. - Нет утечек секретов в логах.
- Настроены алерты на ошибки и задержки.
- Команда умеет найти причину инцидента по одной трассе.
Мини-лестница сложности:
- База: первые 4 пункта.
- Рабочий минимум: первые 7 пунктов.
- Усиление: все пункты + регулярный обзор трасс после релиза.
Что сделать прямо сейчас:
- Пройдите чеклист на одном сервисе.
- Отметьте 2 пробела и назначьте сроки исправления.
Типичные ошибки и как исправить
Простыми словами
Ошибки повторяются почти у всех команд. Хорошая новость: их можно закрыть простыми правилами.
Как сделать на практике
Ошибка: логируете только "ошибка произошла" без контекста. Исправление: добавляйте
trace_id,span,duration_ms,status.Ошибка:
trace_idесть в API, но теряется в очереди. Исправление: передавайтеtrace_idкак обязательное поле сообщения.Ошибка: логируете весь prompt и персональные данные. Исправление: маскируйте чувствительные поля, храните только нужные метаданные.
Ошибка: алерты слишком шумные. Исправление: начните с 3 алертов и настройте пороги по фактической нагрузке.
Ошибка: после релиза никто не смотрит трассы. Исправление: введите короткий "post-release review" на 10 минут.
Мини-лестница сложности:
- База: убрать потерю
trace_id. - Рабочий минимум: снизить шум алертов.
- Усиление: регулярный обзор качества трассировки.
Что сделать прямо сейчас:
- Возьмите последнюю аварию и проверьте, какие поля тогда отсутствовали.
- Добавьте эти поля в стандарт логов.
FAQ
Простыми словами
Короткие ответы на вопросы, которые обычно возникают у новичков.
Как сделать на практике
1. Нужно ли сразу внедрять полный observability-стек?
Нет. Начните с JSON-логов и trace_id, затем подключите трассы для критичных шагов.
2. Что важнее первым: трассы или метрики? Для поиска причины конкретного сбоя чаще полезнее трассы. Для контроля общей стабильности важны метрики. На старте делайте оба, но с минимальным покрытием.
3. Можно ли жить только на логах? Можно на очень маленьком проекте, но при росте нагрузки и числа сервисов это быстро перестает работать.
4. Нужно ли логировать полный prompt?
Обычно нет. Лучше хранить prompt_version, размер и ключевые метаданные. Полный текст храните только при строгих правилах безопасности.
5. Как понять, что внедрение удалось? Если команда находит корень типового инцидента за минуты, а не за часы, вы на правильном пути.
Что сделать прямо сейчас:
- Соберите свои 3 внутренних FAQ по проекту.
- Добавьте ответы в внутреннюю документацию.
Итог и следующий практический шаг
Простыми словами
Трассировка AI-запросов не про "красивую аналитику", а про скорость восстановления сервиса и спокойную эксплуатацию. Самый важный результат: вы перестаете гадать и начинаете видеть точную причину сбоя.
Как сделать на практике
Ваш ближайший шаг на сегодня:
- В одном критичном сценарии внедрить
trace_idот входа до выхода. - Добавить спаны
llm.callиtool.call. - Настроить один алерт на рост ошибок.
Если это сделано, у вас уже есть рабочий минимум, который дает реальную пользу в проде.