G-gen の佐々木です。当記事では、Model Armor の機密データ保護フィルタから Sensitive Data Protection のテンプレートを呼び出し、LLM へのプロンプトに含まれる個人情報を匿名化する方法を解説します。

概要
Model Armor とは
Model Armor は、LLM のプロンプトとレスポンスを検査する Google Cloud のサービスです。プロンプトインジェクションやジェイルブレイクの検出、悪意ある URL の検出、責任ある AI の安全性フィルタ、機密データの検出と匿名化といったフィルタを備えており、ステートレスなセキュリティレイヤーとして動作します。
有効化するフィルタとその設定は、Model Armor テンプレートというリソースにまとめます。アプリケーションは、検査したいテキストをテンプレートに対して送信し、フィルタごとの検査結果を受け取ります。
Model Armor の全体像は以下の記事を参照してください。
Sensitive Data Protection とは
Sensitive Data Protection(旧称 Cloud Data Loss Prevention)は、Google Cloud 内外の機密データを検出・分類・匿名化するためのフルマネージドサービスです。氏名やメールアドレスといった機密データの種類に対応する infoType 検出器で対象を特定し、マスキングや置換、トークン化などの方式で別の値に変換します。
Sensitive Data Protection による機密データの匿名化については、以下の記事で解説しています。
機密データ保護フィルタの構成
Basic 構成と Advanced 構成
Model Armor の機密データ保護フィルタには Basic 構成と Advanced 構成の2つがあり、両者は排他でどちらか一方しか指定できません。Advanced 構成では Sensitive Data Protection のテンプレートをそのまま部品として使用できます。機密データの検出条件と変換方式を定義したテンプレートが、そのまま Model Armor のフィルタとして働く形です。
| 項目 | Basic 構成 | Advanced 構成 |
|---|---|---|
| Sensitive Data Protection のテンプレート | 使用しない | 検査テンプレートが必須、匿名化テンプレートは任意 |
| 使用できる infoType | 固定セットのみ | 検査テンプレートで指定した任意の infoType |
| カスタム infoType | 使用できない | 使用できる |
| 対応する操作 | 検査のみ | 検査と匿名化 |
Basic 構成で使用できる infoType は固定されています。2026年8月現在、すべてのリージョンで検査対象となるのは以下の5種類です。
- クレジットカード番号
- 金融口座番号
- Google Cloud の認証情報
- Google Cloud API キー
- 設定ファイルやコードなどに書かれた平文のパスワード
これに加えて、米国のリージョンに限り、米国社会保障番号(SSN)と米国個人納税者識別番号(ITIN)の2種類が検査対象に追加されます。東京リージョンを含む米国以外のリージョンでは前述の5種類のみが対象であり、日本の個人情報を対象とする検出器は含まれていません。氏名、メールアドレス、電話番号、マイナンバーといった日本のユースケースで想定される機密データを扱う場合、Advanced 構成が必要です。同じ日本語のテキストを Basic 構成で検査するとどうなるかは、当記事の後半で実際のレスポンスとともに示します。
検査テンプレートと匿名化テンプレート
Advanced 構成で指定する Sensitive Data Protection のテンプレートは、検査テンプレートと匿名化テンプレートの2種類です。いずれも検出条件や変換内容を再利用可能な形で保存したリソースであり、Model Armor テンプレートから参照できます。
検査テンプレートは検出設定(InspectConfig)を定義するテンプレートです。検出対象の infoType、検出とみなす確度の下限(minLikelihood)、検出した値そのものをレスポンスに含めるか(includeQuote)といった、何をどこまで検出するかの条件を定義します。
匿名化テンプレートは、変換設定(DeidentifyConfig)を定義するテンプレートです。ここでは検出された値をどの方式で別の値に置き換えるかを定義します。変換の指定方法には、テキスト中の infoType 単位で変換する infoType 変換(infoTypeTransformations)と、テーブル形式のデータを列単位で変換するレコード変換(recordTransformations)の2系統があります。Model Armor が扱うのは LLM のプロンプトとレスポンスのテキストであるため、使用するのは infoType 変換です。
infoType 変換では、infoType のグループごとに変換方式(primitiveTransformation)を1つ指定します。変換方式は2026年8月現在では12種類が提供されており、代表的なものは以下のとおりです。
| 変換方式 | 内容 |
|---|---|
replaceWithInfoTypeConfig |
検出値を infoType 名に置き換える |
replaceConfig |
検出値を指定した固定値に置き換える |
redactConfig |
検出値を削除する |
characterMaskConfig |
検出値の文字を指定した文字でマスクする |
cryptoDeterministicConfig |
検出値を AES-SIV による確定的なトークンに置き換える |
dateShiftConfig |
日付を乱数の日数分ずらす |
cryptoDeterministicConfig のような暗号ベースの方式は、暗号鍵を指定することで元の値へ戻せる可逆な変換です。ただし後述のとおり、Model Armor 自体は匿名化した値を元へ戻す機能を提供していません。
その他の変換方式については、以下の公式ドキュメントを参照してください。
テンプレートの参照関係
Advanced 構成では、Model Armor テンプレートの filterConfig.sdpSettings.advancedConfig に、Sensitive Data Protection のテンプレートをリソース名で指定します。
{ "filterConfig": { "sdpSettings": { "advancedConfig": { "inspectTemplate": "projects/<プロジェクトID>/locations/<ロケーション>/inspectTemplates/<検査テンプレートID>", "deidentifyTemplate": "projects/<プロジェクトID>/locations/<ロケーション>/deidentifyTemplates/<匿名化テンプレートID>" } } } }
Model Armor テンプレートは検出設定を自前で持たず、Sensitive Data Protection 側のテンプレートを参照するだけの構造になっています。そのため、後から検出対象の infoType を追加したり変換方式を変更したりする場合は、Model Armor テンプレートではなく検査テンプレートと匿名化テンプレートを編集します。
匿名化を行うには、検査テンプレートと匿名化テンプレートの両方が必要です。検査テンプレートのみを指定した場合、フィルタはマッチ結果を報告するだけで匿名化は行いません。
- 参考 : Method: projects.locations.templates.create
- 参考 : REST Resource: projects.locations.templates - SdpAdvancedConfig
制限事項
機密データ保護フィルタによる匿名化を行う場合、2026年8月現在、以下の制限があります。
- プロンプトに添付された PDF や DOCX などのファイルに対する匿名化は非対応。検出まではできるが匿名化はできない
- ストリーミングメソッドは匿名化に非対応
- 匿名化テンプレートに含まれるすべての infoType が、検査テンプレートにも含まれている必要がある
- Sensitive Data Protection のテンプレートは、Model Armor テンプレートと同一のロケーションに存在する必要がある
- Model Armor テンプレートのロケーションは、作成後に変更できない
ストリーミングメソッドは、LLM の出力のように逐次流れてくるテキストを、全文が揃うのを待たずにチャンク単位で検査する gRPC の双方向ストリーミング API です。匿名化はテキスト全体の中で検出した値を置き換えて返す処理であるためチャンク単位の処理とは相性が悪く、非対応となっています。
また2026年8月現在、東京リージョンでは、複数言語のテキストを検査するための多言語検出(Multi-language detection)を有効化できません。有効化を試みると、以下のように対応していない旨のエラーが返ります。機密データ保護フィルタによる日本語テキストの検査自体は多言語検出を有効にしなくても動作しますが、プロンプトインジェクション検出など他のフィルタを日本語で使用する場合は、リージョンの選定時に確認が必要です。
{ "error": { "code": 400, "message": "Region 'asia-northeast1' does not support the requested capabilities: 'Multi-language detection'.", "status": "INVALID_ARGUMENT" } }
- 参考 : プロンプトとレスポンスをサニタイズする
検出精度に関する注意事項
Sensitive Data Protection の組み込み infoType 検出器は、パターンマッチやチェックサム、機械学習、文脈解析などを組み合わせて機密データを検出します。ただし公式ドキュメントでは、組み込み検出器は完全に正確な検出ができるものではなく、規制要件への準拠を保証するものでもないと明記されています。何を機密データとみなし、どう保護するかは利用者自身が判断し、設定が要件を満たすことをテストで確認することが推奨されています。
検出の確度は minLikelihood で調整します。値を高く設定すると誤検知は減りますが、その分だけ検出漏れが増えるというトレードオフがあります。また、検出器はパターンだけでなく周辺の文脈やチェックサムも評価するため、形式だけ似せたダミーデータは検出されないことがあります。動作確認では、本番で扱うデータに近い値を使用する必要があります。
- 参考 : 匿名化 - 組み込みの infoType 検出器
- 参考 : 一致の可能性
- 参考 : infoType と infoType 検出器 - 確実性とテスト
料金
Sensitive Data Protection は、単体で使用する場合、処理したデータ量に基づく従量課金のサービスです。一方 Model Armor は、プロンプトとレスポンスのトークン数に基づく課金です。
Model Armor の料金ページには、Model Armor 内で Sensitive Data Protection を有効にしても追加料金は発生しないと明記されています。したがって Advanced 構成で検査テンプレートや匿名化テンプレートを連携させても、課金は Model Armor のトークン課金のみで、Sensitive Data Protection 側の検査・変換の料金は別途発生しません。
- 参考 : Security Command Center pricing - Possible indirect charges associated with Model Armor
- 参考 : Sensitive Data Protection の料金
匿名化したデータの再識別について
2026年8月現在、公式ドキュメントには、Model Armor が匿名化したデータを再識別(re-identification)する機能についての記載はありません。Model Armor は匿名化した結果をレスポンスとして返すのみで、元の値へ戻す経路は提供されていません。
確定的暗号化やフォーマット保持暗号化(FPE)のような可逆な変換方式を使って LLM に渡す前に匿名化し、レスポンス受信後に元の値へ戻すというラウンドトリップを構成する場合は、Sensitive Data Protection の content.reidentify メソッドを呼び出す処理を自前で実装する必要があります。
Sensitive Data Protection 単体との違い
機能と権限の比較
Sensitive Data Protection は、Model Armor を介さずアプリケーションから直接呼び出すこともできます。同じテンプレートを使っていても、Model Armor 経由と単体では、扱えるデータや権限の持ち方が異なります。
| 観点 | Sensitive Data Protection 単体 | Model Armor 経由(Advanced 構成) |
|---|---|---|
| 呼び出すメソッド | content.inspect、content.deidentify、content.reidentify |
sanitizeUserPrompt、sanitizeModelResponse |
| 扱えるデータ | テキスト、テーブル、画像、BigQuery や Cloud Storage 上のデータ | プロンプトとレスポンスのテキスト |
| 変換の指定方法 | infoType 変換とレコード変換 | infoType 変換 |
| 呼び出し側の権限 | アプリケーション自身に DLP ユーザー(roles/dlp.user)が必要 |
アプリケーションには Model Armor の権限のみ |
| 機密データ以外の検査 | 対象外 | プロンプトインジェクションや悪意ある URL の検出などと同時に評価される |
| 適用の強制 | アプリケーションが呼び出さなければ適用されない | サービスの統合により、アプリケーションの実装によらず適用できる |
Model Armor 経由で使用する利点
検査テンプレートと匿名化テンプレートは Sensitive Data Protection のリソースそのものであるため、両者で共有できます。BigQuery のスキャンに使用している検査テンプレートを、そのまま Model Armor から参照するといった構成も可能です。検出ルールを一箇所で管理しながら、LLM の入出力にも同じ基準を適用できる点が、Advanced 構成の利点です。
運用面では、機密データの扱いをアプリケーションの実装から切り離せることが大きな差です。単体で使用する場合、アプリケーションが匿名化を呼び出さなければ機密データはそのまま LLM に渡ります。Model Armor では、Agent Gateway や Gemini Enterprise Agent Platform(旧称 Vertex AI)との統合により、アプリケーションの実装によらず検査を適用できます。
なお Advanced 構成では、Sensitive Data Protection の呼び出しは Model Armor のサービスエージェントが代行します。そのため、プロンプトを送信するアプリケーション側に Sensitive Data Protection の権限は不要です。別プロジェクトのテンプレートを参照する場合は、そのプロジェクトでサービスエージェントに権限を付与します。
Sensitive Data Protection を直接呼び出す場面
一方で、Model Armor が扱えるのは LLM の入出力テキストに限られます。レコード変換やストレージ上のデータのスキャン、可逆な変換を使った再識別を含む処理は、Sensitive Data Protection を直接呼び出す構成が必要です。両者は排他ではないため、同じテンプレートを共有したうえで、用途に応じて使い分けます。
当記事で扱う範囲
当記事では、この2つのサービスの接続部分に絞って解説します。Advanced 構成の指定方法、gcloud での作成手順、そして匿名化されたテキストがどのような形で返るかを扱います。手順はすべて東京リージョン(asia-northeast1)で実行します。
設定手順
事前準備
はじめに、必要な API を有効化します。
# Model Armor と Sensitive Data Protection の API を有効化 $ gcloud services enable modelarmor.googleapis.com dlp.googleapis.com --project=<プロジェクトID>
当記事の手順を実行するユーザーには、プロジェクトレベルで以下のロールが必要です。
- Model Armor 管理者(
roles/modelarmor.admin) - DLP 管理者(
roles/dlp.admin)
Model Armor はリージョンエンドポイントを使用するサービスであり、公式ドキュメントでは gcloud を使用する際にエンドポイントの上書き設定が必要とされています。この設定をせずに --location で東京リージョンを指定して実行すると、以下のように権限エラーとなります。
# エンドポイント上書きなしで東京リージョンのテンプレートを一覧表示(エラーになる) $ gcloud model-armor templates list --location=asia-northeast1 --project=<プロジェクトID> ----- 出力例 ----- ERROR: (gcloud.model-armor.templates.list) PERMISSION_DENIED: Read access to project '<プロジェクトID>' was denied. This command is authenticated as <アカウント> which is the active account specified by the [core/account] property
メッセージは権限の不足を示していますが、実際の原因は送信先のエンドポイントです。--log-http を付けて実行すると、--location の指定がパスには反映される一方で、ホスト名は US のままであることが確認できます。
# HTTP ログを出力して送信先ホスト名を確認 $ gcloud model-armor templates list --location=asia-northeast1 --project=<プロジェクトID> --log-http ----- 出力例 ----- uri: https://modelarmor.us.rep.googleapis.com/v1/projects/<プロジェクトID>/locations/asia-northeast1/templates?alt=json status: 403
以下のように gcloud の設定でエンドポイントを上書きすると、東京リージョンのテンプレートを操作できます。
# Model Armor の API エンドポイントを東京リージョンに上書き $ gcloud config set api_endpoint_overrides/modelarmor https://modelarmor.asia-northeast1.rep.googleapis.com/
この設定は gcloud 全体に適用されます。他のロケーションの Model Armor テンプレートを操作する際は、gcloud config unset api_endpoint_overrides/modelarmor で解除してください。
検査テンプレートの作成
2026年8月現在、Sensitive Data Protection には gcloud のコマンドグループが提供されていないため、テンプレートの作成には REST API を使用します。以下の内容でリクエスト本文のファイル(inspect-template.json)を作成します。
{ "templateId": "jp-pii-inspect", "inspectTemplate": { "displayName": "日本の個人情報の検査", "description": "氏名、メールアドレス、電話番号、マイナンバーを検出する", "inspectConfig": { "infoTypes": [ { "name": "PERSON_NAME" }, { "name": "EMAIL_ADDRESS" }, { "name": "PHONE_NUMBER" }, { "name": "JAPAN_INDIVIDUAL_NUMBER" } ], "minLikelihood": "POSSIBLE", "includeQuote": true } } }
JAPAN_INDIVIDUAL_NUMBER はマイナンバー(個人番号)の検出器です。このように、Advanced 構成では日本固有の infoType を検出対象に指定できます。
テンプレートを作成します。ここで重要なのは、エンドポイントにロケーションを含めることです。公式ドキュメントに記載されているエンドポイントはロケーションを含まない形式であり、そのまま実行するとテンプレートは global に作成されます。
# 東京リージョンに検査テンプレートを作成 $ curl -s -X POST \ -H "Authorization: Bearer $(gcloud auth print-access-token)" \ -H "x-goog-user-project: <プロジェクトID>" \ -H "Content-Type: application/json" \ -d @inspect-template.json \ "https://dlp.googleapis.com/v2/projects/<プロジェクトID>/locations/asia-northeast1/inspectTemplates" ----- 出力例 ----- { "name": "projects/<プロジェクトID>/locations/asia-northeast1/inspectTemplates/jp-pii-inspect", "displayName": "日本の個人情報の検査", "description": "氏名、メールアドレス、電話番号、マイナンバーを検出する", "createTime": "2026-08-22T14:01:23.172799Z", "updateTime": "2026-08-22T14:01:23.172799Z", "inspectConfig": { "infoTypes": [ { "name": "PERSON_NAME" }, { "name": "EMAIL_ADDRESS" }, { "name": "PHONE_NUMBER" }, { "name": "JAPAN_INDIVIDUAL_NUMBER" } ], "minLikelihood": "POSSIBLE", "limits": {}, "includeQuote": true } }
レスポンスの name にロケーション(asia-northeast1)が含まれていることを確認します。

