JSON válido não é dado correto: as cinco falhas que a saída estruturada de LLMs não detecta
A decodificação restrita (constrained decoding) resolveu um problema real nos modelos de linguagem. Antes de métodos baseados em gramática como Outlines e SGLang, obter um JSON válido de um LLM era um ciclo de tentativa e erro: você pedia, parseava, encontrava a vírgula sobrando, pedia de novo. A decodificação restrita encerrou isso ao forçar a seleção de tokens por uma máquina de estados — e todo output passa a parsear.
Mas um problema silencioso se instalou nos códigos de produção: a suposição de que, se o JSON valida contra o schema, o dado está correto. Não está. Os benchmarks da BAML mostram que, em tarefas de function calling, a geração livre com parsing posterior atingiu 93,63% de acurácia, enquanto a decodificação restrita no mesmo modelo marcou 91,37%. O JSON “sempre válido” era menos preciso que o JSON “às vezes quebrado”.
As cinco falhas que sobrevivem ao schema
A validação de schema checa tipos: uma string é uma string, um número é um número. Ela não diz nada sobre se aquela string ou número está correto. Cinco modos de falha produzem saída estruturalmente válida e substantivamente errada:
- Alucinação de enum: o modelo escolhe um valor de enum válido, mas semanticamente errado. Um enum de prioridade
["low","normal","high","urgent"]pode retornar “urgent” para uma solicitação rotineira, e o schema aceita. - Fabricação confiante: campos de texto livre retornam dados plausíveis, mas inventados. A BAML submeteu a foto de um elefante como recibo, e a decodificação restrita devolveu um relatório de despesa completo e válido — em vez de se recusar.
- Contradição entre campos: cada campo valida isoladamente, nunca em conjunto. Um extrator de sentimento pode retornar
{"sentiment":"positive","score":0.1}— um rótulo positivo com nota perto de zero. - Colapso distribucional: o modelo converge para valores “seguros” e genéricos. Scores de confiança que estacionam em 0,98 por semanas são um sinal clássico.
- Alucinação de array: modelos resistem a retornar arrays vazios. Quando o schema exige um campo array, o modelo fabrica entradas em vez de devolver
[]— e o pipeline reporta “3 correspondências” quando o correto é zero.
Por que escrever mais regras não resolve
O instinto é criar mais validações. Para padrões conhecidos, funciona: um model_validator do Pydantic pega start_date > end_date. O problema são as falhas que você ainda não viu. A correção estrutural é fechada — você consegue enumerar toda forma de JSON válido para um schema. A correção semântica é aberta: não dá para escrever regra para uma resposta errada que você ainda não encontrou. Em produção, o modelo acha formas novas de errar mais rápido do que você escreve validadores.
Defesa em três camadas
Schema é o piso, não o teto. A recomendação prática é empilhar três níveis:
- Schema e validação estrutural (Pydantic, JSON Schema, Zod): pega erros de tipo e campos ausentes. Mantenha — resolve bem o problema de sintaxe.
- Validadores semânticos: funções com lógica de negócio entre campos (“se sentimento é positivo, score deve passar de 0,5”) e monitores de distribuição que rastreiam a entropia dos valores ao longo do tempo. Auditorias periódicas de amostras ambíguas pegam a fabricação confiante.
- Surfacing de incerteza: adicione um campo opcional de confiança junto a cada valor extraído, para o modelo expressar o que não sabe. Em campos de alto risco, use verificação “LLM como juiz” — uma segunda chamada que avalia se o valor é sustentado pela entrada.
Os sinais de que o pipeline está falhando silenciosamente são estatísticos: entropia de output caindo, nenhum array nunca vazio, e métricas de negócio derivando sem mudança no modelo ou no prompt. Inspecionar saídas individuais não pega nada disso — é preciso olhar a distribuição.
Descubra mais sobre noticiAI
Assine para receber nossas notícias mais recentes por e-mail.



