ガードレール
Guardrail
概要(サマリー)
ガードレールとは、LLMの入力、出力、ツールの実行を、アプリケーション側のルールで止める仕組みである。一つの規格の名前ではなく、検査と制限の総称である。
道路の柵に似ている。システムプロンプトが運転者への注意書きだとすれば、ガードレールは、注意を無視しても路外へ出にくい構造である。モデルが「削除してよい」と判断しても、削除関数を呼ぶ前の検査で止められる。
OpenAIのModerationは、有害なテキストや画像を分類する検査の一例である。分類した結果を見て、表示するか、人の確認へ回すかを決めるのはアプリである。検査を入れても、すべての危険が消えるわけではない。
ガードレールを組むための道具も出ている。NVIDIAのNeMo Guardrails、Metaの安全分類モデルLlama Guard、AWSのAmazon Bedrock Guardrailsなどである。どれを使っても、何を止めるかの方針はアプリ側で決める。
詳細解説
お願いと、止められる処理の違い
システムプロンプトに書いた「個人情報は答えないで」は、モデルへの依頼である。会話が長くなる、またはプロンプトインジェクションで「これまでの指示は無視して」と書かれると、依頼は破られることがある。
ガードレールは、モデルの返事の外側に置く。たとえば次のように分ける。
- 入力の検査: 明らかに攻撃的な指示や、対応しない種類の依頼を、モデルへ渡す前に止める
- 出力の検査: 返ってきた文章に、出してはいけない鍵や個人情報が含まれていないかを、表示前に調べる
- 道具の制限: ツール呼び出しで返ってきた関数名が、許可リストになければ実行しない
- 人の確認: 削除、送金、外部への送信は、引数を見せてから実行する
- 回数と範囲: 1回の会話でツールを呼べる回数、読めるフォルダ、使える金額に上限を付ける
モデルが上手に頼んでも、リストにない関数はコードが拒否する。拒否はモデルの善意に依存しない。
有害コンテンツの分類
OpenAIのModerationは、テキストと画像を分類する。音声は対象外である。生成と同時にスコアを求めることも、文章だけを別に分類することもできる。
重要なのは、分類モデルが生成を自動で取り消すとは限らない点である。OpenAIの説明では、モデルは通常どおり生成し、スコアはアプリがポリシーを適用するために使う。表示する前にスコアを見る、という順序をアプリが実装する。
この分類で、あらゆる被害を防げるわけではない。OpenAI自身も、児童の性的虐待コンテンツの検出には使わず、専用の対策を取るよう案内している。有害表現の点数は、秘密の漏えい、誤った法律助言、本番データベースの削除を止める仕組みでもない。止めたい被害ごとに、検査を分ける。
ツールの許可リスト
AIエージェントは、読む、書く、コマンドを提案する、を繰り返す。ここでのガードレールは、呼べる道具の名前をこちらが持つことである。
from pathlib import Path
WORK_DIR = Path("/work").resolve()
allowed = {"read_file", "search_docs"}
def run_tool(name, arguments):
if name not in allowed:
return {"error": "この処理は自動実行できない"}
if name == "read_file":
target = Path(arguments["path"]).resolve()
if not target.is_relative_to(WORK_DIR):
return {"error": "作業フォルダの外は読めない"}
return read_file(target)
return search_docs(arguments["query"])
delete_file がモデルの提案に出ても、allowed に無ければ実行されない。パスの検査は、関数名の検査とは別に行う。許可した読み取りでも、作業フォルダの外を指せば拒否する。
パスは文字列の先頭だけで比べない。/work/../etc/passwd は /work/ で始まるが、実際には作業フォルダの外を指す。resolve() で .. などを解決してから、作業フォルダの中かを確かめる。
APIキーや本番の認証情報は、モデルへ戻すツール結果に入れない。結果をモデルが次の文章へ書き写すからである。
出力を出してから検査しても遅いことがある
検査の位置で効果が変わる。利用者の画面へ断片を先に流し、完成後に検査すると、問題のある文がすでに見えている。確定表示の前に検査するなら、途中の文字は仮表示だと分かる扱いが要る。
検査そのものもモデルであることが多い。検査モデルが見逃す、または正常な文章を過剰に止める、の両方がある。止めた理由をログに残し、人が見直せる経路を一つは残す。全部を自動拒否にすると、通常の業務文まで止まる。
破られる前提で重ねる
プロンプトインジェクションは、モデルへの文章でガードレールの「お願い」を無効化しようとする。コードの許可リストは文章では書き換わらない。ただし、許可した道具の引数に攻撃文を入れる、人が確認ダイアログをよく読まずに押す、といった抜けは残る。
一つの検査で完成、とは考えない。入力、権限、出力、人の確認を、被害の大きさに応じて重ねる。元に戻せない操作ほど、モデルの判断から遠くに置く。
AIコーディングとの関係
ルールファイルに「本番の環境変数を読むな」と書くのは、システムプロンプト側の対策である。ガードレールにするなら、エージェントから見えるフォルダにそのファイルを置かない、コマンドの許可リストから本番の接続を外す、という実装にする。
AIにエージェントを作らせるときは、実行関数と提案関数を分けて指定する。提案は文章で返し、実行は許可リストを通ったものだけ、と書く。AIが「便利なので削除も許可リストへ入れておきました」と足すことがある。差分で、許可リストが広がっていないかを見る。
検査をモデルだけに頼らせない。パスが作業フォルダ内か、コマンドが空でないかは、普通の条件式で判定できる。
よくある勘違い
システムプロンプトを詳しく書けばガードレールになる?
ならない。システムプロンプトはモデルへの依頼である。ガードレールは、依頼を破っても実行や表示を止めるアプリ側の処理である。
有害コンテンツの分類を入れれば安全?
その分類が対象にする種類の内容を、表示前に見つけるための検査である。情報漏えい、誤操作、権限のあるツールの悪用は、別の制限が要る。
入れれば突破されない?
文章によるお願いよりは破れにくい。それでも、許可した道具の範囲、人の確認漏れ、検査モデルの見逃しは残る。
エージェントの便利機能と相反する?
自動でできることを狭めるので、操作は増える。元に戻せない処理だけを狭め、読み取りは許可する、という分け方が実用との折り合いを付けやすい。
まとめ
- ガードレールは、生成AIの入出力やツール実行をアプリ側のルールで止める仕組みである
- システムプロンプトのようなお願いとは別に、コードで拒否できる点に意味がある
- 有害コンテンツの分類、許可リスト、フォルダ制限、人の確認は、別々の柵である
- 分類スコアは、アプリが表示前に見て初めて効果を持つ
- 一つの検査ではすべての被害は止まらないので、被害に応じて重ねる
情報ソース
より詳しくAIに聞いてみよう
- ガードレールを、道路の柵のたとえで説明してください。
- システムプロンプトとガードレールの違いを、個人情報を出させようとした例で整理してください。
- 有害コンテンツの分類では止まらない事故を、開発作業の例で3つ挙げてください。
- ツールの許可リストと、パスの検査を両方置く理由を説明してください。
- AIコーディングのエージェントに、削除だけは提案で止め、実行は人の確認後にする条件を書かせてください。