LLM-Guardrails in der Praxis: Was wirklich funktioniert

Kontrollieren Sie das Risiko, nicht nur das Modell.

Inhaltsverzeichnis

LLMs sind unvorhersehbar. Sie halluzinieren, lecken Daten, generieren schädliche Inhalte oder lehnen legitime Anfragen ab. Guardrails (Schutzmechanismen) begrenzen das Modellverhalten, ohne die Fähigkeiten einzuschränken.

Der Schlüssel liegt darin zu wissen, welche Guardrails wichtig sind und welche nur Rauschen darstellen.

Guardrails dienen nicht der Kontrolle des Modells. Sie dienen der Kontrolle des Risikos.

LLM Guardrails in der Praxis

Eingabvalidierung

Das wichtigste Guardrail. Schlechte Eingaben führen zu schlechten Ausgaben, und schlechte Eingaben können auch Ihr System durch Prompt-Injection kompromittieren.

Strategie 1: Prompt-Sanitisierung

Sanitieren Sie gefährliche Muster frühzeitig:

import re

class PromptSanitizer:
    def __init__(self):
        self.dangerous_patterns = [
            r"ignore\s+previous\s+instructions",
            r"system\s+prompt",
            r"you\s+are\s+now\s+free",
            r"break\s+out\s+of",
        ]

    def sanitize(self, prompt: str) -> str:
        for pattern in self.dangerous_patterns:
            prompt = re.sub(pattern, "[REDACTED]", prompt, flags=re.IGNORECASE)
        return prompt

Dies ist nicht wasserdicht. Adversäre Eingaben sind kreativ. Aber es fängt die offensichtlichen Fälle, und die sind die häufigsten.

Strategie 2: Eingabelängenbegrenzung

Längenbeschränkungen verhindern Token-Verbrauch und Timeouts:

class InputValidator:
    def __init__(self, max_length: int = 10000):
        self.max_length = max_length

    def validate(self, prompt: str) -> tuple[bool, str]:
        if len(prompt) > self.max_length:
            return False, f"Eingabe zu lang: {len(prompt)} > {self.max_length}"
        return True, "OK"

Strategie 3: Content-Filtering

Content-Filtering blockiert Verstöße gegen Richtlinien. Die Muster hier hängen von Ihrem Bereich ab:

class ContentFilter:
    def __init__(self):
        self.blocked_topics = [
            "violence", "hate speech", "self-harm",
            "sexual content", "illegal activities",
        ]

    def filter(self, prompt: str) -> tuple[bool, str]:
        prompt_lower = prompt.lower()
        for topic in self.blocked_topics:
            if topic in prompt_lower:
                return False, f"Blocked: {topic}"
        return True, "OK"

Einfaches String-Matching ist schnell, aber ungenau. Für den Produktiveinsatz verwenden Sie ein Klassifikationsmodell – selbst ein kleines wie qwen3-1.7b – um Richtlinienverstöße zu erkennen. Es ist genauer und schwerer zu umgehen.

Ausgabe-Filtering

Die Ausgabe des Modells muss ebenfalls überprüft werden. Struktur, Inhalt und Fakten.

Strategie 1: Antwortvalidierung

Validieren Sie zuerst die Struktur. Wenn Sie JSON erwarten, prüfen Sie auf JSON:

class ResponseValidator:
    def __init__(self):
        self.required_fields = ["answer", "confidence"]

    def validate(self, response: dict) -> tuple[bool, str]:
        for field in self.required_fields:
            if field not in response:
                return False, f"Fehlendes Feld: {field}"
        return True, "OK"

Strategie 2: Content-Filtering

Filtern Sie schädliche Inhalte:

class OutputFilter:
    def __init__(self):
        self.blocked_patterns = [
            r"kill\s+someone",
            r"bomb\s+recipe",
            r"hate\s+speech",
            r"self-harm",
        ]

    def filter(self, response: str) -> tuple[bool, str]:
        for pattern in self.blocked_patterns:
            if re.search(pattern, response, re.IGNORECASE):
                return False, f"Blocked: {pattern}"
        return True, "OK"

Strategie 3: Faktenprüfung

Faktenprüfung ist schwieriger. Sie können nicht jede Behauptung validieren, also wählen Sie die aus, die wichtig sind:

class FactChecker:
    def __init__(self):
        self.known_facts = {
            "capital of france": "Paris",
            "population of usa": "330 million",
            "speed of light": "299,792,458 m/s",
        }

    def check(self, claim: str) -> tuple[bool, str]:
        claim_lower = claim.lower()
        for fact, truth in self.known_facts.items():
            if fact in claim_lower and truth not in claim_lower:
                return False, f"Faktcheck fehlgeschlagen: {fact}"
        return True, "OK"

Für echte Faktenprüfung benötigen Sie eine Retrieval-Pipeline. Prüfen Sie Behauptungen gegen eine Wissensdatenbank, nicht gegen ein hardcoded Dictionary.

Sicherheitsmechanismen

Strategie 1: Rate Limiting

Rate Limiting verhindert Missbrauch:

import time
from collections import deque

class RateLimiter:
    def __init__(self, max_requests: int = 10, window: int = 60):
        self.max_requests = max_requests
        self.window = window
        self.requests = deque()

    def allow(self) -> bool:
        now = time.time()
        while self.requests and self.requests[0] < now - self.window:
            self.requests.popleft()

        if len(self.requests) >= self.max_requests:
            return False

        self.requests.append(now)
        return True

Strategie 2: Token-Budgetierung

Token-Budgetierung begrenzt die Kosten pro Anfrage:

