Guarda-redes para LLMs 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. As barreiras de segurança (guardrails) restringem o comportamento do modelo sem sacrificar a capacidade.
A chave é saber quais barreiras de segurança importam e quais são apenas ruído.
As barreiras de segurança não se tratam de controlar o modelo. Elas tratam-se de controlar o risco.

Validação de entrada
A barreira de segurança mais importante. Entrada ruim gera saída ruim, e entrada ruim também pode injetar prompts no seu sistema.
Estratégia 1: Sanitização de Prompt
Sane padrões perigosos precocemente:
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. As 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 de Entrada
Limites de comprimento previnem o desperdício de tokens e 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ítica. 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 simples de strings é rápida, mas imprecisa. Para produção, use um modelo de classificador — mesmo um pequeno como o qwen3-1.7b — para detectar violações de política. É mais preciso e mais difícil de burlar.
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 por 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 cada afirmação, então escolha as 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. 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:
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)
A poda por janela deslizante é simples, mas perde o contexto inicial. Abordagens melhores usam sumarização ou compressão baseada em atenção, mas essas adicionam latência.
Conformidade
Sistemas empresariais precisam de barreiras de segurança de conformidade. Duas que mais importam:
Padrão 1: Residência de Dados
Residência de dados — garantir 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
Registro de auditoria — registrar todas as interações com o 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 registros 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: Barreiras de Segurança Simples
Um pipeline simples de barreiras de segurança:
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: Barreiras de Segurança Avançadas
Barreiras de segurança avançadas 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 as barreiras de segurança importam
As barreiras de segurança importam quando você está construindo sistemas voltados ao usuário, manipulando dados sensíveis ou executando em produção. Elas também importam quando você tem requisitos de conformidade — GDPR, HIPAA, SOC 2.
Elas não importam quando você está prototipando, usando modelos apenas para ferramentas internas ou não manipulando dados sensíveis. Pule-as até precisar delas.
O trade-off é sempre capacidade versus segurança. Mais barreiras de segurança significam menos falhas, mas também menos capacidades. Encontre o equilíbrio que funcione para o seu sistema.
As barreiras de segurança cobrem a conversa do modelo, mas param no ponto onde um agente chama uma ferramenta ou transfere trabalho para outro agente. Uma vez que você implanta ferramentas MCP ou agentes A2A, você também precisa de segurança de protocolo — identidade, autorização escopada, limites de delegação e rastros de auditoria para quem pode agir em nome de quem. Essa camada é coberta em Segurança de Agentes A2A e MCP: Identidade, Delegação e Rastros de Auditoria.
Trade-offs
| Estratégia | Segurança | Capacidade | Latência |
|---|---|---|---|
| Sem barreiras de segurança | 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 |
Relacionado
- Estratégias de Roteamento de Modelos — roteamento baseado em capacidade, ciente de custos e latência
- Otimização de Custos para Sistemas de 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, barreiras de segurança e orquestração