mcpField
G
guardrails-safety-filter-builder

guardrails-safety-filter-builder

github.com/patricio0312revセキュリティ63286 回インストール41 週間前に更新
リポジトリ

guardrails-safety-filter-builder について

LLM アプリケーションの安全対策を構築する開発者向けのスキルです。PII の検出とマスキング、プロンプトインジェクション検出、トピック制約、出力検証を組み合わせます。

主な機能

  1. 01入力フィルタリングと注入検出
  2. 02PII 検出とマスキング
  3. 03トピックポリシーと拒否テンプレート
  4. 04出力検証とログ記録の指針

活用シーン

  1. 01悪意あるプロンプトの遮断
  2. 02出力内の個人情報のマスキング
  3. 03アプリの話題範囲の制限

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/patricio0312rev/skills --skill guardrails-safety-filter-builder

インストール後、Claude Code で/guardrails-safety-filter-builderを入力して読み込まれたか確認します。

詳細

ガードレールと安全性フィルタービルダー

LLM アプリケーション向けの包括的な安全システムを構築します。

安全性レイヤー

  1. 入力フィルタリング:悪意のあるプロンプトをブロックします
  2. 出力フィルタリング:機密データをマスキングします
  3. トピック制約:ポリシーに基づいて拒否します
  4. PII 検出:個人情報をマスキングします
  5. プロンプトインジェクション:操作の試みを検出します

PII の検出とマスキング

import re
from presidio_analyzer import AnalyzerEngine
from presidio_anonymizer import AnonymizerEngine

analyzer = AnalyzerEngine()
anonymizer = AnonymizerEngine()

def redact_pii(text: str) -> str:
    # Detect PII
    results = analyzer.analyze(
        text=text,
        language='en',
        entities=["EMAIL_ADDRESS", "PHONE_NUMBER", "CREDIT_CARD", "SSN"]
    )

    # Anonymize
    anonymized = anonymizer.anonymize(text, results)
    return anonymized.text

# Example: "My email is [email protected]" → "My email is <EMAIL_ADDRESS>"

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

def detect_prompt_injection(user_input: str) -> bool:
    """Detect common prompt injection patterns"""
    patterns = [
        r'ignore (previous|above) instructions',
        r'disregard (all|any) (prior|previous)',
        r'you are now',
        r'new instructions',
        r'system:',
        r'override',
    ]

    for pattern in patterns:
        if re.search(pattern, user_input, re.IGNORECASE):
            return True

    return False

# Block if detected
if detect_prompt_injection(user_input):
    return "I cannot process that request."

トピック制約

# Define allowed/disallowed topics
POLICY = {
    "allowed_topics": [
        "product_features",
        "troubleshooting",
        "billing",
        "account_management"
    ],
    "disallowed_topics": [
        "medical_advice",
        "legal_advice",
        "financial_advice",
        "politics",
        "violence"
    ],
    "requires_disclaimer": [
        "security_practices",
        "data_privacy"
    ]
}

# Classify topic
def classify_topic(query: str) -> str:
    classification_prompt = f"""
    Classify this query into one of these topics:
    {', '.join(POLICY['allowed_topics'] + POLICY['disallowed_topics'])}

    Query: {query}

    Return only the topic name.
    """
    return llm(classification_prompt)

# Check policy
def check_policy(query: str) -> dict:
    topic = classify_topic(query)

    if topic in POLICY["disallowed_topics"]:
        return {
            "allowed": False,
            "reason": f"Cannot provide {topic}",
            "refusal": REFUSAL_TEMPLATES[topic]
        }

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

拒否テンプレート

REFUSAL_TEMPLATES = {
    "medical_advice": """
        I cannot provide medical advice. Please consult with a healthcare
        professional for medical concerns.
    """,
    "legal_advice": """
        I cannot provide legal advice. For legal matters, please consult
        with a qualified attorney.
    """,
    "out_of_scope": """
        I'm designed to help with product documentation and support.
        This question is outside my area of expertise.
    """,
}

def refuse_safely(reason: str) -> str:
    return REFUSAL_TEMPLATES.get(reason, REFUSAL_TEMPLATES["out_of_scope"])

出力検証

def validate_output(output: str) -> dict:
    """Check output before returning to user"""
    issues = []

    # Check for PII
    pii_results = analyzer.analyze(output, language='en')
    if pii_results:
        issues.append("Contains PII")
        output = redact_pii(output)

    # Check for banned phrases
    banned_phrases = ["password", "api key", "secret"]
    for phrase in banned_phrases:
        if phrase.lower() in output.lower():
            issues.append(f"Contains banned phrase: {phrase}")

    # Check toxicity
    toxicity_score = toxicity_classifier(output)
    if toxicity_score > 0.7:
        issues.append("High toxicity detected")

    return {
        "safe": len(issues) == 0,
        "issues": issues,
        "sanitized_output": output
    }

ガードレールの完全なパイプライン

def apply_guardrails(user_input: str) -> dict:
    # 1. Input validation
    if detect_prompt_injection(user_input):
        return {
            "allowed": False,
            "response": "Invalid request detected."
        }

    # 2. Policy check
    policy_check = check_policy(user_input)
    if not policy_check["allowed"]:
        return {
            "allowed": False,
            "response": policy_check["refusal"]
        }

    # 3. Generate response
    response = llm(user_input)

    # 4. Output validation
    validation = validate_output(response)
    if not validation["safe"]:
        return {
            "allowed": True,
            "response": validation["sanitized_output"],
            "warnings": validation["issues"]
        }

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

ベストプラクティス

  • 複数の防御を重ねる
  • ブロックしたリクエストをすべて記録する
  • 役立つ拒否メッセージを提示する
  • 可能な場合は拒否せず、マスキングする
  • パターンを定期的に更新する
  • 判断が難しいケースは人間が確認する

出力チェックリスト

  • PII 検出を実装済み
  • プロンプトインジェクションの検出
  • トピック分類
  • ポリシー制約の定義
  • 拒否テンプレートの作成
  • 出力検証
  • ロギング/モニタリング
  • バイパスに対するテストケース

コメント