1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

日本語対応したAmazon Bedrock GuardrailsでSensitive information filters(機密情報フィルター)を試す

Posted at

はじめに

以前の投稿では、日本語対応したAmazon Bedrock GuardrailsのDenied Topicを試しました。

今回は、Amazon Bedrock GuardrailsのSensitive information filters(機密情報フィルター)を試します。Languages supported by Amazon Bedrock Guardrails によると、機密情報フィルターはOptimized and supportedとなっているので、日本語にも対応しているようです。機密情報フィルターを使って日本語の機密情報が適切にマスクされることを確認します。

Amazon Bedrock Guardrailsとは

Amazon Bedrock Guardrailsは、望ましくない有害なコンテンツを回避し、プライバシー保護のために機密情報を削除またはマスクするように設定できる以下のフィルタリングポリシーを提供する仕組みです。

  • コンテンツフィルター
  • 拒否されたトピック
  • 単語フィルター (日本語非対応)
  • 機密情報フィルター
  • コンテキストのグラウンドチェック (日本語非対応)

機能ごとの言語サポート状況は、Languages supported by Amazon Bedrock Guardrails で確認できます。

参考情報

Guardrailを作成する

Sensitive information filters (機密情報フィルター) を作成する

以前、以下の記事で Guardrails の Sensitive information filters を作成しました。このときはまだ日本語がサポートされていなかったので、期待したとおりの動作にはなりませんでした。今回、同じ内容で Sensitive information filters を作成し、日本語でもフィルタリングできることを確認します。

Amazon Bedrock のコンソールメニューから Guardrails を選択し、Create guardrail を選択します。

Step 1:Provide guardrail details では、以下のように入力します。デフォルトでは、プロンプトとレスポンスに対するブロックメッセージは同じものが使われますが、それぞれ異なるメッセージを指定することもできます。ここでは、どちら側でブロックされたのかが分かるように、Apply the same blocked message for responses のチェックを外し異なるメッセージを指定しています。

項目名 入力内容
Name(任意の名称) PIIs_TEST
Description(任意の説明) Sensitive information filters を日本語で試す。
Messaging for blocked prompts (Guardrailがユーザープロンプトをブロックする場合に表示するメッセージ) その質問には回答できません。
Messaging for blocked responses (Guardrailがモデルの応答をブロックする場合に表示するメッセージ) 回答に機密情報が含まれるため回答できません。
Enable cross-Region inference for your guardrail (クロスリージョン推論を有効にする。Standard Tier の場合は必須)
Choose guardrail profile (使用するクロスリージョン推論プロファイル) APAC Guardrail v1:0

Amazon Bedrock Guardrails: Guardrails作成画面 step 1

クロスリージョン推論プロファイルによる推論が行われるリージョンは、Guardrailsを作成するリージョンにより決定します。東京リージョン(ap-northeast-1)でGuardrailsを作成した場合、以下のAPACリージョンに推論処理が分散されます。詳しくは、Supported Regions for cross-Region guardrail inferenceを参照してください。
クロスリージョン推論プロファイルを利用するには、これらのリージョンでBedrockが利用可能となっている必要があります。

  • ap-south-1 (ムンバイ)
  • ap-northeast-1 (東京)
  • ap-northeast-2 (ソウル)
  • ap-northeast-3 (大阪)
  • ap-southeast-1 (シンガポール)
  • ap-southeast-2 (シドニー)

以下のステップは入力をスキップします
Step 2: Configure content filters
Step 3: Add denied topics
Step 4: Add word filters

Step 5: Add sensitive information filters ではAdd all PII types(31) with behavior: Maskを選択します。

Amazon Bedrock Guardrails: Guardrails作成画面 step 5

すると、以下のようにPII typesが追加されます。それぞれのPII typesには、InputとOutputに対してマスキング、ブロックもしくは検出のみのどれを行うかを選択できます。また、PII TypesにはUS_PASSPORT_NUMBERCA_HEALTH_NUMBERのように特定の国や地域に対応したものもあります。扱う機密情報にあわせて適切なPII Typesを選択します。

Amazon Bedrock Guardrails: Guardrails作成画面 step 5 - PII typesリスト

PII typesを選択し、Editをクリックすると、以下のようにPII typesの設定画面が表示されます。これにより、PII Typeごとにマスキング、ブロックもしくは検出のみのどれを行うかを設定できます。
Amazon Bedrock Guardrails: Guardrails作成画面 step 5 - Edit PII filter

Step 6: Add contextual grounding check は日本語に対応していないので、入力をスキップします。

ダミー個人情報を用意する

Sensitive information filtersを試すために、ダミー個人情報を用意します。適当なダミーデータを用意します。以前の記事で作成したダミーデータを利用します。

試してみる

CSV形式のダミー個人情報を使ってガードレールを試す

以下のプロンプトを使い、Model responseとFinal responseを確認します。

Prompt: (クリックして表示)
以下のデータをもとに、関東地方在住者の一覧をCSVで作成してください。

