LLM-beveiliging in de praktijk: wat echt werkt

Beheers het risico, niet alleen het model.

Inhoud

LLM’s zijn onvoorspelbaar. Ze hallucineren, lekken data, genereren schadelijke inhoud of weigeren legitieme verzoeken. Guardrails (beveiligingsmaatregelen) beperken het modelgedrag zonder de capaciteiten ten koste te gaan.

De sleutel is te weten welke guardrails essentieel zijn en welke slechts ruis zijn.

Guardrails gaan niet over het controleren van het model. Ze gaan over het beheersen van het risico.

LLM guardrails in de praktijk

Validatie van invoer

De belangrijkste beveiligingsmaatregel. Slechte invoer levert slechte uitvoer op, en slechte invoer kan ook prompt-injectie in uw systeem veroorzaken.

Strategie 1: Prompt-sanitisatie

Sanitizeer gevaarlijke patronen vroeg:

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

Dit is niet waterdicht. Adversariële invoer is creatief. Maar het vangt de voor de hand liggende gevallen, en die zijn het meest voorkomend.

Strategie 2: Lengtebeperkingen voor invoer

Lengtebeperkingen voorkomen tokenverbruik en time-outs:

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"Invoer te lang: {len(prompt)} > {self.max_length}"
        return True, "OK"

Strategie 3: Contentfiltering

Contentfiltering blokkeert beleidsovertredingen. De patronen hier zijn afhankelijk van uw domein:

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"Geblokkeerd: {topic}"
        return True, "OK"

Eenvoudige stringmatching is snel maar onnauwkeurig. Gebruik voor productie een classificatiemodel — zelfs een klein model zoals qwen3-1.7b — om beleidsovertredingen te detecteren. Het is nauwkeuriger en moeilijker te omzeilen.

Uitvoerfiltering

De uitvoer van het model moet ook worden gecontroleerd. Structuur, inhoud en feiten.

Strategie 1: Responsvalidatie

Valideer eerst de structuur. Als u JSON verwacht, controleer dan op 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"Ontbrekend veld: {field}"
        return True, "OK"

Strategie 2: Contentfiltering

Filter schadelijke inhoud:

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"Geblokkeerd: {pattern}"
        return True, "OK"

Strategie 3: Feitencontrole

Feitencontroleren is moeilijker. U kunt niet elke bewering valideren, dus kies die welke er toe doen:

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"Feitencheck mislukt: {fact}"
        return True, "OK"

Voor echte feitencontrole hebt u een retrieval-pijplijn nodig. Controleer beweringen tegen een kennisbank, niet tegen een hardgecodeerde dictionary.

Veiligheidsmechanismen

Strategie 1: Rate Limiting (Aanvraagbeperking)

Aanvraagbeperking voorkomt misbruik:

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: Tokenbudgettering

Tokenbudgettering stelt kostenlimieten per aanvraag:

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"Tokenlimiet overschreden: {token_count} > {self.max_tokens}"
        return True, "OK"

Strategie 3: Contextvensterbeheer

Beheer van het contextvenster voorkomt overloop:

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)

Schuifvenstertrimmen is eenvoudig, maar verliest vroege context. Betere benaderingen gebruiken samenvatting of compressie op basis van aandacht, maar die voegen latentie toe.

Compliance

Enterprise-systemen hebben compliance-beveiligingsmaatregelen nodig. Twee die het meest van belang zijn:

Patroon 1: Data-residentie

Data-residentie — zorg dat data binnen de vereiste geografische grenzen blijft:

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"Regio niet toegestaan: {region}"
        return True, "OK"

Patroon 2: Auditlogging

Auditlogging — log alle modelinteracties:

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")

Auditlogs zijn cruciaal voor debugging en compliance. Maak ze gestructureerd, alleen aan te vullen (append-only) en sla ze veilig op.

Het samenbrengen

Patroon 1: Simpele Guardrails

Een simpele guardrail-pijplijn:

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"Fout: {message}"

        response = self.call_model(prompt)

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

        return response

Patroon 2: Geavanceerde Guardrails

Geavanceerde guardrails voegen sanitatie, aanvraagbeperking en tokenbudgetten toe:

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"Fout: {message}"

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

        if not self.rate_limiter.allow():
            return "Fout: Aanvraaglimiet overschreden"

        response = self.call_model(prompt)

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

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

        return response

Wanneer guardrails belangrijk zijn

Guardrails zijn belangrijk wanneer u systeem voor eindgebruikers bouwt, gevoelige data verwerkt of in productie draait. Ze zijn ook belangrijk wanneer u compliance-eisen heeft — AVG (GDPR), HIPAA, SOC 2.

Ze zijn niet belangrijk wanneer u prototypen, modellen alleen voor interne tools gebruikt of geen gevoelige data verwerkt. Sla ze over tot u ze nodig heeft.

De afweging is altijd capaciteit versus veiligheid. Meer guardrails betekenen minder falen, maar ook minder capaciteiten. Vind het evenwicht dat werkt voor uw systeem.

Guardrails dekken het modelgesprek, maar ze stoppen op het punt waar een agent een tool aanroept of werk aan een ander agent overdraagt. Zodra u MCP-tools of A2A-agents implementeert, heeft u ook protocolbeveiliging nodig — identiteit, geblokkeerde autorisatie, delegatiebeperkingen en audittrails voor wie namens wie mag handelen. Deze laag wordt behandeld in A2A and MCP Agent Security: Identity, Delegation, and Audit Trails.

Afwegingen

Strategie Veiligheid Capaciteit Latentie
Geen guardrails Laagst Hoogst Laagst
Invoervalidatie Hoog Midden Laag
Uitvoerfiltering Hoog Midden Laag
Veiligheidsmechanismen Hoogst Laagst Hoogst
Compliance Hoogst Laagst Hoogst

Gerelateerd

Abonneren

Ontvang nieuwe berichten over systemen, infrastructuur en AI-engineering.