Аудит AI-агентов: почему логам нельзя доверять и что делать

Аудит AI-агентов: почему логам нельзя доверять и что делать

AI-агент стирает не ту таблицу в базе. Или отправляет данные не туда. Или вызывает API, который никто не санкционировал. Дальше всё по учебнику: идёшь в логи, чтобы понять, что произошло. Логи чистые. Конечно, чистые: писал их тот же процесс, который устроил инцидент. Он честно, в валидном формате, отчитался об «успехе», указывая на неверную цель, а мониторинг, построенный вокруг вопроса «выполнилось ли?», загорелся зелёным.

Это не баг конкретной системы, а структурное свойство эпохи агентов: свидетель почти всегда оказывается подозреваемым. Действующая система сама пишет отчёт о своих действиях. На dev.to этой ловушке посвящено отдельное эссе «The Witness Was the Suspect», и как только замечаешь описанный в нём сдвиг, привычные опоры («у нас есть логи», «у нас есть аудит-трейл», «у нас есть шаг верификации») перестают держать. Разбираем, почему так и что с этим можно сделать инженерно.

Почему ошибки ИИ не кричат

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

Ошибка ИИ ведёт себя наоборот. Она проваливается правдоподобно. Функция выглядит корректной, аккуратной, правильной по форме, но в непроверенном случае даёт неверный результат. Запрос возвращает число, которое выглядит нормально. Резюме уверенное, структурное и тихо упускает ровно ту деталь, которая была важна. Ни исключения, ни красного флага: ничего не подсказывает «посмотри сюда».

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

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

Свидетель и подозреваемый

Теперь представь, что ты наконец идёшь разбираться с инцидентом. Что ты делаешь? Смотришь логи. Читаешь аудит-трейл. Открываешь мониторинг. Говоришь «у нас же есть шаг верификации». Каждое из этих движений опирается на допущение, которое почти никогда не проговаривается вслух: система, ведущая запись, честна.

Раньше это допущение было безопасным, потому что действующий и записывающий были разными системами. База данных фиксировала то, что с ней сделал твой код. Балансировщик логировал запросы, которые получил. Наблюдатель стоял снаружи того, за чем наблюдал, и не имел интереса врать. Агенты ломают это разделение: тот, кто решает, действует и затем пишет «вот что я сделал», это одна система.

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

Естественная реакция: добавить проверяющего. Пусть кто-то ещё сверяет отчёт агента. Именно на этом инстинкте стоит остановиться и присмотреться.

Почему верификаторы не спасают

Допустим, ты добавил чекер: второй процесс, который проверяет то, что заявил агент. Хорошо. Теперь очевидный вопрос: а кто проверяет чекер? Чекер тоже просто процесс. Его отчёт тоже может быть неверным, скомпрометированным или собранным на плохих входных данных. Чтобы доверять ему, нужен верификатор верификатора. Потом верификатор для того верификатора. Проблема не решена: она поднята на уровень выше и получила ещё один ящик. Это верификаторы до самого низа.

Часто на этом месте вспоминают про CI: «мы перепроверяем отчёт вне агента, в пайплайне». Это помогает ровно в одном случае: если CI читает первоисточник сам. Если же CI доверяет тому, что сообщил агент, ты не сбежал никуда. Ровно та же проблема доверия, только теперь в бейджике CI. Регрессу всё равно, на каком слое ты находишься.

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

Значит, неправильно поставлен вопрос. «Можно ли доверять этой записи?» чистого ответа не имеет: тот, кого ты позвал бы подтвердить, и есть потенциальный лжец. Перестань пытаться ответить на него и спроси другое.

Подлог должен оставлять след

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

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

Что это даёт по сути? Когда тайно переписать запись нельзя, ложь перестаёт давать чистый результат. Она даёт дыру. Пропущенный шаг виден как разрыв в цепочке. Подделанное решение видно как последовательность, которая не сходится. Удалённое действие видно как провал между соседними записями. Ты больше не спрашиваешь «правда ли это» (неотвечаемо), ты спрашиваешь «цела ли форма, нет ли в ней дыры» (отвечаемо, структурно, без веры чьим-то словам). Это и завершает регресс: доверие не добывают проверками, его обеспечивают тем, что подлог не может остаться незамеченным.

Пять элементов на практике

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

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

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

Записывай убеждения, а не только действия. Истории с «удалением не той базы» учат: действие агента часто было защитимым с точки зрения того, во что он верил. Он думал, что это dev-среда. Он думал, что это тестовая цель. Поэтому фиксируй картину мира агента в момент решения: какое окружение, какая роль, какая цель, и всё это запечатай до действия. Само действие не объясняет почему, а убеждение объясняет.

Имя, а не роль. «Кто это санкционировал» должно разрешаться в конкретного человека, которому есть что терять, и это должно быть записано. Не «ревьюер», не «система». Иначе полномочие превращается в ещё одно анонимное правдоподобное «почему», придуманное после факта. Линию провёл кто-то конкретный, и запись должна говорить, кто.

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

Честные пределы подхода

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

Он доказывает, кто что заявил и когда. Он не доказывает, что одобривший человек понял, что именно он одобряет. А при усталости от одобрений и сорока промптах с печатью «ок» за сессию это и есть по-настоящему нерешённая половина.

И главное: он делает подлог видимым, а не невозможным. Гарантия тут это заметность, а не предотвращение. Плохое всё ещё можно сделать, просто нельзя сделать это тихо. Обещание слабее, чем «надёжные логи», и в этом весь смысл: «надёжные логи» никогда не были на столе предложения с того момента, как свидетель стал подозреваемым. «Ложь обязана оставить след» это самая сильная честная планка из существующих.

Это уже работает в реальной инфраструктуре

Ничего из перечисленного не лабораторная экзотика. Публичные прозрачные журналы TLS-сертификатов (Certificate Transparency) годами живут по такой схеме: append-only лог с хеш-деревом, куда сертификаты попадают навсегда, а независимые мониторы следят за попытками выдать сертификат не по правилам. Регуляторы уже требуют ведение журналов событий для систем высокого риска: в EU AI Act это отдельное требование для high-risk систем. Хранилища WORM (write once, read many) давно отдельный класс продуктов в корпоративной инфраструктуре. Приём «сделай подлог заметным» не новость для индустрии; новость в том, что его пора применять и к агентам.

Часто задаваемые вопросы

Разве обычных логов недостаточно?

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

Хеш-цепочка это что, блокчейн?

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

Небольшой команде это точно нужно?

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

Итог

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

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

← Все записи