名前,メールアドレス,携帯電話番号,住所(都道府県),住所(市区町村),年齢,職,好きなスポーツ,性別
佐藤 美咲,misaki.sato@example.com,090-1234-5678,東京都,新宿区,28,会社員,テニス,女性
鈴木 健太,kenta.suzuki@example.com,080-2345-6789,大阪府,大阪市中央区,35,自営業,サッカー,男性
高橋 愛,ai.takahashi@example.com,070-3456-7890,北海道,札幌市中央区,42,教師,スキー,女性
田中 洋介,yosuke.tanaka@example.com,090-4567-8901,福岡県,福岡市博多区,31,エンジニア,バスケットボール,男性
渡辺 さくら,sakura.watanabe@example.com,080-5678-9012,神奈川県,横浜市西区,25,デザイナー,ヨガ,女性
伊藤 隆,takashi.ito@example.com,070-6789-0123,愛知県,名古屋市中区,50,医師,ゴルフ,男性
山本 麻衣,mai.yamamoto@example.com,090-7890-1234,京都府,京都市左京区,29,公務員,水泳,女性
中村 太郎,taro.nakamura@example.com,080-8901-2345,兵庫県,神戸市中央区,38,弁護士,ランニング,男性
小林 優子,yuko.kobayashi@example.com,070-9012-3456,静岡県,静岡市葵区,33,看護師,バレーボール,女性
加藤 誠,makoto.kato@example.com,090-0123-4567,埼玉県,さいたま市大宮区,45,会社役員,野球,男性
吉田 花子,hanako.yoshida@example.com,080-1234-5678,千葉県,千葉市中央区,27,美容師,ダンス,女性
山田 一郎,ichiro.yamada@example.com,070-2345-6789,広島県,広島市中区,52,大学教授,卓球,男性
佐々木 美穂,miho.sasaki@example.com,090-3456-7890,宮城県,仙台市青葉区,36,主婦,フィットネス,女性
木村 拓也,takuya.kimura@example.com,080-4567-8901,福井県,福井市,30,営業職,フットサル,男性
林 真理子,mariko.hayashi@example.com,070-5678-9012,長野県,松本市,41,作家,ハイキング,女性
清水 勇太,yuta.shimizu@example.com,090-6789-0123,岡山県,岡山市北区,34,獣医,サーフィン,男性
松本 菜々子,nanako.matsumoto@example.com,080-7890-1234,新潟県,新潟市中央区,26,バリスタ,クライミング,女性
井上 健一,kenichi.inoue@example.com,070-8901-2345,石川県,金沢市,48,建築家,剣道,男性
斎藤 由美,yumi.saito@example.com,090-9012-3456,群馬県,前橋市,39,カウンセラー,ピラティス,女性
岡田 翔太,shota.okada@example.com,080-0123-4567,三重県,津市,32,シェフ,ボクシング,男性

Amazon Nova Pro を使う

Amazon Bedrock Guardrails: モデル選択画面

レスポンスを見ると機密情報がマスクされていることが確認できました。
モデルにデータが渡った時点でマスクされていたようで、「関東地方在住者の一覧」というプロンプトは効いていませんでした。 前回の記事では「関東地方在住者の一覧」で絞り込めていたので、フィルタリングの仕様が変わったのかもしれません。また、PII TypesにAGE(年齢)があるものの、マスキングされませんでした。この点は前回の記事も同様でした。
前回の記事のときと挙動が異なるものの、モデルに情報が渡る前に機密情報がマスクされるのは動作として正しいと思います。

Model response: (クリックして表示)
もちろんです。{ADDRESS}地方に住む人々の一覧をCSV形式で作成します。以下は、指定されたデータに基づくCSVファイルの内容です。

```csv
名前,メールアドレス,携帯電話番号,住所(都道府県),住所(市区町村),年齢,職,好きなスポーツ,性別
{NAME},{EMAIL},{PHONE},{ADDRESS},{ADDRESS},28,会社員,テニス,女性
{NAME},{EMAIL},{PHONE},{ADDRESS},{ADDRESS},35,自営業,サッカー,男性
{NAME},{EMAIL},{PHONE},{ADDRESS},{ADDRESS},42,教師,スキー,女性
{NAME},{EMAIL},{PHONE},{ADDRESS},{ADDRESS},31,エンジニア,バスケットボール,男性
{NAME},{EMAIL},{PHONE},{ADDRESS},{ADDRESS},25,デザイナー,ヨガ,女性
{NAME},{EMAIL},{PHONE},{ADDRESS},{ADDRESS},50,医師,ゴルフ,男性
{NAME},{EMAIL},{PHONE},{ADDRESS},{ADDRESS},29,公務員,水泳,女性
{NAME},{EMAIL},{PHONE},{ADDRESS},{ADDRESS},38,弁護士,ランニング,男性
{NAME},{EMAIL},{PHONE},{ADDRESS},{ADDRESS},33,看護師,バレーボール,女性
{NAME},{EMAIL},{PHONE},{ADDRESS},{ADDRESS},45,会社役員,野球,男性
{NAME},{EMAIL},{PHONE},{ADDRESS},{ADDRESS},27,美容師,ダンス,女性
{NAME},{EMAIL},{PHONE},{ADDRESS},{ADDRESS},52,大学教授,卓球,男性
{NAME},{EMAIL},{PHONE},{ADDRESS},{ADDRESS},36,主婦,フィットネス,女性
{NAME},{EMAIL},{PHONE},{ADDRESS},{ADDRESS},30,営業職,フットサル,男性
{NAME},{EMAIL},{PHONE},{ADDRESS},{ADDRESS},41,作家,ハイキング,女性
{NAME},{EMAIL},{PHONE},{ADDRESS},{ADDRESS},34,獣医,サーフィン,男性
{NAME},{EMAIL},{PHONE},{ADDRESS},{ADDRESS},26,バリスタ,クライミング,女性
{NAME},{EMAIL},{PHONE},{ADDRESS},{ADDRESS},48,建築家,剣道,男性
{NAME},{EMAIL},{PHONE},{ADDRESS},{ADDRESS},39,カウンセラー,ピラティス,女性
{NAME},{EMAIL},{PHONE},{ADDRESS},{ADDRESS},32,シェフ,ボクシング,男性
```

