
AIエージェントの非決定性監査とは、エージェントが同一の入力に対しても異なる出力を生成しうる性質を前提に、その判断過程を記録し事後に検証できるようにするプロセスである。
生成AIを組み込んだエージェントは、同じ問いに毎回同じ答えを返すとは限らない。だからこそ「なぜこの判断に至ったのか」を後から説明できる証跡が、品質保証とインシデント対応の前提になる。本ガイドは、エージェントの説明責任を求められるエンジニアや品質管理担当者に向けて、再現可能な監査ログの設計と運用手順を、設計の前提から記録項目、異常検知、失敗パターンまで順を追って整理する。
従来のソフトウェアは「同じ入力なら同じ出力」を前提にデバッグできた。だが生成AIを核に持つエージェントでは、この前提が崩れる。まずは、監査を難しくしている3つの構造的な要因を分けて見ていく。
決定論的なシステムでは、バグの再現は「同じ入力を流し直す」ことで成立する。入力・コード・状態が同じなら出力も同じになるため、ログに残った入力さえあれば原因にたどり着ける。
エージェントはこの再現性を保証しない。同じプロンプトを与えても、モデルは確率分布からトークンを選ぶため、文面・結論・呼び出すツールの順序が変わりうる。つまり「結果のログ」だけを残しても、次に同じ入力を流したときに別の結果が出てしまい、ログと現在の挙動が食い違う。
このため監査の発想を切り替える必要がある。記録すべきは「その一回の実行で何が起きたか」であり、後から流し直して確かめられるという前提を捨て、実行時点のすべての判断材料をその場で固定して残すことが出発点になる。
非決定性の主要な発生源は、出力トークンを選ぶ際のサンプリングにある。温度(temperature)やtop-pといったパラメータは、確率の高い候補だけを選ぶか、低い候補にも余地を残すかを調整する。温度を上げれば表現は多様になるが、同一入力でのばらつきも大きくなる。
温度をゼロに近づければ出力は安定する方向に向かうが、それでも完全な決定性は保証されない。バックエンドの並列処理やハードウェアの浮動小数点演算の順序、モデル提供側のアップデートによって、わずかな差が生まれることがある。
監査の観点では、これらのパラメータ値そのものをログに残すことが欠かせない。温度やtop-p、シード値、モデルのバージョンを記録していなければ、「なぜこの出力になったのか」を後から議論する土台が失われる。出力の揺れを責めるのではなく、揺れを生む条件を完全に記録しておくことが現実的な対処になる。
単発の応答であれば、出力の揺れは一箇所で観察できる。問題は、エージェントが複数のステップを連鎖させて動くときに起きる。あるステップの出力が次のステップの入力になる構造では、初期の小さな揺れが後段の判断を大きく変えてしまう。
たとえば、最初のステップでツールの選択がわずかに変わると、取得するデータが変わり、最終的な結論がまったく別物になることがある。途中の各ステップは個別には「もっともらしい」判断に見えるため、結果だけを見ても、どこで分岐したのかを特定できない。
この連鎖を監査するには、ステップ間の中間状態をすべて記録する必要がある。各ステップの入力・出力・選択したツールを時系列で残しておけば、最終結果から逆向きにたどり、どのステップが分岐点だったかを切り分けられる。中間を省いて結果だけを残す設計は、この連鎖の追跡を不可能にする。

