Por que Saídas Estruturadas Superam a Formatação de JSON Baseada em Prompt
Todo desenvolvedor que integrou um LLM em um pipeline já escreveu um prompt como "responda apenas com JSON válido, sem nenhum outro texto."
Busque em todas as páginas da documentação
Todo desenvolvedor que integrou um LLM em um pipeline já escreveu um prompt como "responda apenas com JSON válido, sem nenhum outro texto."
Essa instrução geralmente funciona.
"Geralmente" é o problema.
Saídas estruturadas resolvem isso movendo a garantia de JSON do prompt para a própria requisição da API, usando um parâmetro chamado output_config.format. Em vez de pedir gentilmente ao Claude para formatar sua resposta de uma certa maneira, você declara a forma exata que requer, e a API restringe a geração para que a resposta a conforme. Esta página explica por que essa distinção importa, o que muda na forma como você constrói com a API Claude depois de confiar nela, e onde suas garantias param.
output_config.format restringe a resposta do Claude no momento da geração para corresponder a um JSON Schema que você fornece, em vez de depender da redação do prompt para solicitar JSON.max_tokens antes que o JSON seja fechado.Antes que as saídas estruturadas existissem como um recurso em nível de requisição, o padrão padrão para obter JSON de um LLM era inteiramente baseado em prompt.
Você escrevia um prompt de sistema instruindo o modelo a "apenas gerar JSON válido correspondendo a esta forma", talvez incluísse um exemplo, e então analisava qualquer texto que voltasse com json.loads().
Isso funciona na maioria das vezes, que é exatamente por que é arriscado.
O modelo está gerando texto token por token, e "responda apenas com JSON" é uma preferência que ele geralmente honra, não uma regra que ele não pode quebrar.
Sob certas entradas, especialmente conversas mais longas, instruções ambíguas ou dados de casos de borda, o modelo pode adicionar uma explicação de uma linha antes do JSON, envolver o objeto em um bloco de código markdown, usar um nome de campo que é próximo, mas não exatamente o que você pediu, ou deixar um valor de fora inteiramente.
Cada uma dessas saídas ainda "parece" que o modelo tentou cooperar, mas cada uma delas quebra uma chamada json.loads() ingênua.
Saídas estruturadas invertem essa relação.
Em vez de descrever a forma desejada em prosa, você a descreve com um JSON Schema, uma especificação legível por máquina da forma exata de campos, tipos e propriedades exigidas que sua resposta deve ter.
Você passa esse schema no campo output_config.format da sua requisição, e a API restringe o próprio processo de geração para que o conteúdo retornado se conforme ao schema.
O prompt não está mais fazendo o trabalho de imposição.
Um modelo mental simples: formatação baseada em prompt é como pedir a um colega para preencher um formulário corretamente descrevendo o formulário para ele em palavras. Saídas estruturadas é como entregar o formulário real para ele, com campos que só aceitam o tipo certo de entrada. Um depende de interpretação; o outro restringe o espaço de respostas possíveis antes que a geração ocorra.
from anthropic import Anthropic
client = Anthropic()
schema = {
"type": "object",
"properties": {
"name": {"type": "string"},
"is_urgent": {"type": "boolean"},
},
"required": ["name", "is_urgent"],
"additionalProperties": False,
}
response = client.messages.create(
model="claude-sonnet-5",
max_tokens=1024,
output_config={"format": {"type": "json_schema", "schema": schema}},
messages=[{"role": "user", "content": "Extraia o assunto do ticket e a urgência."}],
)Note o que está faltando no prompt: nenhum "responda apenas com JSON", nenhuma instrução de formatação, nenhum exemplo de saída. O schema faz esse trabalho.
A diferença prática entre as duas abordagens se mostra mais claramente em como as falhas se comportam.
Com JSON baseado em prompt, uma falha é uma falha completa de análise. Seu código chama json.loads() em uma string que pode conter texto introdutório, comentário final, ou um bloco de markdown, e se qualquer um desses estiver presente, a análise falha e você não tem nada utilizável. Você está então no negócio de escrever lógica defensiva de remoção de strings: regex para encontrar o primeiro { e o último }, remover blocos ```json, capturar e tentar novamente em JSONDecodeError. Esse código defensivo é um imposto que você paga em cada integração, para sempre, porque a garantia subjacente nunca melhorou - você apenas ficou melhor em limpar depois dela.
Com output_config.format, a restrição é aplicada durante a geração, não depois dela. A API está impondo o schema token por token à medida que a resposta é produzida, então uma resposta bem-sucedida é válida de acordo com o schema por construção, não por sorte. Isso remove uma categoria inteira de bugs de análise do seu código, porque não há mais um resultado de "o modelo quase acertou" para lidar - a resposta ou satisfaz o schema, ou algo mais aconteceu (truncamento, recusa, ou um erro genuíno da API) e você lida com isso como sua própria condição distinta e detectável em vez de texto ruidoso.
É aqui que o helper de nível superior do SDK Python também importa. client.messages.create(...) ainda retorna o conteúdo bruto da resposta que você extrairia e desserializaria. client.messages.parse(...) vai um passo adiante: ele retorna um objeto já validado e já analisado, comumente suportado por um modelo Pydantic que você define junto com o schema. A distinção é a mesma de output_config.format em si - mover o trabalho de "escrever código para verificar isso" para "deixar o framework garantir isso".
from pydantic import BaseModel
from anthropic import Anthropic
class Ticket(BaseModel):
name: str
is_urgent: bool
client = Anthropic()
response = client.messages.parse(
model="claude-sonnet-5",
max_tokens=1024,
output_config={"format": {"type": "json_schema", "schema": Ticket.model_json_schema()}},
messages=[{"role": "user", "content": "Ticket: servidor caiu, por favor ajude rápido!"}],
)
ticket = response.parsed_output # uma instância Ticket validada, não uma string brutaHá uma sutileza que vale a pena internalizar aqui: a imposição do schema acontece na camada da API, mas não é mágica que apaga todos os modos de falha. Duas condições ainda exigem seu próprio tratamento. Primeiro, a resposta pode ser truncada se atingir max_tokens antes que o objeto JSON seja fechado - o texto parcial não será um JSON válido, mesmo que a API estivesse tentando fielmente seguir seu schema. Segundo, nem toda construção que você pode querer expressar em JSON Schema é suportada pelo motor de imposição da API; existem limites em tipos de campo, tratamento de enum e certas restrições de schema, o que significa que o próprio design do schema se torna uma habilidade com seu próprio material de referência (veja Relacionados abaixo) em vez de "apenas escreva qualquer JSON Schema que você quiser".
Uma vez que você confia em saídas estruturadas, a forma do seu código de integração muda de uma maneira que se acumula em uma base de código, não apenas em uma única requisição.
A formatação de JSON baseada em prompt empurra a lógica de validação para downstream e a duplica: cada local de chamada que espera JSON de volta precisa de sua própria análise, seu próprio tratamento de erros, sua própria verificação "o modelo realmente seguiu as instruções desta vez". Saídas estruturadas centralizam essa garantia na definição do schema. Mude o schema uma vez, e cada resposta que o usa é validada da mesma forma, pela mesma camada de imposição, com os mesmos modos de falha.
Isso importa mais exatamente nos lugares onde o JSON baseado em prompt é mais arriscado: pipelines de produção com volume, onde uma taxa de falha de análise de baixa porcentagem de um dígito é invisível em testes, mas cara em escala; e sistemas downstream (bancos de dados, outros serviços, componentes de UI) que falharão ou corromperão o estado com entrada malformada em vez de apenas exibir uma string feia para um humano.
Vale a pena ser preciso sobre o que "garantia" significa aqui, no entanto. output_config.format garante que a resposta, se gerada com sucesso, esteja em conformidade com seu schema. Não garante que a resposta seja correta no sentido de ser factualmente certa ou completa - o modelo ainda pode colocar um valor plausível, mas errado, em um campo corretamente tipado. Saídas estruturadas resolvem um problema de confiabilidade sintática, não um problema de precisão semântica. Você ainda precisa de suas próprias verificações de correção, revisão humana ou verificações downstream; você apenas não precisa mais se defender contra sintaxe malformada em cima disso.
| Abordagem | Força | Fraqueza | Melhor Ajuste |
|---|---|---|---|
| Requisição de JSON baseada em prompt | Nenhuma superfície de API para aprender, funciona com qualquer modelo | Probabilístico; saída malformada requer análise defensiva e retentativas | Protótipos rápidos, uso manual de baixo volume |
output_config.format (bruto) | Garante JSON válido de acordo com o schema no nível da API | Você ainda analisa o texto retornado sozinho | Quando você quer a garantia, mas não um objeto tipado |
client.messages.parse() com Pydantic | Schema garantido e um objeto tipado validado em uma chamada | Requer a definição de modelos Pydantic; camada de conveniência específica do SDK Python | A maioria das integrações Python de produção que extraem dados estruturados |
max_tokens antes que o modelo termine de escrever o JSON, o que retorna é uma string incompleta, mesmo que o modelo estivesse cooperando com o schema durante todo o tempo em que estava gerando.output_config) nas mesmas chamadas messages.create() / messages.parse() que você já usa.client.messages.create() ainda retorna o conteúdo da resposta como texto; a garantia é que o texto é um JSON válido de acordo com o schema, não que já está desserializado.client.messages.parse() em vez disso se você quiser um objeto já analisado e validado de volta.create() retorna a resposta bruta; você extrai o conteúdo de texto e o analisa sozinho.parse() valida a resposta contra seu schema (frequentemente um modelo Pydantic) e retorna um objeto analisado pronto para uso.max_tokens antes que o objeto JSON seja fechado, o que trunca a saída no meio da estrutura.output_config.format restringe a resposta da mensagem inteira em si, independentemente de qualquer ferramenta estar envolvida ou não - e os dois podem ser combinados para que tanto a resposta quanto quaisquer parâmetros de chamada de ferramenta sejam garantidos como válidos.client.messages.create().client.messages.parse() porque Model.model_json_schema() gera o schema para você e você obtém uma instância validada de volta.output_config.format é o que impõe a forma.Versões de Stack: Escrito contra a linha de modelos Claude atual a partir de ~junho de 2026 - Claude Fable 5, Claude Opus 4.8, Claude Sonnet 5 (o padrão), e Claude Haiku 4.5 - e o SDK oficial
anthropicpara Python (última versão 0.x). Nomes de modelos, versões de SDK e preços mudam rapidamente - verifique os detalhes atuais em platform.claude.com/docs antes de confiar neles.
Revisado por Chris St. John·Última atualização: 15 de jul. de 2026