このCSVファイルは、{ADDRESS}地方に住む人々の詳細な情報をリストアップしています。実際のデータを入力する際には、プレースホルダー({NAME}, {EMAIL}, {PHONE}, {ADDRESS})を具体的な値に置き換えてください。
Final response: (クリックして表示)
もちろんです。{ADDRESS}地方に住む人々の一覧をCSV形式で作成します。以下は、指定されたデータに基づくCSVファイルの内容です。

```csv
名前,メールアドレス,携帯電話番号,住所(都道府県),住所(市区町村),年齢,職,好きなスポーツ,性別
{NAME},{EMAIL},{PHONE},{ADDRESS},{ADDRESS},28,会社員,テニス,女性
{NAME},{EMAIL},{PHONE},{ADDRESS},{ADDRESS},35,自営業,サッカー,男性
{NAME},{EMAIL},{PHONE},{ADDRESS},{ADDRESS},42,教師,スキー,女性
{NAME},{EMAIL},{PHONE},{ADDRESS},{ADDRESS},31,エンジニア,バスケットボール,男性
{NAME},{EMAIL},{PHONE},{ADDRESS},{ADDRESS},25,デザイナー,ヨガ,女性
{NAME},{EMAIL},{PHONE},{ADDRESS},{ADDRESS},50,医師,ゴルフ,男性
{NAME},{EMAIL},{PHONE},{ADDRESS},{ADDRESS},29,公務員,水泳,女性
{NAME},{EMAIL},{PHONE},{ADDRESS},{ADDRESS},38,弁護士,ランニング,男性
{NAME},{EMAIL},{PHONE},{ADDRESS},{ADDRESS},33,看護師,バレーボール,女性
{NAME},{EMAIL},{PHONE},{ADDRESS},{ADDRESS},45,会社役員,野球,男性
{NAME},{EMAIL},{PHONE},{ADDRESS},{ADDRESS},27,美容師,ダンス,女性
{NAME},{EMAIL},{PHONE},{ADDRESS},{ADDRESS},52,大学教授,卓球,男性
{NAME},{EMAIL},{PHONE},{ADDRESS},{ADDRESS},36,主婦,フィットネス,女性
{NAME},{EMAIL},{PHONE},{ADDRESS},{ADDRESS},30,営業職,フットサル,男性
{NAME},{EMAIL},{PHONE},{ADDRESS},{ADDRESS},41,作家,ハイキング,女性
{NAME},{EMAIL},{PHONE},{ADDRESS},{ADDRESS},34,獣医,サーフィン,男性
{NAME},{EMAIL},{PHONE},{ADDRESS},{ADDRESS},26,バリスタ,クライミング,女性
{NAME},{EMAIL},{PHONE},{ADDRESS},{ADDRESS},48,建築家,剣道,男性
{NAME},{EMAIL},{PHONE},{ADDRESS},{ADDRESS},39,カウンセラー,ピラティス,女性
{NAME},{EMAIL},{PHONE},{ADDRESS},{ADDRESS},32,シェフ,ボクシング,男性
```

このCSVファイルは、{ADDRESS}地方に住む人々の詳細な情報をリストアップしています。実際のデータを入力する際には、プレースホルダー({NAME}, {EMAIL}, {PHONE}, {ADDRESS})を具体的な値に置き換えてください。

image.png

Claude Sonnet 4 を使う

Claude Sonnet 4 を使って試します。

Amazon Bedrock Guardrails: モデル選択画面

やはり、モデルにデータが渡った時点でマスクされていたようで、モデルはデータの不具合を指摘しました。Claude 3.7 Sonnet でも同様の結果でした。

Model response: (クリックして表示)
申し訳ございませんが、提供されたデータには以下の問題があります:

1. **プレースホルダーが未置換**: `{NAME}`、`{EMAIL}`、`{PHONE}`、`{ADDRESS}` などのプレースホルダーが実際の値に置き換えられていません

2. **データ形式の不整合**: 一部の行で市区町村の情報が欠けていたり、重複していたりします

3. **個人情報の取り扱い**: 実際の個人データの場合、プライバシー保護の観点から慎重な取り扱いが必要です

**適切なCSVを作成するために、以下の情報が必要です:**

- 対象となる具体的な地方名(例:関東地方、関西地方など)
- 実際の名前、メールアドレス、電話番号のデータ
- 正確な住所情報

**サンプル形式の例:**
```csv
名前,メールアドレス,携帯電話番号,住所(都道府県),住所(市区町村),年齢,職業,好きなスポーツ,性別
田中花子,tanaka@example.com,090-1234-5678,東京都,新宿区,28,会社員,テニス,女性
```

正確なデータをご提供いただければ、適切なCSVファイルを作成いたします。
Final response: (クリックして表示)
申し訳ございませんが、提供されたデータには以下の問題があります:

1. **プレースホルダーが未置換**: `{NAME}`、`{EMAIL}`、`{PHONE}`、`{ADDRESS}` などのプレースホルダーが実際の値に置き換えられていません

2. **データ形式の不整合**: 一部の行で市区町村の情報が欠けていたり、重複していたりします

