
Saída estruturada em JSON com LLM: como evitar quebras no fluxo
Compare esquema, validação e novas tentativas para que a saída JSON do modelo seja aproveitada por outros sistemas sem quebrar o fluxo da empresa.
Quer aplicar isso na sua empresa?
Agendar conversa com o Juan →Saída estruturada em JSON com LLM: como evitar quebras no fluxo
Para obter saída estruturada em JSON de um LLM de forma confiável, combine três camadas: um esquema claro que o modelo deve seguir, uma validação feita pelo seu próprio código antes de qualquer sistema consumir o resultado e uma política de novas tentativas com limite e plano B. Nenhuma camada resolve sozinha. Pedir JSON no prompt costuma funcionar nos testes e falhar no caso estranho, e é nesse caso que o fluxo quebra.
Principais pontos
- JSON válido não é o mesmo que saída correta: o texto pode ter sintaxe perfeita e conteúdo errado.
- Restringir a saída por esquema reduz falhas de formato, mas a validação no seu código continua obrigatória.
- Esquemas pequenos, com valores permitidos explícitos e uma saída para incerteza, quebram menos que esquemas grandes e abertos.
- Nova tentativa só vale para falhas que podem mudar na segunda chamada, com limite fixo e destino final para casos que não passam.
- Comece por um fluxo real, registre cada falha e decida com um critério combinado antes de ampliar.
Por que a saída do modelo quebra o fluxo?
Um LLM gera texto provável, não objetos garantidos. Quando outro sistema espera um objeto com campos e tipos definidos (um CRM, um ERP, uma fila, uma planilha), qualquer desvio vira erro em cadeia. Os desvios mais comuns que vemos descritos e que aparecem em testes de implementação são estes:
- Texto extra em volta do JSON, como uma frase de introdução ou uma cerca de formatação.
- Resposta cortada no meio porque o limite de tokens de saída foi atingido.
- Campo obrigatório ausente ou com nome ligeiramente diferente do combinado.
- Tipo errado, como número entregue em forma de texto ou data em formato inesperado.
- Valor fora da lista permitida, por exemplo uma categoria que não existe no seu cadastro.
- Valor bem formatado, mas inventado: um telefone, um número de pedido ou uma data que o texto de origem não continha.
- Mudança de comportamento depois de trocar a versão do modelo ou editar o prompt.
Os cinco primeiros são falhas de formato e podem ser tratadas com esquema e validação. Os dois últimos exigem mais: checagem contra a origem e testes de regressão. Vale separar os dois grupos, porque as defesas são diferentes.
Esquema, modo JSON ou prompt: o que cada camada garante?
Separando o que é documentação oficial do que é experiência de implementação: os provedores de modelos costumam oferecer mais de um mecanismo, com nomes diferentes. Confirme sempre na documentação do seu provedor o que está disponível e quais são as limitações, porque elas mudam.
- Pedir no prompt: você descreve o formato e inclui exemplos. É a opção mais flexível e a menos garantida. Serve para protótipo e como complemento das outras camadas.
- Modo JSON do provedor: em geral aumenta a chance de a resposta ser JSON sintaticamente válido, mas não garante que os campos e tipos sigam o seu esquema.
- Saída com esquema (muitas vezes chamada de saída estruturada) ou chamada de ferramenta com parâmetros tipados: o provedor restringe a geração a um esquema informado. Costuma aceitar apenas parte da especificação de JSON Schema, então esquemas muito elaborados podem ser rejeitados ou simplificados. Para entender como o modelo preenche argumentos de ferramentas, veja function calling explicado.
- Validação no seu código: roda depois de qualquer um dos três acima. É a única camada que você controla por completo e que conhece as regras do seu negócio.
Mesmo com restrição por esquema, trate como possíveis uma resposta cortada por limite de tokens e uma recusa do modelo, que podem não entregar o objeto completo (confirme o comportamento exato na documentação do provedor). Por isso a validação não é redundante.
Um guia rápido de decisão:
- Se o resultado só é lido por pessoas, o prompt com exemplos basta.
- Se o resultado alimenta outro sistema, use saída com esquema ou ferramenta tipada, quando o provedor oferecer, e valide sempre.
- Se o provedor ou o modelo escolhido não oferece restrição por esquema, use o modo JSON, se existir, mais validação rigorosa e novas tentativas com devolução do erro.
- Se o resultado dispara uma ação com efeito externo (cobrança, cancelamento, envio de mensagem), acrescente aprovação humana ou regras determinísticas antes da execução.
Como desenhar um esquema que o modelo erra menos?
O esquema é parte do prompt. Um desenho ruim aumenta as falhas mesmo com restrição ativa. Algumas práticas que costumam ajudar (experiência de implementação, a validar no seu caso):
- Poucos campos. Peça só o que o próximo sistema realmente consome. Isso também ajuda na minimização de dados prevista na LGPD: se o sistema não precisa do CPF, não peça que o modelo o devolva.
- Valores permitidos explícitos. Use listas fechadas (enum) para categorias, status e prioridades, e mantenha a lista alinhada ao cadastro real.
- Saída para incerteza. Permita valor nulo ou uma opção como não identificado. Sem isso, o modelo tende a preencher algo plausível para cumprir o formato.
- Nomes e descrições claros. Um campo chamado data_preferida_do_cliente com uma descrição curta erra menos que um campo chamado data.
- Pouco aninhamento. Estruturas profundas e listas de tamanho livre aumentam a chance de truncamento e de erro de tipo.
- Formatos fixos para datas, moeda e telefone, descritos no esquema e normalizados depois pelo seu código.
- Versão do esquema. Um campo ou um nome de arquivo com versão permite saber qual contrato cada registro seguiu.
- Separar extrair de decidir. Um passo extrai fatos do texto; outro, determinístico ou revisado, decide o que fazer com eles.
A instrução em linguagem natural também importa. Para ver como escrever instruções que sustentam esse tipo de contrato, leia como escrever o prompt de atendimento com IA. O guia da Anthropic sobre escrever ferramentas eficazes para agentes trata do mesmo princípio: nomes, descrições e parâmetros claros reduzem erros de uso.
O que validar além do formato?
Validar o formato responde se o objeto tem a forma esperada. O que realmente protege o fluxo são as camadas seguintes, em ordem:
- Sintaxe: o texto é JSON completo e interpretável?
- Esquema: campos obrigatórios presentes, tipos corretos, valores dentro da lista permitida?
- Regras de negócio: a data está no futuro quando deveria estar? O valor está dentro de uma faixa aceitável? O identificador existe no cadastro?
- Consistência com a origem: o dado extraído aparece de fato na mensagem, no documento ou no registro de onde veio? Um número de pedido que não consta no texto é sinal de invenção.
- Permissão da ação: mesmo que tudo esteja correto, este fluxo pode executar esta ação neste contexto?
O que falha em qualquer camada não segue adiante. Vai para uma fila de revisão humana, com o motivo registrado. Essa lógica de checar entrada, saída e ação está detalhada em guardrails para agentes de IA.
Há também um ponto de segurança: a saída do modelo é dado não confiável. O OWASP trata o tratamento inadequado de saídas como um risco específico no Top 10 para aplicações com LLM. Na prática, isso significa nunca montar uma consulta ao banco, um comando ou um HTML concatenando diretamente campos devolvidos pelo modelo. Use consultas parametrizadas e escape adequado, como faria com qualquer entrada de usuário.
Quando tentar de novo e quando parar?
Nova tentativa é útil quando a segunda chamada tem chance real de resultar diferente. Não é útil quando o problema está no pedido, no esquema ou nos dados. Uma regra simples de decisão:
- Resposta cortada: tente de novo com mais espaço de saída ou com um pedido mais enxuto, e reveja o esquema se acontecer com frequência.
- JSON inválido ou campo ausente: reenvie a mesma tarefa incluindo a mensagem de erro de validação, de forma curta e objetiva, para o modelo corrigir.
- Valor fora da lista permitida: uma nova tentativa com o erro específico pode funcionar; se repetir, a lista ou a descrição está ambígua.
- Violação de regra de negócio: não repita às cegas. Pode ser dado ruim na origem. Encaminhe para revisão.
- Erro de limite de taxa ou indisponibilidade do provedor: é problema de infraestrutura, não de conteúdo. Use espera progressiva e fila, como descrito em rate limit e queda de API de LLM.
Alguns cuidados que evitam danos ao repetir:
- Limite fixo de tentativas, por exemplo duas ou três, definido por fluxo.
- Destino final claro: depois do limite, o caso vai para uma pessoa ou para um estado de erro visível, nunca é descartado em silêncio.
- Idempotência nas ações. Se a tentativa repetida disparar o mesmo efeito duas vezes (duas cobranças, duas mensagens), o problema é pior que a falha original. O conceito de chave de idempotência está bem explicado na documentação da Stripe sobre requisições idempotentes, que serve de referência mesmo fora de pagamentos.
- Registro de cada tentativa: entrada, esquema, versão do modelo, saída bruta, resultado da validação e motivo da falha. Sem isso não há como melhorar. Cuide de mascarar dados pessoais nesses registros.
Passo a passo para colocar em produção sem surpresas
O método que aplicamos em trabalhos desse tipo segue quatro movimentos: mapear, limitar, pilotar e transferir. Aplicado à saída estruturada, fica assim:
- Mapear: descreva o fluxo atual e identifique quem consome a saída do modelo (sistema, planilha, pessoa) e quais campos esse consumidor realmente usa. Meça como o trabalho é feito hoje, para ter uma linha de base. O passo a passo está em mapeamento de processos antes de aplicar IA.
- Limitar: reduza o esquema ao mínimo necessário, feche as listas de valores, defina quais ações o fluxo pode executar sozinho e quais exigem aprovação.
- Montar um conjunto de casos de teste com entradas comuns, entradas ruins e entradas ambíguas, cada uma com o resultado esperado. A documentação de avaliações da OpenAI descreve a lógica geral de testar saídas de modelos de forma sistemática.
- Pilotar: rode um único fluxo real, com registro de falhas por tipo (sintaxe, esquema, regra, origem) e um critério de sucesso combinado antes de começar. Para escolher métricas e pontos de decisão, veja como medir um piloto de automação com IA.
- Ativar regressão: toda mudança de prompt, esquema ou modelo roda de novo o conjunto de testes antes de ir ao ar.
- Transferir: entregue o esquema versionado, os testes, o painel de falhas e o procedimento para a fila de revisão. Depois, decidir entre ampliar, ajustar ou parar com base nos registros, não na impressão.
Cenário ilustrativo: uma clínica recebe pedidos de remarcação por mensagem e quer que o modelo devolva um objeto com tipo de pedido, data preferida e um identificador do paciente para o sistema de agenda. O esquema aceita só três tipos de pedido, permite data nula e não pede nenhum dado clínico. A validação confere se a data está no futuro e se o identificador existe no cadastro. Se a data vier fora de formato, o sistema reenvia uma vez com o erro de validação. Se o identificador não existir, não há nova tentativa: o caso vai para a recepção com o motivo anotado. A remarcação só é gravada na agenda depois de passar por todas as checagens, e a gravação usa uma chave de idempotência para que uma repetição não duplique o horário. Para o contexto do canal, veja agendamento automático no WhatsApp com IA.
Perguntas frequentes
Qual a diferença entre modo JSON e saída com esquema? O modo JSON, em geral, busca garantir que a resposta seja JSON sintaticamente válido, sem garantir quais campos ela traz. A saída com esquema restringe a geração a uma estrutura que você define, com campos e tipos. Verifique na documentação do seu provedor o que cada modo cobre, e valide no seu código de qualquer forma.
Se o provedor garante o esquema, ainda preciso validar? Sim. O esquema trata da forma, mas não sabe se a data faz sentido, se o cliente existe no seu cadastro ou se o valor foi inventado. Além disso, respostas cortadas ou recusas podem não trazer o objeto completo. A validação com regras de negócio é a sua rede de segurança.
Quantas novas tentativas devo permitir? Poucas, com limite fixo por fluxo, e só para falhas que podem mudar na segunda chamada, como formato inválido ou resposta cortada. Depois do limite, o caso deve ir para uma pessoa ou para um estado de erro visível. Repetir sem parar aumenta custo e latência sem melhorar o resultado.
Como saber se a saída estruturada está boa o bastante para ampliar o uso? Combine antes um critério de sucesso e registre as falhas por tipo durante o piloto, usando um conjunto de casos de teste que inclua entradas difíceis. Se as falhas de formato estão controladas e as de regra e de origem caem para a fila de revisão sem causar dano, a decisão de ampliar tem base. Se os registros mostram problemas recorrentes de esquema ou de dados, ajuste antes de expandir.