🚨

Azure OpenAI Serviceのコンテンツフィルタをオフにするのは許さぬ(後編)

に公開

はじめに

以前、「Azure OpenAI Serviceのコンテンツフィルタをオフにしてみる」という記事を書きました。
https://zenn.dev/tomot/articles/3137700208c055
https://zenn.dev/tomot/articles/38e1a33db82dd0

そもそものコンテンツフィルタとは何か?みたいな話は上の記事で読んでいただくとして、
前編・中編でやったことは「コンテンツフィルタオフの状態で使われたら困るよ」というのをどうやって制御したらいいかね?というのを検討するための前段の準備まででした。
その制御を後編で考えようと思っていたのですが、思っていて早3ヶ月。やっと書けるところまできたので記録に残します。

こういった検討は、生成AI界隈の人ではなくて、Azure自体、Azureインフラに軸足を置く私のような人の役割だと思うんです。ということで早速本題に入ります。

ユースケース

フルスタックエンジニアが下から上まで全部担当してます!という世界線もあると思いますが、エンプラ界隈ではまだまだアプリケーション担当とインフラ担当、統制担当といった役割で分かれていると思います。
そのような中で、「アプリ担当」と呼ばれる役割にできるだけ権限を委譲しながら開発のスピードを速めながら、「インフラ担当」や「統制担当」がセキュリティ面・統制面で守りたい事柄を仕組み化し、アプリ担当が好き勝手開発できる権限を渡すけど、これだけはやったらまずいという設定を守る…というのが目指したいユースケースです。

Azure OpenAIのコンテンツフィルタは、こういった要素の典型だと思います。責任あるAIを目指すためには統制担当の許可なくフィルタ条件を緩めたくない。
一方でアプリ担当やインフラ担当からすると、フィルタを含むAOAIリソースは自分で設定したいし、誰かの許可をもらいながらでは開発のスピードに大きく悪影響が出てしてしまう。

そういった中で、Azure Policyを使うことで制御したいというのが今回の目的です。

特定のコンテンツフィルタを使ってもらう

「事前に作成した特定のコンテンツフィルタを設定することを強制する」というのは、世の中にも情報がありました。勝手にLinkさせていただきますが、Microsoftの中の人の記事です。
https://zenn.dev/microsoft/articles/20241213-enforce-content-filter
これ自体は素晴らしいですし、この設定はするべきだと思います。

一方で私は性格が悪く(?)、開発者としてどうやって抜け穴を突けるかなー?と悪いことを考えてしまいます…

そう、このカスタムフィルターの中身をいじって、ガバガバにしてしまえばこの制御は実質無効化できますね…?
※もしかすると、権限の制御(RBAC)で「コンテンツフィルタは操作させない」ということができるかもしれません。それはそれで1テーマになりますね。

カスタムフィルタの作成を制御する

ということでカスタムフィルタを作成する際に、どうやったらフィルタの設定値を制御できるか?というのを考えます。

コンテンツフィルタのオフを許さぬポリシー

前提が長くなりましたが、こんなAzure Policyを考えてみました。

deny-disable-contentfilter.json
{
  "properties": {
    "displayName": "deny-disable-contentfilter",
    "policyType": "Custom",
    "mode": "All",
    "policyRule": {
      "if": {
        "allOf": [
          {
            "field": "type",
            "equals": "Microsoft.CognitiveServices/accounts/raiPolicies"
          },
          {
            "not": {
              "field": "Microsoft.CognitiveServices/accounts/raiPolicies/contentFilters[*].enabled",
              "Equals": "true"
            }
          }
        ]
      },
      "then": {
        "effect": "deny"
      }
    }
  }

以下の配列は、コンテンツフィルタの中身の「Selfhalm」や「sexual」といったカテゴリおよび「jailbreak」などの項目ごとのパラメータを保持しており、上記の記載により「全部有効じゃなければ、deny(リソースの作成を拒否)」という制御としている例です。

"Microsoft.CognitiveServices/accounts/raiPolicies/contentFilters[*].enabled"

ポリシー条件のカスタマイズ

この場では発想の元だけ記載しておきます。
まず、ARMテンプレートで、コンテンツフィルタがどう記載されているか見てみましょう。
※デフォルトで作成されている「DefaultV2」のものです。

            "type": "Microsoft.CognitiveServices/accounts/raiPolicies",
            "apiVersion": "2024-10-01",
            "name": "[concat(parameters('aoaiリソース名'), '/Microsoft.DefaultV2')]",
            "dependsOn": [
                "[resourceId('Microsoft.CognitiveServices/accounts', parameters(''aoaiリソース名'))]"
            ],
            "properties": {
                "mode": "Blocking",
                "contentFilters": [
                    {
                        "name": "Hate",
                        "severityThreshold": "Medium",
                        "blocking": true,
                        "enabled": true,
                        "source": "Prompt"
                    },
                    {
                        "name": "Hate",
                        "severityThreshold": "Medium",
                        "blocking": true,
                        "enabled": true,
                        "source": "Completion"
                    },
                    {
                        "name": "Sexual",
                        "severityThreshold": "Medium",
                        "blocking": true,
                        "enabled": true,
                        "source": "Prompt"
                    },
                    {
                        "name": "Sexual",
                        "severityThreshold": "Medium",
                        "blocking": true,
                        "enabled": true,
                        "source": "Completion"
                    },
                    {
                        "name": "Violence",
                        "severityThreshold": "Medium",
                        "blocking": true,
                        "enabled": true,
                        "source": "Prompt"
                    },
                    {
                        "name": "Violence",
                        "severityThreshold": "Medium",
                        "blocking": true,
                        "enabled": true,
                        "source": "Completion"
                    },
                    {
                        "name": "Selfharm",
                        "severityThreshold": "Medium",
                        "blocking": true,
                        "enabled": true,
                        "source": "Prompt"
                    },
                    {
                        "name": "Selfharm",
                        "severityThreshold": "Medium",
                        "blocking": true,
                        "enabled": true,
                        "source": "Completion"
                    },
                    {
                        "name": "Jailbreak",
                        "blocking": true,
                        "enabled": true,
                        "source": "Prompt"
                    },
                    {
                        "name": "Protected Material Text",
                        "blocking": true,
                        "enabled": true,
                        "source": "Completion"
                    },
                    {
                        "name": "Protected Material Code",
                        "blocking": false,
                        "enabled": true,
                        "source": "Completion"
                    }
                ]
            }
        }

こうしてみると
・「著作権保護(Protected Material Text)」は不要だけど、「Violence」のフィルタは有効にしたい、といったカテゴリごとのオンオフ
・フィルタは有効だけどBlockはしなくていい(annotateだけで良い)
・フィルタは「ミディアム」以上の強度にしたい
といった、システムごとの守りたいラインを設定することができますね

動作確認

最後に、このポリシーを設定した状態で、ガバガバコンテンツフィルタを作成しようとしてみます。

早速ですが、作成直前のパラメータ確認画面です。
このように「入力」の「violence」を無効にしてみました。

「フィルターの作成」ボタンを押下すると…

はい、無事期待通りの動作です。 Azure Policyによりブロックされた旨が表示され、コンテンツフィルターの作成に失敗しました。

おわりに

以上、「Azure Policyを使って、コンテンツフィルタをオフにさせないよう制御する」ことを実装してみました。責任あるAIという概念の実践のためにも、安全に使う方法は考えていかないといけませんが、開発のブレーキにならないやり方にしないといけないですね。

Discussion