Resultados estruturados em API compatíveis com OpenAI: guia de JSON Schema

Guia prático para aplicar JSON Schema estrito em Responses e Chat Completions, validar resultados, tratar falhas e testar a compatibilidade de cada rota.

Resultados estruturados em API compatíveis com OpenAI: guia de JSON Schema

Structured Outputs permite pedir JSON conforme a um esquema definido, em vez de apenas dizer ao modelo para «devolver JSON». Numa API compatível com OpenAI, o mesmo JSON Schema pode ser usado com Responses ou Chat Completions, mas o invólucro muda e o suporte deve ser verificado no modelo e na rota exatos.

O padrão seguro de produção tem três camadas: usar um esquema strict quando suportado, analisar e validar novamente o JSON na aplicação e, só então, aplicar regras de negócio determinísticas. A conformidade estrutural reduz erros de formato; não prova correção semântica ou factual.

Structured Outputs não é o mesmo que o modo JSON

Método JSON válido Impõe o esquema Uso típico
Apenas instruções Não garantido Não Protótipos que toleram falhas de análise
Modo JSON Sim, quando suportado e concluído Não JSON flexível validado pela aplicação
Structured Outputs com strict: true Sim, com tratamento da conclusão e de recusas Sim, no subconjunto suportado Extração tipada e fluxos da aplicação

O guia OpenAI Structured Outputs recomenda esta opção em vez do modo JSON quando o modelo e o endpoint a suportam. Um formato estruturado serve para devolver um objeto previsível; Function Calling serve para pedir uma ação à aplicação. Os esquemas podem ser semelhantes, mas os identificadores de chamada e as mensagens de resultado pertencem a outro contrato.

Defina o esquema antes de escolher o endpoint

Uma triagem de suporte precisa de quatro campos:

{
  "type": "object",
  "properties": {
    "category": {
      "type": "string",
      "enum": ["billing", "technical", "account"]
    },
    "priority": {
      "type": "integer",
      "minimum": 1,
      "maximum": 3
    },
    "requires_human": {
      "type": "boolean"
    },
    "summary": {
      "type": "string"
    }
  },
  "required": ["category", "priority", "requires_human", "summary"],
  "additionalProperties": false
}

Tornar todas as propriedades obrigatórias e usar additionalProperties: false cria um objeto estável. Isso não torna todas as palavras-chave de JSON Schema portáteis. A OpenAI documenta um subconjunto, enquanto outro fornecedor pode implementar um subconjunto diferente ou não disponibilizar um modo de esquema estrito.

Envie o esquema com Responses API

Responses coloca o esquema em text.format:

export MODELFLARE_API_KEY="<YOUR_API_KEY>"
export MODEL_ID="<MODEL_WITH_VERIFIED_STRUCTURED_OUTPUT_SUPPORT>"

curl -sS https://modelflare.dev/v1/responses \
  -H "Authorization: Bearer $MODELFLARE_API_KEY" \
  -H "Content-Type: application/json" \
  -d "{
    \"model\": \"$MODEL_ID\",
    \"input\": \"O cliente foi cobrado duas vezes e pretende um reembolso.\",
    \"text\": {
      \"format\": {
        \"type\": \"json_schema\",
        \"name\": \"support_ticket\",
        \"schema\": {
          \"type\": \"object\",
          \"properties\": {
            \"category\": {
              \"type\": \"string\",
              \"enum\": [\"billing\", \"technical\", \"account\"]
            },
            \"priority\": {
              \"type\": \"integer\",
              \"minimum\": 1,
              \"maximum\": 3
            },
            \"requires_human\": { \"type\": \"boolean\" },
            \"summary\": { \"type\": \"string\" }
          },
          \"required\": [\"category\", \"priority\", \"requires_human\", \"summary\"],
          \"additionalProperties\": false
        },
        \"strict\": true
      }
    }
  }"

Envie para POST https://modelflare.dev/v1/responses com Authorization: Bearer <YOUR_API_KEY>. O conteúdo aparece em itens de saída tipados. Os SDK podem fornecer funções auxiliares, mas um cliente HTTP deve localizar o texto completo e analisá-lo como JSON; não deve assumir que existe um objeto tipado no nível superior.

Envie o mesmo esquema com Chat Completions

Chat Completions usa response_format.json_schema:

curl -sS https://modelflare.dev/v1/chat/completions \
  -H "Authorization: Bearer $MODELFLARE_API_KEY" \
  -H "Content-Type: application/json" \
  -d "{
    \"model\": \"$MODEL_ID\",
    \"messages\": [
      {
        \"role\": \"user\",
        \"content\": \"O cliente foi cobrado duas vezes e pretende um reembolso.\"
      }
    ],
    \"response_format\": {
      \"type\": \"json_schema\",
      \"json_schema\": {
        \"name\": \"support_ticket\",
        \"schema\": {
          \"type\": \"object\",
          \"properties\": {
            \"category\": {
              \"type\": \"string\",
              \"enum\": [\"billing\", \"technical\", \"account\"]
            },
            \"priority\": {
              \"type\": \"integer\",
              \"minimum\": 1,
              \"maximum\": 3
            },
            \"requires_human\": { \"type\": \"boolean\" },
            \"summary\": { \"type\": \"string\" }
          },
          \"required\": [\"category\", \"priority\", \"requires_human\", \"summary\"],
          \"additionalProperties\": false
        },
        \"strict\": true
      }
    }
  }"

