HAKUYUCHIAI導入・業務自動化の支援

AIの書き込みを後から追えるようにする — before/after/reason の監査ログ設計

悠 Yu NiiboriAIエンジニア運営者について

AIに書き込み権限を渡すなら、監査ログはあとから足す機能ではなく前提条件になる。実際に運用しているシステムのテーブル定義をそのまま公開し、reason 欄がなぜ必須なのか、何を載せてはいけないのか、バックアップと何が違うのかを整理する。

目次
  1. AIの書き込みに対する監査ログとは
  2. テーブル定義をそのまま出す
  3. reason 欄が実際に効く場面
  4. 載せてはいけないものを先に決める
  5. 監査ログとバックアップは別物である
  6. 付け忘れないための置き場所
  7. FAQ
  8. まとめ

AIの書き込みに対する監査ログとは

AIの書き込みに対する監査ログとは、変更の前後の値だけでなく「AIが述べた変更理由」を、追記専用で残す記録です。

人間のオペレータの操作ログと決定的に違うのは、あとから当人に聞けないことです。人間なら「なぜこれを消したのか」を本人に確認できます。AI にはそれができません。同じモデルに同じ質問をしても、それは当時の判断の再現ではなく新しい生成です。当時の理由は、その時に書き残さなければ永久に失われます。

だから設計としては、before / after に加えて reason を必須項目として扱います。以下は実際に運用しているシステムの実装です。

テーブル定義をそのまま出す

このシステムでは、AI による変更は例外なく1行が残ります。実テーブルの列はこうなっています。

何を入れるか
idTEXT主キー(UUID)
project_idTEXTどの案件の変更か(複数案件を1基盤で回す将来構成のための外部キー。現在は単一)
actorTEXThuman:<id> / agent:<name> / system
actionTEXTcontent.publish / experiment.adopt など動詞
entity_type / entity_idTEXT何に対する変更か
before_json / after_jsonTEXT変更前後の値(JSON)
reasonTEXTAIが述べた変更理由
experiment_id / resultTEXT実験に紐づく変更かどうか
created_atINTEGER記録時刻(UNIX秒)

索引は2つだけ置いています。(entity_type, entity_id, created_at DESC)(actor, created_at DESC) です。この2本は、事故のときに実際に投げる質問がこの2種類に集約されるからです。「この記事に何が起きたか」「このエージェントが何をしたか」。前者は影響範囲の特定に、後者は暴走したエージェントの停止判断に使います。監査ログの索引は「あとで分析するため」ではなく、「事故対応で最初に打つクエリ」から決めるとよいでしょう。

書き込み関数は追記しかしません。UPDATE も DELETE も用意していません。更新できる監査ログは監査ログではないからで、これは性能や容量の話より先に決めるべき性質です。

reason 欄が実際に効く場面

before / after は「何が起きたか」しか示しません。ロールバックの判断に必要なのは、たいていそこではありません。

差分だけを見て「これは戻すべき変更か」を判断できる場面は、そう多くありません。値が変わったこと自体は正しい変更でも起きるからです。判断を分けるのは、その変更が何を意図していたかです。「A/B の勝ち筋が出たので採用した」と「参照していた指標が欠測していたので暫定値で埋めた」は、after が同じでも扱いがまったく違います。

そこで、書き込みを行う AI に「なぜそうしたか」を自分の言葉で書かせる欄を必須にしています。運用してみて分かったのは、この欄の副作用のほうが大きいということでした。理由を書けない変更は、たいてい根拠が薄いものです。 reason が空欄になりがちな経路は、権限設計を見直したほうがよい箇所です。

載せてはいけないものを先に決める

監査ログは「全部記録する」が正しく見えるが、そのまま実装すると個人情報の複製装置になってしまいます。

このシステムでは、問い合わせフォームから届いた連絡先を after に載せないと決めてあります。リードのレコード自体は保存するが、監査ログ側には残しません。監査ログは長期に残り、追記専用で消せず、権限の異なる複数の経路から読まれます。削除できない場所に個人情報を入れると、あとから取り消せません。

同じ理由で、APIキーなどの秘密情報も載せません。監査ログに残すべきは「誰が・いつ・何を・なぜ変えたか」であって、値そのものが必ず要るわけではありません。機微なフィールドは、値ではなく「変更があった事実」だけを残す設計にできます。

医療・美容医療の領域でこの設計をそのまま使う場合、ここは特に慎重に扱う必要があります。監査のために残した記録が、本来アクセス制御されるべき情報の抜け道になり得るからです。

医療機関で使う場合の院内規程は院内の生成AI利用ガイドラインの作り方で扱っています。

監査ログとバックアップは別物である

「データベースの復元機能があるから監査ログは要らない」という整理は成り立ちません。両者は目的が違います。

Cloudflare の D1 は公式ドキュメントの説明ではこうなっています。

D1 is Cloudflare's managed, serverless database with SQLite's SQL semantics, built-in disaster recovery, and Worker and HTTP API access.

同ドキュメントは復元機能(Time Travel)について、直近30日以内の任意の時点へ復元できると説明しています。

バックアップ / 復元監査ログ
目的状態を戻す何が起きたかを説明する
粒度データベース全体1変更ごと
意図の記録無いreason に残る
保持期限がある追記して残す

復元は「壊れた状態から戻す」ための手段で、どの時点に戻すべきかは教えてくれません。その判断材料が監査ログです。逆に監査ログはデータを戻せません。片方だけでは事故対応が完結しません。

付け忘れないための置き場所

監査ログの一番の失敗は、設計の欠陥ではなく付け忘れです。新しい書き込み経路を足したときに、そこだけログが無い、という形です。

このシステムでは、書き込みが必ず通るリポジトリ層の関数に権限チェックを置き、監査ログもその同じ経路に寄せています。AI がデータベースへ直接アクセスすることを禁じているので、権限チェックを通った書き込みは監査も通ります。「必ず通る場所」を1か所に決めて、そこに全部載せるのが、規律で守るより確実です。

チェックリストとしては次の3つで足ります。

  1. 書き込み経路は1か所に集約されているか(迂回路が無いか)
  2. その経路で reason が必須になっているか
  3. 個人情報・秘密情報が before / after に入らないことがテストで固定されているか

FAQ

Q. 監査ログは全部の書き込みに必要ですか。 AI が実行する書き込みには必要です。人間なら事後に意図を確認できますが、AI には確認先がありません。

Q. reason は何字くらい書かせるべきですか。 長さより粒度です。「更新した」ではなく「何を根拠にそう判断したか」が1文で読めれば足ります。

Q. ログが増えすぎませんか。 1変更1行なので、AI の書き込み頻度が現実的な範囲なら問題になりません。肥大するのは before / after に大きな本文を丸ごと入れた場合です。

Q. バックアップがあれば監査ログは不要では。 不要になりません。復元は状態を戻しますが、どこへ戻すべきかの判断材料は監査ログにしかありません。

まとめ

AI に書き込ませる設計で先に用意すべきなのは、賢さではなく説明可能性です。

  • before / after に加えて reason を必須にする(当時の意図は再現できない)
  • 追記専用にする(更新できる監査ログは監査ログではない)
  • 個人情報・秘密情報は載せない(消せない場所に入れると取り消せない)
  • 権限チェックと同じ「必ず通る場所」に置く(付け忘れを構造で防ぐ)

自律的に動く AI を業務に入れるとき、この記録があるかどうかが「試せる」と「試せない」の境目になります。設計と実装のご相談を承っています。

出典

  1. Cloudflare Docs(公式ドキュメントのソース)— D1 overview(参照 2026-08-09)