Три разных журнала
Application log помогает разработчику найти исключение. Trace показывает длительность и связи вызовов. Audit log отвечает на вопросы контроля: кто инициировал действие, на каком основании оно было разрешено и какой внешний эффект произошло. Один поток stdout редко удовлетворяет всем трём задачам.
Единицы аудита
События строятся вокруг задания, решения и эффекта. Полезные типы: job.accepted, model.decision, tool.requested, policy.evaluated, approval.granted, tool.executed, artifact.published. Каждое событие получает event_id, trace_id, parent_id и серверное время.
Что фиксировать
- человека или сервис, tenant и делегированную роль;
- версии workflow, prompt, модели, tool schema и policy;
- idempotency key и внешний reference;
- решение allow/deny и идентификатор правила;
- approval: кто, что именно и до какого времени разрешил;
- результат, latency и код ошибки.
Не складывайте секреты в журнал
Prompt и tool arguments могут содержать персональные данные, токены и документы. По умолчанию храните hash, размер, классификацию и ссылку на защищённый payload store. Redaction выполняйте до отправки в общую систему логирования. Доступ к полным данным выдавайте отдельно и тоже аудируйте.
Целостность и порядок
Audit storage должен быть append-only для обычных операторов. Используйте отдельные права записи и чтения, immutable retention или последовательную hash-chain для обнаружения изменения. Не полагайтесь только на время клиента: распределённые часы расходятся, поэтому сохраняйте sequence внутри workflow и причинные parent links.
Связь с OpenTelemetry
Trace и span дают удобный каркас причинности: модель, retrieval и каждый tool call становятся spans, а audit event ссылается на trace/span ID. Но high-cardinality labels и чувствительный payload не следует бездумно отправлять в metrics backend. Для расследования храните контролируемые атрибуты и ссылки.
Retention и права субъекта
Срок хранения зависит от риска действия и требований бизнеса. Сырые prompts могут жить меньше агрегированного аудита. Опишите legal basis, удаление, hold для расследования и восстановление из backup. Удаление пользовательского payload не должно уничтожать минимальное доказательство самого факта операции, если оно требуется.
Проверка расследованием
Проведите tabletop exercise: выберите ошибочно отправленное письмо и попробуйте за час ответить, кто запустил workflow, какой документ повлиял, какая версия policy разрешила действие и был ли approval. Недостающие ответы превращаются в конкретные поля и алерты, а не в пожелание «логировать больше».
Схема события
Используйте стабильный envelope: event_id, event_type, occurred_at, actor, tenant, resource, trace/span, policy decision и outcome. Поля развиваются версионно; потребитель не должен разбирать свободный текст ради критичного признака. Для параметров храните классификацию данных и hash канонической формы.
Алерты, а не только архив
Audit stream должен обнаруживать аномалии: массовое чтение секретов, рост denied actions, смену policy перед опасным tool call, действия после отзыва approval и необычный объём одного tenant. Алерт содержит идентификаторы и безопасное резюме, но не копирует чувствительный payload в новый канал.
Доказательство полного пути
Регулярно сверяйте количество принятых jobs, завершённых workflows и terminal audit events. Разрыв означает потерю телеметрии или незавершённую работу. Для критичных действий внешний receipt — ID письма, платежа или commit — связывается с локальным событием и участвует в reconciliation.