O JSON normalmente é uma cadeia de texto em choices[0].message.content e ainda precisa de ser analisado.

Objetivo Responses API Chat Completions
Contentor text.format response_format.json_schema
Tipo text.format.type response_format.type
Nome text.format.name response_format.json_schema.name
Esquema text.format.schema response_format.json_schema.schema
Indicador de modo estrito text.format.strict response_format.json_schema.strict
Resultado Itens de saída / função auxiliar choices[0].message.content

A camada de compatibilidade da Modelflare converte os invólucros em rotas OpenAI/Codex suportadas, mas não cria Structured Outputs num modelo de origem sem essa capacidade. Nas famílias em que Chat Completions é transmitido sem transformação, o contrato do fornecedor continua a ser a fonte de verdade.

Valide estrutura e significado separadamente

{
  "category": "billing",
  "priority": 2,
  "requires_human": true,
  "summary": "O cliente comunica uma cobrança duplicada e pede um reembolso."
}

Validação estrutural

Um validador de JSON Schema confirma propriedades obrigatórias, ausência de propriedades adicionais, tipos, valores enumerados e limites. Mesmo quando o fornecedor promete conformidade estrita, a validação protege contra rotas incompatíveis, erros de integração, conteúdo truncado e alterações futuras.

Validação semântica e de negócio

O esquema não sabe se a cobrança duplicada existiu, se priority: 2 está correto ou quem pode aprovar o reembolso. Trate o objeto como uma classificação proposta, compare-o com dados oficiais e aplique permissões e limites financeiros em código determinístico. Um JSON válido nunca deve contornar a autorização, a faturação ou a segurança.

Trate saídas incompletas e excepcionais

Recusas

Verifique o estado e a representação da recusa antes de procurar JSON. Uma recusa de segurança não é um erro de análise.

Truncamento e limites de saída

Se a geração parar antes do fecho do objeto, o esquema não recupera a parte em falta. Verifique o estado de conclusão e o motivo da paragem, e use um limite de saída suficiente, mas controlado.

Palavras-chave não suportadas

Comece com objetos, arrays, tipos primitivos, valores enumerados, propriedades obrigatórias e regras explícitas para propriedades adicionais. Consulte a documentação antes de usar referências, recursão, uniões complexas ou validação avançada.

Latência do primeiro esquema

Alguns fornecedores pré-processam e guardam um esquema novo em cache. Reutilize esquemas estáveis e versionados e meça a primeira utilização separadamente do regime estável.

Modelo ou rota incompatível

Um endpoint pode aceitar Chat Completions, rejeitar json_schema ou ignorar strict. Um 200 com JSON não prova conformidade estrita. Inclua entradas inválidas e casos-limite.

Execute uma matriz de compatibilidade

Teste Evidência
Objeto obrigatório mínimo Estado, modelo, rota, objeto analisado e validação
Cada valor enumerado Produção e análise de todos os valores
Informação ausente Valor limitado ou pedido de esclarecimento
Entrada que ativa segurança Formato da recusa e tratamento
Limite de saída baixo Estado de conclusão e truncamento
Funcionalidade não suportada Erro explícito ou restrição ignorada
Invólucros Responses e Chat Objetos equivalentes na aplicação
esquema estável repetido Primeira utilização contra regime estável

Mantenha constantes o esquema, as instruções, a região, o modo de streaming e o limite de saída, e registe a data.

Escolha o endpoint após testar o fluxo de trabalho

Responses é adequado para itens de saída tipados, eventos de streaming e fluxos de ferramentas mais amplos. Chat Completions é adequado para uma integração baseada em mensagens quando a rota suporta response_format. Consulte Responses API e Chat Completions.

Em qualquer opção:

  1. mantenha uma fonte de verdade versionada para JSON Schema;
  2. altere apenas o invólucro, não o significado;
  3. valide a resposta completa;
  4. aplique regras determinísticas depois da estrutura;
  5. monitorize separadamente análise, recusas, truncamento e compatibilidade.

Para a migração, use o guia de APIs compatíveis com OpenAI; para fluxos incompletos, o guia de streaming de APIs de IA. Consulte Modelos e preços e teste Structured Outputs na rota exata da chave de API.

Structured Outputs torna a resposta uma interface mais fiável, mas não substitui a verificação factual, a autorização nem a lógica de faturação. «Compatível com OpenAI» continua a ser uma afirmação que deve ser testada funcionalidade a funcionalidade.