はじめに:AIエージェントの「安全」から「監査可能」へ

EU AI ActのAnnex III point 5(b)により、クレジットスコアリングは高リスク用途に分類され、記録保持や透明性といった具体的な義務が課される(AWS Buildersの解説記事)。この規定は、AIシステムが「何をしたか」を事後的に証明できることを前提としている。つまり、規制対応の本質は攻撃を遮断する防御ではなく、行為の痕跡を体系的に蓄積し、必要に応じて外部へ提出可能な形に変換する「証拠生成」にある。

従来のAIセキュリティ設計では、プロンプトインジェクションの検出や有害出力のフィルタリング——すなわち「ブロック」——が最優先されていた。これは技術的に正しい判断だが、コンプライアンスの文脈では不十分だ。規制当局が求めるのは、システムが特定の入力に対してどのように反応し、どのサブエージェントが呼び出され、どこで判断が分岐したかという一連の記録そのものである。ブロックされた事象も、許可された事象も、いずれが監査対象となり得る。

本記事では、AWS Strandsのagents-as-toolsパターンとTraccia SDKを用いて、この「ブロック」と「証明」の両方を満たす実装設計を解説する。具体的には、Amazon BedrockのNova Proを基盤モデルとする合成ローン審査クルーを例に、ガードレール検出からPII除去、ランタイムポリシー執行、そして最終的なエビデンスパック生成までのデータフローを設計する。

読者は、技術的な防御メカニズムがどのようにOpenTelemetryのspanに蓄積され、それが規制対応のエビデンスチェーンとして機能するかを理解できる。特に、SDK層とプラットフォーム層の境界で何をどこまで自動化し、どこで人間の判断を挟むべきかという設計判断の基準を提示する。

前提:高リスクAIシステムにおけるガバナンスの二重構造

Tracciaのガバナンスアーキテクチャは、認証キーを必要としないSDK層と、プラットフォームキーが必要なプラットフォーム層の二層で構成される(AWS Buildersの解説記事)。この分離は、単なる技術的なモジュール分割ではなく、運用上のコスト構造と法的責任の所在を明確にする設計判断である。

SDK層:キー不要のリアルタイム処理

SDK層では、プロンプトインジェクションの検出、PIIの自動マスク、EU AI Actの透明性スタンプ付与といった、データが流れるたびに実行される処理が担われる。これらの機能はプラットフォームキーを必要としないため、開発環境やローカル実行でも同一のロジックが動作する。コスト面で言えば、SDKのインストールと初期化だけで済むため、開発段階でガバナンスの振る舞いを検証する際の摩擦が極小になる。

プラットフォーム層:キーが必要な執行と管理

プラットフォーム層では、ランタイムポリシーの強制執行(@governデコレータによるSpend CapやLoop Capの適用)と、Governance Hub上のインシデント管理・エビデンスパック生成が担われる。これらの機能はTracciaのプラットフォームキーを必要とするため、本番環境でのみ有効化するのが定石である。この層の存在意義は、単にポリシーを適用することではなく、違反発生時の責任所在を組織的に特定し、規制当局への提出物を自動生成することにある。

二層分離の設計判断

なぜこの分離が重要か。高リスク用途のAIシステムでは、開発・テスト環境で数百回実行される回数が、本番環境の数十倍に達する。仮にすべての実行にプラットフォームキーを課金していた場合、開発コストが実質的にガバナンスコストを押し上げ、開発チームの反発を招く。SDK層をキー不要にすることで、「開発時は軽量に、本番時は厳格に」という段階的な適用が可能になる。これはEU AI Actの記録保持義務と、現実的な開発サイクルの両立を実現する最小構成である。

層認証情報主な機能EU AI Act対応の位置づけ
SDK層不要ガードレール検出、PII除去、透明性スタンプ記録保持・透明性の基盤データ生成
プラットフォーム層Tracciaキーランタイムポリシー執行、インシデント管理、エビデンスパック責任所在の明確化・規制当局への提出

アーキテクチャ設計:Strands agents-as-toolsパターンでの統合

