Журнал действий агента: минимальный набор полей
Через неделю вопрос будет не «что он сделал», а «почему он решил, что так можно». Разбираю, какие поля отвечают на второй вопрос и почему журналов нужно два.
Короткий ответ: журнал должен позволять восстановить решение, а не только результат. Значит на каждое действие нужны: время, задача, шаг, инструмент, полные аргументы, исход, наблюдение после и признак того, спрашивали ли человека.
И отдельно — то, до чего доходят не сразу: журналов нужно два. Один про действия, второй про права.
Почему одного мало
Ситуация, ради которой всё это пишется: через неделю выясняется, что агент удалил каталог. В журнале действий видно — вызов был, аргументы такие, исход успешный.
Не видно главного: почему ему это было позволено. Разрешение выдали месяц назад в другой задаче, оно действует до отзыва, и в журнале действий его нет — потому что это не действие, а решение о доверии.
Отсюда разделение:
Журнал действий — что агент делал. Пишется на каждый вызов инструмента, растёт быстро, живёт недолго.
Журнал решений о правах — кому и что разрешили или отозвали. Пишется редко, растёт медленно, хранится долго. Субъект (область прав, сервер инструментов, конкретный инструмент), его идентификатор, вердикт «разрешено» или «отозвано», задача, в которой это произошло.
Второй журнал маленький, и именно он отвечает на вопросы, которые задают после инцидента.
Поля журнала действий
По убыванию того, как часто они спасают.
Полные аргументы вызова. Не «удалил файл», а какой именно путь был передан. Без этого запись бесполезна: восстановить аргумент по описанию нельзя.
Наблюдение после. Что вернулось: код ответа, размер результата, изменилось ли состояние. Отличает «вызвал» от «получилось» — а это разные вещи, и половина разборов упирается именно сюда.
Идентификатор задачи и номер шага. Без них журнал — плоский список, по которому нельзя собрать один запуск.
Признак подтверждения. Спрашивали ли человека и что он ответил. Отвечает на вопрос «это прошло мимо меня или я согласился и забыл».
Модель и её версия. Провайдеры обновляют модели под тем же именем, и без записи вы не отличите свою правку от чужого обновления — регрессии в промптах ровно про это.
Токены на входе и выходе. Стоимость — тоже регрессия, и замечают её обычно позже качества.
Чего в журнале быть не должно
Содержимое файлов и переписки целиком. Журнал разрастётся, а вместе с ним вырастет и то, что придётся защищать: если в данных есть персональные, журнал становится их хранилищем со всеми последствиями — что нельзя отправлять наружу. Хранить надо путь и размер, а не содержимое.
Секреты в аргументах. Ключи и пароли, попавшие в вызов, окажутся в журнале. Их надо маскировать при записи, а не при чтении.
Свободный текст вместо полей. «Агент прочитал конфиг и решил, что надо поправить» — красиво и непригодно: по такой записи нельзя ни отфильтровать, ни посчитать.
Срок хранения
Журнал действий содержит следы работы с данными, и держать его вечно — это не осторожность, а накопление риска. Разумно: действия — недели, права — пока действуют плюс запас.
Срок стоит задавать настройкой, а не намерением: ограничение, записанное в конфигурации, переживает того, кто его придумал.
Условие несогласия
Для агента, который только читает и ничего не меняет, второй журнал избыточен: прав, о которых стоит помнить, у него нет. Достаточно действий, и то ради стоимости.
Второй журнал становится обязательным ровно тогда, когда появляются права, действующие дольше одной задачи. Признак простой: если разрешение, выданное сегодня, будет работать завтра — оно должно быть записано.
Чего я делать не стал бы
Не стал бы писать журнал только в консоль. Он нужен через неделю, а консоль живёт до перезапуска.
Не стал бы полагаться на журнал как на защиту. Он объясняет, а не предотвращает; подтверждение необратимых операций делает другую работу и не заменяется записью.
Не стал бы откладывать журнал «до продакшена». Он нужен раньше всего на отладке: половина странного поведения агента объясняется аргументом, который никто не видел.
Открытый вопрос
Журнал фиксирует, что агент сделал, и не фиксирует, почему он выбрал именно это. Рассуждение модели можно записать, но оно не является причиной выбора — это такой же порождённый текст, объясняющий решение задним числом.
Получается, что на главный вопрос разбора — «почему он так решил» — журнал отвечает только косвенно: через состояние, которое агент видел перед шагом. Поэтому наблюдение в записи важнее рассуждения, хотя читается хуже.