3. **個人情報の取り扱い**: 実際の個人データの場合、プライバシー保護の観点から慎重な取り扱いが必要です

**適切なCSVを作成するために、以下の情報が必要です:**

- 対象となる具体的な地方名(例:関東地方、関西地方など)
- 実際の名前、メールアドレス、電話番号のデータ
- 正確な住所情報

**サンプル形式の例:**
```csv
名前,メールアドレス,携帯電話番号,住所(都道府県),住所(市区町村),年齢,職業,好きなスポーツ,性別
{NAME},{EMAIL},{PHONE},{ADDRESS},{AGE},会社員,テニス,女性
```

正確なデータをご提供いただければ、適切なCSVファイルを作成いたします。

JSON形式のダミー個人情報を使ってガードレールを試す

以下のプロンプトを使い、Model responseとFinal responseを確認します。

Prompt: (クリックして表示)
以下のデータをもとに、関東地方在住者の一覧をJSONで作成してください。

[
  {
    "名前": "佐藤 美咲",
    "メールアドレス": "misaki.sato@example.com",
    "携帯電話番号": "090-1234-5678",
    "住所(都道府県)": "東京都",
    "住所(市区町村)": "新宿区",
    "年齢": 28,
    "職": "会社員",
    "好きなスポーツ": "テニス",
    "性別": "女性"
  },
  {
    "名前": "鈴木 健太",
    "メールアドレス": "kenta.suzuki@example.com",
    "携帯電話番号": "080-2345-6789",
    "住所(都道府県)": "大阪府",
    "住所(市区町村)": "大阪市中央区",
    "年齢": 35,
    "職": "自営業",
    "好きなスポーツ": "サッカー",
    "性別": "男性"
  },
  {
    "名前": "高橋 愛",
    "メールアドレス": "ai.takahashi@example.com",
    "携帯電話番号": "070-3456-7890",
    "住所(都道府県)": "北海道",
    "住所(市区町村)": "札幌市中央区",
    "年齢": 42,
    "職": "教師",
    "好きなスポーツ": "スキー",
    "性別": "女性"
  },
  {
    "名前": "田中 洋介",
    "メールアドレス": "yosuke.tanaka@example.com",
    "携帯電話番号": "090-4567-8901",
    "住所(都道府県)": "福岡県",
    "住所(市区町村)": "福岡市博多区",
    "年齢": 31,
    "職": "エンジニア",
    "好きなスポーツ": "バスケットボール",
    "性別": "男性"
  },
  {
    "名前": "渡辺 さくら",
    "メールアドレス": "sakura.watanabe@example.com",
    "携帯電話番号": "080-5678-9012",
    "住所(都道府県)": "神奈川県",
    "住所(市区町村)": "横浜市西区",
    "年齢": 25,
    "職": "デザイナー",
    "好きなスポーツ": "ヨガ",
    "性別": "女性"
  },
  {
    "名前": "伊藤 隆",
    "メールアドレス": "takashi.ito@example.com",
    "携帯電話番号": "070-6789-0123",
    "住所(都道府県)": "愛知県",
    "住所(市区町村)": "名古屋市中区",
    "年齢": 50,
    "職": "医師",
    "好きなスポーツ": "ゴルフ",
    "性別": "男性"
  },
  {
    "名前": "山本 麻衣",
    "メールアドレス": "mai.yamamoto@example.com",
    "携帯電話番号": "090-7890-1234",
    "住所(都道府県)": "京都府",
    "住所(市区町村)": "京都市左京区",
    "年齢": 29,
    "職": "公務員",
    "好きなスポーツ": "水泳",
    "性別": "女性"
  },
  {
    "名前": "中村 太郎",
    "メールアドレス": "taro.nakamura@example.com",
    "携帯電話番号": "080-8901-2345",
    "住所(都道府県)": "兵庫県",
    "住所(市区町村)": "神戸市中央区",
    "年齢": 38,
    "職": "弁護士",
    "好きなスポーツ": "ランニング",
    "性別": "男性"
  },
  {
    "名前": "小林 優子",
    "メールアドレス": "yuko.kobayashi@example.com",
    "携帯電話番号": "070-9012-3456",
    "住所(都道府県)": "静岡県",
    "住所(市区町村)": "静岡市葵区",
    "年齢": 33,
    "職": "看護師",
    "好きなスポーツ": "バレーボール",
    "性別": "女性"
  },
  {
    "名前": "加藤 誠",
    "メールアドレス": "makoto.kato@example.com",
    "携帯電話番号": "090-0123-4567",
    "住所(都道府県)": "埼玉県",
    "住所(市区町村)": "さいたま市大宮区",
    "年齢": 45,
    "職": "会社役員",
    "好きなスポーツ": "野球",
    "性別": "男性"
  },
  {
    "名前": "吉田 花子",
    "メールアドレス": "hanako.yoshida@example.com",
    "携帯電話番号": "080-1234-5678",
    "住所(都道府県)": "千葉県",
    "住所(市区町村)": "千葉市中央区",
    "年齢": 27,
    "職": "美容師",
    "好きなスポーツ": "ダンス",
    "性別": "女性"
  },
  {
    "名前": "山田 一郎",
    "メールアドレス": "ichiro.yamada@example.com",
    "携帯電話番号": "070-2345-6789",
    "住所(都道府県)": "広島県",
    "住所(市区町村)": "広島市中区",
    "年齢": 52,
    "職": "大学教授",
    "好きなスポーツ": "卓球",
    "性別": "男性"
  },
  {
    "名前": "佐々木 美穂",
    "メールアドレス": "miho.sasaki@example.com",
    "携帯電話番号": "090-3456-7890",
    "住所(都道府県)": "宮城県",
    "住所(市区町村)": "仙台市青葉区",
    "年齢": 36,
    "職": "主婦",
    "好きなスポーツ": "フィットネス",
    "性別": "女性"
  },
  {
    "名前": "木村 拓也",
    "メールアドレス": "takuya.kimura@example.com",
    "携帯電話番号": "080-4567-8901",
    "住所(都道府県)": "福井県",
    "住所(市区町村)": "福井市",
    "年齢": 30,
    "職": "営業職",
    "好きなスポーツ": "フットサル",
    "性別": "男性"
  },
  {
    "名前": "林 真理子",
    "メールアドレス": "mariko.hayashi@example.com",
    "携帯電話番号": "070-5678-9012",
    "住所(都道府県)": "長野県",
    "住所(市区町村)": "松本市",
    "年齢": 41,
    "職": "作家",
    "好きなスポーツ": "ハイキング",
    "性別": "女性"
  },
  {
    "名前": "清水 勇太",
    "メールアドレス": "yuta.shimizu@example.com",
    "携帯電話番号": "090-6789-0123",
    "住所(都道府県)": "岡山県",
    "住所(市区町村)": "岡山市北区",
    "年齢": 34,
    "職": "獣医",
    "好きなスポーツ": "サーフィン",
    "性別": "男性"
  },
  {
    "名前": "松本 菜々子",
    "メールアドレス": "nanako.matsumoto@example.com",
    "携帯電話番号": "080-7890-1234",
    "住所(都道府県)": "新潟県",
    "住所(市区町村)": "新潟市中央区",
    "年齢": 26,
    "職": "バリスタ",
    "好きなスポーツ": "クライミング",
    "性別": "女性"
  },
  {
    "名前": "井上 健一",
    "メールアドレス": "kenichi.inoue@example.com",
    "携帯電話番号": "070-8901-2345",
    "住所(都道府県)": "石川県",
    "住所(市区町村)": "金沢市",
    "年齢": 48,
    "職": "建築家",
    "好きなスポーツ": "剣道",
    "性別": "男性"
  },
  {
    "名前": "斎藤 由美",
    "メールアドレス": "yumi.saito@example.com",
    "携帯電話番号": "090-9012-3456",
    "住所(都道府県)": "群馬県",
    "住所(市区町村)": "前橋市",
    "年齢": 39,
    "職": "カウンセラー",
    "好きなスポーツ": "ピラティス",
    "性別": "女性"
  },
  {
    "名前": "岡田 翔太",
    "メールアドレス": "shota.okada@example.com",
    "携帯電話番号": "080-0123-4567",
    "住所(都道府県)": "三重県",
    "住所(市区町村)": "津市",
    "年齢": 32,
    "職": "シェフ",
    "好きなスポーツ": "ボクシング",
    "性別": "男性"
  }
]