- 参考 : 機密データの保護の検査テンプレートの作成
匿名化テンプレートの作成
続いて匿名化テンプレートを作成します。当記事では、検出した値を infoType 名に置き換える replaceWithInfoTypeConfig を使用します。変換後のテキストを見たときに、どの位置にどの種類の機密データがあったかを読み取れるためです。
以下の内容でリクエスト本文のファイル(deidentify-template.json)を作成します。
{ "templateId": "jp-pii-deidentify", "deidentifyTemplate": { "displayName": "日本の個人情報の匿名化", "description": "検出値を infoType 名に置き換える", "deidentifyConfig": { "infoTypeTransformations": { "transformations": [ { "infoTypes": [ { "name": "PERSON_NAME" }, { "name": "EMAIL_ADDRESS" }, { "name": "PHONE_NUMBER" }, { "name": "JAPAN_INDIVIDUAL_NUMBER" } ], "primitiveTransformation": { "replaceWithInfoTypeConfig": {} } } ] } } } }
transformations は配列であり、要素ごとに対象の infoType と変換方式の組み合わせを指定します。当記事では4つの infoType をまとめて1つの要素にしていますが、要素を分ければ、氏名は infoType 名への置換(replaceWithInfoTypeConfig)、メールアドレスは * によるマスキング(characterMaskConfig)のように、infoType ごとに異なる変換方式を使い分けることができます。
ここで指定する infoType は、検査テンプレート側にもすべて含まれている必要があります。検査テンプレートで検出していない infoType を匿名化テンプレートに書いても、その値は変換されません。
# 東京リージョンに匿名化テンプレートを作成 $ curl -s -X POST \ -H "Authorization: Bearer $(gcloud auth print-access-token)" \ -H "x-goog-user-project: <プロジェクトID>" \ -H "Content-Type: application/json" \ -d @deidentify-template.json \ "https://dlp.googleapis.com/v2/projects/<プロジェクトID>/locations/asia-northeast1/deidentifyTemplates" ----- 出力例 ----- { "name": "projects/<プロジェクトID>/locations/asia-northeast1/deidentifyTemplates/jp-pii-deidentify", "displayName": "日本の個人情報の匿名化", "description": "検出値を infoType 名に置き換える", "createTime": "2026-08-22T14:20:22.343392Z", "updateTime": "2026-08-22T14:20:22.343392Z", "deidentifyConfig": { "infoTypeTransformations": { "transformations": [ { "infoTypes": [ { "name": "PERSON_NAME" }, { "name": "EMAIL_ADDRESS" }, { "name": "PHONE_NUMBER" }, { "name": "JAPAN_INDIVIDUAL_NUMBER" } ], "primitiveTransformation": { "replaceWithInfoTypeConfig": {} } } ] } } }

