vibecode.wiki
RU EN
~/wiki / dannye-i-khranenie / trassirovka-ai-zaprosov-kak-bystro-naiti-sboi-v-prode

Трассировка AI-запросов: как быстро найти сбой

Следующий шаг

Открой бота или продолжай маршрут внутри раздела.

$ cd раздел/ $ open @mmorecil_bot

Статья -> план в ИИ

Отправь ссылку на эту статью в любой ИИ и получи план внедрения под свой проект.

Прочитай эту статью: https://vibecode.morecil.ru/ru/dannye-i-khranenie/trassirovka-ai-zaprosov-kak-bystro-naiti-sboi-v-prode/ Работай в контексте моего текущего проекта. Сделай план внедрения под мой стек: 1) что изменить 2) в каких файлах 3) риски и типичные ошибки 4) как проверить, что всё работает Если есть варианты, дай "быстрый" и "production-ready".
Как использовать
  1. Скопируй этот промпт и отправь в чат с ИИ.
  2. Прикрепи проект или открой папку репозитория в ИИ-инструменте.
  3. Попроси изменения по файлам, риски и короткий чеклист проверки.

Введение

Простыми словами

Когда AI-функция ломается в проде, обычно видно только итог: пользователь получил ошибку, бот завис, задача не дошла до конца. Но непонятно, где именно всё сломалось: в API, в очереди, в модели, в базе данных или в вашем коде.

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

Как сделать на практике

Сразу запомните главный принцип: один пользовательский запрос = один идентификатор трассы (trace_id) на всех шагах. Если этого нет, вы не можете уверенно сказать, где произошел сбой.

Мини-лестница сложности:

  1. База: пишем структурированные логи в JSON.
  2. Рабочий минимум: добавляем trace_id и прокидываем его через все вызовы.
  3. Усиление: подключаем OpenTelemetry и смотрим трассы в UI.

Что сделать прямо сейчас:

  • Выберите один критичный сценарий (например, "создать ответ ассистента").
  • Проверьте, есть ли сейчас единый trace_id в каждом шаге.
  • Если нет, внесите это в ближайшую задачу как обязательное требование.

Коротко: суть в 5 пунктах

Простыми словами

Если упростить до минимума, наблюдаемость AI-сценария строится не вокруг "красивых дашбордов", а вокруг ответа на вопрос: "почему этот запрос сломался или стал медленным".

Как сделать на практике

  1. Логи без структуры почти бесполезны в момент инцидента.
  2. Без trace_id нельзя связать шаги одного запроса.
  3. Сначала покройте только 3 точки: вход, вызов модели, запись результата.
  4. Настройте 3 алерта: рост ошибок, рост задержки, рост таймаутов.
  5. Регулярно проверяйте 5-10 реальных трасс после релиза.

Мини-лестница сложности:

  1. База: читаемые логи с едиными полями.
  2. Рабочий минимум: трассировка и базовые алерты.
  3. Усиление: 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 — возврат ответа.

Мини-лестница сложности:

  1. База: пишете логи на каждом блоке.
  2. Рабочий минимум: в каждом блоке есть trace_id и duration_ms.
  3. Усиление: добавляете model_name, prompt_version, retry_count, token_usage.

Что сделать прямо сейчас:

  • Нарисуйте текущий путь запроса в 5-7 шагах.
  • Для каждого шага выпишите, где сейчас теряется контекст.
  • Определите 3 шага, которые нужно покрыть первыми.

Практическая часть по шагам

Шаг 1. Введите единый формат логов

Простыми словами

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

Как сделать на практике

Минимальные поля JSON-лога:

  • timestamp
  • level
  • service
  • trace_id
  • span
  • message
  • status
  • duration_ms

Пример на инструменте: Node.js + pino

bash
npm i pino pino-http
js
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,
  });
}

Мини-лестница сложности:

  1. База: единый JSON-формат.
  2. Рабочий минимум: обязательные поля валидируются в коде.
  3. Усиление: схема логов проверяется в CI.

