Comparação de saída estruturada entre provedores populares de LLMs: OpenAI, Gemini, Anthropic, Mistral e AWS Bedrock
APIs ligeiramente diferentes exigem uma abordagem especial.
Aqui está uma comparação lado a lado do suporte a saída estruturada (obter JSON confiável) entre os principais provedores de LLM, com exemplos mínimos em Python

Já analisamos como solicitar saída estruturada do LLM hospedado no Ollama. Uma vez que o JSON está disponível na resposta, validação de saída estruturada de LLM em Python que é robusta percorre a análise, verificações do Pydantic, tentativas novamente e testes no seu serviço. Aqui revisamos como solicitar o mesmo de outros provedores.
Matriz TL;DR
| Provedor | Modo “JSON” Nativo | Aplicação de Schema JSON | Parâmetro Típico | Observações |
|---|---|---|---|---|
| OpenAI | Sim | Sim (nativo) | response_format={"type":"json_schema", ...} |
Funciona via API de Respostas ou Chat Completions; também pode usar chamadas de função. |
| Google Gemini | Sim | Sim (nativo) | response_schema= + response_mime_type="application/json" |
Retorna JSON estritamente validado quando o schema está definido. |
| Anthropic (Claude) | Indireto | Sim (via Uso de Ferramenta com schema JSON) | tools=[{input_schema=...}] + tool_choice |
Força o modelo a “chamar” sua ferramenta definida por schema; gera argumentos com formato de schema. |
| Mistral | Sim | Parcial (apenas JSON; sem schema no servidor) | response_format={"type":"json_object"} |
Garante JSON, mas você valida contra seu schema no lado do cliente. |
| AWS Bedrock (plataforma) | Varia conforme o modelo | Sim (via schema de Ferramenta/Converse) | toolConfig.tools[].toolSpec.inputSchema |
A API Converse do Bedrock valida a entrada da ferramenta contra um schema JSON. |
Saída Estruturada de LLM - Informações Gerais
A saída estruturada de LLM refere-se à capacidade de grandes modelos de linguagem (LLMs) de gerar respostas que aderem estritamente a um formato ou estrutura predefinida, em vez de produzir texto livre. Essa saída estruturada pode estar em formatos como JSON, XML, tabelas ou modelos, tornando os dados legíveis por máquina, consistentes e facilmente analisáveis por software para uso em várias aplicações.
As saídas estruturadas diferem das saídas tradicionais de LLM, que tipicamente geram texto de linguagem natural aberto. Em vez disso, as saídas estruturadas impõem um schema ou formato, como objetos JSON com chaves e tipos de valores definidos, ou classes específicas na saída (por exemplo, respostas de múltipla escolha, classes de sentimento ou formatos de linhas de banco de dados). Esta abordagem melhora a confiabilidade, reduz erros e alucinações, e simplifica a integração em sistemas como bancos de dados, APIs ou fluxos de trabalho.
A geração de saídas estruturadas em LLMs geralmente envolve técnicas como:
- Especificar instruções detalhadas no prompt para orientar o modelo a produzir a saída no formato desejado.
- Usar ferramentas de validação e análise como Pydantic em Python para garantir que a saída corresponda ao schema.
- Às vezes, impor restrições de decodificação baseadas em gramática ou máquinas de estados finitos para garantir conformidade no nível de token com o formato.
Os benefícios das saídas estruturadas de LLM incluem:
- Legibilidade por máquina e facilidade de integração.
- Redução de variabilidade e erros.
- Melhoria na previsibilidade e verificabilidade para tarefas que exigem formatos de dados consistentes.
Os desafios incluem o design de schemas eficazes, o tratamento de dados aninhados complexos e limitações potenciais nas capacidades de raciocínio em comparação com a geração de texto livre.
No geral, a saída estruturada permite que os LLMs sejam mais úteis em aplicações que exigem dados precisos e formatados, em vez de apenas texto legível por humanos.
Exemplos de Saída Estruturada em Python
Todos os trechos extraem informações do evento como JSON: {title, date, location}. Substitua chaves/modelos conforme desejar.
1) OpenAI — JSON Schema (estrito)
from openai import OpenAI
import json
client = OpenAI()
schema = {
"name": "Event",
"schema": {
"type": "object",
"properties": {
"title": {"type": "string"},
"date": {"type": "string", "description": "AAAA-MM-DD"},
"location": {"type": "string"}
},
"required": ["title", "date", "location"],
"additionalProperties": False
},
"strict": True
}
resp = client.chat.completions.create(
model="gpt-4o-mini",
messages=[
{"role": "user", "content": "Extraia o evento de: 'PyData Sydney é em 2025-11-03 no Darling Harbour.'"}
],
response_format={"type": "json_schema", "json_schema": schema},
)
data = json.loads(resp.choices[0].message.content)
print(data)
O recurso Structured Outputs do OpenAI aplica este schema no lado do servidor.
2) Google Gemini — schema de resposta + MIME JSON
import google.generativeai as genai
from google.genai import types
# Configure com sua chave de API
# genai.configure(api_key="sua-chave-de-api")
schema = types.Schema(
type=types.Type.OBJECT,
properties={
"title": types.Schema(type=types.Type.STRING),
"date": types.Schema(type=types.Type.STRING),
"location": types.Schema(type=types.Type.STRING),
},
required=["title", "date", "location"],
additional_properties=False,
)
resp = genai.generate_content(
model="gemini-2.0-flash",
contents="Extraia o evento de: 'PyData Sydney é em 2025-11-03 no Darling Harbour.'",
generation_config=genai.GenerationConfig(
response_mime_type="application/json",
response_schema=schema,
),
)
print(resp.text) # já é JSON válido conforme o schema
O Gemini retornará JSON estrito que conforma com response_schema.
3) Anthropic (Claude) — Uso de Ferramenta com schema JSON
from anthropic import Anthropic
import json
client = Anthropic()
tool = {
"name": "extract_event",
"description": "Retorna detalhes do evento.",
"input_schema": {
"type": "object",
"properties": {
"title": {"type": "string"},
"date": {"type": "string"},
"location": {"type": "string"}
},
"required": ["title", "date", "location"],
"additionalProperties": False
}
}
msg = client.messages.create(
model="claude-3-5-sonnet-20241022",
max_tokens=256,
tools=[tool],
tool_choice={"type": "tool", "name": "extract_event"}, # força schema
messages=[{"role": "user", "content":
"Extraia o evento de: 'PyData Sydney é em 2025-11-03 no Darling Harbour.'"}],
)
# O Claude irá "chamar" a ferramenta; pegue os argumentos (que correspondem ao seu schema)
tool_use = next(b for b in msg.content if b.type == "tool_use")
print(json.dumps(tool_use.input, indent=2))
O Claude não tem um interruptor genérico de “modo JSON”; em vez disso, o Uso de Ferramenta com um input_schema fornece argumentos validados com formato de schema (e você pode forçar seu uso).
4) Mistral — modo JSON (validação no lado do cliente)
from mistralai import Mistral
import json
client = Mistral()
resp = client.chat.complete(
model="mistral-large-latest",
messages=[{"role":"user","content":
"Retorne JSON com chaves title, date (AAAA-MM-DD), location para: "
"'PyData Sydney é em 2025-11-03 no Darling Harbour.'"}],
response_format={"type": "json_object"} # garante JSON válido
)
data = json.loads(resp.choices[0].message.content)
print(data)
# Dica: valide `data` contra seu Pydantic/JSON Schema localmente.
O json_object do Mistral impõe a estrutura JSON (não seu schema exato) — valide no lado do cliente.
5) AWS Bedrock — schema de Ferramenta da API Converse (agnóstico ao modelo)
import boto3, json
bedrock = boto3.client("bedrock-runtime", region_name="us-east-1")
model_id = "anthropic.claude-3-5-sonnet-20240620-v1:0"
tools = [{
"toolSpec": {
"name": "extract_event",
"inputSchema": {
"json": {
"type": "object",
"properties": {
"title": {"type": "string"},
"date": {"type": "string"},
"location": {"type": "string"}
},
"required": ["title","date","location"],
"additionalProperties": False
}
}
}
}]
resp = bedrock.converse(
modelId=model_id,
toolConfig={"tools": tools},
toolChoice={"tool": {"name": "extract_event"}}, # força schema
messages=[{"role":"user","content":[{"text":
"Extraia o evento de: 'PyData Sydney é em 2025-11-03 no Darling Harbour.'"}]}],
)
# Extraia o conteúdo toolUse
tool_use = next(
c["toolUse"] for c in resp["output"]["message"]["content"] if "toolUse" in c
)
print(json.dumps(tool_use["input"], indent=2))
O Bedrock valida a entrada da ferramenta contra seu schema JSON e muitos modelos hospedados (por exemplo, Claude) suportam isso através do Converse.
Orientação prática e Validação
- Se você deseja as garantias mais fortes no lado do servidor: Saídas estruturadas do OpenAI ou schema de resposta do Gemini.
- Se você já usa Claude/Bedrock: defina uma Ferramenta com um schema JSON e force seu uso; leia os argumentos da ferramenta como seu objeto tipado.
- Se você usa Mistral: ative
json_objecte valide localmente (por exemplo, com Pydantic).
Padrão de validação (funciona para todos)
from pydantic import BaseModel, ValidationError
class Event(BaseModel):
title: str
date: str
location: str
try:
event = Event.model_validate(data) # `data` de qualquer provedor
except ValidationError as e:
# lidar / tentar novamente / pedir ao modelo para corrigir com e.errors()
print(e)
Links úteis
- https://platform.openai.com/docs/guides/structured-outputs
- https://ai.google.dev/gemini-api/docs/structured-output
- https://docs.mistral.ai/capabilities/structured-output/json_mode/
- https://aws.amazon.com/blogs/machine-learning/structured-data-response-with-amazon-bedrock-prompt-engineering-and-tool-use
- https://github.com/aws-samples/anthropic-on-aws/blob/main/complex-schema-tool-use/README.md
- https://docs.aws.amazon.com/bedrock/latest/userguide/model-parameters-anthropic-claude-messages.html
- Como Solicitar Saída Estruturada do LLM hospedado no Ollama
- Cheat sheet de Python
- AWS SAM + AWS SQS + Python PowerTools
- Comparação de desempenho do AWS lambda: JavaScript vs Python vs Golang