本設計の基盤モデルはAmazon BedrockのNova Pro(モデルID: amazon.nova-pro-v1:0)である。Nova Proは長文脈の理解と構造化出力の生成に強いモデルであり、ローン審査のような複数ステップの判断を要するタスクに適している(AWS Buildersの解説記事)。Python 3.10+環境で、strands-agents およびboto3を依存関係として使用する。

agents-as-toolsパターンの設計意図

AWS Strandsのagents-as-toolsパターンは、サブエージェントを親エージェントの「ツール」として登録する設計である。通常のマルチエージェント構成では、エージェント同士の通信がピアツーピアに行われ、呼び出し関係がフラットになりがちだ。これに対してagents-as-toolsパターンでは、親エージェントが各サブエージェントを関数呼び出しのように扱うため、OpenTelemetryのtrace/span構造が自然にツリー形を形成する。

この設計の利点は、監査ログの生成コストが構造的に抑えられる点にある。親エージェントのspanがブロックされた場合、その下流に属するサブエージェントのspanはそもそも生成されない。つまり、不要なログデータが蓄積される前に実行が止まり、ストレージコストと後続のログ解析コストの両方を削減できる。Traccia SDKのガードレール検出がモデル呼び出し前にクルー全体をブロックする仕組みと、このツリー構造が組み合わさることで、検出時の副作用が最小限に抑えられる。

ローン審査クルーの構成

合成ローン審査クルーは、親エージェント(オーケストレーター)が3つのサブエージェント——信用調査、書類検証、リスク評価——をagents-as-toolsとして呼び出す構成で構築される。各サブエージェントはNova Proを基盤モデルとし、Traccia SDKの@observeデコレータでトレース対象となる。この構成により、申請者の入力から最終判断までの全経路が単一のtraceに収まり、EU AI Actが要求する記録保持の粒度を満たす。

flowchart TD
    A["申請者入力"] --> B["オーケストレーター (Nova Pro)"]
    B --> C["信用調査エージェント"]
    B --> D["書類検証エージェント"]
    B --> E["リスク評価エージェント"]
    C --> F["最終判断 (Nova Pro)"]
    D --> F
    E --> F
    F --> G["審査結果 + 監査span"]

このデータフローにおいて、Traccia SDKの@observeデコレータが各ノードにspanを付与し、ガードレール検出の結果やPII除去の履歴がspan属性として記録される。次節以降では、このspanがどのようにOpenTelemetryのトレース構造に埋め込まれ、最終的にエビデンスパックに変換されるかを順に解説する。

実装:OpenTelemetryネイティブなトレースとガードレール検出

Traccia SDKはOpenTelemetryネイティブで実装されており、@observeデコレータを関数に付与するだけでトレースspanが自動生成される。手動でspan IDを管理したり、トレーサーの初期化コードを各モジュールに散りばめたりする必要がない。これはエージェントのオーケストレーションロジックとガバナンスロジックを分離する上で重要な設計判断である。エージェントの業務ロジック(信用調査、書類検証、リスク評価)を修正する際に、監査ログの生成コードを同時に触る必要がなくなるため、リグレッションリスクが低減される。

各spanにはガードレール検出の結果が属性として記録される。具体的には、どのガードレールが評価され、その判定(許可/ブロック)が何であったかがspan metadataに埋め込まれる。これにより、単一のspanを参照するだけで「このエージェント呼び出しにおいて、プロンプトインジェクション検出が実行され、判定は許可であった」あるいは「検出され、ブロックされた」が即座に確認可能になる。

ここで設計上の重要な分岐点がある。ガードレールがプロンプトインジェクションを検出すると、モデル呼び出しの前にクルー全体がブロックされる。下流のサブエージェントspanは生成されない。この挙動には二つの理由がある。第一に、インジェクションが疑われる入力を下流エージェントに渡さないことで、攻撃面を最小化する。第二に、ブロックされた実行に対しては不要なログデータを蓄積しないことで、ストレージコストとログのノイズを抑制する。

一方、この設計にはトレードオフも存在する。ブロック時点で下流spanが生成されないため、「どのサブエージェントが影響を受けていたか」を直接のトレースデータから復元することはできない。ただし、オーケストレーターレベルのspanにはブロックの理由と時刻が記録されるため、インシデント調査時には「この時点でクルー全体が停止した」という事実を証明できる。個別サブエージェントの呼び出し履歴は、ブロック前の正常な実行のトレースと比較することで推定可能である。

