Noções Básicas de Saídas Estruturadas
10 exemplos para você começar com Saídas Estruturadas - 7 básicos e 3 intermediários.
Pré-requisitos
- Instale o SDK oficial:
pip install anthropic. - Defina sua chave de API no ambiente:
export ANTHROPIC_API_KEY=sk-ant-.... - Opcional, mas recomendado para definições de schema:
pip install pydantic. - Todos os exemplos abaixo assumem
from anthropic import Anthropiceclient = Anthropic()a menos que mostrado de outra forma.
Exemplos Básicos
1. Uma Requisição Mínima com Schema Restrito
A menor chamada possível de output_config.format - um campo de string, garantido como JSON válido.
from anthropic import Anthropic
client = Anthropic()
response = client.messages.create(
model="claude-sonnet-5",
max_tokens=1024,
output_config={
"format": {
"type": "json_schema",
"schema": {
"type": "object",
"properties": {"greeting": {"type": "string"}},
"required": ["greeting"],
"additionalProperties": False,
},
}
},
messages=[{"role": "user", "content": "Say hello in French."}],
)
print(response.content[0].text)output_config.formaté o que impõe a forma - o prompt em si não precisa de uma instrução "retorne JSON".requiredeadditionalProperties: Falsesão partes necessárias de um schema bem formado, não extras opcionais.- O texto da resposta é garantido como JSON válido correspondente a este schema, mas ainda é uma string - você ainda chama
json.loads()nele aqui.
2. Usando client.messages.parse em Vez de create
Pule a etapa manual de json.loads() usando o helper de análise do SDK.
from anthropic import Anthropic
client = Anthropic()
schema = {
"type": "object",
"properties": {
"language": {"type": "string"},
"greeting": {"type": "string"},
},
"required": ["language", "greeting"],
"additionalProperties": False,
}
response = client.messages.parse(
model="claude-sonnet-5",
max_tokens=1024,
output_config={"format": {"type": "json_schema", "schema": schema}},
messages=[{"role": "user", "content": "Say hello in French."}],
)
print(response.parsed_output)client.messages.parsevalida a resposta contra seu schema e retorna um valor analisado emresponse.parsed_output.- Nenhuma chamada
json.loads()é necessária em nenhum lugar deste trecho. - Este é o ponto de entrada recomendado para a maioria das cargas de trabalho de saída estruturada em Python.
3. Definindo o Schema com um Modelo Pydantic
Use Pydantic para definir a forma de destino uma vez e reutilizá-la tanto para o schema quanto para o tipo de resultado analisado.
from pydantic import BaseModel
from anthropic import Anthropic
class Greeting(BaseModel):
language: str
greeting: str
client = Anthropic()
response = client.messages.parse(
model="claude-sonnet-5",
max_tokens=1024,
output_config={
"format": {"type": "json_schema", "schema": Greeting.model_json_schema()}
},
messages=[{"role": "user", "content": "Say hello in French."}],
)
greeting: Greeting = response.parsed_output
print(greeting.language, greeting.greeting)Greeting.model_json_schema()gera o JSON Schema a partir do modelo Pydantic, então você não o escreve à mão duas vezes.response.parsed_outputaqui é uma instânciaGreetingreal, não um dicionário simples.- Essa combinação (modelo Pydantic +
parse) é o padrão mais comum para extração estruturada em Python.
4. Solicitando um Array de Objetos
Schemas não se limitam a um único objeto plano - solicite uma lista de itens estruturados em uma única chamada.
from anthropic import Anthropic
client = Anthropic()
schema = {
"type": "object",
"properties": {
"todos": {
"type": "array",
"items": {
"type": "object",
"properties": {
"task": {"type": "string"},
"done": {"type": "boolean"},
},
"required": ["task", "done"],
"additionalProperties": False,
},
}
},
"required": ["todos"],
"additionalProperties": False,
}
response = client.messages.parse(
model="claude-sonnet-5",
max_tokens=1024,
output_config={"format": {"type": "json_schema", "schema": schema}},
messages=[{"role": "user", "content": "Give me 3 sample todo items."}],
)
for item in response.parsed_output["todos"]:
print(item["task"], item["done"])- A resposta de nível superior ainda é um único objeto JSON - envolva arrays em um campo nomeado em vez de retornar um array puro.
- Cada objeto aninhado precisa de seu próprio
requiredeadditionalProperties: False, não apenas o externo. - Este padrão é comum para tarefas de extração do tipo "me dê N itens".
5. Usando um Enum para Restringir os Valores de um Campo
Restrinja um campo a um conjunto fixo de valores em vez de aceitar qualquer string.
from anthropic import Anthropic
client = Anthropic()
schema = {
"type": "object",
"properties": {
"sentiment": {"type": "string", "enum": ["positive", "neutral", "negative"]},
},
"required": ["sentiment"],
"additionalProperties": False,
}
response = client.messages.parse(
model="claude-sonnet-5",
max_tokens=1024,
output_config={"format": {"type": "json_schema", "schema": schema}},
messages=[{"role": "user", "content": "Classify: 'This product exceeded my expectations!'"}],
)
print(response.parsed_output["sentiment"])enumgarante que o valor retornado seja uma das strings listadas - nenhuma validação posterior de texto livre é necessária.- Este é o padrão padrão para respostas do tipo classificação.
- Enums são uma das construções bem suportadas - verifique a referência de tipos de campo antes de confiar em palavras-chave de schema menos comuns.
6. Verificando stop_reason Antes de Confiar na Saída
Sempre confirme se a resposta realmente terminou antes de tratá-la como JSON completo.
from anthropic import Anthropic
client = Anthropic()
response = client.messages.create(
model="claude-sonnet-5",
max_tokens=256,
output_config={
"format": {
"type": "json_schema",
"schema": {
"type": "object",
"properties": {"summary": {"type": "string"}},
"required": ["summary"],
"additionalProperties": False,
},
}
},
messages=[{"role": "user", "content": "Summarize the plot of a 300-page novel in detail."}],
)
if response.stop_reason == "max_tokens":
print("Response was truncated - retry with a larger max_tokens.")
else:
print(response.content[0].text)stop_reason == "max_tokens"significa que o modelo ficou sem espaço antes de terminar - o JSON pode estar cortado no meio da estrutura.- Uma garantia de schema só é válida para uma resposta que realmente completou a geração.
- Verificar
stop_reasonantes de analisar é um seguro barato contra umJSONDecodeErrorconfuso posteriormente.
7. Definindo um max_tokens Generoso Antecipadamente
Reduza o risco de truncamento para respostas estruturadas maiores dimensionando max_tokens para a saída esperada.
from anthropic import Anthropic
client = Anthropic()
schema = {
"type": "object",
"properties": {
"bullet_points": {"type": "array", "items": {"type": "string"}},
},
"required": ["bullet_points"],
"additionalProperties": False,
}
response = client.messages.parse(
model="claude-sonnet-5",
max_tokens=4096, # generous headroom for a multi-item array response
output_config={"format": {"type": "json_schema", "schema": schema}},
messages=[{"role": "user", "content": "List 10 detailed release notes for a v2.0 launch."}],
)
print(response.parsed_output["bullet_points"])- Campos maiores ou mais numerosos precisam de mais margem de
max_tokensdo que uma única string curta. - Um
max_tokensmuito apertado é a causa mais comum de saída estruturada truncada na prática. - Esta é uma heurística inicial, não uma garantia - combine-a com a verificação de
stop_reasondo Exemplo 6 em código de produção.
Exemplos Intermediários
8. Um Schema de Extração com Múltiplos Campos e Objetos Aninhados
Combine múltiplos tipos de campo, incluindo um objeto aninhado, em um único schema de extração.
from pydantic import BaseModel
from anthropic import Anthropic
class Address(BaseModel):
city: str
country: str
class Contact(BaseModel):
name: str
email: str
is_customer: bool
address: Address
client = Anthropic()
response = client.messages.parse(
model="claude-sonnet-5",
max_tokens=1024,
output_config={"format": {"type": "json_schema", "schema": Contact.model_json_schema()}},
messages=[{
"role": "user",
"content": (
"Extract contact info: Jane Doe, jane@example.com, existing "
"customer, lives in Austin, USA."
),
}],
)
contact: Contact = response.parsed_output
print(contact.name, contact.address.city)- Modelos Pydantic podem ser aninhados uns dentro dos outros, e
model_json_schema()os achata em entradas$ref/$defque a API entende. response.parsed_outputretorna um objetoContacttotalmente aninhado e tipado - incluindo oAddressaninhado.- Schemas aninhados são suportados, mas aninhamento muito profundo ou recursivo não é - mantenha as estruturas rasas para confiabilidade.
9. Tentando Novamente em Caso de Truncamento com um Limite Maior de Tokens
Detecte uma resposta estruturada truncada e tente novamente com mais espaço.
from anthropic import Anthropic
client = Anthropic()
schema = {
"type": "object",
"properties": {"report": {"type": "string"}},
"required": ["report"],
"additionalProperties": False,
}
def get_report(max_tokens: int = 512) -> str:
response = client.messages.create(
model="claude-sonnet-5",
max_tokens=max_tokens,
output_config={"format": {"type": "json_schema", "schema": schema}},
messages=[{"role": "user", "content": "Write a detailed incident report."}],
)
if response.stop_reason == "max_tokens" and max_tokens < 4096:
return get_report(max_tokens=max_tokens * 2)
return response.content[0].text
print(get_report())- A nova tentativa dobra
max_tokensa cada vez, limitada por um teto, em vez de tentar indefinidamente. - Este padrão pertence a qualquer lugar onde o tamanho de uma resposta estruturada seja difícil de prever com antecedência.
- Veja a página dedicada de tratamento de truncamento para uma versão mais completa e pronta para produção deste padrão.
10. Saída Estruturada Combinada com uma Definição de Ferramenta Estrita
Combine output_config.format com strict: true em uma ferramenta para que tanto a resposta final quanto quaisquer parâmetros de chamada de ferramenta sejam garantidos como válidos.
from anthropic import Anthropic
client = Anthropic()
tools = [{
"name": "log_ticket",
"description": "Log a support ticket in the tracking system.",
"strict": True,
"input_schema": {
"type": "object",
"properties": {
"priority": {"type": "string", "enum": ["low", "medium", "high"]},
"summary": {"type": "string"},
},
"required": ["priority", "summary"],
"additionalProperties": False,
},
}]
response = client.messages.create(
model="claude-sonnet-5",
max_tokens=1024,
tools=tools,
messages=[{"role": "user", "content": "Server is down, customers can't check out. Log this."}],
)
for block in response.content:
if block.type == "tool_use":
print(block.input) # guaranteed to match the strict input_schemastrict: Trueem uma definição de ferramenta é o equivalente de uso de ferramenta deoutput_config.formatem uma resposta de mensagem.- Ambos os recursos podem ser usados na mesma solicitação quando um fluxo de trabalho precisa de uma resposta final validada e parâmetros de ferramenta validados.
- Schemas
strictseguem as mesmas regras derequired/additionalProperties: falseque os schemasoutput_config.format.
Versões da Stack: Escrito contra a linha de modelos Claude atual em aproximadamente 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.