Настройка логирования запросов и ответов AI-модели

Когда обращение в поддержку разбирается часами, потому что непонятно, что ушло в модель и что она вернула, страдает вся команда. Мы настраиваем логирование LLM под ключ: проектируем схему сбора, правила доступа и регламенты разбора. Время диагностики инцидентов сокращается в разы, а спорные ответы перестают быть загадкой.
Часто задаваемые вопросы

Логирование LLM: где ломается сбор запросов и ответов

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

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

Ещё одна причина — персональные данные и ключи внутри промптов: из-за них логирование LLM часто выключают целиком либо маскируют так, что от текста остаётся непригодный для отладки набор символов. Из-за этого страдает отладка AI-интеграции. Работающее решение — правила редактирования на стороне приложения до записи: чувствительные поля заменяются, остальное сохраняется полностью. Выгрузку удобно строить на открытом стандарте OpenTelemetry — единый формат снимает привязку журнала к одному поставщику модели.

Для поддержки и продукта это оборачивается слепой зоной: воспроизвести жалобу нельзя, качество ответов не измерить, доля неудачных вызовов неизвестна. Разбираем, как сбор запросов и ответов закрывается на каждом из этих участков.

Что меняется после настройки: время разбора и классы отказов

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

Трассировка запросов закрывает это напрямую. Каждому обращению присваивается идентификатор, который связывает запрос пользователя, итоговый промпт, ответ модели, вызванные инструменты и время каждого шага. Инженер открывает одну карточку и видит последовательность целиком — без догадок. На практике время разбора инцидента падает с часов до 10–15 минут, а спорные случаи разбираются по фактическим данным, а не по описанию.

Наблюдаемость AI-сервиса даёт второе следствие — управление классами отказов модели. Вместо одного «сервис не ответил» в статистике появляются разделимые категории: превышение времени ожидания у провайдера, отказ разбора структуры ответа, расхождение с обязательным форматом, отказ собственной проверки. Для каждого класса настраивается своё поведение: повтор, откат на резервную модель или корректный отказ с понятным сообщением. Часть сбоев перестаёт доходить до пользователя просто потому, что теперь она обнаруживается на нашей стороне.

Контроль качества ответов меняется не меньше. Когда каждая пара «запрос — ответ» сохранена и размечена, сплошная ручная вычитка не нужна: достаточно выборочной проверки по выборке и автоматических правил на формат и запрещённые формулировки. Доля обращений, требующих участия человека, снижается до нескольких процентов. Собираем это на базе стандарта распределённой трассировки OpenTelemetry — совместимые выгрузки остаются у вас, а не растворяются в чужой панели.

Способы сбора: промежуточный слой, обёртка вызова, поток событий

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

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

Вариант Когда подходит Ограничения
Промежуточный слой Разнородный стек, есть вызовы из чужого кода, нужен единый формат записи Не видит бизнес-контекст без меток в заголовках; становится точкой отказа на пути запроса
Обёртка вызова модели Один сервис, важен полный контекст сессии и пользователя Правки в каждой точке вызова; обращения в обход обёртки не фиксируются
Поток событий Высокая частота обращений, аналитика и хранение отдельно от продукта Задержка до попадания в хранилище; нужен контроль переполнения и дублей

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

Этапы внедрения: от разведки до передачи регламентов

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

  1. Разведка потоков. Инвентаризация: какие сервисы обращаются к модели, где вызовы синхронные, а где пакетные, какие пиковые объёмы и в каких полях запроса встречаются персональные данные.
  2. Схема потоков данных. Фиксируем состав записи (запрос, ответ, длительность, признак ошибки), место и срок хранения, разграничение доступа и правила маскирования чувствительных полей до записи.
  3. Настройка перехвата. Сбор ставим на отдельный слой перед моделью, чтобы приложение не обрастало обвязкой. Записи приводим к единому формату, связываем идентификатором запроса, версией шаблона и учётной записью инициатора.
  4. Проверка на живом трафике. Включаем постепенно: сначала малая доля запросов, затем полный поток. Замеряем задержку, долю потерь записей и полноту полей, сверяя лог с фактическими вызовами.
  5. Обучение команды. Показываем, как найти конкретный диалог, воспроизвести сбой и разобрать спорный ответ модели по сохранённым данным, без выгрузок из продуктивной среды.
  6. Передача документации. Отдаём схему потоков, описание полей, политики хранения и доступа, порядок обновления при появлении новых сценариев.

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

