aicert.study
Study Track/Saída estruturada é um contrato que não é confiável por padrão

Saída estruturada é um contrato que não é confiável por padrão

75 min

Original content in Portuguese — translation coming soon.
We recommend seeing first: A Messages API é uma máquina de estados

Lesson objectives

  • Forçar formato com tool use e tool_choice em vez de instrução solta
  • Validar, tentar de novo e devolver o erro semântico ao modelo
  • Separar falha de forma (schema) de falha de conteúdo (fato errado)

O problema

Um time pede ao modelo, em texto livre, para "responder em JSON com os campos nome, valor e data". Na maioria das vezes funciona. De vez em quando o modelo envolve o JSON em um parágrafo explicativo, usa aspas simples em vez de duplas, ou esquece um campo. O parser quebra em produção, silenciosamente, uma vez a cada algumas centenas de chamadas — raro o suficiente para não aparecer nos testes manuais, frequente o suficiente para virar um incidente real em escala.

A causa não é o modelo "ter falhado ocasionalmente". É ter tratado uma instrução em linguagem natural ("responda em JSON") como se fosse uma garantia estrutural, quando na verdade instrução em prompt é uma sugestão forte, não um contrato.

Forçar formato com tool use, não com instrução solta

A forma correta de garantir estrutura não é pedir educadamente no prompt — é usar tool use com um schema JSON explícito e tool_choice para forçar o modelo a preencher esse schema. Quando a "ferramenta" é na verdade só uma forma de extrair dados estruturados (não uma ação real), essa técnica ainda se aplica: você define um schema de tool use que descreve exatamente os campos esperados, e usa tool_choice para obrigar o modelo a chamá-la, garantindo que a saída sempre venha no formato do schema.

Isso reduz drasticamente falhas de forma (JSON malformado, campo faltando, tipo errado) porque a geração fica restrita pela definição do schema, não é apenas guiada por uma instrução em texto. Mas reduzir não é eliminar: mesmo com schema estrito, validação semântica continua sendo necessária — o schema garante que o campo valor é um número, não que esse número está correto.

Validar, tentar de novo, devolver o erro semântico

Quando uma saída falha validação — seja de forma, seja de conteúdo — a resposta ingênua é simplesmente descartar e tentar de novo com o mesmo prompt, esperando um resultado diferente por sorte. Isso funciona ocasionalmente e desperdiça chamadas na maioria das vezes, porque o modelo não tem nenhuma informação nova sobre o que deu errado.

A abordagem correta fecha o loop: quando a validação falha, o erro específico — não um genérico "tente de novo", mas "o campo data não está no formato ISO-8601" ou "o valor total não bate com a soma dos itens" — é devolvido ao modelo como parte da próxima tentativa. Isso transforma uma retentativa cega em uma correção guiada, com taxa de sucesso muito mais alta, porque o modelo agora sabe exatamente o que corrigir.

Duas falhas independentes, duas defesas independentes

Essa lição conecta diretamente com a validação de saída: falha de forma (schema errado) e falha de conteúdo (fato errado dentro de um schema correto) são problemas diferentes que exigem defesas diferentes.

  • Defesa contra falha de forma: tool use com schema + tool_choice, validação de schema automática, retry com o erro de schema devolvido ao modelo.
  • Defesa contra falha de conteúdo: validação semântica que verifica o dado contra a fonte ou contra regras de domínio (o valor bate com o documento original? a data está dentro de um intervalo plausível?), não apenas contra o formato.

Uma implementação madura trata as duas camadas separadamente, porque uma saída pode passar na primeira e falhar na segunda — e um pipeline que só valida forma está, na prática, sem nenhuma defesa contra a segunda categoria de erro, que é geralmente a mais cara.

Onde a intuição erra

  • "Se eu pedir claramente no prompt para responder em JSON, o modelo vai obedecer sempre." Instrução em linguagem natural é uma sugestão forte, não uma garantia estrutural — falhas ocasionais de forma são esperadas nesse modelo de uso.
  • "Se a validação falhar, é só tentar de novo com o mesmo prompt." Sem devolver o erro específico ao modelo, uma nova tentativa tem a mesma chance de falhar do mesmo jeito — o ganho real vem de fechar o loop com o erro semântico.
  • "Um schema JSON estrito garante que os dados estão corretos." Garante forma, não conteúdo. Validação semântica continua necessária mesmo com schema perfeito.

Coloque em prática

No laboratório desta lição você vai implementar um pipeline de extração com duas camadas de validação — forma e conteúdo — e um mecanismo de retry que devolve o erro específico da falha para uma segunda tentativa, medindo a diferença de taxa de sucesso contra um retry "cego".

Hands-on lab

Clone the repository and run it locally:

git clone https://github.com/aicertstudy/labs
cd labs/ccar-f/lessons/09-structured-output-and-defensive-parsing
View folder on GitHub

Ready to test it for real?

Take the full CCAR-F mock exam, in the same format as the official test.

See mock exams

Lesson checkpoint

Loading quiz...