はじめに
従来のソフトウェア開発において、A という入力に対して B という出力が返ってくるのは「絶対の安心」でした。しかし、LLM(大規模言語モデル)の導入はこの前提を根底から覆しました。
同じプロンプトを投げても結果が変わる 「非決定性(Nondeterminism)」。これは単なる挙動のムラではなく、サイバーセキュリティにおける 「再現困難な脆弱性」 という新たな脅威を意味します。
1. 「決定論的システム」との決別
我々が慣れ親しんできたDartやGo、Pythonなどのコードは決定論的(Deterministic)です。
-
コード:
if (is_malicious(input)) return BLOCK; - 結果: 1億回実行しても、条件に合致すれば1億回ブロックされます。
対してLLMは確率的(Probabilistic)です。入力に対して「次に来る最もらしいトークン」を予測するプロセスには、本質的に統計的な揺らぎが含まれています。
2. なぜ temperature=0 は万能薬ではないのか
多くの開発者は、ランダム性を制御する temperature パラメータを 0 に設定すれば、挙動は固定されると考えがちです。しかし、実際には以下の要因で出力は揺らぎます。
-
GPUの並列演算(Floating Pointの罠): 数千のコアで並列処理を行う際、浮動小数点の加算順序がわずかに変わることがあります。数学的には
(a + b) + c == a + (b + c)ですが、コンピュータの計算では極小の誤差が生じ、それがソフトマックス関数を経てトークン選択を逆転させることがあります。 - モデルのシャーディング: 巨大なモデルを複数のGPUやノードに分散して推論させる際、ネットワークの遅延やタイミングが計算結果に微妙な影響を及ぼすことがあります。
教訓: LLMプロバイダーのAPIドキュメントには、多くの場合「完全な再現性は保証されない」と明記されています。
3. セキュリティ上の致命的なリスク:確率的バイパス
この非決定性は、攻撃者にとっての「希望」となります。
防御側(Defender)の視点
LLMを検知器として使い、「このプロンプトが攻撃的か判定せよ」というガードレールを置いたとします。99回は正しくブロックできても、計算の揺らぎで1回だけ「安全」と判定してしまうかもしれません。
攻撃側(Attacker)の視点
攻撃者は、プロンプトを少しも変える必要すらありません。**「当たるまで同じプロンプトを連打する(Brute-force Prompting)」**だけで、確率の壁を突き破り、防御をすり抜けることが可能です。
4. エンジニアが取るべき対策
「揺れる」システムをどう守るか。それは、非決定性を前提とした**「多層防御(Defense in Depth)」**の再定義です。
- ハイブリッド・フィルタリング: LLMに判定を丸投げせず、前段に正規表現やキーワードベースの決定論的なバリデータを置く。
- セマンティック・ファイアウォール: ベクトルデータベースを活用し、過去に「悪意がある」と判定されたプロンプトとの数学的距離を計算する。これはLLMの生成プロセスを通らないため、より安定した検知が可能です。
- アンサンブル判定: 重要な判定には複数のモデル(あるいは同じモデルへの複数回試行)を用い、多数決をとることで「揺らぎ」によるエラーを統計的に排除する。
まとめ:Secure by Designの新基準
これからのAIインテグレーションにおいて、エンジニアには「確率論的な思考」が求められます。
「一度テストして通ったから安全」という考えは捨てなければなりません。ペネトレーションテストの考え方を開発プロセスの初期段階から取り入れ、 「モデルが気まぐれを起こした時に、バックエンドのロジックで食い止められるか」 を設計の核に据える必要があります。