Tokia

Structured Outputs (JSON mode)

Structured Outputs permite forçar o modelo a responder em JSON válido, seguindo um schema que você define. Essencial para pipelines de dados, classificação, extração de entidades e qualquer caso onde você precisa parsear a resposta programaticamente.

JSON mode (básico)

O modo mais simples: o modelo retorna JSON válido, mas sem schema fixo. Use response_format: { "type": "json_object" }:

python
from openai import OpenAI

client = OpenAI(
    api_key="sk-...",
    base_url="https://api.usetokia.com/v1",
)

response = client.chat.completions.create(
    model="gpt-4o-mini",
    messages=[
        {
            "role": "system",
            "content": "Extraia os dados do texto em JSON com campos: nome, idade, cidade"
        },
        {
            "role": "user",
            "content": "João tem 32 anos e mora em Belo Horizonte"
        }
    ],
    response_format={"type": "json_object"},
)

import json
data = json.loads(response.choices[0].message.content)
print(data)
# {"nome": "João", "idade": 32, "cidade": "Belo Horizonte"}

JSON Schema (avançado)

Para garantir que a resposta siga um schema específico, use json_schema. O modelo é forçado a gerar JSON que valida contra o schema:

python
response = client.chat.completions.create(
    model="gpt-4o-mini",
    messages=[
        {
            "role": "system",
            "content": "Extraia as entidades do texto"
        },
        {
            "role": "user",
            "content": "A reunião da Tokia com a IT Booster será em 15/10 às 14h em Brasília"
        }
    ],
    response_format={
        "type": "json_schema",
        "json_schema": {
            "name": "entidades_extraidas",
            "strict": True,
            "schema": {
                "type": "object",
                "properties": {
                    "empresas": {
                        "type": "array",
                        "items": {"type": "string"},
                        "description": "Nomes de empresas mencionadas"
                    },
                    "data": {
                        "type": "string",
                        "description": "Data do evento em formato ISO (YYYY-MM-DD)"
                    },
                    "hora": {
                        "type": "string",
                        "description": "Horário no formato HH:MM"
                    },
                    "local": {
                        "type": "string",
                        "description": "Cidade ou local mencionado"
                    }
                },
                "required": ["empresas", "data", "hora", "local"],
                "additionalProperties": False
            }
        }
    },
)

data = json.loads(response.choices[0].message.content)
# {
#   "empresas": ["Tokia", "IT Booster"],
#   "data": "2026-10-15",
#   "hora": "14:00",
#   "local": "Brasília"
# }

TypeScript

typescript
import OpenAI from "openai";

const client = new OpenAI({
  apiKey: process.env.TOKIA_KEY,
  baseURL: "https://api.usetokia.com/v1",
});

const res = await client.chat.completions.create({
  model: "gpt-4o-mini",
  messages: [
    { role: "system", content: "Classifique o sentimento do texto" },
    { role: "user", content: "O produto é excelente, adorei a entrega rápida!" },
  ],
  response_format: {
    type: "json_schema",
    json_schema: {
      name: "analise_sentimento",
      strict: true,
      schema: {
        type: "object",
        properties: {
          sentimento: {
            type: "string",
            enum: ["positivo", "negativo", "neutro"],
          },
          confianca: {
            type: "number",
            description: "Score de confiança de 0 a 1",
          },
          palavras_chave: {
            type: "array",
            items: { type: "string" },
          },
        },
        required: ["sentimento", "confianca", "palavras_chave"],
        additionalProperties: false,
      },
    },
  },
});

const data = JSON.parse(res.choices[0].message.content!);
console.log(data.sentimento);  // "positivo"
console.log(data.confianca);   // 0.95

Modelos com suporte

ModoModelos
json_objectGPT-4o, GPT-4o-mini, GPT-4-turbo, Claude (todos), Gemini, DeepSeek, Mistral, Llama 3.1+
json_schema (strict)GPT-4o, GPT-4o-mini (suporte nativo); outros modelos podem ter suporte parcial

Fallback para modelos sem suporte

Se o modelo não suporta response_format, use o prompt para instruir o formato:

python
response = client.chat.completions.create(
    model="claude-3-haiku-20240307",
    messages=[
        {
            "role": "system",
            "content": """Responda APENAS com JSON válido, sem texto antes ou depois.
Use exatamente este formato:
{
  "sentimento": "positivo" | "negativo" | "neutro",
  "resumo": "frase curta"
}"""
        },
        {
            "role": "user",
            "content": "O atendimento foi péssimo, esperei 2 horas"
        }
    ],
)

import json
try:
    data = json.loads(response.choices[0].message.content)
except json.JSONDecodeError:
    # Fallback: extrair JSON do texto
    text = response.choices[0].message.content
    start = text.find("{")
    end = text.rfind("}") + 1
    data = json.loads(text[start:end])

Casos de uso comuns

  • Extração de entidades: extrair nomes, datas, valores de textos não estruturados
  • Classificação: categorizar textos (sentimento, tópico, urgência) com labels fixos
  • Geração de dados: criar registros estruturados a partir de descrições em linguagem natural
  • Parsing de documentos: converter faturas, contratos, currículos em JSON
  • Pipeline de dados: cada etapa recebe e retorna JSON, sem parsing de texto livre

Boas práticas

  • Sempre use strict: true quando disponível — garante que o schema é respeitado
  • Use enum para campos com valores fixos (evita variações como “Positivo” vs “positivo”)
  • Defina additionalProperties: false para evitar campos extras
  • Valide o JSON no seu código mesmo com strict mode — defesa em profundidade
  • Use descriptions nos campos do schema para guiar o modelo

Próximos passos