LESSON 30分

ストーリー

田中VPoE
Guardrailsの全体像を把握したところで、まずは「入力フィルタリング」を詳しく学ぼう。玄関のセキュリティチェックのようなものだ
あなた
AIに渡す前に、不正な入力をブロックするということですね
田中VPoE
その通り。形式バリデーション、インジェクション検出、PII検出、有害コンテンツ検知、トピック分類の5段階でチェックする。順番に見ていこう

入力フィルタリングパイプライン

ユーザー入力


┌──────────────────────────────────┐
│  1. 形式バリデーション             │ → 文字数超過、制御文字
│  2. プロンプトインジェクション検出   │ → 攻撃パターン
│  3. PII検出・マスキング           │ → 個人情報
│  4. 有害コンテンツ検知             │ → 暴力、差別
│  5. トピック分類                  │ → 業務範囲外
└──────────────────────────────────┘


  LLM処理

1. 形式バリデーション

最初の防御線として、基本的な入力制約を適用します。

from dataclasses import dataclass

@dataclass
class InputValidationConfig:
    max_length: int = 2000
    min_length: int = 1
    block_special_chars: bool = True

def validate_format(text: str, config: InputValidationConfig) -> dict:
    """入力の形式バリデーション"""
    errors = []

    if len(text) < config.min_length:
        errors.append("入力が空です")

    if len(text) > config.max_length:
        errors.append(f"入力が{config.max_length}文字を超えています")

    if config.block_special_chars:
        import re
        if re.search(r"[\x00-\x08\x0b\x0c\x0e-\x1f]", text):
            errors.append("不正な制御文字が含まれています")

    return {"valid": len(errors) == 0, "errors": errors}

2. プロンプトインジェクション検出

パターンベース検出

class PromptInjectionDetector:
    """正規表現パターンによるインジェクション検出"""

    PATTERNS = {
        "instruction_override": [
            r"ignore\s+(previous|all|above)\s+(instructions|rules|prompts)",
            r"(以前|)(指示|命令|ルール)(無視|忘れ|破棄)",
        ],
        "role_manipulation": [
            r"you\s+are\s+now\s+",
            r"(DAN|jailbreak|unrestricted)\s+mode",
            r"制限(のない|なし|を解除)",
        ],
        "system_extraction": [
            r"(show|reveal|print)\s+(system\s*)?prompt",
            r"システムプロンプト.*(表示|教えて|出力)",
            r"\[(SYSTEM|INST)\]",
        ],
    }

    def detect(self, text: str) -> dict:
        import re
        detections = []
        for category, patterns in self.PATTERNS.items():
            for pattern in patterns:
                if re.search(pattern, text, re.IGNORECASE):
                    detections.append({"category": category, "pattern": pattern})
        return {
            "is_injection": len(detections) > 0,
            "detections": detections,
            "risk_level": "HIGH" if detections else "LOW",
        }

ML分類器ベース検出

class MLInjectionDetector:
    """機械学習モデルによるインジェクション検出"""

    def __init__(self):
        self.classifier = load_model("injection_classifier_v2")

    def detect(self, text: str) -> dict:
        score = self.classifier.predict_proba(text)
        return {
            "is_injection": score > 0.7,
            "confidence": score,
            "risk_level": "CRITICAL" if score > 0.9 else "HIGH" if score > 0.7 else "LOW",
        }
手法メリットデメリット
パターンベース高速、説明可能、誤検知少未知パターンに対応不可
ML分類器未知パターンにも対応可能誤検知リスク、ブラックボックス
ハイブリッド両方の利点を活用実装コスト高

3. PII検出・マスキング