Amazon Nova Pro を使う

プロンプトに示した「関東地方在住者」という絞り込みは行われませんでした。やはりモデルにデータが渡った時点でマスクされていることがわかります。先ほどと異なり、AGE(年齢)がマスクされました。モデルにとっては、CSVデータよりJSONデータのほうが扱いやすいようです。

Model response: (クリックして表示)
以下は、指定されたデータに基づいて `{ADDRESS}` 地方の住民の一覧をCSV形式で表したものです。実際のデータでは `{ADDRESS}` を具体的な住所に置き換え、 `{NAME}`, `{EMAIL}`, `{PHONE}`, および `{AGE}` を実際の値に置き換える必要があります。

```csv
名前,メールアドレス,携帯電話番号,住所(都道府県),住所(市区町村),年齢,職,好きなスポーツ,性別
{NAME},{EMAIL},{PHONE},{ADDRESS},{ADDRESS},{AGE},会社員,テニス,女性
{NAME},{EMAIL},{PHONE},{ADDRESS},{ADDRESS},{AGE},自営業,サッカー,男性
{NAME},{EMAIL},{PHONE},{ADDRESS},{ADDRESS},{AGE},教師,スキー,女性
{NAME},{EMAIL},{PHONE},{ADDRESS},{ADDRESS},{AGE},エンジニア,バスケットボール,男性
{NAME},{EMAIL},{PHONE},{ADDRESS},{ADDRESS},{AGE},デザイナー,ヨガ,女性
{NAME},{EMAIL},{PHONE},{ADDRESS},{ADDRESS},{AGE},医師,ゴルフ,男性
{NAME},{EMAIL},{PHONE},{ADDRESS},{ADDRESS},{AGE},公務員,水泳,女性
{NAME},{EMAIL},{PHONE},{ADDRESS},{ADDRESS},{AGE},弁護士,ランニング,男性
{NAME},{EMAIL},{PHONE},{ADDRESS},{ADDRESS},{AGE},看護師,バレーボール,女性
{NAME},{EMAIL},{PHONE},{ADDRESS},{ADDRESS},{AGE},会社役員,野球,男性
{NAME},{EMAIL},{PHONE},{ADDRESS},{ADDRESS},{AGE},美容師,ダンス,女性
{NAME},{EMAIL},{PHONE},{ADDRESS},{ADDRESS},{AGE},大学教授,卓球,男性
{NAME},{EMAIL},{PHONE},{ADDRESS},{ADDRESS},{AGE},主婦,フィットネス,女性
{NAME},{EMAIL},{PHONE},{ADDRESS},{ADDRESS},{AGE},営業職,フットサル,男性
{NAME},{EMAIL},{PHONE},{ADDRESS},{ADDRESS},{AGE},作家,ハイキング,女性
{NAME},{EMAIL},{PHONE},{ADDRESS},{ADDRESS},{AGE},獣医,サーフィン,男性
{NAME},{EMAIL},{PHONE},{ADDRESS},{ADDRESS},{AGE},バリスタ,クライミング,女性
{NAME},{EMAIL},{PHONE},{ADDRESS},{ADDRESS},{AGE},建築家,剣道,男性
{NAME},{EMAIL},{PHONE},{ADDRESS},{ADDRESS},{AGE},カウンセラー,ピラティス,女性
{NAME},{EMAIL},{PHONE},{ADDRESS},{ADDRESS},{AGE},シェフ,ボクシング,男性
```

