Saídas Estruturadas para Modelos Anthropic Claude no Amazon Bedrock

O que mudou no Amazon Bedrock

A AWS anunciou suporte nativo a saídas estruturadas para todos os modelos Anthropic Claude disponíveis no Amazon Bedrock. O recurso funciona tanto no endpoint bedrock-runtime — acessado via Boto3 e APIs do Bedrock — quanto no endpoint bedrock-mantle, utilizado pela Messages API. Em ambos os casos, as respostas do modelo passam a ser Notação de Objeto JavaScript (JSON) rigorosamente compatíveis com o esquema definido pela aplicação.

Na prática, isso significa que desenvolvedores não precisam mais escrever código de validação, lógica de retentativa por falha de parsing ou pós-processamento para garantir que o modelo retornou os campos esperados. A conformidade com o esquema é garantida durante a própria geração dos tokens.

Como funciona a geração com restrições

A diferença fundamental em relação à abordagem anterior está em quando a conformidade é aplicada. Antes, a validação acontecia depois que o modelo já havia gerado a resposta — um processo probabilístico que podia falhar. Agora, o Amazon Bedrock utiliza decodificação restrita: o modelo simplesmente não produz tokens que violem o esquema fornecido. A geração de saída deixa de ser probabilística e passa a ser determinística em relação à estrutura.

O fluxo interno funciona assim:

  • Validação do esquema: o Amazon Bedrock valida o esquema JSON fornecido contra o subconjunto suportado do JSON Schema Draft 2020-12.
  • Compilação de gramática: para esquemas novos, o serviço compila um artefato de gramática. A primeira requisição pode ser ligeiramente mais lenta por conta dessa etapa.
  • Cache de gramática: gramáticas compiladas ficam em cache por 24 horas, tornando requisições subsequentes mais rápidas. O cache é por conta AWS e é invalidado apenas quando a estrutura do esquema muda — alterações em nomes ou descrições de campos não invalidam o cache.
  • Geração restrita: o modelo gera tokens que produzem JSON válido conforme o esquema.

Dois mecanismos complementares

A AWS disponibilizou dois mecanismos que cobrem cenários distintos:

  • Formato de saída JSON Schema: controla a estrutura da resposta do modelo. Indicado para extração de dados, geração de relatórios e respostas de Interface de Programação de Aplicação (API).
  • Uso estrito de ferramentas (strict tool use): valida parâmetros de ferramentas contra esquemas no momento da geração. Indicado para fluxos agênticos, chamadas de função e automações de múltiplas etapas.

O que isso significa para quem desenvolve

Com saídas estruturadas, cada resposta é um JSON válido — sem erros de JSON.parse() ou exceções de parsing. Os tipos de campo são respeitados, campos obrigatórios estão sempre presentes e o modelo não adiciona campos fora do esquema. Isso traz três ganhos diretos:

  • Confiabilidade: não é mais necessário fazer retentativas para lidar com violações de esquema.
  • Segurança de tipos: a integração com bancos de dados, sistemas de CRM ou outras APIs é mais segura porque os tipos dos campos são garantidos.
  • Redução de custos: ao restringir as respostas apenas aos campos definidos, o número de tokens de saída cai — o que pode reduzir custos de inferência em cargas de trabalho de alto volume.

Disponibilidade e compatibilidade

O recurso é compatível com inferência em lote (batch inference), permitindo processar grandes volumes de requisições de forma assíncrona com saídas conformes ao esquema. No endpoint bedrock-runtime, também funciona com inferência entre regiões (cross-Region inference), sem necessidade de configuração adicional. Para quem precisa de respostas em tempo real, é possível transmitir respostas estruturadas como eventos tipados via streaming.

Exemplo prático: extração de dados com a API InvokeModel

O exemplo abaixo, retirado do post original da AWS, demonstra como extrair dados estruturados de um e-mail de cliente usando Boto3 com um modelo Claude:

import boto3
import json

REGION = "us-east-1"  # Choose your preferred region
bedrock_runtime = boto3.client(service_name="bedrock-runtime", region_name=REGION)

# Define the JSON schema for structured output
schema = {
    "type": "object",
    "properties": {
        "name": {"type": "string", "description": "Customer name"},
        "email": {"type": "string", "description": "Customer email address"},
        "plan_interest": {"type": "string", "description": "Product plan of interest"},
        "demo_requested": {"type": "boolean", "description": "Whether a demo was requested"}
    },
    "required": ["name", "email", "plan_interest", "demo_requested"],
    "additionalProperties": False
}