いきなりログの項目を決める前に、整えておくべき前提がある。何を・どこに・誰の責任で残すのかが曖昧なまま実装を始めると、後から設計をやり直すことになりやすい。ここでは設計に着手する前の3つの前提を確認する。
最初に決めるのは、どこからどこまでを監査対象とするかの境界だ。エージェントの全実行を等しく詳細に記録しようとすると、コストと運用負荷が現実的でなくなる。
実務では、リスクの高い操作とそうでない操作を分けて考えると整理しやすい。外部への書き込み、決済、個人データへのアクセス、不可逆な操作を伴うステップは、入力から判断根拠まで最も詳細に残す。一方、読み取り中心で影響範囲の小さい処理は、要約レベルのログにとどめる選択もありうる。
スコープの定義は一度決めて終わりではない。新しいツールや権限をエージェントに追加したときは、その操作が監査対象に含まれているかを必ず見直す。境界の設計を曖昧にしたまま機能だけ増やすと、最も説明責任が問われる操作がログから漏れる事態を招く。
監査ログは「いざというときに参照できる」ことに価値があるため、保存先の選定と保持期間の設計が品質を左右する。アプリケーションの稼働ログと同じ場所に混ぜると、ローテーションで古い記録が消え、肝心なときに証跡が残っていないことがある。
保存インフラを選ぶ際は、改ざんが難しい形で書き込めること、検索性が確保できること、長期保管のコストが見合うことを基準にする。書き込み専用(追記のみ)の領域に出力すると、後からの編集を防ぎやすく、証跡としての信頼性が高まる。
保持ポリシーは、業務上・法令上の要請から逆算して決める。規制対象の業務では数年単位の保管が必要になることもあり、その場合はコストを抑えるために、検索が速いホットな領域と低コストのアーカイブを分ける設計が現実的だ。どれだけの期間・どの粒度で残すかを最初に文書化しておくことが、後の運用の判断を楽にする。
監査ログは技術的な仕組みであると同時に、組織の責任分界の問題でもある。誰がログを設計し、誰が日常的に監視し、インシデント発生時に誰が説明する立場になるのかを、実装の前に決めておく必要がある。
ありがちなのは、開発チームが「ログは出している」と考え、運用チームは「監視対象として共有されていない」と考え、結果として誰も見ていない状態だ。出力されているだけのログは、参照する責任者と手順が決まって初めて証跡として機能する。
役割分担を明文化する際は、少なくとも「ログ設計の責任者」「定常監視の担当」「インシデント時の説明責任者」の3つを区別する。エージェントが下した判断について外部から問われたとき、その根拠を提示し説明する人が誰かを事前に決めておくことが、監査ログを単なる記録から説明責任の手段へと変える。

前提が整ったら、具体的に何を残すかを決める。再現と説明の両方を成り立たせるには、結果だけでなく、その結果に至るまでの判断材料を欠けなく押さえる必要がある。ここでは記録すべき項目を3つの層に分けて示す。
最初に残すべきは、その実行でモデルに渡された入力の全体だ。ユーザーからの問いだけでなく、システムプロンプト、参照させた文書、過去の会話履歴、テンプレートに埋め込まれた変数まで、モデルが実際に「見た」ものをそのまま固定する。
ここで注意したいのは、入力を要約したり整形したりして残さないことだ。後から再現や検証を行うとき、実際に渡された生のテキストと、人間が読みやすく整えた要約とでは意味が変わる。判断の根拠を問われたときに頼れるのは、整形前のスナップショットだけだ。
RAGのように外部から文書を取得して文脈に加える構成では、取得結果そのものも記録する。同じ問いでも、検索のタイミングやインデックスの状態によって取得される文書は変わるため、「そのとき何を読んだか」を残さなければ、出力の妥当性を後から判断できない。個人データを含む場合は、保管時の暗号化やアクセス制御とあわせて設計する。
同じ入力でも、どのモデルにどのパラメータで問い合わせたかによって出力は変わる。したがって、モデル名とバージョン、温度やtop-pなどのサンプリング設定、シード値、最大トークン数といった呼び出し条件を、実行ごとに記録する。
特にモデルのバージョンは見落とされやすい。モデル提供側がアップデートを行えば、まったく同じプロンプトでも挙動が変わることがある。「先月までは正しく動いていた」という事象を調べるとき、当時どのバージョンを使っていたかが分からなければ、原因の切り分けが進まない。
バージョン情報は、エージェントのコード側のバージョンとあわせて記録すると有効だ。プロンプトのテンプレートやツールの定義もコードの一部として変化するため、「モデルのバージョン」と「エージェント実装のバージョン」の両方を紐付けておくことで、変更のどちらが挙動の変化を生んだのかを追跡できる。
エージェントの判断は、モデルの出力だけでなく、外部ツールやAPIの呼び出し結果に強く依存する。どのツールを・どんな引数で呼び、何が返ってきたかを、呼び出した順序のまま逐次記録する。
ここでの要点は、呼び出しの「引数」と「戻り値」を対で残すことだ。たとえば在庫を照会するツールを呼んだなら、照会したIDと、返ってきた在庫数の両方を記録する。戻り値を残していなければ、エージェントが「何を見てその判断をしたか」が再構成できず、結果の妥当性を検証できない。
外部APIは応答が時間とともに変わるため、特に注意が必要になる。同じツールを同じ引数で呼んでも、翌日には別の結果が返るのが普通だ。だからこそ、その瞬間の戻り値を証跡として固定しておくことが、後からの説明を可能にする。失敗・タイムアウト・リトライといった例外的な挙動も、同じ粒度で残しておく。

