Um chatbot em produção é como um atendente novo que fala rápido, nunca cansa e atende todo mundo ao mesmo tempo. O detalhe é que ele também pode ser “convencido” a dizer coisas que a empresa jamais colocaria num FAQ: instruções perigosas, conteúdo inadequado, incentivo à autolesão, discurso de ódio, ou até vazamento acidental de dados. Guardrails fracos quase nunca parecem um problema no dia 1 — eles aparecem no dia em que alguém testa o limite ou quando um usuário comum tropeça num tema sensível e o sistema responde sem freio.
A boa notícia: reduzir risco não exige “censurar tudo”. Exige projetar o fluxo com três travas simples e consistentes: filtrar entrada, limitar saída e ter uma rota segura quando o conteúdo passa do limite. Um exemplo prático é usar recursos de moderação disponíveis em APIs de modelos (como a API da OpenAI) para detectar conteúdo potencialmente nocivo e orientar a resposta do sistema.
AS-IS — chama o modelo e devolve a resposta “como vier”
No AS-IS, o chatbot simplesmente encaminha o texto do usuário para o modelo e imprime a resposta. Sem checagem de conteúdo, sem limite de tokens, sem fallback, sem trilha clara do que aconteceu.
# AS-IS (Python): chatbot “cru” sem filtros nem limites reais
from openai import OpenAI
client = OpenAI()
def chat_as_is(user_text: str) -> str:
resp = client.responses.create(
model="gpt-4.1-mini",
input=user_text,
)
return resp.output_text
O problema desse desenho é que ele assume que “bom senso” vai emergir sempre. Em produção, isso falha: usuários tentam burlar instruções (“ignore suas regras”), pedem conteúdo perigoso, inserem instruções maliciosas em textos colados, ou levam a conversa para temas sensíveis.
TO-BE — filtra entrada, limita saída e modera a resposta antes de exibir
No TO-BE, o chatbot opera como um sistema governável:
- Modera a entrada (bloqueia ou redireciona pedidos claramente inadequados).
- Limita tamanho de entrada e de saída (reduz chance de abuso e também custo).
- Modera a saída (se o modelo “escapar”, a resposta não vai para o usuário).
- Define respostas seguras (recusar com orientação alternativa; ou escalar para humano quando necessário).
- Registra uma trilha simples (o suficiente para auditar e corrigir sem debate infinito).
# TO-BE (Python): guardrails práticos com moderação de entrada/saída + limites + fallback
# Exemplo usando a API da OpenAI como referência de implementação.
from openai import OpenAI
from typing import Tuple, Dict, Any
import time
import uuid
client = OpenAI()
MOD_MODEL = "omni-moderation-latest"
CHAT_MODEL = "gpt-4.1-mini"
def moderate(text: str) -> Tuple[bool, Dict[str, Any]]:
m = client.moderations.create(
model=MOD_MODEL,
input=text
)
flagged = bool(m.results[0].flagged)
return (not flagged), {"flagged": flagged, "categories": m.results[0].categories}
def safe_refusal() -> str:
return (
"Não dá para ajudar com esse tipo de pedido. "
"Se você descrever o objetivo de forma segura (ex.: prevenção, proteção, bem-estar), eu ajudo com alternativas."
)
def chat_to_be(user_text: str, user_id: str = "anon") -> str:
request_id = f"cb_{uuid.uuid4().hex}"
started = time.time()
user_text = (user_text or "").strip()
# 1) Limite de entrada (evita abuso e custo)
if len(user_text) > 4000:
return "A mensagem ficou muito longa. Resuma em poucas linhas e tente de novo."
# 2) Moderação de entrada
ok_in, in_details = moderate(user_text)
if not ok_in:
print("[CHAT_AUDIT]", {
"request_id": request_id,
"user_id": user_id,
"stage": "blocked_input",
"moderation": in_details,
})
return safe_refusal()
# 3) Chamada ao modelo com limites e instruções defensivas
resp = client.responses.create(
model=CHAT_MODEL,
input=[
{"role": "system", "content": (
"Responder de forma útil e segura. "
"Se houver pedido perigoso, ilegal, sexual inadequado, autolesão ou ódio, recusar e oferecer alternativa segura. "
"Não inventar dados pessoais nem instruções operacionais sensíveis."
)},
{"role": "user", "content": user_text},
],
max_output_tokens=350,
)
answer = resp.output_text or ""
# 4) Moderação de saída (segunda trava)
ok_out, out_details = moderate(answer)
if not ok_out:
print("[CHAT_AUDIT]", {
"request_id": request_id,
"user_id": user_id,
"stage": "blocked_output",
"moderation": out_details,
})
return safe_refusal()
# 5) Trilha mínima (sem armazenar texto sensível inteiro)
print("[CHAT_AUDIT]", {
"request_id": request_id,
"user_id": user_id,
"stage": "served",
"latency_ms": int((time.time() - started) * 1000),
"input_len": len(user_text),
"output_len": len(answer),
"in_flagged": in_details["flagged"],
"out_flagged": out_details["flagged"],
})
return answer
Antes, o chatbot operava na confiança. Agora, ele opera em mecanismos: se a entrada é problemática, não entra; se a saída escapa, não sai; e a conversa tem um caminho seguro quando chega em temas de risco.
Análise — reduzir risco é trocar “confiança” por mecanismos
Guardrails fracos normalmente significam uma aposta: “o usuário não vai tentar nada estranho” e “o modelo sempre vai entender o contexto”. Em produção, essa aposta não escala.
A virada de jogo é pragmática:
- consistência: o sistema responde do mesmo jeito em casos de risco (recusa curta + alternativa segura);
- controle de cauda: limites e moderação pegam justamente os casos que viram incidente;
- correção rápida: trilha simples para investigar e ajustar sem guerra interna.
Se quiser evoluir, o próximo passo natural é sair do “bloqueia ou libera” e ter rotas: responder normalmente, responder com cuidado (tom e conteúdo restritos), recusar, ou escalar para humano — sempre com o mesmo padrão operacional.