ブログ

LLM時代のシステム設計:信頼できない入力から身を守るためのアーキテクチャ再考

GitHub という記事を読み、AIを組み込んだ現代のシステムにおいて、プロンプトインジェクションなどの新たな脅威にどう向き合うべきか、その設計思想について改めて整理してみました。

プロンプトインジェクションに注意です。


昨今、大規模言語モデル(LLM)をアプリケーションに組み込むケースが増えていますが、それに伴い「ユーザーからの入力をどこまで信頼してよいか」という古典的かつ本質的な課題が、より複雑な形で再浮上しています。今回は、セキュリティとシステム設計の観点から、堅牢なアーキテクチャを構築するためのポイントをいくつか挙げてみます。

信頼できない入力を「隔離」する設計思想

システム設計の基本原則として、外部からの入力はすべて「信頼できないもの」として扱う必要があります。これはSQLインジェクションやクロスサイトスクリプティング(XSS)への対策と同じですが、LLMを介す場合は、入力が「命令(インストラクション)」として解釈されてしまう点が厄介です。

これを防ぐためには、単なる文字列のサニタイズだけでなく、実行環境そのものを隔離する(アイソレーション)という考え方が重要になります。

処理のフローイメージ

ユーザーの入力がどのように処理され、安全性が確保されるべきか、一つのモデルを以下の図に示します。

flowchart TD
  User["ユーザー / 外部クライアント"] --> Gateway["APIゲートウェイ<br>(認証・認可)"]
  Gateway --> Validator["バリデーション層<br>(不正なパターン検知)"]
  Validator --> Guardrails["セキュリティ・ガードレール<br>(Prompt Injection対策)"]
  Guardrails --> ExecutionEnv["隔離された実行環境<br>(Sandbox / Worker)"]
  ExecutionEnv --> LLM["LLM API / バックエンド"]
  LLM --> OutputSanitizer["出力サニタイズ層"]
  OutputSanitizer --> User

このように、複数の層(Defense in Depth)を設けることで、仮に一つの層が突破されても、システム全体への影響を最小限に抑えることが期待できます。

実行環境の選択とコストのバランス

セキュリティを高めるために環境を細かく分離しようとすると、今度は「計算リソースのコスト」と「レイテンシ」が問題になります。

たとえば、リクエストごとに完全に独立したコンテナを立ち上げるのは安全ですが、コストや起動時間がかさみます。ここで、最近注目されているのが「Cloudflare Workers」に代表されるエッジコンピューティングや、軽量なサーバーレス環境の活用です。

AWS Lambdaのような従来のサーバーレス構成と、より軽量なV8アイソレートを利用した環境を比較してみると、以下のような違いがあるかと思います。

項目 従来のサーバーレス (Lambda等) 軽量アイソレート (Cloudflare等)
起動速度 (Cold Start) 数百ミリ秒〜 数ミリ秒以下
隔離レベル プロセス / コンテナ単位 V8 アイソレート単位
コスト構造 リクエスト数 + 実行時間 比較的安価な定額 + リクエスト
主な用途 重い計算処理、長時間実行 高速なプロキシ、検証、フィルタリング

セキュリティフィルターやバリデーションのような「リクエストのたびに必ず通る軽い処理」については、より軽量な環境で行うことで、コストを抑えつつ安全性を担保できるかもしれません。

エンジニアに求められる「システム設計」の視点

プログラミングの手法自体はAIによる自動化が進んでいますが、こうした「どの技術を組み合わせ、どこに境界線を引くか」というアーキテクチャの設計能力は、今後ますます重要になるかと思います。

OWASPなどが提唱しているガイドラインを参考にしつつ、以下の3つのポイントを意識してみるのが良さそうです。

  1. 最小権限の原則: LLMに与えるAPIキーやデータベースへのアクセス権限を必要最小限に絞る。
  2. 入力の構造化: 自由記述のテキストをそのまま流すのではなく、可能な限り構造化されたデータとして扱う。
  3. 観測可能性 (Observability): どのような入力が送られ、モデルがどう反応したかを常にモニタリングし、異常を検知できる状態にする。

「プログラミングが死んだ」といった極端な議論もありますが、実際には計算機科学の基礎やシステム設計の素養があるエンジニアの価値は、むしろ高まっているように感じます。ハードウェアの特性を理解し、ソフトウェアの抽象化を適切に行う能力は、どんなにツールが進化しても腐ることのないスキルと言えるでしょう。

まとめ

特定の脆弱性への対策も大切ですが、より重要なのは「変化し続ける脅威に対して、柔軟かつ堅牢に対応できる構造」を設計することだと考えています。

まずは、自分の管理しているシステムで「信頼できない入力」がどこを通っているのか、改めて見直してみるのもいいかもしれません。こちらで紹介した設計思想が、皆さんの開発のヒントになれば幸いです。

参照記事