このCSVデータは、実際のデータを入力してから使用する準備が整います。
Final response: (クリックして表示)
以下は、指定されたデータに基づいて `{ADDRESS}` 地方の住民の一覧をCSV形式で表したものです。実際のデータでは `{ADDRESS}` を具体的な住所に置き換え、 `{NAME}`, `{EMAIL}`, `{PHONE}`, および `{AGE}` を実際の値に置き換える必要があります。

```csv
名前,メールアドレス,携帯電話番号,住所(都道府県),住所(市区町村),年齢,職,好きなスポーツ,性別
{NAME},{EMAIL},{PHONE},{ADDRESS},{ADDRESS},{AGE},会社員,テニス,女性
{NAME},{EMAIL},{PHONE},{ADDRESS},{ADDRESS},{AGE},自営業,サッカー,男性
{NAME},{EMAIL},{PHONE},{ADDRESS},{ADDRESS},{AGE},教師,スキー,女性
{NAME},{EMAIL},{PHONE},{ADDRESS},{ADDRESS},{AGE},エンジニア,バスケットボール,男性
{NAME},{EMAIL},{PHONE},{ADDRESS},{ADDRESS},{AGE},デザイナー,ヨガ,女性
{NAME},{EMAIL},{PHONE},{ADDRESS},{ADDRESS},{AGE},医師,ゴルフ,男性
{NAME},{EMAIL},{PHONE},{ADDRESS},{ADDRESS},{AGE},公務員,水泳,女性
{NAME},{EMAIL},{PHONE},{ADDRESS},{ADDRESS},{AGE},弁護士,ランニング,男性
{NAME},{EMAIL},{PHONE},{ADDRESS},{ADDRESS},{AGE},看護師,バレーボール,女性
{NAME},{EMAIL},{PHONE},{ADDRESS},{ADDRESS},{AGE},会社役員,野球,男性
{NAME},{EMAIL},{PHONE},{ADDRESS},{ADDRESS},{AGE},美容師,ダンス,女性
{NAME},{EMAIL},{PHONE},{ADDRESS},{ADDRESS},{AGE},大学教授,卓球,男性
{NAME},{EMAIL},{PHONE},{ADDRESS},{ADDRESS},{AGE},主婦,フィットネス,女性
{NAME},{EMAIL},{PHONE},{ADDRESS},{ADDRESS},{AGE},営業職,フットサル,男性
{NAME},{EMAIL},{PHONE},{ADDRESS},{ADDRESS},{AGE},作家,ハイキング,女性
{NAME},{EMAIL},{PHONE},{ADDRESS},{ADDRESS},{AGE},獣医,サーフィン,男性
{NAME},{EMAIL},{PHONE},{ADDRESS},{ADDRESS},{AGE},バリスタ,クライミング,女性
{NAME},{EMAIL},{PHONE},{ADDRESS},{ADDRESS},{AGE},建築家,剣道,男性
{NAME},{EMAIL},{PHONE},{ADDRESS},{ADDRESS},{AGE},カウンセラー,ピラティス,女性
{NAME},{EMAIL},{PHONE},{ADDRESS},{ADDRESS},{AGE},シェフ,ボクシング,男性
```

このCSVデータは、実際のデータを入力してから使用する準備が整います。

Claude Sonnet 4 を使う

やはり、モデルにデータが渡った時点でマスクされていたようで、モデルはデータの不具合を指摘しました。Claude 3.7 Sonnet でも同様の結果でした。

Model response: (クリックして表示)
申し訳ございませんが、提供されたデータにはプレースホルダー({NAME}、{EMAIL}、{PHONE}、{ADDRESS}、{AGE})が含まれており、実際の個人情報は含まれていません。

また、個人情報を含むCSVファイルの作成は、プライバシー保護の観点から適切ではありません。

代わりに、以下のような対応をご提案いたします:

1. **サンプルCSVフォーマットの提供**:
```csv
名前,メールアドレス,携帯電話番号,住所(都道府県),住所(市区町村),年齢,職業,好きなスポーツ,性別
[実際のデータを入力],,[実際のデータを入力],[実際のデータを入力],[実際のデータを入力],[実際のデータを入力],[実際のデータを入力],[実際のデータを入力],[実際のデータを入力]
```

2. **匿名化されたサンプルデータでの例**:
実在しない架空のデータを使用したサンプルをご希望の場合は作成可能です。