記録する項目が決まったら、それらを後から追える形に構造化する。バラバラのテキストとして出力するだけでは、必要なときに目的の記録を見つけられない。ここでは、再現性と検索性を両立させる3つの設計原則を扱う。
一つのユーザー操作は、内部では複数のモデル呼び出しやツール実行に分かれて進む。これらを後からまとめて追うために、実行の起点で一意のトレースIDを発行し、関連するすべてのログに同じIDを付与する。
トレースIDがあれば、「この一件で何が起きたか」をIDで検索するだけで、関係するログを時系列に集められる。逆にIDがないと、タイムスタンプとユーザー名を頼りに断片的なログをつなぎ合わせることになり、複数の実行が並行しているときには取り違えが起きやすい。
マルチステップのエージェントでは、トレースID(実行全体)とスパンID(個々のステップ)を階層的に持たせると追跡しやすい。全体を貫くIDと、各ステップを識別するIDを組み合わせることで、「どのステップで分岐したか」を木構造としてたどれるようになる。
ログを時系列に並べて初めて、判断の流れが読める。各レコードには、いつ発生したかを示すタイムスタンプを、可能な限り高い精度で記録する。秒単位では、同じ瞬間に複数のイベントが並んだときに前後関係が分からなくなる。
ただし、タイムスタンプだけでは因果順序を保証しきれない場合がある。複数のサーバーにまたがって処理が走ると、各サーバーの時計のずれによって、実際には後から起きたイベントが先に記録されることがある。
この問題を避けるには、時刻に加えて、ステップの実行順を示す通し番号や、前のステップを参照する識別子を持たせる。「何時に起きたか」と「どの順で起きたか」を別々に記録しておくことで、時計のずれに左右されずに因果関係を再構成できる。順序が崩れた証跡は、分岐点の特定を誤らせる原因になる。
監査ログを人間が読める文章として出力すると、量が増えたときに機械的な検索・集計ができなくなる。1行に1イベントをJSONで書くJSON-Lines形式のように、構造化されたフォーマットに統一しておくと、後の分析が格段に楽になる。
構造化の利点は、フィールド単位で絞り込めることだ。「特定のトレースIDの」「ツール呼び出しだけを」「失敗したものに限って」抽出するといった操作が、フォーマットが揃っていれば数行のクエリで済む。自由記述のログでは、同じことに人手の読み込みが必要になる。
フォーマットを決める際は、トレースID・タイムスタンプ・イベント種別・対象・結果といった共通フィールドを最初に固定し、イベントごとの詳細はその下にまとめる。共通フィールドの名前と意味を最初に標準化しておけば、ツールやチームが変わってもログを横断して扱える。スキーマを文書化し、変更時はバージョンを添えて互換性を保つ。

