Inteligência artificial, sem ruído.
Tutoriais4 min

Seu LLM pode devolver JSON perfeito e ainda assim estar errado

Structured Outputs garantem forma, não verdade. Como evitar que o modelo invente valores com campos nullable e evidência.

Seu LLM pode devolver JSON perfeito e ainda assim estar errado

Três semanas depois de ativar Structured Outputs num pipeline que extraía mensagens de confirmação de pagamento, um engenheiro notou um padrão silencioso de erros: transações em que o valor e o remetente batiam, mas a data estava errada. Cerca de 2 a 3% do volume — o suficiente para notar, mas não para parecer óbvio de imediato.

O motivo, descrito por Benjamin Nweke num artigo do Towards Data Science, expõe uma armadilha sutil da geração estruturada: um LLM pode devolver JSON perfeitamente válido e, ainda assim, estar errado.

A armadilha do schema perfeito

As Structured Outputs resolvem um problema real: antes da imposição nativa de schema, obter JSON confiável de um LLM exigia regex, loops de retry e prompts implorando “só JSON, sem markdown”. Com o SDK da OpenAI e um modelo Pydantic, essa dor desaparece.

O problema surge quando a fonte não contém um campo que o schema marca como obrigatório. No caso real, a mensagem era algo como “Pagamento recebido de Chinedu, ₦45.000, ref TXN-82K91” — sem data nenhuma. Mas o schema dizia transaction_date: date, required. O modelo não podia devolver nada. Então inventou: preencheu a data com o dia em que o job rodou, errando por menos de uma hora.

“O modelo alcança o que quer que o leve a um valor válido: a data atual, o cutoff de treinamento, um palpite plausível”, escreve Nweke. “O que volta passa no type-check perfeitamente. E é completamente inventado.”

A correção: campos nullable

O primeiro ajuste é uma mudança de mentalidade, não de código: um campo vazio não é um erro de extração — muitas vezes é a verdade. Tornar os campos nullable tira do modelo a pressão de inventar:

class Transaction(BaseModel):
    sender: str | None
    amount: float | None
    transaction_id: str | None
    transaction_date: date | None

Isso ainda revela uma distinção importante entre extração (“diga exatamente o que está no texto”) e inferência (“diga o que isso implica”). Uma mensagem que diz “pago na terça” e um schema que exige data ISO é inferência — queira você ou não.

Evidência e proveniência

Campos nullable resolvem a invenção, mas não o outro problema: o modelo devolve um valor e você não tem como saber se ele leu aquele valor ou chutou por reconhecimento de padrão. A solução é pedir, ao lado de cada valor, o trecho exato do texto fonte que o sustenta:

class Extracted(BaseModel):
    value: float | date | str | None
    evidence: str | None

Se o value está preenchido mas a evidence está vazia — ou contém texto que não existe na fonte — o descompasso é a alucinação aparecendo nos próprios dados. O custo não é gratuito: num lote de centenas de mensagens, os campos de evidência aumentaram os tokens de saída em cerca de um terço. “Não vale a pena para um CEP de cinco dígitos. Mas para um valor financeiro com o qual alguém vai agir, definitivamente vale.”

Validação determinística, sem LLM

O terceiro ajuste é tirar a “sanidade” dos dados do modelo e entregá-la a um validador que acerta sempre:

@model_validator(mode="after")
def check_sane_values(self):
    if self.amount is not None and self.amount <= 0:
        raise ValueError("amount must be positive")
    if self.transaction_date is not None and self.transaction_date > date.today():
        raise ValueError("date in the future")
    return self

Quando o validador lança erro, há duas opções: mandar o registro para um humano ou devolver o erro ao modelo para nova tentativa — com um limite rígido de retries (o autor usa dois). “Duas falhas seguidas quase sempre significam que o documento fonte é o problema, não o prompt”, avisa.

A conclusão é direta: Structured Outputs garantem forma, não verdade. “Depois que você para de se preocupar com chaves e aspas, a pergunta real continua lá: cada valor nesse objeto tem uma razão real para existir?”



Descubra mais sobre noticiAI

Assine para receber nossas notícias mais recentes por e-mail.

R
Sobre o autorRedação Noticiai

Equipe editorial dedicada a explicar inteligência artificial com clareza, independência e contexto.