3. **データ処理のスクリプト提供**:
実際のデータをお持ちの場合、地域でフィルタリングしてCSVを生成するためのプログラムコードをご提供できます。

どちらの対応をご希望でしょうか?
Final response: (クリックして表示)
申し訳ございませんが、提供されたデータにはプレースホルダー({NAME}、{EMAIL}、{PHONE}、{ADDRESS}、{AGE})が含まれており、実際の個人情報は含まれていません。

また、個人情報を含むCSVファイルの作成は、プライバシー保護の観点から適切ではありません。

代わりに、以下のような対応をご提案いたします:

1. **サンプルCSVフォーマットの提供**:
```csv
名前,メールアドレス,携帯電話番号,住所(都道府県),住所(市区町村),年齢,職業,好きなスポーツ,性別
[実際のデータを入力],,[実際のデータを入力],[実際のデータを入力],[実際のデータを入力],[実際のデータを入力],[実際のデータを入力],[実際のデータを入力],[実際のデータを入力]
```

2. **匿名化されたサンプルデータでの例**:
実在しない架空のデータを使用したサンプルをご希望の場合は作成可能です。

3. **データ処理のスクリプト提供**:
実際のデータをお持ちの場合、地域でフィルタリングしてCSVを生成するためのプログラムコードをご提供できます。

どちらの対応をご希望でしょうか?

コードで書いてみる

以下のコードは、コマンドライン引数で入力されたテキストに対してAmazon Bedrock Guardrailsを使って回答を生成するものです。Converse APIであれば、guardrailConfigを指定することでGuardrailを適用できます。
Claude Sonnet 4 を使うので、事前に Amazon Bedrock のモデルアクセスで Claude Sonnet 4 を有効にしておく必要があります。

コード: (クリックして表示)
app.py
import json
import logging
import sys

import boto3
from botocore.exceptions import ClientError

logging.basicConfig(format="%(asctime)s [%(levelname)s] %(message)s", level=logging.INFO)
logger = logging.getLogger(__name__)


def get_bedrock_client():
    """Bedrock クライアントを取得する"""
    return boto3.client(service_name="bedrock-runtime", region_name="ap-northeast-1")

def generate_response(input_text: str) -> str:
    """応答を生成する"""
    bedrock_client = get_bedrock_client()

    messages = [{"role": "user", "content": [{"text": f"<text>{input_text}</text>"}]}]

    modelid = "apac.anthropic.claude-sonnet-4-20250514-v1:0"

    inference_config = {
        "temperature": 0,
        "maxTokens": 500,
        "topP": 0.99,
    }

    guardrail_id = "xxxxxxxxxxxx" # Guardrail ID を指定する
    guardrail_version = "DRAFT"   # Guardrail Version を指定する

    guardrail_config = {
        "guardrailIdentifier": guardrail_id,
        "guardrailVersion": guardrail_version,
        "trace": "enabled"
    }

    try:
        response_body = bedrock_client.converse(
            messages=messages,
            modelId=modelid,
            inferenceConfig=inference_config,
            guardrailConfig=guardrail_config
        )

        logger.info("Usage: %s",  json.dumps(response_body['usage'], indent=2, ensure_ascii=False))
        logger.info("Output: %s", json.dumps(response_body['output'], indent=2, ensure_ascii=False))
        logger.info("stopReason: %s", json.dumps(response_body['stopReason'], indent=2, ensure_ascii=False))
        logger.info("Trace: %s", json.dumps(response_body['trace'], indent=2, ensure_ascii=False))

        return response_body['output']['message']['content'][0]['text']

    except Exception as e:
        logger.error("Failed to generate response: %s", e)
        raise


def main():
    # コマンドライン引数を取得する
    if len(sys.argv) < 2:
        print("Usage: python3 ./guardrails.py <input_text>")
        sys.exit(1)

    input_text = sys.argv[1]

    logger.info("Original query: %s", input_text)


    try:
        print("Final response: " f"{generate_response(input_text)}")


    except ClientError  as err:
        message = err.response['Error']['Message']
        logger.error("A client error occurred: %s", message)


if __name__ == "__main__":
    main()

実行結果

実行結果: (クリックして表示)

IPA(独立行政法人情報処理推進機構)の連絡先をモデルに尋ねてみました。住所や電話番号、URLがマスクされる結果を期待しました。結果、ビル名の途中がマスクされていませんでした。住所全体である 〒113-6591 東京都文京区本駒込2-28-8 文京グリーンコートセンターオフィス15階 のうち、グリーンコートセンターオフィが住所と見なされずマスクされませんでした。そのほかの情報(電話番号、FAX番号、URL)はマスクされました。

 ❯ python3 ./app.py "IPAの連絡先を教えて。"