class PIIDetectionPipeline:
    """個人識別情報を検出・マスキングする"""

    REGEX_PATTERNS = {
        "email": r"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}",
        "phone_jp": r"0\d{1,4}[\s-]?\d{1,4}[\s-]?\d{3,4}",
        "credit_card": r"\b\d{4}[\s-]?\d{4}[\s-]?\d{4}[\s-]?\d{4}\b",
        "my_number": r"\b\d{4}\s?\d{4}\s?\d{4}\b",
    }

    # PIIタイプ別の処理方針
    ACTIONS = {
        "email": "mask",        # マスキングして通す
        "phone_jp": "mask",     # マスキングして通す
        "credit_card": "block", # ブロック(入力拒否)
        "my_number": "block",   # ブロック(入力拒否)
    }

    def process(self, text: str) -> dict:
        import re
        findings = []
        should_block = False

        for pii_type, pattern in self.REGEX_PATTERNS.items():
            for match in re.finditer(pattern, text):
                findings.append({"type": pii_type, "value": match.group()})
                if self.ACTIONS[pii_type] == "block":
                    should_block = True

        if should_block:
            return {"allowed": False, "reason": "機密性の高い個人情報が含まれています"}

        masked = text
        for pii_type, pattern in self.REGEX_PATTERNS.items():
            if self.ACTIONS[pii_type] == "mask":
                masked = re.sub(pattern, f"[{pii_type.upper()}]", masked)

        return {"allowed": True, "processed_text": masked, "findings": findings}

4. 有害コンテンツ検知

class HarmfulContentDetector:
    """有害なコンテンツを検出する"""

    CATEGORIES = {
        "violence": "暴力、脅迫に関する内容",
        "hate_speech": "差別、ヘイトスピーチ",
        "illegal": "違法行為の教唆",
        "self_harm": "自傷行為に関する内容",
        "sexual": "性的に不適切な内容",
    }

    def detect(self, text: str) -> dict:
        # コンテンツモデレーションAPIを使用
        result = content_moderation_api.classify(text)
        flagged = [
            {"category": cat, "score": score}
            for cat, score in result.items()
            if score > 0.7
        ]
        return {
            "is_harmful": len(flagged) > 0,
            "flagged_categories": flagged,
            "action": "block" if flagged else "allow",
        }

5. 統合パイプライン

class InputFilteringPipeline:
    """全フィルタを統合したパイプライン"""

    def __init__(self):
        self.config = InputValidationConfig()
        self.injection_detector = PromptInjectionDetector()
        self.pii_pipeline = PIIDetectionPipeline()
        self.harm_detector = HarmfulContentDetector()

    def process(self, user_input: str) -> dict:
        # Step 1: 形式バリデーション
        validation = validate_format(user_input, self.config)
        if not validation["valid"]:
            return {"allowed": False, "stage": "validation", "reason": validation["errors"]}

        # Step 2: インジェクション検出
        injection = self.injection_detector.detect(user_input)
        if injection["is_injection"]:
            return {"allowed": False, "stage": "injection", "reason": "不正な入力パターン"}

        # Step 3: PII検出・マスキング
        pii_result = self.pii_pipeline.process(user_input)
        if not pii_result["allowed"]:
            return {"allowed": False, "stage": "pii", "reason": pii_result["reason"]}

        processed_text = pii_result.get("processed_text", user_input)

        # Step 4: 有害コンテンツ検知
        harm = self.harm_detector.detect(processed_text)
        if harm["is_harmful"]:
            return {"allowed": False, "stage": "harmful", "reason": "不適切なコンテンツ"}

        return {"allowed": True, "processed_text": processed_text}

まとめ

フィルタ目的主な技術
形式バリデーション不正な形式の入力を排除文字数・文字種チェック
インジェクション検出AIへの不正指示を検出パターンマッチ、ML分類器
PII検出個人情報の混入を防止正規表現、NERモデル
有害コンテンツ検知暴力・差別等を排除コンテンツ分類API

チェックリスト

  • 入力フィルタリングの5段階パイプラインを説明できる
  • パターンベースとML分類器のインジェクション検出を比較できる
  • PII検出のタイプ別処理方針(マスク/ブロック)を理解した
  • 統合パイプラインの実装パターンを把握した

次のステップへ

次は出力フィルタリングの実装手法を学びます。


推定所要時間: 30分