AvalonOpsDocumentação

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

O que acontece quando um check falha
AçãoEfeito
denyBloqueia: a requisição recusa 446 guardrail_negou. O corpo diz qual guardrail e qual check falhou — nunca o conteúdo detectado.
monitorNão bloqueia, mas marca: o status sobe de 200 para 246, sinal barato de "passou, mas algo foi anotado". O detalhe fica na trilha.
asyncLog-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

o que o seu código manda
{
  "model": "gpt-4o-mini",
  "messages": [{
    "role": "user",
    "content": "O cliente 529.982.247-25 pediu reembolso pelo e-mail fabio@empresa.com.br"
  }]
}
o que o provedor recebe (e o que fica na trilha)
{
  "model": "gpt-4o-mini",
  "messages": [{
    "role": "user",
    "content": "O cliente ***.***.***-25 pediu reembolso pelo e-mail f***@empresa.com.br"
  }]
}
As máscaras, tipo a tipo
DetectadoMascarado
529.982.247-25***.***.***-25
11.222.333/0001-81**.***.***/0001-**
(11) 98765-4321(11) *****-**21
fabio@empresa.com.brf***@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

O que o modo decide
ModoEfeito
Bloquearfalha o check quando acha PII — só recusa a requisição de fato se este guardrail também tiver deny ativo
Mascararsubstitui o trecho encontrado por uma versão mascarada, sem bloquear
Observarsó 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.