Model Armor テンプレートの作成
作成した2つのテンプレートを参照する Model Armor テンプレートを、gcloud で作成します。Advanced 構成は --advanced-config-inspect-template と --advanced-config-deidentify-template の2つのフラグでそれぞれのテンプレート(検査・匿名化)を指定します。
# SDP テンプレートを参照する Advanced 構成の Model Armor テンプレートを作成 $ gcloud model-armor templates create ma-jp-pii \ --project=<プロジェクトID> \ --location=asia-northeast1 \ --advanced-config-inspect-template=projects/<プロジェクトID>/locations/asia-northeast1/inspectTemplates/jp-pii-inspect \ --advanced-config-deidentify-template=projects/<プロジェクトID>/locations/asia-northeast1/deidentifyTemplates/jp-pii-deidentify ----- 出力例 ----- Created template [ma-jp-pii].
Basic 構成を使用する場合は、代わりに --basic-config-filter-enforcement=enabled を指定します。前述のとおり両者は排他であるため、同時には指定できません。
作成されたテンプレートを確認します。
# 作成した Model Armor テンプレートの内容を表示 $ gcloud model-armor templates describe ma-jp-pii --location=asia-northeast1 --project=<プロジェクトID> ----- 出力例 ----- createTime: '2026-08-22T14:32:41.063443078Z' filterConfig: sdpSettings: advancedConfig: deidentifyTemplate: projects/<プロジェクトID>/locations/asia-northeast1/deidentifyTemplates/jp-pii-deidentify inspectTemplate: projects/<プロジェクトID>/locations/asia-northeast1/inspectTemplates/jp-pii-inspect name: projects/<プロジェクトID>/locations/asia-northeast1/templates/ma-jp-pii templateMetadata: dataResidencyCompliant: true updateTime: '2026-08-22T14:32:41.308232521Z'