2025-07-21 16:12:45,365 [INFO] Original query: IPAの連絡先を教えて。
2025-07-21 16:12:53,757 [INFO] Usage: {
  "inputTokens": 25,
  "outputTokens": 327,
  "totalTokens": 352
}
2025-07-21 16:12:53,757 [INFO] Output: {
  "message": {
    "role": "assistant",
    "content": [
      {
        "text": "IPA(独立行政法人情報処理推進機構)の主な連絡先をお教えします:\n\n## 本部({ADDRESS})\n- **住所**: {ADDRESS}グリーンコートセンターオフィ{ADDRESS}\n- **代表電話**: {PHONE}\n- **FAX**: {PHONE}\n\n## 主な問い合わせ窓口\n- **セキュリティセンター**: {PHONE}\n- **IT人材育成センター**: {PHONE}\n- **デジタル基盤センター**: {PHONE}\n\n## その他\n- **公式ウェブサイト**: {URL}\n- **セキュリティ情報届出**: {URL}\n\n具体的にどのような件でお問い合わせされたいかによって、適切な窓口が異なる場合があります。詳細は公式ウェブサイトでご確認いただくか、代表電話にお問い合わせください。"
      }
    ]
  }
}
2025-07-21 16:12:53,758 [INFO] stopReason: "guardrail_intervened"
2025-07-21 16:12:53,758 [INFO] Trace: {
  "guardrail": {
    "modelOutput": [
      "{\"message\":{\"role\":\"assistant\",\"content\":[{\"text\":\"IPA(独立行政法人情報処理推進機構)の主な連絡先をお教えします:\\n\\n## 本部(東京)\\n- **住所**: 〒113-6591 東京都文京区本駒込2-28-8 文京グリーンコートセンターオフィス15階\\n- **代表電話**: 03-5978-7500\\n- **FAX**: 03-5978-7510\\n\\n## 主な問い合わせ窓口\\n- **セキュリティセンター**: 03-5978-7591\\n- **IT人材育成センター**: 03-5978-7600\\n- **デジタル基盤センター**: 03-5978-7543\\n\\n## その他\\n- **公式ウェブサイト**: https://www.ipa.go.jp/\\n- **セキュリティ情報届出**: https://www.ipa.go.jp/security/vuln/report/\\n\\n具体的にどのような件でお問い合わせされたいかによって、適切な窓口が異なる場合があります。詳細は公式ウェブサイトでご確認いただくか、代表電話にお問い合わせください。\"}]}}"
    ],
    "inputAssessment": {
      "hqjk7te3rzcv": {
        "invocationMetrics": {
          "guardrailProcessingLatency": 262,
          "usage": {
            "topicPolicyUnits": 0,
            "contentPolicyUnits": 0,
            "wordPolicyUnits": 0,
            "sensitiveInformationPolicyUnits": 1,
            "sensitiveInformationPolicyFreeUnits": 0,
            "contextualGroundingPolicyUnits": 0
          },
          "guardrailCoverage": {
            "textCharacters": {
              "guarded": 25,
              "total": 25
            }
          }
        }
      }
    },
    "outputAssessments": {
      "hqjk7te3rzcv": [
        {
          "sensitiveInformationPolicy": {
            "piiEntities": [
              {
                "match": "東京",
                "type": "ADDRESS",
                "action": "ANONYMIZED"
              },
              {
                "match": "〒113-6591 東京都文京区本駒込2-28-8 文京",
                "type": "ADDRESS",
                "action": "ANONYMIZED"
              },
              {
                "match": "ス15階",
                "type": "ADDRESS",
                "action": "ANONYMIZED"
              },
              {
                "match": "03-5978-7500",
                "type": "PHONE",
                "action": "ANONYMIZED"
              },
              {
                "match": "03-5978-7510",
                "type": "PHONE",
                "action": "ANONYMIZED"
              },
              {
                "match": "03-5978-7591",
                "type": "PHONE",
                "action": "ANONYMIZED"
              },
              {
                "match": "03-5978-7600",
                "type": "PHONE",
                "action": "ANONYMIZED"
              },
              {
                "match": "03-5978-7543",
                "type": "PHONE",
                "action": "ANONYMIZED"
              },
              {
                "match": "https://www.ipa.go.jp/",
                "type": "URL",
                "action": "ANONYMIZED"
              },
              {
                "match": "https://www.ipa.go.jp/security/vuln/report/",
                "type": "URL",
                "action": "ANONYMIZED"
              }
            ]
          },
          "invocationMetrics": {
            "guardrailProcessingLatency": 391,
            "usage": {
              "topicPolicyUnits": 0,
              "contentPolicyUnits": 0,
              "wordPolicyUnits": 0,
              "sensitiveInformationPolicyUnits": 1,
              "sensitiveInformationPolicyFreeUnits": 0,
              "contextualGroundingPolicyUnits": 0
            },
            "guardrailCoverage": {
              "textCharacters": {
                "guarded": 449,
                "total": 449
              }
            }
          }
        }
      ]
    }
  }
}
Final response: IPA(独立行政法人情報処理推進機構)の主な連絡先をお教えします:

## 本部({ADDRESS})
- **住所**: {ADDRESS}グリーンコートセンターオフィ{ADDRESS}
- **代表電話**: {PHONE}
- **FAX**: {PHONE}

## 主な問い合わせ窓口
- **セキュリティセンター**: {PHONE}
- **IT人材育成センター**: {PHONE}
- **デジタル基盤センター**: {PHONE}

## その他
- **公式ウェブサイト**: {URL}
- **セキュリティ情報届出**: {URL}

具体的にどのような件でお問い合わせされたいかによって、適切な窓口が異なる場合があります。詳細は公式ウェブサイトでご確認いただくか、代表電話にお問い合わせください。

まとめ

今回試した結果では、前回の記事の検証とは異なりモデルにデータが渡った時点でマスクされていることがわかりました。また、CSV と JSON のデータ形式では、マスクされる内容が異なることがわかりました。
また、モデルに情報を問い合わせた結果では、住所の一部が不自然にマスクされない状況でした。Sensitive information filters (機密情報フィルター) は日本語対応しているものの、期待どおりに動作しない場合もあるようです。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?