AI observability: почему ответы модели деградируют в продакшене
Отказ, который не видно на дашбордах, — самый дорогой. Сервис отвечает, время отклика в норме, доля ошибок нулевая, а качество ответов тихо уезжает: модель стала чаще пропускать условия из инструкции, в ответах появились факты без источника, на части запросов потерялся контекст предыдущих шагов. Инфраструктурный мониторинг такое не поймает — он смотрит на доступность и задержки, а не на смысл того, что вернулось пользователю.
Типовых мест потери контекста три. Первое — сбой одного шага в цепочке вызовов: поиск вернул пустой результат, шаг нормализации отдал обрезанный фрагмент, и дальше модель достроила ответ по догадке. Второе — незамеченная смена поведения после обновления модели или промпта: формально тот же контракт, но изменились длина ответа, формат ссылок, готовность следовать ограничениям. Третье — ответы без источника, когда ссылка на документ либо отсутствует, либо ведёт не туда.
Ловятся такие отказы обычно от пользователей: приходит жалоба на конкретный ответ, и дальше начинается разбор инцидента по логам. Диагностика упирается в то, что запрос и ответ сохранены как одна строка, без разбивки по шагам, без входных данных каждого вызова, без версии промпта и модели. Воспроизвести ситуацию не получается — входные данные уже изменились, а сборки оценок и регрессионных наборов нет.
Именно это закрывает наблюдаемость AI-сервисов: трассировка всей цепочки с сохранением промежуточных результатов, привязка к версиям промптов и моделей, регулярная оценка ответов по набору проверок и алерты на сдвиг качества, а не только на ошибки. Ниже разбираем, как это устроено и какие инструменты для AI observability берём в работу.
Что даёт AI observability: измеримые изменения
Трассировка обращений к модели даёт связку «запрос — найденный контекст — ответ — оценка». Сбор метрик идёт на стороне приложения, поэтому видно не только факт сбоя, но и шаг, где он возник: подготовка промпта, поиск по базе знаний, вызов инструмента, постобработка.
Платформы этого класса — от открытого Langfuse до облачных сервисов — принимают такие трассировки без переписывания логики приложения. Эффект от наблюдаемости считается в проверяемых величинах.
Время разбора инцидентов
Жалоба «модель отвечает не то» раньше разбиралась вручную: воспроизвести диалог, найти версию промпта, сопоставить с релизом. По трассировке инцидент локализуется за минуты — видны входные данные, сработавшие инструменты и полный текст ответа, поэтому не приходится гадать о контексте.
Доля пойманных отклонений
Автоматические оценки считают долю ответов, прошедших проверки на релевантность, корректность формата и отсутствие выдуманных фактов. Отклонения видны на всей выборке, а не только на тех диалогах, которые кто-то успел открыть.
Объём ручных проверок
Ручной просмотр сужается до среза: система сама отбирает ответы с низкой оценкой, долгим откликом или необычным расходом токенов. Объём обращений к модели виден по каждому сценарию — понятно, какие подсказки и разделы базы знаний тянут нагрузку, а какие не используются.
Варианты подключения наблюдаемости: сравнение
Телеметрию снимают двумя способами: изнутри приложения — клиентской библиотекой платформы, либо снаружи — шлюзом между приложением и моделью. Первый видит всю цепочку шагов, поиск по базе знаний и вызовы инструментов; второй не требует правок в коде, но фиксирует только обмен с моделью. Ниже — пять режимов сбора телеметрии и границы каждого.
| Вариант | Когда подходит | Ограничения |
|---|---|---|
| Инструментирование внутри приложения | Нужны спаны по шагам цепочки, поиску по базе знаний, вызовам инструментов | Правки в коде и сопровождение версий библиотеки |
| Внешний шлюз телеметрии перед моделью | Быстрый старт без правок в коде, единая точка для всех сервисов | Видит только обмен с моделью, внутренние шаги не раскрывает |
| Облачный сервис наблюдаемости — LangSmith, Helicone | Своего хранилища нет, нужны готовые панели и разбор ошибок | Данные уходят поставщику сервиса, есть лимиты по объёму |
| Открытая платформа трассировки в своём контуре — Langfuse | Требование хранить промпты и ответы у себя | Развёртывание, обновления и резервные копии на вашей стороне |
| Самостоятельная сборка: коллектор телеметрии и своё хранилище | Нестандартные метрики и своя схема хранения | Разработка и поддержка целиком на вашей стороне |
Режимы обычно комбинируют: шлюз собирает сетевой слой по всем сервисам сразу, а библиотека добавляет детализацию на критичных сценариях. Если промпты и ответы не могут покидать ваш контур, облако отпадает — остаётся открытая платформа или самостоятельная сборка.
Порядок внедрения: от аудита до передачи
Наблюдаемость LLM-приложения не появляется от подключения библиотеки: сначала нужно понять, какие вызовы происходят и что по ним требуется восстановить при разборе инцидента. Ниже — порядок работ, по которому мы идём от инвентаризации до передачи регламентов команде заказчика.
Аудит и инвентаризация вызовов
Собираем карту всех точек вызова модели: пользовательские сценарии, фоновые задачи, цепочки агентов, служебные и повторные запросы. Для каждой точки фиксируем состав трассировки — идентификатор сессии, версию промпта, вход и выход, расход токенов, задержку, статус. Отдельным списком идёт то, что хранить нельзя: персональные данные и ключи маскируются до записи.
Схема потоков и хранение данных
Проектируем путь телеметрии до хранилища: запись из приложения или через прокси-слой, поведение при недоступности приёмника, прореживание рутинных вызовов, чтобы объём не рос линейно. Готовые платформы вроде Langfuse закрывают визуализацию, но размещение и срок жизни данных диктуют требования заказчика.
- Инвентаризация вызовов и согласование перечня полей.
- Схема сбора: точки съёма, формат событий, буфер на стороне приложения.
- Настройка хранения: политика очистки, срок жизни записей, маскирование.
- Проверка на тестовом контуре: прогон сценариев, сверка с логами, разбор учебного инцидента.
- Оценка роста объёма и поведение под нагрузкой.
- Передача регламентов: чтение трассировки, алерты, действия при сбое сбора.
Артефакты на выходе: что остаётся у команды
Мы передаём не отчёт о проделанной работе, а работающий контур наблюдаемости, который команда дальше ведёт сама. Все материалы лежат в репозитории рядом с кодом: правки проходят ревью, история изменений сохраняется, а зависимости от внешних сервисов описаны явно.
Конфигурации и схемы
- Конфигурация сбора данных: какие вызовы модели пишутся целиком, что уходит в выборочную запись, где вырезаются персональные данные — до сохранения, а не после.
- Схема потоков телеметрии: точки съёма, буферы, хранилище трейсов, срок хранения и поведение системы, когда приёмник недоступен.
- Настроенный проект в Langfuse с дашбордами: задержка ответа, доля ошибок, расход токенов по моделям и сценариям.
- Справочник метрик и разметки: что считается ошибкой, как помечаются сценарии, по каким разрезам строятся срезы.
Политики доступа и регламенты
- Политики доступа к данным: роли, кому видны полные трейсы, кому — только агрегаты, сроки хранения и порядок удаления по запросу.
- Оповещения об отклонениях: пороги по доле ошибок, задержке и расходу, каналы уведомлений, порядок дежурства.
- Регламент разбора инцидентов: кто открывает разбор, за какое время, что фиксируется в выводе и как проверяется исправление.
После передачи инженеры добавляют новые метрики и меняют пороги без нас — это одна правка в конфигурации, а не отдельный проект.
Кейс: как сократили время разбора инцидентов
Клиент — сервис с AI-ассистентом: ответ собирается из нескольких обращений к модели и вызовов внутренних сервисов. Обратились после серии жалоб — ответы приходили пустыми, обрезанными или не по теме, а воспроизвести сбой по логам приложения не удавалось.
Что было до
Диагностика держалась на текстовых логах: виден факт запроса и код ответа, но не видно, какой шаг цепочки испортил результат. Контекст собирали вручную, и это съедало основную часть времени.
- Локализация сбоя — 5–6 часов, если контекст вообще удавалось собрать.
- Первопричина находилась в 40% случаев, остальное закрывали перезапуском — и жалоба возвращалась.
- Повторные обращения по той же проблеме — около трети пользователей.
- До 25 инцидентов в месяц, часть замечал только клиент.
Что изменилось после
Развернули трассировку на Langfuse: каждый запрос — дерево шагов с входом, выходом, задержкой и числом токенов, поэтому сбойный шаг виден без ручной сборки. Сверху — набор эталонных вопросов с автопроверкой ответов и оповещения на падение доли успешных ответов.
- Локализация сбоя — 15–20 минут вместе с подтверждением причины.
- Первопричина находится в 9 из 10 разборов, спорные случаи закрываются ссылкой на трассу.
- Повторные обращения снизились на 60%: разбор заканчивается правкой, а не перезапуском.
- Инцидентов — с 25 до 8 в месяц, остальное ловит регрессионный набор до релиза.
Каждый разбор пополняет набор проверок, поэтому похожий сбой всплывает на тестировании, а не у клиента.
Чем трассировка отличается от логирования запросов
Логи — плоский поток: строка на входящий запрос, строка на ответ, отдельная на ошибку. Пока запрос один, картина читается; под параллельной нагрузкой события разных пользователей перемешиваются, и причину сбоя восстанавливают по меткам времени — с ошибками на границах шагов.
Трассировка описывает запрос деревом шагов с общим сквозным идентификатором. В одной трассе видно, сколько фрагментов подняли из хранилища, с какими параметрами вызвали модель, какие инструменты дёрнули и сколько занял каждый шаг. Родительско-дочерние связи показывают цепочки вызовов модели, включая вложенные и повторные обращения, которые в журнале выглядят как набор несвязанных строк.
Разница заметна при разборе деградации. По логам видно, что время ответа выросло; по трассе — что тормозит именно поиск по базе знаний, а генерация осталась прежней. Корреляция шагов обработки позволяет сравнивать два прогона одного запроса после смены промпта или модели и видеть, где результаты расходятся, вместо догадок по финальному тексту.
Логирование при этом не отменяется: журналы шире и дешевле, они покрывают инфраструктуру, отказы, ограничения доступа — всё, что происходит вне обработки конкретного запроса. Контекст запроса и ответа хранится на своём уровне трассы и не смешивается с общим потоком, а связка держится на сквозном идентификаторе запроса в каждой записи: от аномалии в метрике переходишь к трассе и к нужным строкам журнала без ручного сопоставления по времени. Из этой связки и собирается наблюдаемость — когда метрики, трассы и журналы ссылаются друг на друга.
Ограничения: хранение данных, приватность, задержки
Трассы растут линейно вслед за трафиком, и объём хранилища телеметрии быстро становится главной статьёй содержания контура. Поэтому срок хранения задаём политикой: детальные трейсы со всеми шагами живут короткое окно, агрегированные метрики качества — длинное. Выборка тоже управляемая: полные трейсы пишутся для доли запросов, остальные дают метрики без тел промптов и ответов.
Приватность данных запросов решается на входе, а не вычисткой задним числом. Чувствительные поля — персональные данные, реквизиты, ключи доступа — размечаются списком правил и закрываются маскированием или хешированием на стороне приложения, ещё до записи в хранилище. В трейсе остаётся структура вызова и метрики, достаточные для разбора, но не текст, который нельзя показывать вне контура. Список правил сопровождается вместе с изменениями в коде — иначе новое поле в форме снова начнёт утекать в телеметрию.
Влияние сбора на задержку ответа снимается тем, что экспорт идёт вне критического пути: запись в локальный буфер, отправка пакетами, никаких синхронных сетевых вызовов между моделью и пользователем. Если политика запрещает вынос данных, трейсы остаются в вашем контуре — Langfuse разворачивается внутри вашей сети, и наружу не уходит ни один фрагмент запроса.
Сбор трейсов замедлит ответы пользователю?
Нет, если он вынесен за критический путь. Приложение пишет событие в локальный буфер, отдельный процесс отправляет пакеты в хранилище. При недоступности хранилища буфер ограничен по размеру и сбрасывает старые события, а не блокирует запрос к модели.
Обсудим задачу: что уточняем на первом разборе
Такой разбор занимает меньше часа и не требует подготовленной инфраструктуры — достаточно, чтобы с вашей стороны был человек, который знает контур, и доступ к описанию того, как сейчас устроены вызовы моделей. Мы разбираем задачу наблюдаемости, фиксируем, что уже собирается, и возвращаемся с оценкой и планом работ.
- перечень исходных данных: какие сервисы обращаются к моделям, где живут промпты, как выглядит текущее логирование и в каком виде приходят трассировки;
- объёмы: примерное число запросов в сутки, длина контекста, доля ответов, которые сейчас разбирают вручную;
- порядок доступа к контуру: кто выдаёт ключи к среде, нужны ли согласования и в каком режиме разрешён доступ — только чтение метрик или развёртывание сборщика;
- требования к приватности: какие поля нельзя выносить за периметр, что маскируем до отправки, где хранится история;
- вопросы, на которые система должна отвечать: где теряется время, какие запросы дороже остальных, почему часть ответов уходит в брак;
- роли: кто со стороны заказчика принимает результат и в какие сроки первого этапа мы укладываемся.
После разбора вы получаете состав этапов с порядком работ, точки контроля и понимание, что понадобится от вашей команды на каждом шаге. Опишите задачу — вернёмся с оценкой и планом.
- Подключают наблюдаемость сразу ко всем сценариям и потокам, вместо одного самого нагруженного участка — объём растёт, а разобрать конкретный сбой по-прежнему нечем.
- Пишут в хранилище каждый запрос и ответ целиком, без выборки и разметки значимых событий: нужный случай тонет в шуме, разбор затягивается.
- Не фиксируют, какая версия запроса к модели и настроек работала в момент сбоя, поэтому нельзя сравнить «до и после» и понять, что именно вызвало деградацию.
- Собирают метрики качества отдельно от трассировки: цифры падают, но связь с конкретным шагом обработки не восстановить, приходится угадывать.
- Оставляют в трассах персональные данные и содержимое обращений без очистки и маскировки — при разборе инцидента открывается доступ к лишнему.
- Не назначают владельца разбора: наблюдаемость включена, данные копятся, но никто не смотрит на отклонения, пока о них не сообщит клиент.
- Отключают сбор после нескольких спокойных недель — к следующему обновлению нет опорной картины, и любое изменение качества снова выглядит необъяснимым.
- Ожидают, что подключённая наблюдаемость сама исправит ответы модели, и не закладывают время на разбор и правки по её сигналам.
- Настраивают оповещения на всё сразу и без порога: уведомлений больше, чем реальных проблем, команда перестаёт на них реагировать.