Артефакты: схемы, правила доступа, регламенты и разметка

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

  • Схема потоков записей — от точки входа запроса до хранилища: где происходит обезличивание, на каком шаге запись становится необратимой, какие сервисы пишут в один поток.
  • Конфигурации сбора — какие поля запроса и ответа фиксируются, уровни детализации, доля сэмплирования, теги сервиса, окружения и версии модели.
  • Политики доступа — роли и области видимости: кому доступно тело ответа, кому только метаданные, как выдаются и отзываются ключи.
  • Правила хранения и удаления — сроки на горячем и архивном контуре, правила жизненного цикла, порядок удаления записей по обращению пользователя.
  • Регламент разбора обращений — как по идентификатору найти полную цепочку обработки, кто отвечает и в какие сроки.
  • Документация по сборам — перечень полей с назначением каждого, список маскируемых данных и способ проверить, что маскирование сработало.
  • Чек-лист приёмки — тестовые сценарии: запись появляется, доступ ограничен ролью, удаление отрабатывает, при смене модели схема не ломается.

Комплект лежит в репозитории заказчика и обновляется вместе с изменениями сбора — так документация не расходится с реальной конфигурацией.

Кейс: как сократили время разбора обращений в поддержку

До внедрения сквозного логирования разбор обращения в поддержку выглядел так: в тикете есть вопрос пользователя и странный ответ модели, а какая версия промпта была в момент вызова, с какими параметрами генерации и что сработало до и после — неизвестно. Причину искали перебором гипотез, часть обращений закрывалась формулировкой «воспроизвести не удалось». Найденный один раз дефект мог вернуться после следующей правки промпта и снова проходил тот же путь.

Что изменили

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

Метрика До После
Доля обращений без объяснимой причины ответа 31% 4%
Время поиска причины по обращению (медиана) 95 минут 12 минут
Доля дефектов, воспроизводимых по логу 18% 94%
Возврат закрытого дефекта после правки промпта замечали постфактум ловится на прогоне перед выкатом

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

Чем отличается логирование LLM от обычного журнала приложения?

Обычный журнал приложения пишется вокруг события: фиксированный набор полей, уровень важности, идентификатор запроса, время. Логирование LLM строится вокруг диалога — единица записи здесь не «сервис вернул ошибку», а полный обмен с моделью, у которого нет стабильной структуры и предсказуемого размера.

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

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

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

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

Частые технические сомнения перед стартом работ

Сомнения перед стартом обычно не про «нужно ли логирование запросов к LLM», а про то, как оно уживается с продом: чувствительные данные в текстах, объём хранилища, влияние на время ответа. Разбираем пять возражений, которые всплывают чаще всего.

В запросах есть персональные данные — что с ними?

Маскируем на входе в хранилище: почта, телефоны, номера документов заменяются плейсхолдерами, оригинал не сохраняется. Сырые записи доступны только отдельной роли и живут ограниченный срок — логирование не превращается во вторую копию базы с клиентскими данными.

Логи быстро займут всё хранилище?

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

Выдержит ли это рабочая нагрузка?

Запись асинхронная: ответ уходит пользователю, не дожидаясь хранилища. Если приёмник недоступен, записи буферизуются, а основной путь не блокируется. На массовых сценариях работает выборочная запись, на критичных — полная.

Как найти все шаги одного диалога?

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

Как понять, что именно отказало?

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

Обсудим вашу задачу: что нужно для оценки и плана

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

  • Схема вызовов: какие сервисы обращаются к модели, синхронно или через очередь, есть ли промежуточный шлюз между приложением и моделью.
  • Профиль нагрузки: сколько запросов в сутки, пиковые окна, доля потоковых ответов и длинных сессий.
  • Требования к хранению: срок жизни журнала, нужны ли полные тексты запросов и ответов или достаточно метаданных, где физически лежат данные.
  • Роли и доступы: кто читает журнал, как разграничиваются права, что нужно маскировать перед записью.
  • Порядок разбора обращений: как сейчас разбираются жалобы на качество ответов, кто принимает решение и в какой срок нужен результат.
  • Инфраструктура: где размещены компоненты, какие хранилища и очереди уже используются, есть ли сетевые ограничения.
  • Текущие инструменты: что уже собирает метрики и связывает записи между сервисами, чтобы не дублировать сбор.

По этим вводным мы описываем схему логирования: точки перехвата, формат записи, разграничение доступа, правила хранения и очистки. После этого возвращаемся с оценкой и планом работ — этапами, зонами ответственности и регламентом разбора обращений.

Направления AI-разработки

Последние работы

  • Разработка сайта компании B2B ADVANCE
    Разработка сайта компании B2B ADVANCE
    1542
  • Разработка веб-приложения для компании FEEDME
    Разработка веб-приложения для компании FEEDME
    1394
  • Разработка веб-сайта для компании БЕЛФИНГРУПП
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    1081
  • Разработка интернет магазина для компании FURNORO
    Разработка интернет магазина для компании FURNORO
    1369
  • Разработка логотипа компании B2B Advance
    Разработка логотипа компании B2B Advance
    816
  • Разработка веб-приложения для компании Enviok
    Разработка веб-приложения для компании Enviok
    1141