РУКОВОДСТВО · ОБНОВЛЕНО 2026-10-11
Наблюдаемость LLM API: request ID, попытки и безопасные журналы
Одна задача может включать очередь, несколько вызовов и инструменты. Разберём идентификаторы и минимальные события, которые помогают найти причину ошибки.
Свяжите локальную задачу, каждую сетевую попытку и результат инструмента устойчивыми идентификаторами. Сохраняйте фактический request ID сервиса, статус, этап и время без секретов. Не считайте HTTP200 завершённой бизнес-задачей и не объединяйте все повторы в одну неразличимую запись.
1. Составьте карту этапов
Запишите путь задачи: вход клиента, ожидание очереди, поиск, генерация, инструменты, валидация и показ результата. Для каждого этапа определите начало, конец и возможную ошибку. Общая длительность не позволяет различить задержку очереди и модели. Если инструмент запускает отдельный сервис, свяжите его событие с исходной задачей. Состояние «принято» не означает «выполнено», а готовый текст не подтверждает исполнение предложенной функции. Карта этапов помогает выбрать нужные события и избежать большого журнала, в котором нет ответа на конкретный вопрос о сбое.
2. Разделите идентификаторы
Создайте локальный ID задачи и отдельный ID каждой попытки. Сохраняйте фактический request ID из ответа сервиса, если он предоставлен. OpenAI описывает x-request-id для диагностики; наличие этого заголовка у другого API нужно проверить отдельно. Для инструмента храните его call ID и связь с попыткой. Не подменяйте ID поставщика самостоятельно придуманным значением. После таймаута может не быть ответа и request ID, хотя обработка уже началась. Такие случаи требуют статуса неизвестного результата, а не уверенного вывода, что вызов ничего не сделал.
3. Сохраняйте минимальные полезные поля
Записывайте версию приложения, разрешённый model ID, этап, исход, длительность и доступные технические счётчики. Отделите транспортный статус от отказа модели, неполного ответа и провала схемы. Поле usage интерпретируйте по контракту метода, не угадывая отсутствующие значения. API-ключи, заголовки авторизации и лишние документы исключайте из обычных логов. Для содержимого определите отдельный режим доступа и хранения, если оно действительно нужно расследованию. OpenTelemetry предлагает общую структуру трассировки, но названия атрибутов и версия используемых соглашений должны быть закреплены явно.
4. Сопоставьте поток и повторы
Для streaming отмечайте подключение, первые данные и подтверждённое завершение согласно протоколу. Закрытое соединение не всегда означает полный ответ. Каждый повтор храните отдельной попыткой, связывая с той же задачей. Не суммируйте или обнуляйте расход по предположению о таймауте: фактический результат проверяется по доступным данным сервиса. Для действий с побочными эффектами сохраняйте ключ идемпотентности или разрешённый идентификатор операции. Так можно отличить вторую генерацию от повторного исполнения действия и объяснить, почему пользователь увидел частичный или задержанный результат.
5. Проверьте журнал на сценариях отказа
На mock transport воспроизведите обычный ответ, отказ, обрыв потока, таймаут без request ID и ошибку инструмента. Проверьте, что по событиям восстанавливаются порядок и финальный статус без чтения секретов. Ограничьте доступ и срок хранения журналов; отсутствие записи может быть следствием фильтра или сбоя логирования. В Tokenmost сверяйте реальный контракт ID и usage, не обещая внутреннюю трассировку внешнего поставщика. Локальный тест доказывает работу вашего журнала, но не живую генерацию или фактические расходы, которых метод не вернул.
Частые вопросы
HTTP200 означает успешную задачу?
Он подтверждает транспортный ответ. Отказ, неполный результат, ошибка схемы и бизнес-действие требуют отдельных проверок.
Один request ID подходит всем повторам?
Сохраняйте ID каждой фактической попытки и связывайте их локальным ID задачи. Не смешивайте разные запросы сервиса.
Можно логировать весь payload ради отладки?
Определите необходимость, права и срок отдельно. Обычный журнал должен исключать секреты и лишнее содержимое; технических событий часто достаточно.
Нет ID — значит генерация не началась?
Нет такого доказательства. При таймауте ответ мог не дойти; сохраните статус неизвестного результата и используйте предусмотренный контрактом способ проверки.