Наблюдаемость LLM-приложений: трассировка, стоимость, задержка, дрейф качества
LLM-приложения ломаются по-особенному, и традиционная наблюдаемость это упускает. Шаблоны для трассировки многошаговых потоков, отслеживания стоимости, которая меняется в 100 раз между вызовами, мониторинга дрейфа качества и отладки галлюцинаций в продакшене.
LLM-приложения ломаются иначе, чем обычное ПО. Обычный баг — это стек-трейс; «баг» LLM — это дрейф качества, который вы замечаете лишь когда жалуются пользователи. Обычная проблема с задержкой — это медленный эндпоинт; задержка LLM — это 30-секундная цепочка рассуждений, пока пользователь смотрит на спиннер.
Традиционная наблюдаемость (Datadog, New Relic, Sentry) сообщит вам, что API-вызов завершился за 8,4 секунды и потребил 12 847 входных токенов. Она не скажет, был ли ответ хорошим, галлюцинировала ли модель, был ли вызван не тот инструмент и не сместилось ли качество по сравнению с прошлой неделей.
Продакшен-системам на LLM нужен другой стек наблюдаемости. Или, как минимум, дополнительные слои поверх традиционного. В этой статье — что здесь особенного, что инструментировать и какие подходы работают.
Что в LLM-наблюдаемости другое
Несколько характерных черт LLM-систем, которые традиционная наблюдаемость не покрывает:
Недетерминизм на уровне единичного вызова. Один и тот же вход даёт разные выходы от вызова к вызову. На вопрос «всё ли отработало правильно?» нельзя ответить, проверив код статуса.
Качество как главная метрика. Задержка и стоимость важны, но качество важнее всего — и его сложнее всего измерять.
Многошаговые трассировки. Один пользовательский запрос может породить от 5 до 50 LLM-вызовов (агентные циклы, RAG-поиск, структурированное извлечение, рефлексия). Каждый вызов — часть более крупной трассировки.
Переменная стоимость на уровне токенов. Один вызов может стоить от €0.001 до €1.00 в зависимости от размера промпта, длины вывода и модели. Совокупные расходы требуют атрибуции по каждому вызову.
Дрейф во времени. Модели обновляются. Промпты эволюционируют. Распределение входных данных смещается. Качество движется — и вы должны видеть это движение.
Чувствительные данные. Входы и выходы часто и есть самые ценные диагностические данные, но они же — самые чувствительные. Дисциплина логирования имеет значение.
Длинные асинхронные потоки. Запуски агентов на минуты. Фоновые батч-задачи. Стриминговые ответы. Традиционная наблюдаемость «запрос/ответ» сюда не вписывается.
Это не теоретические опасения. С ними сталкивается каждая команда, эксплуатирующая LLM-системы в продакшене.
Стек наблюдаемости
Полный стек LLM-наблюдаемости включает следующие слои:
1. Инструментирование на уровне вызовов. Каждый LLM-вызов логируется: вход, выход, задержка, стоимость, модель, статус.
2. Инструментирование на уровне трассировок. Многоэтапные рабочие потоки сшиваются в трассировки. Вы видите полную цепочку вызовов для пользовательского запроса.
3. Метрики на уровне приложения. Агрегации по фичам, пользователям, тенантам.
4. Мониторинг качества. Выборочная или полная автоматическая оценка качества.
5. Сбор обратной связи пользователей. Явные (лайк/дизлайк) и неявные (регенерация, отказ) сигналы.
6. Алертинг. Алерты в реальном времени на скачки стоимости, деградацию задержки, падения качества, рост частоты ошибок.
7. Инструменты отладки. Когда что-то ломается, вы можете найти трассировку, увидеть входы и выходы, понять, что произошло.
Пройдёмся по каждому.
Инструментирование на уровне вызовов
Каждый LLM-вызов должен порождать лог-запись с полями:
{
"call_id": "uuid",
"timestamp": "2026-05-15T14:23:45Z",
"trace_id": "uuid", // for grouping into traces
"span_id": "uuid", // for parent-child relations
"feature": "summarize_document",
"prompt_version": "v3.2",
"model": "claude-4-sonnet",
"provider": "anthropic",
"input_messages": [...],
"output_message": "...",
"input_tokens": 1842,
"output_tokens": 384,
"total_tokens": 2226,
"cost_usd": 0.0084,
"latency_ms": 2340,
"first_token_ms": 1240, // streaming
"status": "success",
"error": null,
"user_id": "user_123",
"tenant_id": "tenant_45",
"metadata": {
"session_id": "...",
"experiment_arm": "v3_test"
}
}Это абсолютный минимум. Захватывайте всё.
Ключевые решения при реализации:
Куда логировать. Варианты:
- Специализированный инструмент наблюдаемости (Helicone, LangSmith, Phoenix, Braintrust, Arize).
- Универсальная платформа наблюдаемости с LLM-расширениями (Datadog LLM Observability, Sentry).
- Собственные логи/база данных.
Для большинства команд: выбирайте специализированный инструмент. У них есть готовые UI для разбора LLM-вызовов. Кривая обучения умеренная по сравнению с собственной разработкой.
Для крупных команд: микс. Используйте специализированный инструмент для LLM-ориентированного UI, но также отправляйте данные в свою центральную платформу наблюдаемости для кросс-системной корреляции.
Как инструментировать. Варианты:
- Прокси между приложением и провайдером LLM (модель Helicone).
- SDK-обёртка в коде приложения.
- Класс-обёртка, который вы вызываете вручную при каждом обращении к LLM.
Прокси проще всего, но добавляют задержку. SDK чище, но требуют интеграции. Ручная обёртка наиболее гибкая, но её легче всего забыть применить.
Прагматичный подход: SDK-обёртка на границе, где приложение обращается к LLM. Одно место для инструментирования; всё остальное проходит через него.
Что логировать. Несколько практических соображений:
- Усекайте очень длинные входы/выходы (но логируйте факт усечения).
- Хэшируйте или редактируйте PII (с возможностью восстановить оригинал через безопасный поиск при необходимости).
- Не логируйте учётные данные, даже в путях ошибок.
- Для стриминга логируйте и first-token-latency, и total-latency.
Инструментирование на уровне трассировок
Одно пользовательское действие часто включает много LLM-вызовов. Без инструментирования на уровне трассировок у вас тысяча логов вызовов и никакого способа узнать, какие из них относились к какому пользовательскому действию.
Реализация:
Генерация trace ID. Сгенерируйте уникальный trace ID в начале пользовательского запроса. Пробрасывайте его во все последующие вызовы.
Спаны «родитель–потомок». В рамках одной трассировки каждый вызов имеет span ID и (опционально) parent span ID. Это создаёт дерево с иерархией вызовов.
Именование операций. Каждый спан именуется («summarize_document», «extract_entities», «tool_call:search»). Трассировка показывает полную цепочку операций.
Вид трассировки в UI:
Trace abc-123 (12.3s total)
├─ classify_intent (450ms) [gpt-5-mini]
├─ retrieve_documents (1.2s) [embedding + search]
├─ generate_response (8.5s) [claude-4-sonnet]
│ ├─ tool_call: search_internal (320ms)
│ ├─ tool_call: lookup_customer (180ms)
│ └─ generate_final_text (7.5s)
└─ judge_response_quality (2.1s) [claude-4-haiku]Теперь вы видите, что именно система сделала для этого пользовательского запроса. Можно найти медленные вызовы, дорогие вызовы, упавшие вызовы — в контексте.
Инструменты, которые с этим хорошо справляются: LangSmith, Phoenix (Arize), Helicone с кастомной интеграцией. Плюс универсальные системы наблюдаемости (Datadog, OpenTelemetry) для кросс-системной трассировки.
Метрики на уровне приложения
Помимо отдельных вызовов — агрегированные метрики:
По фиче.
- Объём вызовов.
- Средняя задержка.
- p50, p95, p99 задержки.
- Средняя стоимость запроса.
- Частота ошибок.
- Оценка качества (если измеряется).
По пользователю/тенанту.
- Вызовы на пользователя в день.
- Стоимость на пользователя.
- Тяжёлые пользователи / шаблоны злоупотреблений.
По модели.
- Объём по моделям.
- Доля стоимости по моделям.
- Частота ошибок по моделям.
- Качество (там, где измеряется) по моделям.
По фиче × по модели.
- Какие фичи используют какие модели?
- Где можно переключиться на более дешёвую модель?
Эти дашборды двигают операционные решения: какие фичи дорогие, какие медленные, какие нуждаются в оптимизации.
Мониторинг качества
Самый сложный слой: автоматическая оценка качества.
Для эвалов (которые мы разбираем отдельно) вы запускаетесь на заданном датасете. Для онлайн-мониторинга качества — оцениваете продакшен-трафик.
Подходы:
LLM-как-судья на выборке. Сэмплируйте, скажем, 1% продакшен-трафика. Для каждого случая запускайте судью-LLM, который оценивает ответ по релевантным измерениям. Отслеживайте оценки во времени. Алертите на падения.
Неявные сигналы. Отслеживайте регенерации, отказы, частоту ошибок, время до завершения, частоту последующих сообщений. Это слабые, но дешёвые сигналы. Используйте как опережающие индикаторы.
Явная обратная связь пользователей. Лайк/дизлайк, кнопки «помогло ли это?», явные жалобы. Самый сильный сигнал, но наименьший объём.
Детекция шаблонов. Конкретные нежелательные шаблоны («I cannot help with that», «I'm just an AI», повторяющиеся отказы) автоматически помечаются. Сразу ловит часть регрессий.
Типичная схема:
- Сэмплируем 1% продакшен-вызовов.
- Запускаем LLM-судью на каждом, оценивая по нескольким измерениям.
- Агрегируем до дневных оценок по фичам.
- Алертим, если какая-то фича падает более чем на 10% неделя к неделе.
Стоимость реальна, но ограничена (1% трафика × небольшая модель-судья = подъёмно для большинства команд).
Наблюдаемость стоимости
Расходы на LLM могут раскрутиться по спирали. Один баг — зацикленные ретраи, фича, расходующая в 10 раз больше токенов, чем ожидалось — может породить десятикратный счёт ещё до того, как кто-нибудь заметит.
Слои наблюдаемости стоимости:
Стоимость каждого вызова. Стоимость считается в момент логирования. Агрегаты доступны сразу.
Алерты по бюджету. Дневные, недельные, месячные бюджеты по фичам/тенантам. Алерт при пересечении порогов (50%, 75%, 90%, 100%).
Детекция аномалий. Дневная стоимость в 5 раз выше типичной? Алерт. Стоимость одного вызова в 100 раз выше типичной? Алерт.
Атрибуция стоимости. По фичам, тенантам, пользователям. Найдите тяжёлых потребителей.
Прогноз. Исходя из текущей траектории, каким будет счёт к концу месяца?
Полезный вид дашборда: одна панель, где сегодняшние расходы сравниваются с остальной частью этой недели и с прошлой неделей, в разбивке по фичам.
Практический совет: где возможно, ставьте жёсткие лимиты. Фича, которая должна стоить €X/день, имеет автоматическое отключение на 10X. Расходы разгоняются быстро; лимит их ловит.
Наблюдаемость задержек
Задержка в LLM устроена тоньше, чем в обычных API:
Полная задержка. От запроса до финального ответа.
Время до первого токена (TTFT). Для стриминга — когда пользователь видит первый символ? Именно это определяет воспринимаемую задержку в чат-UX.
Время до последнего токена (TTLT). Сколько прошло до полного ответа?
Токенов в секунду. Скорость вывода. Одни модели стримят медленнее других.
Задержка вызовов инструментов. Для агентных потоков — время на вызовы инструментов против LLM-вызовов.
Отслеживайте всё это. Разные стратегии оптимизации работают на разные метрики.
Для чата с пользователем главное TTFT. Медленный первый токен ощущается как поломка; медленная скорость токенов в секунду — как постепенность.
Для батч-обработки важна полная задержка; пропускная способность важнее.
Для агентов задержка инструментов часто доминирует; оптимизация LLM не поможет, если медленны инструменты.
Наблюдаемость ошибок
Специфические для LLM ошибки:
API-ошибки. Лимиты, отказы авторизации, серверные ошибки. Как у любого API.
Ошибки валидации. Структурированный вывод не соответствует схеме. Отслеживайте частоту по фичам.
Ошибки контент-фильтра. Провайдер заблокировал запрос. Отслеживайте, чтобы выявлять проблемы с промптом.
Ошибки инструментов. Конкретные инструменты падают. Отслеживайте по каждому.
Ошибки качества. Судья-LLM оценил вывод как плохой. Отслеживайте во времени.
Сигналы галлюцинаций. Детекция вероятных галлюцинаций (модель утверждает то, чего нет в источнике). Сложно детектировать автоматически, но можно аппроксимировать.
Ошибки по стоимости. Вызовы, стоящие сильно дороже ожидаемого. Часто указывают на баг.
У каждой — свой дашборд. Каждая может триггерить алерты.
Инструменты отладки
Когда что-то ломается, нужно найти проблему и понять её. Поверхность отладки включает:
Поиск по трассировкам. Найти запрос конкретного пользователя по trace ID, user ID или таймстампу.
Инспектор вызова. Для любого вызова увидеть полный запрос, ответ, параметры, задержку, стоимость.
Таймлайн трассировки. Для сложных потоков — визуальная цепочка вызовов.
Возможность повтора. Имея старый вызов, можно ли перезапустить его с другим промптом/моделью и увидеть, что бы получилось? Критично для проверки исправлений.
Сравнение (diff). Сравнение двух вызовов — разные версии одного промпта, разные модели — бок о бок.
Поиск по содержанию. Поиск по корпусу прошлых вызовов по конкретным шаблонам («покажи мне вызовы, где модель сказала „I cannot help“»).
Эти возможности и дают специализированные инструменты LLM-наблюдаемости. Сделать их самим — заметный объём работы; использовать готовый инструмент обычно дешевле.
Приватность и PII
Логи LLM-наблюдаемости чувствительны. Входы могут содержать PII; выходы могут цитировать PII. Иногда без их логирования не обойтись — они нужны для отладки.
Практики:
Токенизация/хэширование. Замена идентификаторов на токены. Оригинал восстанавливается через отдельный безопасный поиск. Основная масса логов — без PII.
Редактирование на этапе логирования. Детекция и редактирование PII до того, как они попадут в хранилище наблюдаемости. Конкретные паттерны (email, телефоны, SSN) заменяются на плейсхолдеры.
Изоляция тенантов. Данные наблюдаемости в мультитенантной системе изолированы по тенантам. Данные одного тенанта не видны другому.
Контроль доступа. Кто может видеть сырые входы/выходы? Это логируется.
Политики хранения. Логи старше X дней удаляются или переезжают в холодное хранилище. У хранения PII во многих юрисдикциях есть юридические ограничения.
Право на забвение. Когда пользователь запрашивает удаление (GDPR), его логи должны находиться и удаляться.
Это не опционально для любой системы, работающей с PII. Делайте сразу правильно; ретроспективное доделывание мучительно.
Алертинг
Пороги и сигналы, заслуживающие алертов:
Стоимость.
- Дневная стоимость > 2× типичной.
- Стоимость одного вызова > €5.
- Часовой скачок стоимости > 5×.
Задержка.
- p95-задержка > 2× базовой.
- TTFT > 5 с для чат-UX.
- Растёт число таймаутов на вызовах инструментов.
Частота ошибок.
- Частота ошибок > 1% (типичная база — 0,1–0,5%).
- Скачок конкретного типа ошибок (ошибки валидации, rate limits).
Качество.
- Оценка качества упала более чем на 10% неделя к неделе на любой фиче.
- Доля негативной обратной связи выше базовой.
- Доля регенераций выше базовой.
Шаблоны.
- Конкретные нежелательные фразы появляются чаще.
- Резкое изменение распределения входных данных.
Каждый алерт должен быть конкретным и actionable. «Стоимость высокая» бесполезно; «фича X стоила 10× бюджета за последние 30 минут — вероятно, разгон в сессии клиента Y» — actionable.
Особенности мультитенантности
Для B2B SaaS-приложений:
Метрики по тенанту. Каждый клиент видит своё потребление, расходы и качество.
Алерты по тенанту. Под их собственные пороги.
Отладка по тенанту. Поддержка может видеть трассировки клиента (с надлежащим контролем доступа).
Конфигурация по тенанту. У некоторых клиентов могут быть другие модели, промпты или политики. Слой наблюдаемости это отражает.
Это добавляет сложности, но при масштабе B2B это обязательно. Поддержка не сможет помочь с «ИИ у меня не работает» без доступа к трассировкам на уровне тенанта.
Экосистема инструментов (2026)
Обзор ландшафта LLM-наблюдаемости на момент написания:
Специализированная LLM-наблюдаемость:
- Helicone. Прокси; легко интегрируется; сильные дашборды.
- LangSmith. Связан с экосистемой LangChain; глубокая трассировка.
- Phoenix (Arize). Дружелюбен к open-source; силён в мониторинге качества.
- Braintrust. Силён в сочетании эвалов и наблюдаемости.
- PromptLayer. Сфокусирован на промптах; силён в отслеживании версий.
- Weights & Biases Weave. Удобен ML-командам; интегрируется с экосистемой W&B.
Универсальный APM с LLM-расширениями:
- Datadog LLM Observability. Корпоративного уровня; дорогой.
- New Relic LLM Observability. Похоже.
- OpenTelemetry + ваш APM. У OTel есть семантические соглашения GenAI; инструментируете один раз, смотрите во многих инструментах.
Своё:
- Таблица Postgres с одной строкой на вызов уведёт большинство команд достаточно далеко.
- Добавьте простой UI для поиска и отображения.
- Интегрируйте с существующей инфраструктурой логирования.
Правильный выбор зависит от размера команды, масштаба, бюджета и существующего стека. Большинство команд начинают со специализированного инструмента и мигрируют на более комплексную схему по мере масштабирования.
Практическая схема внедрения
Для типичной команды среднего размера, начинающей с нуля:
Неделя 1: Выберите инструмент (Helicone — частый простой старт). Интегрируйте с основным путём LLM-вызовов. Убедитесь, что вызовы логируются.
Неделя 2: Настройте базовые дашборды. Стоимость, задержка, частота ошибок по фичам.
Неделя 3: Настройте алерты на скачки стоимости и рост частоты ошибок.
Неделя 4: Добавьте инструментирование на уровне трассировок. Соедините спаны между многошаговыми потоками.
Месяц 2: Внедрите сэмплирование качества. Выберите несколько фич. Настройте оценку LLM-судьёй на 1% трафика.
Месяц 3: Добавьте сбор обратной связи пользователей. Подключите лайк/дизлайк или аналог.
Месяц 4: Мультитенантная поддержка, точечный алертинг, инструменты отладки.
Это работающий стек наблюдаемости. Каждый слой добавляет возможность. Каждый стоит того, чтобы его построить. Пропуск любого создаёт слепое пятно.
Что идёт не так без него
Короткий каталог инцидентов, которые мы наблюдали в командах без нормальной LLM-наблюдаемости:
- Баг заставил фичу ретраить вызовы в плотном цикле. За выходные накопились непредвиденные расходы пятизначной величины. Заметили только когда пришёл месячный счёт. (Мы видели вариации этой истории столько раз, что конкретные цифры значат меньше, чем сам шаблон.)
- Обновление модели тихо изменило поведение. Качество упало на ключевой фиче. Пользователи жаловались, но инженеры считали это «случайной странностью». Два месяца, пока связали с обновлением модели.
- Развернули новую версию промпта. Она случайно регрессировала важный пользовательский поток. Без метрик по потокам никто неделями не замечал.
- Агентная система зациклилась. У некоторых сессий было 200+ LLM-вызовов. Часы расследования, чтобы найти цикл, потому что не было инструментирования на уровне трассировок.
- Сбой аутентификации инструмента каскадно ввёл агента в «растерянность». Агент продолжал «пробовать вещи» и накручивать расходы. Без алертов это шло часами.
- Промпт-инъекция заставила ИИ слить системные инструкции. Утекли PII. Без наблюдаемости команда не могла легко определить, каких пользователей это коснулось.
Это не теория. Это случается. Наблюдаемость предотвращает большинство случаев или ловит их быстро.
Ключевая мысль
LLM-наблюдаемость — это самостоятельная дисциплина. Традиционный APM необходим, но недостаточен. Все конкретные слои — на уровне вызовов, трассировок, качества, стоимости, задержек, ошибок, отладки — нужны.
Инструменты существуют. Выберите один. Интегрируйте рано. Вкладывайтесь в дашборды, алерты и процессы, которые ловят проблемы раньше пользователей.
Команды, которые так делают:
- Ловят баги за часы, а не за недели.
- Управляют стоимостью предсказуемо, а не получают сюрпризы в счетах.
- Держат качество во времени, а не дрейфуют.
- Отлаживают системно, а не наугад.
Команды, которые так не делают, рано или поздно сталкиваются с инцидентом, который их вынуждает. Лучше инструментировать до инцидента, чем после.