class TokenBudget:
    def __init__(self, max_tokens: int = 1000):
        self.max_tokens = max_tokens

    def validate(self, response: str) -> tuple[bool, str]:
        token_count = len(response.split())
        if token_count > self.max_tokens:
            return False, f"Token-Limit überschritten: {token_count} > {self.max_tokens}"
        return True, "OK"

Strategie 3: Context-Window-Management

Context-Window-Management verhindert Überlauf:

class ContextManager:
    def __init__(self, max_context: int = 4096):
        self.max_context = max_context
        self.context = []

    def add(self, message: str):
        self.context.append(message)
        self.trim()

    def trim(self):
        while len(" ".join(self.context)) > self.max_context:
            self.context.pop(0)

Sliding-Window-Trimming ist einfach, verliert aber frühen Kontext. Bessere Ansätze verwenden Zusammenfassung oder auf Aufmerksamkeit basierende Komprimierung, aber diese erhöhen die Latenz.

Compliance

Enterprise-Systeme benötigen Compliance-Guardrails. Zwei, die am wichtigsten sind:

Muster 1: Data Residency (Datenresidenz)

Data Residency – stellen Sie sicher, dass Daten innerhalb der erforderlichen geografischen Grenzen bleiben:

class DataResidency:
    def __init__(self, allowed_regions: list[str]):
        self.allowed_regions = allowed_regions

    def validate(self, region: str) -> tuple[bool, str]:
        if region not in self.allowed_regions:
            return False, f"Region nicht erlaubt: {region}"
        return True, "OK"

Muster 2: Audit Logging (Prüfprotokollierung)

Audit Logging – protokollieren Sie alle Modellinteraktionen:

import json
from datetime import datetime

class AuditLogger:
    def __init__(self, log_file: str = "audit.log"):
        self.log_file = log_file

    def log(self, request: dict, response: dict):
        entry = {
            "timestamp": datetime.now().isoformat(),
            "request": request,
            "response": response,
        }
        with open(self.log_file, "a") as f:
            f.write(json.dumps(entry) + "\n")

Audit-Logs sind entscheidend für Debugging und Compliance. Machen Sie sie strukturiert, nur anhängend (append-only) und speichern Sie sie sicher.

Zusammenführung

Muster 1: Einfache Guardrails

Eine einfache Guardrail-Pipeline:

class SimpleGuardrails:
    def __init__(self):
        self.input_validator = InputValidator(max_length=10000)
        self.output_filter = OutputFilter()

    def process(self, prompt: str) -> str:
        valid, message = self.input_validator.validate(prompt)
        if not valid:
            return f"Error: {message}"

        response = self.call_model(prompt)

        valid, message = self.output_filter.filter(response)
        if not valid:
            return f"Error: {message}"

        return response

Muster 2: Erweiterte Guardrails

Erweiterte Guardrails fügen Sanitisierung, Rate Limiting und Token-Budgets hinzu:

class AdvancedGuardrails:
    def __init__(self):
        self.sanitizer = PromptSanitizer()
        self.input_validator = InputValidator(max_length=10000)
        self.content_filter = ContentFilter()
        self.output_filter = OutputFilter()
        self.rate_limiter = RateLimiter(max_requests=10)
        self.token_budget = TokenBudget(max_tokens=1000)

    def process(self, prompt: str) -> str:
        prompt = self.sanitizer.sanitize(prompt)

        valid, message = self.input_validator.validate(prompt)
        if not valid:
            return f"Error: {message}"

        valid, message = self.content_filter.filter(prompt)
        if not valid:
            return f"Error: {message}"

        if not self.rate_limiter.allow():
            return "Error: Rate limit exceeded"

        response = self.call_model(prompt)

        valid, message = self.output_filter.filter(response)
        if not valid:
            return f"Error: {message}"

        valid, message = self.token_budget.validate(response)
        if not valid:
            return f"Error: {message}"

        return response

Wann Guardrails wichtig sind

Guardrails sind wichtig, wenn Sie nutzerorientierte Systeme aufbauen, sensible Daten verarbeiten oder in der Produktion laufen. Sie sind auch wichtig, wenn Sie Compliance-Anforderungen haben – DSGVO, HIPAA, SOC 2.

Sie sind nicht wichtig, wenn Sie prototypen, Modelle nur für interne Tools verwenden oder keine sensiblen Daten verarbeiten. Überspringen Sie sie, bis Sie sie benötigen.

Der Trade-off ist immer Fähigkeit versus Sicherheit. Mehr Guardrails bedeuten weniger Fehler, aber auch weniger Fähigkeiten. Finden Sie das Gleichgewicht, das für Ihr System funktioniert.

Guardrails decken die Modellkonversation ab, hören aber an der Stelle auf, an der ein Agent ein Tool aufruft oder Arbeit an einen anderen Agenten weitergibt. Sobald Sie MCP-Tools oder A2A-Agenten bereitstellen, benötigen Sie auch Protokollsicherheit – Identität, bereichsbasierte Autorisierung, Delegationslimits und Audit-Trails dafür, wer in wessen Namen handeln darf. Diese Ebene wird in A2A and MCP Agent Security: Identity, Delegation, and Audit Trails behandelt.

Trade-offs

Strategie Sicherheit Fähigkeit Latenz
Keine Guardrails Niedrigste Höchste Niedrigste
Eingabvalidierung Hoch Mittel Niedrig
Ausgabe-Filtering Hoch Mittel Niedrig
Sicherheitsmechanismen Höchste Niedrigste Höchste
Compliance Höchste Niedrigste Höchste

Verwandte Themen

Abonnieren

Neue Beiträge zu Systemen, Infrastruktur und KI-Engineering.