Guardrails
Regras determinísticas sobre o conteúdo que entra e o que sai — incluindo PII brasileira, mascarada antes do provedor.
Um guardrail é um conjunto de checks que roda sobre o texto de uma requisição (direção de entrada) ou de uma resposta (direção de saída). Todos os checks são determinísticos: sem rede, sem LLM julgando outro LLM, sem custo por chamada e sem latência de terceiro. Você lê a regra e sabe o que ela vai fazer.
Três decisões, e só três
| Ação | Efeito |
|---|---|
deny | Bloqueia: a requisição recusa 446 guardrail_negou. O corpo diz qual guardrail e qual check falhou — nunca o conteúdo detectado. |
| monitor | Não bloqueia, mas marca: o status sobe de 200 para 246, sinal barato de "passou, mas algo foi anotado". O detalhe fica na trilha. |
async | Log-only: o veredito roda depois que a resposta já saiu. Nunca bloqueia, nunca reescreve, nunca segura o streaming. |
PII brasileira, com máscara
O check pii_brasil detecta oito tipos de dado pessoal brasileiro e, no modo de mascarar, substitui o trecho encontrado antes de a requisição sair para o provedor — e antes de ela ser gravada na trilha e no cache. O provedor nunca vê o dado original; a auditoria também não.
A mesma máscara vale na volta: um guardrail de saída com pii_brasil em modo mascarar reescreve choices[].message.content na resposta do provedor antes de ela chegar ao cliente, ao cache e à trilha — nenhuma das três cópias guarda o dado original. Em streaming, essa reescrita exige juntar a resposta inteira antes de mandar o primeiro byte (a mesma bufferização de qualquer guardrail de saída síncrono, acima); não há como mascarar um quadro incremental sem ver a resposta completa primeiro.
Antes e depois
{
"model": "gpt-4o-mini",
"messages": [{
"role": "user",
"content": "O cliente 529.982.247-25 pediu reembolso pelo e-mail fabio@empresa.com.br"
}]
}{
"model": "gpt-4o-mini",
"messages": [{
"role": "user",
"content": "O cliente ***.***.***-25 pediu reembolso pelo e-mail f***@empresa.com.br"
}]
}| Detectado | Mascarado |
|---|---|
529.982.247-25 | ***.***.***-25 |
11.222.333/0001-81 | **.***.***/0001-** |
(11) 98765-4321 | (11) *****-**21 |
fabio@empresa.com.br | f***@empresa.com.br |
01310-100 | *****-100 |
Os oito tipos
Cada tipo liga e desliga por conta própria — todos vêm ligados por padrão.
- CPF (
cpf) - CNPJ (
cnpj) - Chave PIX (e-mail) (
pix_email) - Chave PIX (telefone) (
pix_telefone) - Chave PIX (aleatória) (
pix_aleatoria) - Telefone (
telefone) - CEP (
cep) - E-mail (
email)
A chave PIX no formato de e-mail roda o mesmo detector do e-mail, e a contagem chega agregada sob email na trilha — a documentação diz isso em voz alta em vez de fingir que existem dois números separados.
Os três modos
| Modo | Efeito |
|---|---|
Bloquear | falha o check quando acha PII — só recusa a requisição de fato se este guardrail também tiver deny ativo |
Mascarar | substitui o trecho encontrado por uma versão mascarada, sem bloquear |
Observar | só conta e registra no log, nunca altera nem bloqueia |
Embeddings e arrays
Em POST /v1/embeddings a varredura é por item do array: dígitos de itens adjacentes nunca são concatenados, então um CPF quebrado entre dois itens não vira um falso acerto. Checks de saída ali são ignorados (a saída é um vetor) e anotados como direcao_inaplicavel — transparência, não silêncio.
O catálogo completo de checks BASIC
Entrada e saída
- Regex Match —
regex_match - Word Count —
word_count - Sentence Count —
sentence_count - Character Count —
character_count - Ends With —
ends_with - Uppercase —
uppercase - Lowercase —
lowercase - PII Brasil —
pii_brasil
Só na saída
Estruturais: só fazem sentido sobre a resposta. O catálogo não oferece nenhum deles como opção de entrada — não mente sobre portas que não abrem.
- JSON Schema —
json_schema - JSON Keys —
json_keys - Contains —
contains - Not Null —
not_null - Valid URLs —
valid_urls - Contains Code —
contains_code
Só na entrada (controle)
Estes decidem sobre a REQUISIÇÃO, não sobre o texto: allowed_request_types é onde se separa chat de embedding, o controle por tipo de operação que o escopo único do data plane não faz.
- Model Whitelist —
model_whitelist - Required Metadata Keys —
required_metadata_keys - Allowed Request Types —
allowed_request_types
Duas limitações ditas em voz alta: regex_match compila sob RE2 (linear por construção, sem backtracking catastrófico), o que recusa na criação sintaxe que o RE2 não suporta — backreferences e lookahead/lookbehind. E json_schema não aceita as keywords pattern, format nem patternProperties em nível nenhum, pelo mesmo motivo; quem precisa validar formato de string usa regex_match.