ログを残すだけでは、問題が起きていることに気づけない。非決定性が許容範囲を超えていないかを能動的に測り、異常を検知する仕組みが要る。ここでは、揺れを定量化しアラートにつなげる3つの実装の勘所を見ていく。
非決定性がどの程度かを知るには、同じ入力を複数回流して、出力がどれだけばらつくかを測るのが基本になる。一度きりの実行では、その出力が安定したものか、たまたま出た外れ値かを区別できない。
実務では、代表的な入力をいくつか選び、それぞれを繰り返し実行して結果の分布を観察する。出力が毎回ほぼ同じなら安定しており、大きく割れるなら、その入力に対するエージェントの挙動は信頼しにくいと判断できる。
この測定は、モデルやプロンプト、ツールの定義を変更したときの回帰チェックとしても使える。変更の前後で同じ入力セットを流し、ばらつきや結論が想定外に変化していないかを比べる。非決定性を完全に消すことはできないが、「どの入力で揺れやすいか」を把握しておけば、リスクの高い部分に監視を集中させられる。
出力のばらつきを測るとき、文字列が一致するかどうかだけで判断すると、実態を見誤る。表現が違っても結論が同じなら問題ない一方、ほぼ同じ文面でも数値や結論が一つ違えば重大な差になる。重要なのは、意味のレベルでどれだけ違うかを捉えることだ。
意味的な差を測る一つの方法は、出力を埋め込みベクトルに変換し、ベクトル間の距離で類似度を見ることだ。文面の細かな違いに左右されず、内容が近いか遠いかを数値で扱える。ただしこの方法も万能ではなく、意味が近く見えても結論が逆という場合を取りこぼすことがある。
そのため、業務にとって致命的な差(最終的な判断や数値、実行するアクション)については、意味的類似度とは別に、その項目だけを抜き出して厳密に突き合わせる。何を「許容できる揺れ」とし、何を「見逃せない差」とするかは、業務の性質から定義する必要がある。
検出の仕組みを作っても、人が常時ログを眺めているわけにはいかない。ばらつきや異常が一定の水準を超えたときに自動で通知が飛ぶよう、しきい値とエスカレーションの経路を設計する。
しきい値の設定では、厳しくしすぎると通知が鳴り続けて無視されるようになり、緩くしすぎると本当の異常を見逃す。最初は控えめに始め、実際の運用で出る通知を見ながら調整するのが現実的だ。何を異常とみなすかの基準は、固定値だけでなく、平常時の分布からの逸脱として定義する方法もある。
エスカレーションは、影響の大きさに応じて段階を分ける。軽微な揺れは記録だけ、許容範囲を超えたら担当者へ通知、不可逆な操作に関わる異常なら処理を止めて人間の確認を挟む、といった具合に経路を分ける。検知から誰が何をするかまでを設計して初めて、異常検知は実害の防止につながる。

最後に、実装でつまずきやすい点を二つ取り上げる。どちらも「動いてはいるが、いざというときに役に立たない」という形で表面化するため、設計の段階で避けておきたい。
最も多い失敗は、最終的な結果だけをログに残し、そこに至る中間の判断を省いてしまうことだ。一見すると、結果さえ分かれば十分に思える。だが非決定性を持つエージェントでは、この設計は致命的になる。
結果ログだけを頼りに原因を調べようとすると、「同じ入力をもう一度流して再現する」しかない。ところがエージェントは同じ入力でも別の結果を返すため、流し直しても当時の状況が再現されず、調査が振り出しに戻る。どのツールを呼び、何が返り、どう判断したかという中間が残っていなければ、結果の妥当性は誰にも説明できない。
この失敗を避ける原則は単純だ。「後で流し直せばよい」という前提を捨て、実行のその場で、判断材料と中間状態をすべて固定して残す。ストレージのコストを理由に中間を削るのは、最も説明責任が問われる場面で証跡を失う取引になる。
中間まで残す重要性を理解すると、今度は逆の問題が起きる。すべてを最大の詳細で残し続けると、ログ量が急速に膨らみ、ストレージコストと検索性能が現実的でなくなる。
この綱引きに対処する基本は、前述したスコープの考え方に立ち返ることだ。リスクの高い操作は詳細に、影響の小さい処理は要約レベルに、と粒度を分ける。すべてを一律に最大粒度で残す設計は、コストの面でも検索の面でも長続きしない。
あわせて、保存期間による階層化が効く。直近の記録は検索しやすいホットな領域に置き、一定期間を過ぎたものは低コストのアーカイブへ移す。サイズの大きいペイロード(参照文書の全文など)は、ログ本体に埋め込むのではなく、別の保管先に置いて参照だけを残す手もある。コストと証跡の十分さは二者択一ではなく、粒度と保持期間の設計で両立させる問題だと捉える。
Chi
ラオス国立大学で情報科学を専攻し、在学中は統計ソフトウェアの開発に従事。データ分析とプログラミングの基礎を実践的に培った。2021 年より Web・アプリケーション開発の道に進み、2023 年からはフロントエンドとバックエンドの両領域で本格的な開発経験を積む。当社では AI を活用した Web サービスの設計・開発を担当し、自然言語処理(NLP)、機械学習、生成 AI・大規模言語モデル(LLM)を業務システムに統合するプロジェクトに携わる。最新技術のキャッチアップに貪欲で、技術検証から本番実装までのスピード感を大切にしている。