Databricks Certified Generative AI Engineer Associate 教科書
第3章 アプリケーション開発(Application Development, 30%)
🎯 この節の学習目標
ガードレール(guardrails)とは、LLMアプリケーションの入力と出力を検査・制御する仕組みの総称です。LLMは確率的にテキストを生成するため、悪意ある入力(プロンプトインジェクション)、トピック外の質問、有害な出力、個人情報(PII)の漏えい、根拠のない回答(ハルシネーション)といったリスクを完全にはゼロにできません。そこで、モデルの前後に「検問所」を設けて、望ましくない入出力を検出・遮断・修正します。
重要な設計原則は多層防御(defense in depth)です。単一の対策に依存せず、複数の層を重ねることで、1つの層が突破されても全体としての安全性を保ちます。
| 層 | 実装場所 | 例 |
|---|---|---|
| 第1層:プロンプト | システムプロンプト内の指示 | 「あなたは社内規程に関する質問にのみ答えます」 |
| 第2層:アプリケーション | チェーンの前後のチェックステージ | 入力分類器、出力の形式検証、PIIマスキング |
| 第3層:プラットフォーム | Model Serving エンドポイント(Unity AI Gateway) | セーフティフィルタ、無効なキーワード、PII検出 |
📝 試験のポイント
「システムプロンプトに『不適切な質問には答えないでください』と書いた。これで十分か?」という趣旨の問題が出たら、答えはノーです。プロンプトによる制約は第一層にすぎず、巧妙な入力で回避されうる(いわゆる jailbreak / prompt injection)ため、独立した検査ステージやエンドポイントレベルのガードレールを併用するのが正解の方向性です。
入力側のガードレールは、ユーザーの入力がLLM本体に届く前に検査を行います。代表的な手法は次の3つです。
アプリの目的から外れた質問(off-topic)や、システムプロンプトの上書きを狙う入力(prompt injection)を、分類器または軽量なLLMによる事前チェックで検出します。
💡 具体例:LLMによる入力チェックステージ
社内IT規程QAボットで、メインのチェーンの前に次のような判定を挟みます。
guard_prompt = """あなたは入力検査器です。次のユーザー入力が
「社内IT規程に関する質問」かどうかを判定し、
'ALLOW' または 'BLOCK' のみを出力してください。
入力: {user_input}"""
verdict = llm.invoke(guard_prompt.format(user_input=query))
if "BLOCK" in verdict.content:
return "この質問にはお答えできません。IT規程に関する質問をどうぞ。"
# ALLOW の場合のみメインのRAGチェーンへ進む
判定専用の呼び出しは短い出力(ラベルのみ)で済むため、小型・低コストのモデルで実装するのが定石です。
ユーザー入力に含まれる氏名・電話番号・メールアドレス・カード番号などのPII(個人識別情報)を、LLMに渡す前に検出してマスク(例:[EMAIL] に置換)します。これにより、PIIが外部モデルへ送信されたり、ログやトレースに平文で残ったりするリスクを下げられます。正規表現による単純な検出から、専用のPII検出モデル・ライブラリの利用まで、要件に応じて選択します。
極端に長い入力はコスト増・コンテキスト超過・攻撃(大量の指示の埋め込み)の温床になります。最大文字数・トークン数の制限、期待する形式(例:質問文であること、特定フィールドの存在)の検証を、LLMを呼ぶ前の軽量なコードで行います。これは最も安価なガードレールであり、必ず入れておくべき層です。
出力側のガードレールは、LLMが生成した応答をユーザーに返す前に検査します。
| 手法 | 内容 | 実装の例 |
|---|---|---|
| 有害性チェック | 暴力・差別・違法行為の助長など有害なコンテンツを検出 | セーフティモデル(Llama Guard 等)に出力を渡して安全/非安全を判定させる |
| 出典の強制 | RAGアプリで、回答に取得ドキュメントへの引用を必ず含めさせ、欠けていれば再生成または拒否 | プロンプトで引用形式を指定+出力に引用が含まれるかをコードで検証 |
| 形式検証 | JSONなど構造化出力のスキーマ適合を検証 | JSONスキーマによるバリデーション。失敗時はリトライまたはエラー処理 |
| 根拠なし回答の拒否 | 検索結果に根拠がない場合に推測で答えさせない | 「文脈に答えがない場合は『わかりません』と答える」指示+回答と文脈の照合チェック |
| PII漏えいチェック | 出力に含まれるPIIを検出・マスク | 入力側と同様の検出処理を出力にも適用 |
💡 具体例:JSONスキーマによる出力検証
import json
def validate_output(raw: str) -> dict:
try:
data = json.loads(raw)
except json.JSONDecodeError:
raise ValueError("出力がJSONではありません")
required = {"category", "answer", "sources"}
if not required.issubset(data.keys()):
raise ValueError(f"必須キーが不足: {required - data.keys()}")
if not data["sources"]:
raise ValueError("出典が空です(根拠なし回答は返さない)")
return data
検証に失敗したら、そのままユーザーに返すのではなく、リトライ(再生成)するか、安全なフォールバック応答を返すのがガードレールとしての正しい振る舞いです。
セーフティモデルは、有害性判定に特化して学習されたモデルです。代表例の Llama Guard は、入力(ユーザープロンプト)と出力(モデル応答)のどちらも判定でき、違反カテゴリの分類も返します。汎用LLMに「これは有害ですか?」と聞くよりも一貫した判定が期待できるため、有害性チェック層の部品としてよく使われます。
アプリケーションのコード内にチェックを実装する方法に加えて、Databricks では Unity AI Gateway のガードレール機能を使って、Model Serving エンドポイントのレベルで入出力を制御できます。エンドポイントの設定として有効化するため、そのエンドポイントを使うすべてのアプリケーションに一律に適用されるのが特徴です。
アプリケーション層のガードレール(この節の2〜3)とエンドポイント層のガードレール(Unity AI Gateway)は排他ではなく併用します。アプリ固有のロジック(トピック制限、出典の強制、スキーマ検証)はアプリ層で、組織共通の安全基準(有害性、PII)はゲートウェイ層で、という役割分担が実務的です。Unity AI Gateway の全体像(レート制限・使用状況トラッキングなどを含む)は 4-4 で扱います。
1-5 で学んだマルチステージのチェーン設計の応用として、ガードレールはチェーンの前後に独立したステージとして挿入します。
ガードレール付きRAGチェーンの構成例:
このように独立したステージにしておくと、各ガードを個別にテスト・改善・差し替えできるうえ、ブロックした件数やブロック理由をログとして記録し、運用改善(第5章のモニタリング)につなげられます。安価なチェック(長さ検証)を先頭に、コストの高いチェック(LLM判定)を後段に置くと、無駄なLLM呼び出しを減らせます。
✅ この節のまとめ
問1. 社内QAボットで、システムプロンプトに「業務に関係のない質問には答えないでください」と記載した。しかし一部のユーザーが巧妙な言い回しでこの制約を回避している。最も適切な対策はどれか。
正解:B
プロンプト内の制約はユーザー入力と同じコンテキストで処理されるため、巧妙な入力(prompt injection)で回避されえます。独立した入力ガード(分類器やLLMによる事前判定)を挟む多層防御が正解です。Aは同じ層を厚くしているだけで根本対策になりません。Cのtemperatureは出力のランダム性の制御であり、トピック外入力の遮断には無関係です。Dも回答の長さを制限するだけで、トピック外の回答自体は防げません。
問2. LLMアプリケーションの出力に有害なコンテンツが含まれていないかを判定する層を追加したい。この用途に最も適した部品はどれか。
正解:B
Llama Guard は入力・出力の有害性判定に特化して学習されたセーフティモデルで、安全/非安全の判定と違反カテゴリを返します。Aの埋め込みモデルはテキストのベクトル化、Cのリランカーは検索結果の並べ替え(3-5)が役割で、有害性判定はできません。DのJSONスキーマ検証は形式の検証であり、内容の有害性は判定できません。
問3. 組織内の複数のGenAIアプリケーションが同じ基盤モデルのエンドポイントを利用している。すべてのアプリに一律で、PII検出とセーフティフィルタを適用したい。Databricks 上で最も効率的な方法はどれか。
正解:C
Unity AI Gateway のガードレールはエンドポイントの設定として適用されるため、そのエンドポイントを使う全アプリに一律に効きます。Aは実装の重複と漏れのリスクがあり非効率です。Bはプロンプト制約のみで回避されうる第一層にすぎません。Dは補完的な施策としては有効ですが、技術的な制御にはなりません。
問4. RAGアプリケーションで「検索結果に根拠がない場合でも、LLMがもっともらしい回答を作ってしまう」問題への出力側ガードレールとして、最も適切な組み合わせはどれか。
正解:A
根拠なし回答(ハルシネーション)への対策は、プロンプトでの拒否指示(第一層)と、出典の存在をコードで検証して欠けていれば返さない(第二層)の組み合わせが定石です。Bは検索品質の改善策であり、根拠がないケースでの回答拒否は保証しません。Cはむしろランダム性を上げてハルシネーションのリスクを高めます。Dは会話の文脈維持の話であり、根拠の担保とは無関係です。