sequenceDiagram
    participant C as クライアント
    participant O as オーケストレーター
    participant G as ガードレール
    participant S as サブエージェント群
    C->>O: 申請者入力
    O->>G: 入力評価
    G-->>O: インジェクション検出
    O->>O: AgentBlockedError 発生
    Note over S: span生成されない
    O-->>C: ブロック結果 + 監査span

このシーケンスにおいて、AgentBlockedErrorがスローされる時点でOpenTelemetryのtraceは正常にクローズされる。つまり、ブロックされた実行もまた完全なtraceとして記録され、「なぜブロックされたか」が単一のtrace IDで追跡可能になる。これが後述するエビデンスパック生成の基盤となる。

データ保護:マルチエージェントツリーにおけるPII自動除去

init(redact_pii=True)を呼び出すことで、マルチエージェントツリー内のすべてのspanで申請者の個人識別情報が自動的にマスクされる。対象となるデータ種別としては、メールアドレス、電話番号、SSN(社会保険番号)が挙げられ、これらは[REDACTED_...]形式のプレースホルダーに置換される。

この処理が「ツリー全体」に適用される点は、単一のspan単位でマスクする設計と比べて重要な設計判断である。エージェント間のコンテキスト伝達(context passing)において、オーケストレーターがサブエージェントにPIIを含むプロンプトを渡す場合がある。このとき、オーケストレーターのspanだけPIIがマスクされ、サブエージェントのspanに生のPIIが残ると、監査ログの整合性が破れる。ツリー全体で統一マスクすることで、どの層のspanを参照しても一貫した非識別化データのみが得られることを保証する。

この機能はSDK層に属し、プラットフォームキーを必要としない。これは実装上の重要な利点であり、開発環境やPoC段階でもPII保護を有効化できる。EU GDPRのデータ最小化原則やAI Actの透明性義務に対応するためには、個人識別情報の処理履歴の記録が必須だが、init(redact_pii=True)一行でこの要件を技術的に満たせる。プラットフォーム層の契約やコストを伴わずに、プライバシー保護の最低限の保証を確保できる点が、段階的な導入を可能にしている。

ただし、注意点として、[REDACTED_...]形式は「何がマスクされたか」の種別(メールか電話番号か)は保持しつつ、実際の値は除去する。監査時には「PIIが処理された事実」を証明できるが、元の値を復元することはできない。これは意図的な設計であり、GDPRの目的制限原則(収集したデータで目的外の利用をしない)に適合する。もし復元可能な形でPIIを保持する必要がある場合は、別の暗号化ストレージとの連携を設計する必要があるが、それはTraccia SDKの範囲外となる。

ポリシー執行:ランタイム制限とエラーハンドリングの設計

@governデコレータは、Spend Cap(コスト上限)やLoop Cap(繰り返し上限)といったランタイムポリシーをエージェント実行に適用する。ポリシー違反が発生するとAgentBlockedErrorがスローされ、実行が停止する可能性がある。これはガードレールによるインジェクションブロックとは異なるレイヤーの防御であり、「攻撃による異常」ではなく「運用上の異常」(コスト超過、無限ループ)に対する対策である。

なぜこの分離が必要なのか。ガードレールは入力側(プロンプト)の安全性を検証するのに対し、@governは実行側(リソース消費)の制約を強制する。プロンプトインジェクションが検出されずに通過したとしても、その実行が無限ループに陥りToken消費が暴走する可能性がある。この場合、ガードレールでは防げないが、Loop Capが回数を制限することでリソース枯渇を防止する。両者は互いに補完する防御レイヤーである。

エラーハンドリングの設計において重要なのは、AgentBlockedErrorがスローされた時点で、違反内容(どのポリシーに違反したか)と関連するspan IDを構造化ログに記録することである。span IDを記録しておくことで、Governance Hub上でそのspanに紐付く全トレースデータを参照でき、根本原因分析が迅速化される。例えば、Loop Capに違反した場合は、どのエージェントが何回繰り返し呼び出しを行ったかがトレースから復元でき、プロンプト設計の修正に直接反映できる。