Sensitive Data Protection のテンプレートが Model Armor テンプレートと異なるロケーションにある場合、テンプレートの作成時に以下のエラーとなります。
----- 出力例 ----- ERROR: (gcloud.model-armor.templates.create) INVALID_ARGUMENT: Please check the SDP templates. Ensure that SDP templates are valid and present in the same location as the Model Armor templates. The format of the inspect template name should be 'projects/*/locations/*/inspectTemplates/*' and the format of the deidentify template name should be 'projects/*/locations/*/deidentifyTemplates/*'.
メッセージはテンプレート名の書式について述べていますが、書式を projects/*/locations/*/inspectTemplates/* の形に修正しても、ロケーションが一致していなければ同じエラーが返ります。Sensitive Data Protection のテンプレートが Model Armor テンプレートと異なるロケーションにある場合は、同じロケーション(当記事では東京リージョン)に作り直してください。特に、前述のとおりロケーションを含まないエンドポイントで作成すると global に作られるため、注意が必要です。
- 参考 : テンプレートの作成と管理
フィルタバージョンの指定
gcloud で作成した直後の Model Armor テンプレートは、フィルタバージョン v1 で動作します。v1 は2026年9月1日に LEGACY へ移行するため、この状態でサニタイズを実行すると、レスポンスの sanitizationMetadata.filterVersionConfig に以下の警告が含まれます。
{ "messageItems": [ { "messageType": "WARNING", "message": "WARNING: This filter version (V1) is in STABLE status and will be moved to LEGACY on 09-01-2026. Please migrate your template to the STABLE or LATEST version to ensure continued protection." } ] }
フィルタバージョンは templateMetadata.filterVersionSelector で指定しますが、2026年8月現在、gcloud model-armor templates create には対応するフラグがありません(gcloud beta model-armor も同様)。明示的に設定するには、REST API の PATCH、Google Cloud コンソール、Terraform のいずれかを使用します。当記事では、動作確認に進む前に REST API で FILTER_VERSION_ALIAS_LATEST を指定し、2026年8月現在の最新である v3 に切り替えます。
# フィルタバージョンを最新(LATEST)に設定 $ curl -s -X PATCH \ -H "Authorization: Bearer $(gcloud auth print-access-token)" \ -H "x-goog-user-project: <プロジェクトID>" \ -H "Content-Type: application/json" \ -d '{"templateMetadata": {"filterVersionSelector": {"alias": "FILTER_VERSION_ALIAS_LATEST"}}}' \ "https://modelarmor.asia-northeast1.rep.googleapis.com/v1/projects/<プロジェクトID>/locations/asia-northeast1/templates/ma-jp-pii?updateMask=templateMetadata"
LATEST エイリアスは、新しいフィルタバージョンがリリースされると自動で追従します。本番環境で挙動を固定したい場合は、alias に FILTER_VERSION_ALIAS_STABLE を指定するか、version で特定のバージョンにピン留めすることを検討してください。

動作確認
sanitizeUserPrompt の実行
作成した Model Armor テンプレートに対して、sanitizeUserPrompt メソッドでプロンプトを検査します。以下の内容でリクエスト本文のファイル(prompt.json)を作成します。
{ "userPromptData": { "text": "山田太郎さんの連絡先は taro@example.com、電話番号は 090-1234-5678 です。マイナンバーは 123456789018 です。" } }
テキスト中のマイナンバーは、チェックディジットが有効な架空の値です。JAPAN_INDIVIDUAL_NUMBER 検出器はチェックディジットを検証するため、桁数を合わせただけの値では検出されません。動作を試す際は注意してください。
# Advanced 構成のテンプレートでユーザープロンプトをサニタイズ $ curl -s -X POST \ -H "Authorization: Bearer $(gcloud auth print-access-token)" \ -H "x-goog-user-project: <プロジェクトID>" \ -H "Content-Type: application/json" \ -d @prompt.json \ "https://modelarmor.asia-northeast1.rep.googleapis.com/v1/projects/<プロジェクトID>/locations/asia-northeast1/templates/ma-jp-pii:sanitizeUserPrompt" ----- 出力例 ----- { "sanitizationResult": { "filterMatchState": "MATCH_FOUND", "filterResults": { "sdp": { "sdpFilterResult": { "deidentifyResult": { "executionState": "EXECUTION_SUCCESS", "matchState": "MATCH_FOUND", "data": { "text": "[PERSON_NAME]の連絡先は [EMAIL_ADDRESS]、電話番号は [PHONE_NUMBER] です。マイナンバーは [JAPAN_INDIVIDUAL_NUMBER] です。" }, "transformedBytes": "59", "infoTypes": [ "EMAIL_ADDRESS", "JAPAN_INDIVIDUAL_NUMBER", "PERSON_NAME", "PHONE_NUMBER" ] } } } }, "sanitizationMetadata": { "filterVersionConfig": { "filterVersion": "v3", "filterVersionAlias": "FILTER_VERSION_ALIAS_LATEST", "releaseDate": { "year": 2026, "month": 5, "day": 25 }, "projectedDeprecationDate": {}, "messageItems": [ { "messageType": "INFO", "message": "NOTE: This filter version (V3) is in LATEST status and will be moved to STABLE on 09-01-2026." } ] } }, "invocationResult": "SUCCESS" } }
レスポンスの読み方
レスポンスの要点を上から順に見ていきます。サニタイズの結果を示す部分だけを以下に抜粋しています。
{ "sanitizationResult": { "filterMatchState": "MATCH_FOUND", "filterResults": { "sdp": { "sdpFilterResult": { "deidentifyResult": { "executionState": "EXECUTION_SUCCESS", "matchState": "MATCH_FOUND", "data": { "text": "[PERSON_NAME]の連絡先は [EMAIL_ADDRESS]、電話番号は [PHONE_NUMBER] です。マイナンバーは [JAPAN_INDIVIDUAL_NUMBER] です。" }, "transformedBytes": "59", "infoTypes": [ "EMAIL_ADDRESS", "JAPAN_INDIVIDUAL_NUMBER", "PERSON_NAME", "PHONE_NUMBER" ] } } } }, // 省略 "invocationResult": "SUCCESS" } }
最上位の filterMatchState は、テンプレートで有効にしたフィルタ全体のマッチ状態です。今回は Sensitive Data Protection フィルタのみを有効にしているため、機密データが検出されたことを MATCH_FOUND が示しています。検出されなかった場合は NO_MATCH_FOUND です。
// 検出されたフィルタ全体のマッチ状態 "filterMatchState": "MATCH_FOUND",
フィルタごとの結果は filterResults に格納されます。Sensitive Data Protection フィルタの結果は sdp.sdpFilterResult であり、Advanced 構成で匿名化テンプレートを指定している場合は、その中の deidentifyResult に匿名化の結果が入ります。
executionState は匿名化処理自体が正常に実行されたかを、matchState は検出の有無を示します。executionState が EXECUTION_SUCCESS 以外の場合はテキストが匿名化されていないため、matchState が MATCH_FOUND であっても注意が必要です。
// 匿名化処理の実行状態と検出の有無 "deidentifyResult": { "executionState": "EXECUTION_SUCCESS", "matchState": "MATCH_FOUND",
匿名化後のテキストは data.text に格納されます。検出された4種類の値がすべて infoType 名に置き換わっており、LLM へ渡すテキストとしてはこの値を使用します。氏名の「山田太郎さん」は、敬称を含めた範囲が [PERSON_NAME] に置換されています。replaceWithInfoTypeConfig では検出器が判定した範囲がそのまま置換対象になるため、変換後のテキストがどうなるかは実際に確認することを推奨します。
// 匿名化後のテキスト "data": { "text": "[PERSON_NAME]の連絡先は [EMAIL_ADDRESS]、電話番号は [PHONE_NUMBER] です。マイナンバーは [JAPAN_INDIVIDUAL_NUMBER] です。" },
infoTypes には検出された infoType の一覧が、transformedBytes には変換されたバイト数が入ります。infoTypes を見れば、どの種類の機密データが含まれていたかをテキストを解析せずに判定できるため、「マイナンバーが含まれていたらリクエストを中断する」のような分岐に使用できます。
// 変換されたバイト数と、検出された infoType の一覧 "transformedBytes": "59", "infoTypes": [ "EMAIL_ADDRESS", "JAPAN_INDIVIDUAL_NUMBER", "PERSON_NAME", "PHONE_NUMBER" ]
なお、当記事では動作確認のために REST API で Model Armor を直接呼び出しています。この場合、Model Armor が行うのは検査と匿名化の結果を返すところまでであり、匿名化後のテキストを LLM へ渡すのか、リクエストを中断するのかは、レスポンスを受け取ったアプリケーション側で実装する必要があります。
実際のユースケースでは、Gemini Enterprise Agent Platform や Apigee、Agent Gateway などの統合を使用することで、アプリケーション側の実装なしに、トラフィックの経路上で Model Armor による検査とブロックを行うことができます。
- 参考 : Model Armor の統合の概要
Basic 構成との比較
同じテキストを Basic 構成のテンプレートで検査し、結果を比較します。比較用のテンプレートを作成します。
# 比較用の Basic 構成の Model Armor テンプレートを作成 $ gcloud model-armor templates create ma-basic-compare \ --project=<プロジェクトID> \ --location=asia-northeast1 \ --basic-config-filter-enforcement=enabled ----- 出力例 ----- Created template [ma-basic-compare].
先ほどと同じ prompt.json を使用して、このテンプレートに対してサニタイズを実行します。
# Basic 構成のテンプレートでユーザープロンプトをサニタイズ $ curl -s -X POST \ -H "Authorization: Bearer $(gcloud auth print-access-token)" \ -H "x-goog-user-project: <プロジェクトID>" \ -H "Content-Type: application/json" \ -d @prompt.json \ "https://modelarmor.asia-northeast1.rep.googleapis.com/v1/projects/<プロジェクトID>/locations/asia-northeast1/templates/ma-basic-compare:sanitizeUserPrompt" ----- 出力例 ----- { "sanitizationResult": { "filterMatchState": "NO_MATCH_FOUND", "filterResults": { "sdp": { "sdpFilterResult": { "inspectResult": { "executionState": "EXECUTION_SUCCESS", "matchState": "NO_MATCH_FOUND" } } } }, // 省略 "invocationResult": "SUCCESS" } }
氏名、メールアドレス、電話番号、マイナンバーのいずれも検出されず、NO_MATCH_FOUND となりました。Basic 構成の固定 infoType に日本の個人情報を対象とする検出器が含まれていないためです。
またレスポンスに含まれるのは inspectResult のみで、deidentifyResult 自体が返っていません。Basic 構成が検査のみをサポートし、匿名化を行わないことが、レスポンスの構造にも表れています。日本の個人情報を扱う AI アプリケーションで機密データ保護フィルタを使用する場合は、Advanced 構成を選択したうえで、検出対象の infoType を検査テンプレートで定義してください。
佐々木 駿太 (記事一覧)
クラウドソリューション部 クラウドエンジニアリング1課
北海道在住
大学院まで社会心理学を専攻し、AI に興味を持ち IT 業界へ。2022年6月に G-gen にジョイン。Google Cloud Partner Top Engineer に選出(2024 / 2025 Fellow / 2026)。好きな Google Cloud プロダクトは Cloud Run。
趣味はコーヒー、小説(SF、ミステリ)、カラオケなど。最近は法律の勉強にも目覚め、2級知的財産管理技能士を取得。最近は個人情報保護法を勉強中。
Follow @sasashun0805