# Make a request with structured outputs via the InvokeModel API
# (reusing the schema defined for the Converse example)
response = bedrock_runtime.invoke_model(
    modelId="global.anthropic.claude-sonnet-5-5",
    body=json.dumps({
        "anthropic_version": "bedrock-2023-05-31",
        "max_tokens": 512,
        "messages": [
            {"role": "user", "content": (
                "Paulo Santos (paulo@example.com) is interested in our Enterprise plan "
                "and wants to schedule a demo for next Tuesday at 2pm."
            )}
        ],
        "output_config": {"format": {"type": "json_schema", "schema": schema}}
    })
)

body = json.loads(response["body"].read())

# Check the stop reason before parsing
if body["stop_reason"] == "end_turn":
    result_text = next(b["text"] for b in body["content"] if b["type"] == "text")
    print(json.dumps(json.loads(result_text), indent=2))
elif body["stop_reason"] == "max_tokens":
    print("Response truncated: increase max_tokens and retry.")

A saída retornada pelo modelo seria:

{
  "name": "Paulo Santos",
  "email": "paulo@example.com",
  "plan_interest": "Enterprise",
  "demo_requested": true
}

Nenhuma validação adicional é necessária. Para mais exemplos de uso da API, incluindo a Messages API, a AWS disponibilizou um notebook de exemplo no GitHub.

Uso estrito de ferramentas para fluxos agênticos

O Amazon Bedrock Mantle é voltado para aplicações agênticas com ferramentas do lado do servidor, inferência em segundo plano e conversas com estado. Com o uso estrito de ferramentas no endpoint bedrock-mantle, é possível garantir que os parâmetros das ferramentas correspondam exatamente ao esquema de entrada definido.

O exemplo abaixo mostra como definir uma ferramenta com aplicação estrita de esquema:

import json
from anthropic import AnthropicBedrockMantle

# Reusing the client created in the Messages API example
client = AnthropicBedrockMantle(aws_region="us-east-1")

message = client.messages.create(
    model="anthropic.claude-sonnet-5",
    max_tokens=512,
    messages=[{"role": "user", "content": "What's the weather like in San Francisco?"}],
    tools=[
        {
            "name": "get_weather",
            "description": "Get the current weather for a specified location",
            "strict": True,
            "input_schema": {
                "type": "object",
                "properties": {
                    "location": {
                        "type": "string",
                        "description": "The city and state, e.g., San Francisco, CA"
                    },
                    "unit": {
                        "type": "string",
                        "enum": ["celsius", "fahrenheit"],
                        "description": "Temperature unit"
                    }
                },
                "required": ["location", "unit"],
                "additionalProperties": False
            }
        }
    ]
)

# Tool inputs conform to the schema
for block in message.content:
    if block.type == "tool_use":
        print(f"Tool: {block.name}")
        print(f"Input: {json.dumps(block.input, indent=2)}")

Com strict: true, o campo location será sempre uma string e unit será sempre celsius ou fahrenheit. O modelo não pode adicionar campos fora do esquema. Isso é especialmente valioso em casos de uso agênticos no Amazon Bedrock Mantle, onde os modelos orquestram fluxos de múltiplas etapas com ferramentas do servidor como busca na web e interpretador de código.

Principais casos de uso

A AWS destaca três padrões onde as saídas estruturadas reduzem mais a complexidade de tratamento de erros:

  • Extração de dados: extrair campos de notas fiscais, contratos, e-mails e transcrições em JSON pronto para ser carregado em bancos de dados ou sistemas de Gestão de Relacionamento com o Cliente (CRM).
  • Chamadas de ferramentas confiáveis em agentes: validar argumentos de ferramentas contra seus esquemas no momento da geração, para que fluxos agênticos de múltiplas etapas rodem sem falhas por entrada malformada.
  • Classificação em escala: classificar tickets, leads ou conteúdo por intenção, prioridade e sentimento para roteamento, moderação e avaliação.

O exemplo abaixo, também do post original, mostra como classificar e rotear tickets de suporte usando o modelo Claude Haiku 5.5:

import boto3
import json

REGION = "us-east-1"  # Choose your preferred region
bedrock_runtime = boto3.client(service_name="bedrock-runtime", region_name=REGION)

# Classification schema: enums restrict output to a fixed set of labels
schema = {
    "type": "object",
    "properties": {
        "category": {
            "type": "string",
            "enum": ["billing", "technical", "account", "sales", "other"],
            "description": "Primary ticket category"
        },
        "priority": {
            "type": "string",
            "enum": ["low", "medium", "high", "urgent"],
            "description": "Urgency based on business impact"
        },
        "sentiment": {
            "type": "string",
            "enum": ["positive", "neutral", "negative"],
            "description": "Customer sentiment"
        },
        "escalate": {"type": "boolean", "description": "Whether a human should review immediately"},
        "reason": {"type": "string", "description": "One-sentence justification for the classification"}
    },
    "required": ["category", "priority", "sentiment", "escalate", "reason"],
    "additionalProperties": False
}

