我が家では、育児相談に乗ってくれる平成ギャルにLINEで相談しながら育児を楽しんでいます。
最近のインターネット上は物騒になってきているので、我が家のギャルちゃんを守らねば!と思いました。
そこで、Google CloudのModel Armorをギャルちゃんに着せてあげようと思います。
Model Armorとは
AIアプリケーションのセキュリティと安全性を向上するためにGoogle Cloudが提供しているサービスです。
ざっくり以下のような機能を持っています。
| 分類 | 機能 |
|---|---|
| セキュリティ | LLMに対する攻撃を無害化 |
| 安全性 | LLMによる有害なコンテンツ生成を抑制 |
仕組みは以下の通りです。★つきの個所がModel Armor利用時に追加実装する箇所です。
- AIアプリケーションがプロンプトを受け取る
- AIアプリケーションがModel Armorにプロンプトを渡し、無害化する★
- AIアプリケーションが無害化されたプロンプトをLLMに渡し、コンテンツ生成する
- AIアプリケーションがModel Armorに生成されたコンテンツを渡し、無害化する★
- AIアプリケーションがユーザーに無害化されたコンテンツを返す
ギャルちゃんにArmorを着せる
それでは、ギャルちゃんを守るためにArmorを着せていきます。
イメージはこんな感じ!
左のギャルちゃんはLINE botのアイコン画像です。
Agent Studioで画像を添付してArmorを着せてとお願いしたら右のギャルちゃんになりました笑
Model Armorのテンプレートを作成
Model Armorでは、何を無害化するか・無害化判定の閾値をどの程度にするかを設定できます。
これらを設定したものをテンプレートといい、テンプレートを指定してModel Armorを利用します。
今回はほぼデフォルトの設定で以下のように作成しました。
「追加の構成」を開いたところにある「多言語サポートを有効にする」をオンにしないと日本語対応してくれない点に要注意です。
LINEメッセージをModel Armorで検閲する
今回はLINEメッセージを検閲して、有害なメッセージの場合には固定のエラーメッセージを返すようにしました。
冒頭で紹介したLLMによる生成コンテンツを無害化する部分は実装していません。
本記事を参考にsanitize_model_responseを使って生成コンテンツの無害化も実装できると思いますので、興味のある方は試してみてください。
ギャルちゃんのシステム構成については下記記事の構成図を参照ください。
Cloud RunからAgent Runtimeを呼び出すまでの間に以下の実装を加えます。
# トップレベルでModel Armorクライアントを作成しておく
from google.cloud import modelarmor_v1
modelArmorClient = modelarmor_v1.ModelArmorClient(transport="rest", client_options = {"api_endpoint" : f"modelarmor.{LOCATION}.rep.googleapis.com"})
# 中略
async def handle_message_async(event):
user_message = event.message.text
user_id = event.source.group_id if hasattr(event.source, "group_id") else event.source.user_id
logger.info(f"Received message: {user_message} from {user_id}")
try:
# Agent Runtime (Reasoning Engine) を呼び出し
if not AGENT_RUNTIME_ID:
reply_text = "ごめん!エージェントの設定がまだ終わってないみたいじゃん。管理者に確認してね!"
else:
# ★ここから追加★
# Model Armorにリクエストするデータの準備
user_prompt_data = modelarmor_v1.DataItem()
user_prompt_data.text = user_message
modelArmorRequest = modelarmor_v1.SanitizeUserPromptRequest(
# 作成したテンプレートを指定
name=f"projects/{PROJECT_ID}/locations/{LOCATION}/templates/{ARMOR_TEMPLATE}",
user_prompt_data=user_prompt_data,
)
# Model ArmorでLINEメッセージを検閲する
modelArmorResponse = modelArmorClient.sanitize_user_prompt(request=modelArmorRequest)
logger.info(f"Model Armor Response: {modelArmorResponse}")
# もし不適切なコンテンツが検出された場合は、処理を中断して警告を返す
if modelArmorResponse.sanitization_result.filter_match_state == modelarmor_v1.FilterMatchState.MATCH_FOUND:
reply_text = "ごめん!そのメッセージはちょっと不適切な内容が含まれているみたいで、お返事できないんだ。別の言葉で話しかけてみて!"
logger.warning(f"Message blocked by Model Armor: {user_message}")
else:
# ★ここまで追加★
# 以下略
Model Armorのクライアントを作成する際、api_endpointはテンプレートのLocationを一致させる必要があります。
今回は我が家でしか使っていないBotのデバッグのためにLINEメッセージを直接ログ出力していますが、他者に提供する場合はプライバシーを守るためにメッセージはログ出力しないようにしましょう。
Cloud RunのSAにModel Armorを利用するための権限を付与する
以下のようにModel Armorユーザーを付与します。
動作確認する
修正したソースコードをCloud Runにデプロイした状態で動作確認してみます。
最初にいつも通りの育児メッセージ、続いて危険なコンテンツを生成させようとするメッセージです。
ちゃんと二つ目のメッセージは拒否してくれましたね。
ログを見てみると以下のようにジェイルブレイクの危険性がHIGHと認定されていました。
これにより、ソースコードの以下の分岐に入り、固定のエラーメッセージを返していました。
# もし不適切なコンテンツが検出された場合は、処理を中断して警告を返す
if modelArmorResponse.sanitization_result.filter_match_state == modelarmor_v1.FilterMatchState.MATCH_FOUND:
reply_text = "ごめん!そのメッセージはちょっと不適切な内容が含まれているみたいで、お返事できないんだ。別の言葉で話しかけてみて!"
logger.warning(f"Message blocked by Model Armor: {user_message}")
上記のソースコードではAgent Runtimeにアクセスしていないため、セッションやメモリーが汚されない点も重要ですね!
まとめ
無事、ギャルちゃんにアーマーを装備させることができました!
AIはものすごい速度で進化し、普及していっています。
一方、AIエージェントもセキュリティホールになり得ます。
せっかく作ったAIエージェントが悪用されないようにしっかりと守っていきたいですね。







