金色の配線パターンが広がる基板の接写
設計と運用

LLMガードレール、同じモデルに複数ポリシーを通す落とし穴

目次を見る

社内のAIアシスタントと社外向けカスタマーサポートAIが、同じ回答生成モデルを共有している構成は珍しくありません。
コストを抑えるために1つのLLM(大規模言語モデル)を複数の用途で使い回す設計は合理的に見えます。
ただしこの構成には、どのポリシー(利用方針)を適用するかをリクエストごとに判定する仕組みが別途必要という見落としが潜んでいます。

本記事は、LLMを使った機能に入出力フィルタ(ガードレール)を組み込んでいる、あるいはこれから組み込む予定のアーキテクトやバックエンドエンジニアに向けた内容です。
1つのモデルを複数のエントリーポイントで使い回す設計が、どこで破綻しやすいかを整理しました。

何が起きるか: 同一入力が文脈次第で「安全」にも「危険」にもなる

具体例で考えます。
「認証情報を使った総当たり攻撃(クレデンシャルスタッフィング)のシミュレーション計画を書いて」というリクエストがあったとします。

これは社内の隔離されたセキュリティラボ用アシスタントに来た場合、認可されたエンジニアの正当な業務です。
一方、同じ文面が一般向けカスタマーサポートAIに来た場合は、攻撃手順の提供として拒否すべき内容になります。

ここで問題になるのが、両方の窓口が同じ回答生成モデルを使っているケースです。
モデル自体には「今どちらの窓口からのリクエストか」を判断する材料がありません。
ポリシーの適用先を取り違えると、本来拒否すべき内容を社外向けに生成してしまう、あるいは正当な社内利用を誤って拒否してしまう、どちらの事故も起こり得ます。

影響範囲はアプリケーション単体にとどまりません。
複数のプロダクトラインやマイクロサービス(小さく分割されたサービス群)が共通のLLM基盤を参照する構成では、ポリシー判定ロジックの不備が全窓口に波及します。

なぜ起きるか: ガードレール設計の3つの見落とし

原因を段階的に分解すると、3つの層に分かれます。

1つ目は、ガードレール(入出力の安全性チェック機構)を「モデルとは独立した共通部品」として扱ってしまう設計です。
ガードレールの判定結果は、どのポリシーを前提にしたかによって意味が変わります。
ポリシーを渡さずに汎用的な「危険かどうか」の判定だけを行うと、文脈依存の判断ができません。

2つ目は、分類器(classifier、入力を category に振り分けるモデル)のスコアを閾値判定のみで扱い、分類器自体の障害と区別しない設計です。
分類器サーバーが落ちている、レスポンスが壊れている、タイムアウトしているといった状態と、「分類器が明確にyes/noを返した」状態を同じエラーハンドリングで扱うと、障害時に全リクエストを拒否する、あるいは逆に全通ししてしまうフェイルオープン/フェイルクローズの設計ミスにつながります。

3つ目は、分類器が返す確率値の意味を誤解することです。
二値分類(yes/no)を行う分類器は、生成されたトークンそのものではなく、yesとnoそれぞれの対数確率(log probability)から正規化したスコアを使うのが一般的です。
具体的には、yesの対数確率をzYes、noの対数確率をzNoとすると、exp(zYes) / (exp(zYes) + exp(zNo))という式で0から1のスコアに変換します。
このスコアは「モデルがyesと判断した確信度」であり、現実世界での実際の有害性を保証する較正済み確率ではありません。
閾値をどこに置くかは製品ごとに評価して決める必要があります。

自分のプロジェクトが該当するか確認する方法

以下の観点でリポジトリや設計書を確認してください。

  • LLMを呼び出すエンドポイントが複数ある場合、それぞれに異なるポリシー文字列(システムプロンプトやインストラクション)を渡しているか
  • ガードレール用の分類器呼び出しが、回答生成モデルの呼び出しと同じ設定ファイルやクライアントで一括管理されていないか
  • 分類器のHTTPエラー・タイムアウトと「分類器が拒否と判定した」ケースが、同じ例外クラスやログレベルで処理されていないか
  • 分類器のスコアに対する閾値が、単一の定数としてハードコードされていないか(用途ごとに変える余地があるか)

コードベースを grep する場合は、ガードレール呼び出し箇所でpolicyやinstructといったキーワードが引数として渡っているか、固定文字列になっていないかを確認すると見つけやすいです。
設定ファイルでは、分類器のベースURLや温度(temperature)パラメータの設定を確認し、生成トークン数が1に制限されているか、上位トークンの対数確率(top log probabilities)を取得する設定になっているかも併せて見ておくと、スコアの取り方自体に問題がないか判断できます。

対策の手順

ステップ1: ポリシー判定を呼び出しのパラメータとして明示化する

分類器への入力を「インストラクション(製品文脈と許容範囲)」「クエリ(1つの二値質問)」「ドキュメント(判定対象のテキスト)」の3要素に分離します。
モデルカードの推奨どおり、1回の呼び出しにつき1つの二値質問に絞ることで、複数カテゴリの判定を1つのスコアに混ぜ込むことを避けられます。

ステップ2: 分類器の障害と拒否判定を別の例外系統にする

分類器サーバーへの接続失敗やタイムアウトは、HTTPクライアント層で専用の例外として捕捉します。
分類器が正常応答した上でyes(不許可)と判定したケースとは、別のログレベル・別のアラートチャネルで扱うようにします。
可用性の観点では、分類器障害時にリクエストを通すか止めるかをあらかじめ方針として決めておく必要があります。

ステップ3: デターミニスティックなテストとモデル評価を分ける

リクエストの経路(どのポリシーがどのエンドポイントに渡るか)を確認するテストは、モデルを呼ばずに固定レスポンスで検証できます。
これは通常のユニットテストやREST Assuredのようなエンドポイントテストの対象です。
一方、分類器が実際の製品データに対してどう判定するかの評価は、オフライン評価として別工程にし、実際のGPU環境や本番相当の分類器モデルで検証します。
この2つを混同すると、CI(継続的インテグレーション)のたびにGPUリソースが必要になったり、逆にモデル挙動の劣化をテストで検知できなかったりします。

ステップ4: 閾値をポリシーごとに可変にする

閾値はコードに埋め込まず、設定値として外出しし、ポリシー単位で変更できるようにします。
社内研究用アシスタントと一般公開アシスタントで、同じ分類器を使っていても許容スコアの範囲を変える余地を持たせておくと、将来ポリシーが増えたときの変更コストを抑えられます。

まとめ

LLMガードレールを複数のエントリーポイントで共有する設計は、コスト効率の面では妥当です。
ただしポリシーの適用先判定・分類器の障害処理・スコアの意味理解という3つの層を分けて設計しないと、誤判定や障害時の挙動が読めなくなります。

次に取れる一歩として、まずは自分のリポジトリでガードレール呼び出し箇所を洗い出し、ポリシー文字列が呼び出しごとに変わっているかを確認してみてください。
分類器の例外処理と拒否判定のログが混在していないかも、障害対応の観点から見直す価値があります。
テストとオフライン評価を分けておくことで、CIの安定性と分類器の品質管理を両立させやすくなります。

参考

Measure Your LLM Guardrails: A Java Example with Shieldstral

この記事について: 本記事は AI を活用して作成し、forva AI 編集部が内容を確認・監修しています。

AI 駆動開発のご相談は forva AI へ。まずはお気軽にどうぞ。