ticket = (
    "Our production API calls have been failing with 500 errors since this morning. "
    "We're losing orders every minute. This is the second outage this month!"
)

# Make a request with structured outputs via the InvokeModel API
response = bedrock_runtime.invoke_model(
    modelId="global.anthropic.claude-haiku-5-5",
    body=json.dumps({
        "anthropic_version": "bedrock-2023-05-31",
        "max_tokens": 512,
        "system": "You are a support ticket classifier. Classify the ticket accurately.",
        "messages": [
            {"role": "user", "content": f"Classify this support ticket:\n\n{ticket}"}
        ],
        "output_config": {"format": {"type": "json_schema", "schema": schema}}
    })
)

body = json.loads(response["body"].read())

# Check the stop reason before parsing
if body["stop_reason"] == "end_turn":
    result_text = next(b["text"] for b in body["content"] if b["type"] == "text")
    result = json.loads(result_text)
    print(json.dumps(result, indent=2))
    # Route the ticket based on the guaranteed-valid labels
    if result["escalate"]:
        print(f"Escalating to on-call: {result['category']} / {result['priority']}")
elif body["stop_reason"] == "max_tokens":
    print("Response truncated: increase max_tokens and retry.")

Requisitos e boas práticas

A AWS recomenda as seguintes diretrizes para usar saídas estruturadas de forma eficaz no Amazon Bedrock:

  • Defina additionalProperties: false em todos os objetos: isso é obrigatório para que as saídas estruturadas funcionem. Sem esse campo, o esquema não será aceito.
  • Use nomes e descrições de campos descritivos: o modelo utiliza nomes e descrições de propriedades para entender quais dados extrair. Nomes claros como customer_email têm desempenho superior a nomes genéricos como field1.
  • Use enum para valores restritos: quando um campo tem um conjunto limitado de valores válidos, use enum para restringir as opções.
  • Comece simples e adicione complexidade gradualmente: esquemas básicos compilam mais rápido, são mais fáceis de depurar e mantêm o payload da requisição enxuto.
  • Reutilize esquemas para se beneficiar do cache: estruture a aplicação para reutilizar esquemas entre requisições. O cache de gramática de 24 horas melhora a performance para consultas repetidas.
  • Verifique o stop_reason em toda resposta: dois cenários podem produzir respostas não conformes — recusas do modelo por razões de segurança e limite de tokens atingido antes de completar a resposta. Ambos os casos devem ser tratados no código.
  • Teste com dados realistas antes de fazer o deploy: valide os esquemas com entradas representativas de produção. Casos extremos em dados reais frequentemente revelam problemas de design no esquema.

Para boas práticas adicionais e recomendações de design de esquemas, consulte a seção Saídas Estruturadas no Guia do Usuário do Amazon Bedrock.

Recursos de JSON Schema suportados

O Amazon Bedrock suporta os seguintes recursos do JSON Schema para saídas estruturadas:

  • Todos os tipos básicos: object, array, string, integer, number, boolean, null.
  • enum (strings, números, booleanos ou nulos).
  • const, anyOf, allOf (com limitações).
  • $ref, $def e definitions (apenas referências internas).
  • Formatos de string: date-time, time, date, duration, email, hostname, uri, ipv4, ipv6, uuid.
  • minItems para arrays (apenas valores 0 e 1).

Não suportados: os seguintes recursos são aceitos pela API, mas não são aplicados durante a geração. Uma requisição que os inclua retorna resposta bem-sucedida, mas o modelo pode retornar valores que os violem — portanto, valide essas restrições na sua aplicação:

  • Esquemas recursivos.
  • Referências $ref externas.
  • Restrições numéricas (minimum, maximum, multipleOf).
  • Restrições de string (minLength, maxLength).
  • additionalProperties definido como qualquer valor diferente de false.

Disponibilidade geral

As saídas estruturadas para modelos Anthropic Claude no Amazon Bedrock estão geralmente disponíveis agora, nos endpoints bedrock-runtime e bedrock-mantle. Para saber mais, acesse a documentação do Amazon Bedrock e explore o notebook de exemplo disponibilizado pela AWS.

Fonte

Structured outputs for Anthropic Claude models on Amazon Bedrock (https://aws.amazon.com/blogs/machine-learning/structured-outputs-for-anthropic-claude-models-on-amazon-bedrock/)

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *