LLM-beveiligingsmaatregelen in de praktijk: wat daadwerkelijk werkt
Beheers het risico, niet alleen het model.
LLM’s zijn onvoorspelbaar. Ze hallucineren, lekken data, genereren schadelijke content of weigeren legitieme verzoeken. Guardrails beperken het gedrag van modellen zonder in te leveren op capaciteit.
De sleutel ligt in het weten welke guardrails essentieel zijn en welke alleen maar ruis toevoegen.
Guardrails gaan niet over het controleren van het model. Ze gaan over het beheersen van het risico.

Validatie van invoer
De belangrijkste guardrail. Slechte invoer levert slechte uitvoer op, en slechte invoer kan ook je systeem injecteren via prompts.
Strategie 1: Prompt-ontsmetting
Ontsmet 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 op, en die zijn het meest voorkomend.
Strategie 2: Lengtebeperkingen voor invoer
Lengtebeperkingen voorkomen tokenverspilling 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 schendingen van het beleid. 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 tekenreeksmatching is snel maar onnauwkeurig. Gebruik voor productie een classificatiemodel — zelfs een klein model zoals qwen3-1.7b — om schendingen van het beleid te detecteren. Het is nauwkeuriger en moeilijker te omzeilen.
Uitvoerfiltering
De uitvoer van het model moet ook worden gecontroleerd. Structuur, content en feiten.
Strategie 1: Validatie van antwoorden
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 content:
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: Fact-checking
Fact-checking is moeilijker. U kunt niet elke bewering valideren, dus kies degenen die ertoe 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"Fact check mislukt: {fact}"
return True, "OK"
Voor echte fact-checking heeft u een retrieval-pipeline nodig. Controleer beweringen tegen een kennisbank, niet tegen een hardcoded dictionary.
Veiligheidsmechanismen
Strategie 1: Rate limiting
Rate limiting 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 een maximum voor kosten per verzoek:
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: Beheer van het contextvenster
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)
Trimmen met een glijdend venster is eenvoudig, maar verliest context aan het begin. Betere methoden gebruiken samenvatting of compressie op basis van attention, maar deze voegen latentie toe.
Compliance
Enterprise-systemen hebben compliance-guardrails nodig. De twee die het meest tellen:
Patroon 1: Dataresidentie
Dataresidentie — zorg ervoor 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 essentieel voor debugging en compliance. Maak ze gestructureerd, alleen aan te vullen (append-only) en bewaar ze veilig.
Het samenbrengen
Patroon 1: Eenvoudige guardrails
Een eenvoudige 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"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 ontsmetting, rate limiting 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: Rate limit 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 bouwt die gericht zijn op eindgebruikers, gevoelige data verwerken of in productie draaien. Ze zijn ook belangrijk wanneer u compliance-eisen heeft — GDPR, HIPAA, SOC 2.
Ze zijn niet belangrijk wanneer u prototype, modellen alleen gebruikt voor interne tools, of geen gevoelige data verwerkt. Sla ze over totdat u ze nodig heeft.
De afweging is altijd capaciteit versus veiligheid. Meer guardrails betekenen minder fouten, maar ook minder capaciteit. Vind de balans die werkt voor uw systeem.
Afwegingen
| Strategie | Veiligheid | Capaciteit | Latentie |
|---|---|---|---|
| Geen guardrails | Laagst | Hoogst | Laagst |
| Validatie van invoer | Hoog | Gemiddeld | Laag |
| Uitvoerfiltering | Hoog | Gemiddeld | Laag |
| Veiligheidsmechanismen | Hoogst | Laagst | Hoogst |
| Compliance | Hoogst | Laagst | Hoogst |
Gerelateerd
- Modellrouteringsstrategieën — routing op basis van capaciteit, kostenbewust en latentiebewust
- Kostenoptimalisatie voor LLM-systemen — tokenbudgettering, fallback-modellen, caching
- Ontwerp van multimodelsystemen — architectuur voor meerdere modellen
- LLM-architectuur — pijler van systeemontwerp: routing, kosten, guardrails en orkestratie