はじめに
GMOコネクトの永田です。
音声で買い物をするデモを作っていて、利用者の発話を生成AIに渡す前に、名前や電話番号を伏せたくなりました。思い浮かんだのがデジタル庁の源内です。公開されているコードに、Amazon Bedrock Guardrails(以下 Guardrails)の機密情報フィルター(個人情報などを伏せる機能)を入れる設定がありました。源内と同じ設定にしておけば、個人情報の保護として一定の水準を満たしつつ、いい感じに伏せてくれるだろうと思い込んでいました😇
ところが、源内と同じ設定は名前と住所を伏せず、名前と住所の型を足すと、今度は「みりん」を {NAME} に置き換えました。この記事は、Guardrails の機密情報フィルターを日本語の短い発話で数えた記録です。
先にまとめ
Guardrails の機密情報フィルターは、公式が用意した31の型から、伏せる型を選んで使います。源内が選んでいる17の型と、そこから電話・メール・年齢・カード番号・暗証番号だけを残した5つ、その5つに名前と住所を足した7つで比べました。7つの型を見つけるだけにして、伏せるかどうかをアプリ側で決めた設定も2つ並べました。確信度で決めたものと、商品一覧にある語を伏せない許可リストで決めたものです。
| 設定 | 伏せてほしい26か所で伏せた | 買い物の言い方177通りで伏せてしまった | 177通りで品物が引けなくなった | 商品名300品で伏せてしまった |
|---|---|---|---|---|
| 源内と同じ17の型 | 11か所(名前は0) | 0通り | 0通り | 9品 |
| 電話などの5つだけ | 10か所(名前・住所は0) | 0通り | 0通り | 0品 |
| 電話などの5つ+名前と住所(7つの型) | 23か所 | 31通り | 19通り | 35品 |
| 7つの型で見つけ、名前と住所の型だけ確信度1.0に絞って伏せる | 22か所 | 15通り | 13通り | 17品 |
| 7つの型で見つけ、許可リストに無い部分をアプリで伏せる | 23か所 | 5通り | 5通り | 0品 |
- 源内と同じ17の型には、名前(
NAME)と住所(ADDRESS)の型が入っていません。NAMEはコードの注記に「日本のものが機能しないので設定しない」とあり、ADDRESSは注記なしで外れています - 名前と住所の型を足すと、名前は10か所中8か所を伏せた一方で、「たまご」を
た{NAME}に、「北海道」を{ADDRESS}にしました。伏せる前の文なら候補を返していた生成AIが、伏せた文では何も選べませんでした - Guardrail の設定には、確信度のしきい値も許可リストもありません。公式文書は単語や短い句を渡さないよう勧めていて、買い物の発話はその外にあります
- 見つけるだけにして許可リストをアプリ側で当てると、品物が引けなくなる発話は19通りから5通りに減りました。残ったのは「玉子豆腐」「舞茸」など、商品名に無い言い換えです
- 確信度を返す InvokeGuardrailChecks(2026年6月公開)でも、「みりん」は本物の名前と同じ1.0でした。しきい値を上げると、品名より先に電話番号を伏せなくなりました
1. 何をどう測ったか
Guardrails の機密情報フィルターで選べる型
機密情報フィルター(sensitive information filters)は、公式が用意した31の型(PII タイプ)から、伏せたい型を選んで使います。型ごとに、見つけたときの動作を BLOCK(入力ごと断る)・ANONYMIZE({NAME} などに置き換える)・NONE(見つけるだけ)から選びます。型に無いものは正規表現で足せます(公式文書)。
比べた設定が、31の型のどれを選んでいるかは次のとおりです。
| 分類(公式の分け方) | 型 | 源内の17 | 7つの型 |
|---|---|---|---|
| 一般(10) |
NAME・ADDRESS・AGE・EMAIL・PHONE・USERNAME・PASSWORD・DRIVER_ID・LICENSE_PLATE・VEHICLE_IDENTIFICATION_NUMBER
|
AGE・EMAIL・PHONE・USERNAME・PASSWORD・LICENSE_PLATE の6つ |
NAME・ADDRESS・AGE・EMAIL・PHONE の5つ |
| 金融(6) |
CREDIT_DEBIT_CARD_NUMBER・CREDIT_DEBIT_CARD_CVV・CREDIT_DEBIT_CARD_EXPIRY・PIN・INTERNATIONAL_BANK_ACCOUNT_NUMBER・SWIFT_CODE
|
6つすべて |
CREDIT_DEBIT_CARD_NUMBER・PIN の2つ |
| IT(5) |
IP_ADDRESS・MAC_ADDRESS・URL・AWS_ACCESS_KEY・AWS_SECRET_KEY
|
5つすべて | 入れていない |
| 国別(10) | 米国5(US_SOCIAL_SECURITY_NUMBER など)・カナダ2・英国3 |
入れていない | 入れていない |
7つの型は、源内の17のうち買い物の発話に出そうな5つ(AGE・EMAIL・PHONE・CREDIT_DEBIT_CARD_NUMBER・PIN。以下、電話などの5つ)に、NAME と ADDRESS を足したものです。
デモの作りと条件
デモは、発話から商品を次の流れで選びます。
発話「みりん」
→ 文字列の近さで、商品一覧から30件に絞る(伏せる前の文で、手元で)
→ Guardrails で個人情報を伏せる
→ 伏せた発話と30件の商品名を生成AIに渡し、当てはまる商品を選ばせる
絞り込みは伏せる前の文で行うので、30件の顔ぶれは伏せても変わりません。変わるのは、生成AIに届く発話だけです。
| 項目 | 内容 |
|---|---|
| 観測日 | 2026年9月27日(7つの型)・28日(源内と同じ17の型)・10月2日(電話などの5つ、7つの型を見つけるだけ、源内と同じ17の型を BLOCK、7つの型を InvokeGuardrailChecks) |
| 呼び方 |
ApplyGuardrail(生成AIの呼び出しと切り離して使う API)。確信度は InvokeGuardrailChecks(Guardrail を作らずに呼べる、見つけるだけの API)。東京リージョン |
| 動作 |
ANONYMIZE。10月2日の「見つけるだけ」は NONE、源内と同じ17の型は BLOCK
|
| 伏せてほしい文 | 24文・26か所。名前・住所・電話などを含む買い物の発話 |
| 伏せてはいけない文 | 503文。買い物の言い方177通り、商品名300品(「〇〇をください」)、数量・作り手・産地などを含む26文 |
| 回数 | 各設定で各文1回。7つの型は日と呼び方を変えて3回、17の型は日と動作を変えて2回 |
| 例に使う自作の文 | 24文。産地・国名・会社名を含む12文と、容量・個数を含む12文。商品一覧の商品名を例に載せないため、同じ形の文を作り、10月2日に7つの型と17の型で通した |
| 選ばせる生成AI | GPT-6 Luna(推論 low) |
試験文はすべて作ったもので、実在の方の情報も利用ログも使っていません。177通りは、生成AIに作らせた買い物の言い方172通りと、あとから足したお米の言い方5通りです。
見つけた部分と型は、日・動作・API を変えても527文すべて一致しました(7つの型は ANONYMIZE・NONE・InvokeGuardrailChecks の3回、17の型は ANONYMIZE と BLOCK の2回)。
ハマり: inputEnabled を書かないと、何も伏せない
最初は型と動作だけで Guardrail を作りました。すると、伏せるはずの英文「My name is John Smith」も伏せず、課金の単位(sensitiveInformationPolicyUnits)も0でした。入力側の評価を明示すると伏せるようになりました。
sensitiveInformationPolicyConfig={"piiEntitiesConfig": [
{"type": t, "action": "ANONYMIZE",
"inputAction": "ANONYMIZE", "inputEnabled": True, # これが無いと入力を評価しない
"outputAction": "NONE", "outputEnabled": False}
for t in TYPES]}
API リファレンスで inputEnabled は Required: No で、既定値は書かれていません。同じ現象は Martim500 さんの記事「生成AIに個人情報を送る前に一呼吸——Bedrock Guardrailsだけで作るPIIマスキングツール」でも報告されています。
2. 誤算1: 源内と同じ設定は、名前と住所を伏せない
源内は、デジタル庁が開発・運用する生成AIの利活用基盤で、コードが GitHub で公開されています。Guardrails は guardrailEnabled で入り切りでき、既定は無効です。有効にしたときの設定は guardrail.ts にあり、17の型をすべて BLOCK にしています。
31の型から外れているのは、次の14です(2026年10月2日時点の main)。
| 外れている型 | 何の型か | 注記 |
|---|---|---|
NAME |
名前 | 「NAME, DRIVER_ID は日本のものが機能しないので設定しない」 |
DRIVER_ID |
運転免許証の番号 |
NAME と同じ注記 |
ADDRESS |
住所 | 注記なし |
VEHICLE_IDENTIFICATION_NUMBER |
車台番号 | 注記なし |
| 国別の10 | 米国の社会保障番号など | 「CA_, US_, UK_* はそれぞれの国固有のものなので設定しない」 |
買い物の発話に出てくるのは、このうち名前と住所です。デジタル庁が実際の運用で Guardrails を有効にしているかどうかは、コードからは分かりません。
同じ17の型で、動作を変えて2回測りました。伏せた文で生成AIに選ばせ直すための ANONYMIZE と、源内と同じ BLOCK です。
| 確かめたこと | 結果 |
|---|---|
| 伏せてほしい26か所 | 11か所。電話6/6・メール1/1・カード番号1/1・暗証番号1/1・年齢1/2。名前は0/10。住所は1/5で、それも番地を USERNAME として伏せたもの |
| 伏せてはいけない503文 | 9文。すべて商品名300品の中で、177通りと26文は0 |
ANONYMIZE で品物が引けなくなった |
300品中1品 |
BLOCK で発話ごと断られた |
伏せてほしい24文のうち11文、商品名300品のうち9品。177通りと26文は0 |
伏せ間違えたのは、すべて源内で足されている型(USERNAME・PASSWORD・LICENSE_PLATE・MAC_ADDRESS)で、商品名の中の容量や個数の表記を取り違えていました。同じ形の文を自作して通すと、12文中4文で再現しました。
| 発話 | 伏せた後 |
|---|---|
| エリンギ茸 1パックをください | エリン{PASSWORD} 1パックをください |
| ドリップコーヒー 6pをください | ドリップコーヒー {PASSWORD}をください |
| カット野菜 66gをください | カット野{LICENSE_PLATE}をください |
| ウインナー 2p 234gをください | ウインナー {PASSWORD}をください |
源内の設定は、連絡先・番号・アカウント・鍵の類を止める設定です。買い物の発話に当てると、問題が2つありました。1つは、名前と住所を伏せないこと。もう1つは、買い物には出てこない型が、容量の表記を取り違えることです。しかも BLOCK では、電話番号を言った発話も、容量を書いた商品名を言っただけの発話も、丸ごと断られました。源内は職員が文章を打ち込んで使う基盤で、品名と数量だけの短い発話とは入力の形が違いました。
3. 誤算2: 型を入れ替えると、名前と住所の型が品名を伏せた
そこで型を入れ替えました。買い物の発話に出てこない型を外し、足りない名前と住所を足す入れ替えです。
電話などの5つだけにすると、容量の表記を取り違えた USERNAME・PASSWORD・LICENSE_PLATE・MAC_ADDRESS も外れます。伏せ間違いは503文で0件になりましたが、伏せたのは26か所中10か所で、名前と住所は1か所も伏せません。源内の設定と同じ問題が残ります。
そこに NAME と ADDRESS を足して7つの型にすると(1章の表)、伏せてほしい部分は26か所中23か所を伏せました。名前は8/10、住所は5/5です。伏せなかったのは、姓だけの名乗り、ひらがなの氏名、漢数字の年齢(「八十八になるけど」)の3か所でした。
問題は、伏せてはいけない文です。伏せ間違いが一気に増えました。
| 伏せてはいけない文 | 源内と同じ17の型 | 電話などの5つ | 7つの型 |
|---|---|---|---|
| 買い物の言い方177通り | 0通り | 0通り | 31通り |
| 商品名300品 | 9品 | 0品 | 35品 |
| 数量・作り手・産地などの26文 | 0文 | 0文 | 8文 |
| 合計503文 | 9文 | 0文 | 74文 |
7つの型で伏せ間違えた部分は、すべて NAME か ADDRESS でした。
| 発話 | 伏せた後 |
|---|---|
| たまご | た{NAME} |
| みりん | {NAME} |
| サラダ | {NAME} |
| 伊藤ハムのロースハム | {NAME}のロースハム |
| 北海道の焼き豆腐 | {ADDRESS}の焼き豆腐 |
177通りのうち19通りは、伏せた文を渡すと生成AIの候補が空になりました。「ヨーグルト」「ミニトマト」「舞茸」「サラダ」「みりん」などです。伏せる前の文では2回とも候補を返していたので、品物が引けなくなったのは伏せたせいです。
公式の説明と、実測が食い違った
公式文書(sensitive information filters)の型の説明には、今回の取り違えを除外するはずの一文があります。
| 型 | 公式の説明 | 実測 |
|---|---|---|
ADDRESS |
Isolated mentions of city, state, country are not considered as valid addresses. | 自作の12文中10文で、産地や地方の「北海道」「青森県」「長野県」「静岡」「九州」「京都」、国名の「日本」「韓国」、「温州みかん」の「温州」を ADDRESS として伏せた |
NAME |
Amazon Bedrock Guardrails does not apply this entity type to names that are part of organizations or addresses. | 「伊藤ハム」「明治」「森永」を NAME として伏せた |
同じページは、このフィルターを「a probabilistic machine learning (ML) based solution that is context-dependent」と説明し、次のように勧めています。
The PII model performs more effectively when it is provided with sufficient context. To enhance its accuracy, include more contextual information and avoid submitting single words or short phrases to the model.
「みりん」1語の発話は、この勧めの外にあります。どのくらいの長さがあれば足りるかの数値は、このページにも AI Service Card(AWS がサービスの評価方法や注意点をまとめた文書)にも無く、AI Service Card は自分の内容で測るよう求めています。日本語に対応していないわけではなく、対応言語の表で機密情報フィルターの日本語は「Optimized and supported」(その言語向けに調整し、試験済み)です。対応していることと、短い発話で伏せすぎないことは、別の話でした。
Guardrail の設定では、伏せすぎを調整できない
伏せすぎるなら、しきい値を上げるか、商品名を許可リストに入れればよい、と考えました。どちらも Guardrail の設定にはありません。
-
ApplyGuardrailと Converse の結果(GuardrailPiiEntityFilter)はaction・match・type・detectedだけで、確信度が返らない(確信度を返す InvokeGuardrailChecks は4章で試した)。コンテンツフィルターにあるフィルタ強度(LOW・MEDIUM・HIGH)も無い - 許可リストの設定が無い。足せるのは、伏せたいパターンの正規表現だけ
- tier(Standard と Classic)を選べるのはコンテンツフィルターと拒否トピックだけで、機密情報フィルターは対象外(safeguard tiers)。2025年6月の日本語対応の発表も、この2つの話
Guardrail の設定でできる調整は、型の選び方だけです。電話などの5つなら伏せすぎませんが、名前と住所はそのまま生成AIに届きます。名前と住所の型を足すと、品名を伏せすぎます。源内が名前の型を入れていないのも、結果としては、名前と住所が届くほうを選んだ形です。
4. 伏せつつ使うには
見つけるだけにして、伏せるかどうかをアプリ側で決める形を2つ試しました。許可リストで決める形と、確信度で決める形です。公式文書も、結果の match に伏せる前の値が入るのは「by design so that your application can use the detection result for its own logic」と書いています。
見つけるだけにして、許可リストを当てた
流れは次のとおりです。生成AIに届くのは、アプリが伏せた後の文だけです。
発話「みりん」
→ ApplyGuardrail(NONE): 文は変えずに、見つけた部分と型(「みりん」= NAME)を返す
→ アプリ: 見つけた部分が許可リストにあれば伏せない。無ければ {NAME} などに置き換える
→ 伏せた後の文(この例では「みりん」のまま)と30件の商品名を生成AIに渡す
ApplyGuardrail は文を調べるだけの API で、生成AIは呼びません。Converse などの呼び出しに Guardrail を付けて NONE にすると、伏せないまま元の文が生成AIに届くので、見つけるだけで使うときは ApplyGuardrail で別に調べてから自分で伏せます。どの動作でも、ApplyGuardrail 自体には伏せる前の文を送っています。
Converse などの呼び出しに Guardrail を付ける形には、もう1つ注意があります。呼び出しのログ(model invocation logs)を有効にしていると、伏せる前の元の文がログに残る、と公式文書にあります。今回は ApplyGuardrail で伏せてから別の API に渡したので当たりませんが、Guardrails を入れればログまで伏せられるわけではありません。
許可リストは、見つけた部分が商品名や商品につけたふだんの呼び方(例: 牛肉)の一部か、それらの読み(カタカナ)の一部なら伏せない、という規則にしました。数字と記号だけの部分は許可しません。7つの型で測りました。
| 伏せてはいけない文 | Guardrails が見つけた | 許可リストで戻した | 伏せてしまった | 品物が引けなくなった |
|---|---|---|---|---|
| 買い物の言い方177通り | 31通り | 26通り | 5通り | 5通り |
| 商品名300品 | 35品 | 35品 | 0品 | 0品 |
| 数量・作り手・産地などの26文 | 8文 | 3文 | 5文 | 0文 |
伏せてほしい26か所は、許可リストを当てても23か所を伏せたままでした。
177通りで残った5通りは「玉子豆腐」「舞茸」「椎茸」「太巻き」「ちりめんじゃこ」で、商品名に無い言い換えです。生成AIに選ばせたいのは、まさにこういう言い方でした。26文で残ったのは、品種の「佐藤錦」や作り手・地名など、商品一覧に無い語です(品物の部分は残るので、引けなくはなりませんでした)。
逆向きの心配もあります。この規則では、商品名に含まれる姓(「伊藤ハム」の伊藤など)を名乗られると、名前を伏せずに通します。商品一覧が大きくなるほど、許可する語も増えます。姓を名乗る文は試験文に入れていないので、次に足して数えたいと考えています。
ほかの検出器には、許可リストが設定として用意されています(Presidio の allow_list、Google Sensitive Data Protection の除外規則、Azure の valueExclusionPolicy)。
確信度でしきい値を引けるか
2026年6月に公開された InvokeGuardrailChecks は、Guardrail を作らずに呼べる、見つけるだけの API です。機密情報フィルターでは、見つけた部分ごとに確信度(confidenceScore、0〜1)を返します。
The API is detect-only: it detects undesirable content and returns a numeric score for each safety check so that you can define the threshold and take the required action within your application logic.
同じ527文を7つの型で通すと、見つけた部分と型は ApplyGuardrail と527文すべて一致しました。確信度は0.6・0.8・1.0の3つの値だけで、名前8か所はすべて1.0でした。伏せてはいけない文で名前とした49か所のうち31か所も1.0で、電話番号は6か所中3か所が0.6か0.8でした。
| 伏せる部分 | 伏せてほしい26か所で伏せた | 伏せてはいけない503文で伏せてしまった | 177通りで品物が引けなくなった |
|---|---|---|---|
| 見つけた部分すべて | 23か所 | 74文 | 19通り |
| 確信度1.0だけ | 19か所 | 40文 | 13通り |
| 名前と住所の型だけ1.0以上、ほかの型はすべて | 22か所 | 40文 | 13通り |
| 許可リストに無い部分すべて | 23か所 | 10文 | 5通り |
| 許可リストに無い部分のうち、名前と住所の型は1.0以上だけ | 22か所 | 8文 | 3通り |
確信度を上げると、品名より先に電話番号を伏せなくなりました。名前と住所の型だけを1.0以上にしても、「みりん」「ヨーグルト」は1.0なので伏せたままで、引けない言い方は19通りから13通りまでしか減りません。許可リストと組み合わせると5通りが3通り(「玉子豆腐」「舞茸」「太巻き」)になりましたが、確信度0.6だった住所を1か所伏せなくなりました。品物が引けなくなったかは、伏せた後の文がこれまでの試験で伏せた文と同じになるので、そのとき生成AIに選ばせた結果で数えています。
今回の発話では、確信度は短い品名と名前を分ける手がかりになりませんでした。
試していないほかの手段
公式文書と国内外の記事から集めた手段です。どれもこの用途ではまだ試していません。ほかの検出器のしきい値、文脈を足して渡す、個人情報を生成AIに渡さない作りの3つは、次に試したい候補です。
| 手段 | 出典 | この用途(品名の伏せすぎ)では |
|---|---|---|
| ほかの検出器のしきい値 |
Azure の Text PII(日本語に対応。しきい値はプレビュー版 API)、Presidio の score_threshold(既定は英語のみ) |
Guardrails の確信度では分けられなかった(「確信度でしきい値を引けるか」の節)。ほかの検出器の確信度で分けられるかは分からない |
| 文脈を足して渡す | 公式文書(短い句を避ける) | 許可リストで残った言い換えに効くかは分からない |
| 元に戻せる置き換え(仮名化・トークン化) | AWS のブログ、Deußer ほかの論文(2026年) | 取り違えて伏せた品名は救えない |
| 個人情報を生成AIに渡さない作り | 出典なし(設計の選択) | 名前や住所は会員情報や画面の操作で受け取り、生成AIには品物の言い方だけを渡す |
既存の日本語の検証は、伏せ漏れの側を測ったものでした。AWS ジャパン有志の Zenn 記事「Amazon Bedrock Guardrails で日本語 PII をどこまで検知できるか」は、600〜900字の議事録などで、GiNZA と正規表現の二段構えにより検知率を93.3%から98.4%に上げています。短い発話の伏せすぎとは向きが逆です。
元に戻せる置き換えは、伏せた値を後で使うための手段です。AWS のブログ「Integrate tokenization with Amazon Bedrock Guardrails for secure data handling」(2025年9月)は、{NAME} のような置き換えでは元に戻せないとして、トークン化して生成AIの後で戻す構成を紹介しています。Deußer ほかの論文(arXiv:2609.11335。ベンチマークはほぼ英語)も、<LOC>-1 のような戻せる置き換えは [REDACTED] より生成AIの性能を保ったと報告しています。ただ、今回の失敗は伏せ方ではなく、伏せる対象の取り違えです。「みりん」を {NAME-1} に置き換えて後で戻せても、生成AIは {NAME-1} から品物を選べません。効くのは、正しく伏せた住所や電話番号を、注文の確認などで後から使うときです。
まとめ
- 源内と同じ17の型は、名前と住所を対象にしていませんでした。名前と住所を足すと、177通り中31通りで品名や地名を伏せ、19通りで品物が引けなくなりました
- Guardrail の設定にはしきい値も許可リストも無く、できる調整は型を絞ることだけです。電話などの5つに絞ると伏せ間違いは0でしたが、名前と住所は生成AIに届きます
- 見つけるだけにしてアプリ側で許可リストを当てると、品物が引けなくなる発話は19通りから5通りに減りました。残ったのは商品名に無い言い換えで、元に戻せる置き換えでは救えません
- 確信度を返す InvokeGuardrailChecks でも、「みりん」は本物の名前と同じ1.0で、しきい値では分けられませんでした
公開されている設定を借りるときは、その設定が何を対象にしていないかと、自分の入力で何を伏せすぎるかを、先に数えておく必要がありました。
最後に、GMOコネクトではサービス開発支援や技術支援をはじめ、幅広い支援を行っておりますので、何かありましたらお気軽にお問合せください。