Что сделать прямо сейчас:

  • Зафиксируйте обязательные поля логов в docs/logging.md.
  • Добавьте проверку, что trace_id не пустой.

Шаг 2. Прокиньте trace_id через весь сценарий

Простыми словами

trace_id должен создаваться один раз на входе и идти дальше в каждый вызов. Тогда вы всегда сможете собрать полную картину.

Как сделать на практике

  • На входе HTTP берите traceparent из заголовка или генерируйте новый trace_id.
  • Передавайте его в функции, фоновые задачи и внешние API.
  • Возвращайте trace_id в ошибке, чтобы саппорт быстро находил трассу.

Пример на инструменте: Express middleware

js
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();
}

Мини-лестница сложности:

  1. База: trace_id в HTTP-слое.
  2. Рабочий минимум: trace_id в очередях и воркерах.
  3. Усиление: поддержка стандарта 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;
  • краткую причину ошибки без чувствительных данных.

Важно: не логируйте секреты, токены и персональные данные. Если нужно, делайте маскирование.

Мини-лестница сложности:

  1. База: отдельные спаны для llm.call и tool.call.
  2. Рабочий минимум: фиксируете длительность и статус каждого спана.
  3. Усиление: добавляете версии промптов и агентов.

Что сделать прямо сейчас:

  • Добавьте 2 спана: llm.call и tool.call.
  • Убедитесь, что в логах нет токенов и паролей.

Шаг 4. Подключите OpenTelemetry и просмотр трасс

Простыми словами

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

Как сделать на практике

Базовый запуск в Node.js:

bash
npm i @opentelemetry/sdk-node @opentelemetry/auto-instrumentations-node
js
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) и проверяйте, что цепочка запроса отображается целиком.

Мини-лестница сложности:

  1. База: автосбор базовых спанов.
  2. Рабочий минимум: ручные спаны на критичных шагах.
  3. Усиление: кастомные атрибуты (версия релиза, промпта, клиента).

Что сделать прямо сейчас:

  • Поднимите локально один backend для трасс.
  • Проверьте, что один реальный запрос виден целиком.

Шаг 5. Настройте алерты, которые реально полезны

Простыми словами

Без алертов вы узнаете о проблеме от пользователей. Но слишком много алертов тоже плохо: команда перестает реагировать. Нужен рабочий минимум.

Как сделать на практике

Стартовый набор алертов:

  • Ошибки: доля status=error выше порога за 5 минут.
  • Задержка: p95 времени ответа выше порога.
  • Таймауты внешнего провайдера: рост timeout в llm.call.

Пример стартовых порогов:

  • error rate > 3% за 5 минут;
  • p95 > 6 секунд за 10 минут;
  • timeout на LLM > 2% за 10 минут.

Мини-лестница сложности:

  1. База: 1 алерт на ошибки.
  2. Рабочий минимум: 3 алерта (ошибки, задержка, таймауты).
  3. Усиление: отдельные пороги по моделям и типам запросов.

Что сделать прямо сейчас:

  • Настройте хотя бы один алерт на рост ошибок.
  • Проверьте, кто и как получает уведомление.

Реальные сценарии использования

Простыми словами

Ниже три типовых случая, где трассировка экономит часы ручного разбора.

Как сделать на практике

  1. Ошибка "500" только у части пользователей. По трассе видно: падает один инструмент crm.lookup при редком формате входного поля.
  2. Резкий рост задержки. По спанам видно: не LLM, а медленная запись в БД после ответа модели.
  3. Плавающий дубль сообщений. По trace_id видно повторную доставку задачи из очереди и отсутствие проверки ключа операции.

Мини-лестница сложности:

  1. База: ищете проблему по одной трассе.
  2. Рабочий минимум: группируете похожие трассы по ошибке.
  3. Усиление: строите дешборд по классам инцидентов.

Что сделать прямо сейчас:

  • Разберите последний продовый сбой через одну трассу.
  • Зафиксируйте, какого поля не хватило для быстрого анализа.

Инструменты и технологии

Простыми словами

Не нужно ставить "всё и сразу". Для старта достаточно одного логгера, одного сборщика трасс и одного интерфейса для просмотра.

Как сделать на практике

Рабочий набор для новичка:

  • pino или winston для структурированных логов в Node.js.
  • OpenTelemetry SDK для сбора спанов.
  • Jaeger/Tempo/Sentry для просмотра трасс.
  • PostgreSQL или ClickHouse для хранения агрегированных логов.

Как выбрать просто:

  • Если нужен быстрый старт на локалке: Jaeger.
  • Если уже есть Grafana: Tempo.
  • Если нужен продукт с готовыми алертами и issue workflow: Sentry.

Мини-лестница сложности:

  1. База: один инструмент визуализации трасс.
  2. Рабочий минимум: логи + трассы + 3 алерта.
  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.
  • Нет утечек секретов в логах.
  • Настроены алерты на ошибки и задержки.
  • Команда умеет найти причину инцидента по одной трассе.

Мини-лестница сложности:

  1. База: первые 4 пункта.
  2. Рабочий минимум: первые 7 пунктов.
  3. Усиление: все пункты + регулярный обзор трасс после релиза.

Что сделать прямо сейчас:

  • Пройдите чеклист на одном сервисе.
  • Отметьте 2 пробела и назначьте сроки исправления.

Типичные ошибки и как исправить

Простыми словами

Ошибки повторяются почти у всех команд. Хорошая новость: их можно закрыть простыми правилами.

Как сделать на практике

  1. Ошибка: логируете только "ошибка произошла" без контекста. Исправление: добавляйте trace_id, span, duration_ms, status.

  2. Ошибка: trace_id есть в API, но теряется в очереди. Исправление: передавайте trace_id как обязательное поле сообщения.

  3. Ошибка: логируете весь prompt и персональные данные. Исправление: маскируйте чувствительные поля, храните только нужные метаданные.

  4. Ошибка: алерты слишком шумные. Исправление: начните с 3 алертов и настройте пороги по фактической нагрузке.

  5. Ошибка: после релиза никто не смотрит трассы. Исправление: введите короткий "post-release review" на 10 минут.

Мини-лестница сложности:

  1. База: убрать потерю trace_id.
  2. Рабочий минимум: снизить шум алертов.
  3. Усиление: регулярный обзор качества трассировки.

Что сделать прямо сейчас:

  • Возьмите последнюю аварию и проверьте, какие поля тогда отсутствовали.
  • Добавьте эти поля в стандарт логов.

FAQ

Простыми словами

Короткие ответы на вопросы, которые обычно возникают у новичков.

Как сделать на практике

1. Нужно ли сразу внедрять полный observability-стек? Нет. Начните с JSON-логов и trace_id, затем подключите трассы для критичных шагов.

2. Что важнее первым: трассы или метрики? Для поиска причины конкретного сбоя чаще полезнее трассы. Для контроля общей стабильности важны метрики. На старте делайте оба, но с минимальным покрытием.

3. Можно ли жить только на логах? Можно на очень маленьком проекте, но при росте нагрузки и числа сервисов это быстро перестает работать.

4. Нужно ли логировать полный prompt? Обычно нет. Лучше хранить prompt_version, размер и ключевые метаданные. Полный текст храните только при строгих правилах безопасности.

5. Как понять, что внедрение удалось? Если команда находит корень типового инцидента за минуты, а не за часы, вы на правильном пути.

Что сделать прямо сейчас:

  • Соберите свои 3 внутренних FAQ по проекту.
  • Добавьте ответы в внутреннюю документацию.

Итог и следующий практический шаг

Простыми словами

Трассировка AI-запросов не про "красивую аналитику", а про скорость восстановления сервиса и спокойную эксплуатацию. Самый важный результат: вы перестаете гадать и начинаете видеть точную причину сбоя.

Как сделать на практике

Ваш ближайший шаг на сегодня:

  1. В одном критичном сценарии внедрить trace_id от входа до выхода.
  2. Добавить спаны llm.call и tool.call.
  3. Настроить один алерт на рост ошибок.

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

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