ここで設計上の判断基準となるのが、プラットフォームキーの要否である。@governの執行にはプラットフォームキーが必要であり、SDK層のガードレール検出やPII除去とは異なる。これは、ポリシーの定義・更新・監査がプラットフォーム側で行われるためである。開発環境では@governを無効化してコストを抑え、本番環境のみで有効化する段階的な導入が現実的な選択肢となる。ただし、この場合、開発環境ではLoop Capの挙動を検証できないため、ローカルでのモック実行や統合テスト環境での検証を別途設計する必要がある。

透明性:EU AI Act Art. 50に基づく対話証拠の記録

EU AI Act Art. 50は、対象者がAIと対話していることを示す透明性証拠(disclosure)の記録を義務付けている。これは「AIに操作された」というユーザーの認識を保障するための仕組みであり、単に「AIが利用された」ことを示すだけでは不十分である。対話の文脈、タイミング、どのエージェントが応答したかといった情報まで含めて、後から検証可能な形で保存しておく必要がある。

spanへの記録とエビデンスチェーンの形成

Tracciaでは、このdisclosure情報をOpenTelemetryのspanに記録する。Traccia SDK v0.1.29はOpenTelemetryネイティブであり、@observeデコレータでトレースされた関数ごとにspanが生成されるため、disclosureの記録もそのspanに紐付く。具体的には、ユーザーがAIエージェントと対話を開始した時点のspanに、対話の開始時刻、対象エージェントの識別情報、disclosureが提示された事実が属性として付与される。

ここで重要なのは、このdisclosure記録が孤立したデータ点ではない点である。同じマルチエージェントツリー内で、ガードレールの検出結果(何がブロックされ何が許可されたか)やPII処理履歴(init(redact_pii=True)によりマスクされたフィールドの記録)が隣接するspanに蓄積されている。これらが時系列で連続することで、規制当局に対して「システムはこの時点でどのように動作し、どのようなデータを処理し、ユーザーにどのような開示を行ったか」を一貫して証明できるエビデンスチェーンが形成される。

設計上の注意点として、disclosureの記録タイミングはエージェントの応答生成前であるべきである。応答生成後に記録した場合、エージェントが応答を返してからdisclosureが提示されるまでの時間差が生じ、Art. 50の要件を充足しているか曖昧になる。Tracciaのspan構造では、@observeで囲まれた関数の入口にdisclosure属性を設定することで、このタイミング保証をコードレベルで確立できる。

運用:Governance Hubでのインシデント管理とエビデンスパック

TracciaプラットフォームのGovernance Hubは、システム登録、人間のレビュー、インシデント管理、およびEU AI Act対応のエビデンスパックの生成を提供する。これらの機能はプラットフォームキーが使用に必要であり、SDK層のガードレール検出やPII削除とは異なる運用前提を持つ。

インシデント管理のワークフロー

インシデントが発生した場合、Governance Hubでは関連span IDを起点に詳細なトレースデータを復元する。例えば、プロンプトインジェクションが検出されてクルー全体がブロックされた場合、そのブロックイベントを記録したspanから、どの入力に対してどのガードレールが反応したか、下流のどのサブエージェントが実行されずに停止したかを把握できる。この復元結果がインシデント記録としてGovernance Hubに格納され、人間のレビューを経て根本原因分析と是正措置の記録が完了する。

エビデンスパックは、規制当局への提出時に必要な情報を構造化してまとめたものである。spanに蓄積されたガードレール結果、PII処理履歴、disclosure記録、ポリシー違反の経緯などが、EU AI Actの各条項に対応する形式で自動生成される。手動でログを抽出・整形する作業が不要になるため、監査対応のリードタイムが大幅に短縮される。

Governance Hubの機能と目的

機能目的運用上のポイント
システム登録管理対象のAIシステムをインベントリ化する高リスク用途の特定に紐付く
人間のレビューAIの判断に対する人間の承認・却下を記録Art. 14の人間監督の義務に対応
インシデント管理違反・異常の検知から是正までの記録span IDからトレースを復元
エビデンスパック規制当局への提出用資料を自動生成条項ごとに構造化された形式

