Guarda-chuveias de LLM na Prática: O Que Realmente Funciona
Controle o risco, não apenas o modelo.
Os LLMs são imprevisíveis. Eles alucinam, vazam dados, geram conteúdo prejudicial ou recusam solicitações legítimas. Os guardrails (barreiras de segurança) restringem o comportamento do modelo sem sacrificar a capacidade.
A chave é saber quais guardrails são importantes e quais são apenas ruído.
Guardrails não se tratam de controlar o modelo. Tratam-se de controlar o risco.

Validação de entrada
A barreira de segurança mais importante. Entrada ruim gera saída ruim, e uma entrada ruim também pode injetar prompts no seu sistema.
Estratégia 1: Sanitização de Prompts
Sanitize padrões perigosos cedo:
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
Isso não é à prova de balas. Entradas adversárias são criativas. Mas isso captura as óbvias, e as óbvias são as mais comuns.
Estratégia 2: Limites de Comprimento da Entrada
Limites de comprimento previnem o desperdício de tokens e tempos limite (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"Input too long: {len(prompt)} > {self.max_length}"
return True, "OK"
Estratégia 3: Filtragem de Conteúdo
A filtragem de conteúdo bloqueia violações de políticas. Os padrões aqui dependem do seu domínio:
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"
A correspondência de strings simples é rápida, mas imprecisa. Para produção, use um modelo de classificação — mesmo um pequeno como o Qwen2.5-1.5B — para detectar violações de políticas. É mais preciso e mais difícil de ser burlado.
Filtragem de saída
A saída do modelo também precisa de verificação. Estrutura, conteúdo e fatos.
Estratégia 1: Validação de Resposta
Valide a estrutura primeiro. Se você espera JSON, verifique se há 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"Missing field: {field}"
return True, "OK"
Estratégia 2: Filtragem de Conteúdo
Filtre conteúdo prejudicial:
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"
Estratégia 3: Verificação de Fatos
A verificação de fatos é mais difícil. Você não pode validar toda afirmação, então escolha aquelas que importam:
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 failed: {fact}"
return True, "OK"
Para verificação de fatos real, você precisa de um pipeline de recuperação (retrieval). Verifique as afirmações contra uma base de conhecimento, não um dicionário codificado.
Mecanismos de segurança
Estratégia 1: Limitação de Taxa (Rate Limiting)
A limitação de taxa previne abuso:
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
Estratégia 2: Orçamento de Tokens
O orçamento de tokens limita os custos por solicitação:
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 exceeded: {token_count} > {self.max_tokens}"
return True, "OK"
Estratégia 3: Gerenciamento da Janela de Contexto
O gerenciamento da janela de contexto previne transbordamento (overflow):
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)
O recorte por janela deslizante é simples, mas perde o contexto inicial. Abordagens melhores usam sumarização ou compressão baseada em atenção, mas isso adiciona latência.
Conformidade
Sistemas empresariais precisam de guardrails de conformidade. Dois que importam mais:
Padrão 1: Residência de Dados
Residência de dados — garanta que os dados permaneçam dentro das fronteiras geográficas exigidas:
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 not allowed: {region}"
return True, "OK"
Padrão 2: Registro de Auditoria (Audit Logging)
Registro de auditoria — registre todas as interações do modelo:
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")
Os logs de auditoria são críticos para depuração e conformidade. Torne-os estruturados, apenas para acréscimo (append-only) e armazenados com segurança.
Juntando tudo
Padrão 1: Guardrails Simples
Um pipeline de guardrails simples:
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
Padrão 2: Guardrails Avançados
Guardrails avançados adicionam sanitização, limitação de taxa e orçamentos de tokens:
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
Quando os guardrails importam
Os guardrails importam quando você está construindo sistemas voltados para o usuário, manipulando dados sensíveis ou executando em produção. Eles também importam quando você tem requisitos de conformidade — GDPR, HIPAA, SOC 2.
Eles não importam quando você está prototipando, usando modelos apenas para ferramentas internas ou não manipulando dados sensíveis. Pule-os até precisar deles.
A compensação (tradeoff) é sempre capacidade versus segurança. Mais guardrails significam menos falhas, mas também menos capacidades. Encontre o equilíbrio que funcione para o seu sistema.
Compensações (Tradeoffs)
| Estratégia | Segurança | Capacidade | Latência |
|---|---|---|---|
| Sem guardrails | Mais baixa | Mais alta | Mais baixa |
| Validação de entrada | Alta | Média | Baixa |
| Filtragem de saída | Alta | Média | Baixa |
| Mecanismos de segurança | Mais alta | Mais baixa | Mais alta |
| Conformidade | Mais alta | Mais baixa | Mais alta |
Relacionados
- Estratégias de Roteamento de Modelos — roteamento baseado em capacidade, sensível a custos e latência
- Otimização de Custos para Sistemas LLM — orçamento de tokens, modelos de fallback, cache
- Design de Sistema Multi-Modelo — arquitetura para múltiplos modelos
- Arquitetura de LLM — pilar de design de sistema: roteamento, custo, guardrails e orquestração