運用上の判断基準として、Governance Hubの機能は本番環境でのみ有効化するのが原則である。開発環境ではプラットフォームキーを付与しないことで、コストと設定の複雑さを抑えられる。ただし、インシデント管理のフローを検証するためには、最低限の統合テスト環境でプラットフォームキーを有効化した状態での動作確認を推奨する。

トレードオフ:フレームワーク非依存性と実装コスト

Traccia SDKはOpenAI Agents、LangGraph、CrewAI、LangChainなど、特定のエージェントフレームワークに依存せずに動作する。自動インスツルメンテーションをサポートしているため、既存のエージェントコードに@observeや@governデコレータを追加するだけでトレースとポリシー執行が有効化される。フレームワークの移行や再実装を伴わない点が、既存システムへの組み込みにおいて重要な利点である。

コスト構造の分岐点

一方で、導入コストはSDK層とプラットフォーム層で大きく異なる。SDK層はキー不要で動作するため、追加のライセンス費用や認証情報の管理が不要である。対してプラットフォーム層では、キーの発行・管理、Governance Hubへの接続設定、インシデント対応の運用体制の整備が必要となる。

この分岐点は、自社サービスのリスク分類に直接関係する。EU AI Act Annex III point 5(b)に該当するクレジットスコアリングなどの高リスク用途では、記録保持と透明性が法的義務となるため、プラットフォーム層の導入が事実上必須となる。一方、リスク分類外の用途であれば、SDK層のガードレール検出とPII除去のみで十分に対応でき、コストを最小限に抑えられる。

項目SDK層プラットフォーム層
必要な認証情報キー不要プラットフォームキー
主な機能ガードレール検出、PII除去、disclosure記録@govern執行、Governance Hub、エビデンスパック
EU AI Act対応範囲透明性・データ保護の記録ポリシー執行・監査・提出準備
導入コストデコレータ追加のみキー管理+Hub連携+運用体制

実装上の落とし穴として、SDK層の自動インスツルメンテーションがすべての呼び出し経路をカバーしているかを確認する必要がある。フレームワーク内部で非同期処理や並列実行が行われている場合、@observeの付与位置が不十分だとspanツリーが断片化し、エビデンスチェーンの連続性が損なわれる。導入後は、意図したエージェントツリーがspanとして正しく階層化されているかを、実際のトレース出力で検証する手順をテスト計画に含めるべきである。

まとめ:ガバナンスを設計段階から組み込む重要性

本記事では、AWS Strandsのagents-as-toolsパターンとTraccia SDK・プラットフォーム層を用いた、EU AI Act対応のマルチエージェントガバナンス設計について解説した。核心的なポイントは、ガバナンスを「開発後の追加機能」ではなく「設計段階で確定すべきアーキテクチャ要素」として位置づけることである。

具体的には、以下の設計判断が早期に必要となる。第一に、どのエージェント呼び出しをspanとしてトレースするか、すなわち@observeの付与範囲である。第二に、ガードレールがブロックした際に下流spanを生成しない設計(E5の挙動)を前提として、エラーハンドリングのフローを設計すること。第三に、disclosure記録のタイミングとPII除去の適用範囲を、データフロー図上で明示的に定義すること。

これらの判断を設計段階で行うことで、実装フェーズで「どこにログを取るべきか」「どのレベルでブロックすべきか」を都度検討するコストが削減される。特にマルチエージェント構成では、エージェント間の依存関係が複雑になるため、トレースの粒度とポリシーの適用境界を事前に決定しておかないと、運用後に追跡不能な経路が混入するリスクがある。

技術的な防御(ブロック)と法的な証明(エビデンス生成)は、同じトレースデータから派生する二つの側面である。OpenTelemetryネイティブなspan構造の上に、ガードレール結果・PII処理履歴・disclosure記録を一貫して乗せる設計により、この両方を一つのデータソースから実現できる。規制対応の負荷を「運用時の手作業」ではなく「設計時の一時的な判断コスト」に転換するアプローチとして、本記事のパターンが参考になればと思う。

関連記事

参考

本記事は海外の技術トレンド「AI Agent Governance on AWS: Block Agents, Prove EU AI Act Compliance」(DEV)で話題のテーマをもとに、両儀システムソリューションズが独自に解説したものです。