- Extrair campos tipados de texto não estruturado (faturas, e-mails, tickets de suporte).
- Pipelines em que o código downstream exige um JSON schema garantido.
- Tarefas de classificação com um conjunto de saídas controlado (valores de enum, flags booleanas).
- Gerar objetos de configuração ou payloads de API diretamente a partir de linguagem natural.
Início rápido
Gere respostas JSON estruturadas com conformidade garantida com o schema.curl -X POST https://router.toqan.ai/eu/v3/router/responses \
-H "Authorization: Bearer $TOQAN_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "openai/gpt-5.6-sol",
"input": "Extract info: John Doe, 30, john@example.com, knows Python and React",
"text": {
"format": {
"type": "json_schema",
"name": "user",
"schema": {
"type": "object",
"properties": {
"name": {"type": "string"},
"age": {"type": "integer"},
"email": {"type": "string"},
"skills": {"type": "array", "items": {"type": "string"}}
},
"required": ["name", "age", "email", "skills"],
"additionalProperties": false
}
}
}
}'
import OpenAI from "openai";
import { z } from "zod";
import { zodTextFormat } from "openai/helpers/zod";
const client = new OpenAI({
apiKey: process.env.TOQAN_API_KEY,
baseURL: "https://router.toqan.ai/eu/v3/router",
});
const UserSchema = z.object({
name: z.string(),
age: z.number(),
email: z.string(),
skills: z.array(z.string()),
});
const response = await client.responses.parse({
model: "openai/gpt-5.6-sol",
input: "Extract info: John Doe, 30, john@example.com, knows Python and React",
text: { format: zodTextFormat(UserSchema, "user") },
});
const user = response.output_parsed;
console.log(user.name);
console.log(user.skills);
from openai import OpenAI
from pydantic import BaseModel
import os
client = OpenAI(
api_key=os.environ.get("TOQAN_API_KEY"),
base_url="https://router.toqan.ai/eu/v3/router",
)
class UserSchema(BaseModel):
name: str
age: int
email: str
skills: list[str]
response = client.responses.parse(
model="openai/gpt-5.6-sol",
input="Extract info: John Doe, 30, john@example.com, knows Python and React",
text_format=UserSchema,
)
user = response.output_parsed
print(user.name)
print(user.skills)
import OpenAI from "openai";
import { z } from "zod";
import { zodResponseFormat } from "openai/helpers/zod";
const client = new OpenAI({
apiKey: process.env.TOQAN_API_KEY,
baseURL: "https://router.toqan.ai/eu/v3/router",
});
const UserSchema = z.object({
name: z.string(),
age: z.number(),
email: z.string(),
skills: z.array(z.string()),
});
const response = await client.chat.completions.parse({
model: "openai/gpt-5.6-sol",
messages: [
{
role: "user",
content: "Extract info: John Doe, 30, john@example.com, knows Python and React",
},
],
response_format: zodResponseFormat(UserSchema, "user"),
});
const user = response.choices[0].message.parsed;
console.log(user.name);
console.log(user.skills);
Opções de configuração
Tipos de formato de resposta
| Tipo | Descrição |
|---|---|
"text" | Formato de resposta padrão para respostas em texto |
"json_object" | Saída JSON básica (sem validação de schema) |
"json_schema" | JSON estruturado com validação de schema |
Modo texto (padrão)
| Parâmetro | Tipo | Descrição |
|---|---|---|
type | "text" | Formato de resposta padrão para saídas em texto |
Modo JSON Schema
| Parâmetro | Tipo | Descrição |
|---|---|---|
type | "json_schema" | Habilita a validação de schema |
json_schema.name | string | Nome/identificador do schema |
json_schema.schema | object | Definição do JSON Schema |
json_schema.strict | boolean | Segue exatamente o schema. O padrão é false. Quando true, apenas um subconjunto do JSON Schema é suportado. |
Modo JSON simples
| Parâmetro | Tipo | Descrição |
|---|---|---|
type | "json_object" | Saída JSON básica (sem schema) |
Exemplos de schema
Extração simples de dados
{
"type": "json_schema",
"json_schema": {
"name": "contact_info",
"schema": {
"type": "object",
"properties": {
"name": { "type": "string" },
"email": { "type": "string", "format": "email" },
"phone": { "type": "string" },
"company": { "type": "string" }
},
"required": ["name", "email"]
}
}
}
Estrutura aninhada complexa
{
"type": "json_schema",
"json_schema": {
"name": "product_analysis",
"schema": {
"type": "object",
"properties": {
"product": {
"type": "object",
"properties": {
"name": { "type": "string" },
"price": { "type": "number" },
"category": { "type": "string" }
}
},
"features": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": { "type": "string" },
"importance": { "type": "integer", "minimum": 1, "maximum": 5 }
}
}
},
"summary": { "type": "string" }
},
"required": ["product", "features", "summary"]
}
}
}
Exemplos de código
curl -X POST https://router.toqan.ai/eu/v3/router/responses \
-H "Authorization: Bearer $TOQAN_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "openai/gpt-5.6-sol",
"input": "Extract user information from: John Doe, 30 years old, john@example.com, Software Engineer",
"text": {
"format": {
"type": "json_schema",
"name": "user_info",
"schema": {
"type": "object",
"properties": {
"name": {"type": "string"},
"age": {"type": "integer"},
"email": {"type": "string"},
"occupation": {"type": "string"}
},
"required": ["name", "age", "email", "occupation"],
"additionalProperties": false
}
}
}
}'
curl -X POST https://router.toqan.ai/eu/v3/router/chat/completions \
-H "Authorization: Bearer $TOQAN_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "openai/gpt-5.6-sol",
"messages": [
{
"role": "user",
"content": "Extract user information from: John Doe, 30 years old, john@example.com, Software Engineer"
}
],
"response_format": {
"type": "json_schema",
"json_schema": {
"name": "user_info",
"schema": {
"type": "object",
"properties": {
"name": {"type": "string"},
"age": {"type": "integer"},
"email": {"type": "string"},
"occupation": {"type": "string"}
},
"required": ["name", "age", "email", "occupation"]
}
}
}
}'
import OpenAI from "openai";
import { z } from "zod";
import { zodTextFormat } from "openai/helpers/zod";
const client = new OpenAI({
apiKey: process.env.TOQAN_API_KEY,
baseURL: "https://router.toqan.ai/eu/v3/router",
});
const UserInfoSchema = z.object({
name: z.string(),
age: z.number(),
email: z.string(),
occupation: z.string(),
});
const response = await client.responses.parse({
model: "openai/gpt-5.6-sol",
input: "Extract user information from: John Doe, 30 years old, john@example.com, Software Engineer",
text: { format: zodTextFormat(UserInfoSchema, "user_info") },
});
const user = response.output_parsed;
console.log(`Name: ${user.name}`);
console.log(`Occupation: ${user.occupation}`);
from openai import OpenAI
from pydantic import BaseModel
import os
client = OpenAI(
api_key=os.environ.get("TOQAN_API_KEY"),
base_url="https://router.toqan.ai/eu/v3/router",
)
class UserInfo(BaseModel):
name: str
age: int
email: str
occupation: str
response = client.responses.parse(
model="openai/gpt-5.6-sol",
input="Extract user information from: John Doe, 30 years old, john@example.com, Software Engineer",
text_format=UserInfo,
)
user = response.output_parsed
print(f"Name: {user.name}")
print(f"Occupation: {user.occupation}")
import OpenAI from "openai";
import { z } from "zod";
import { zodResponseFormat } from "openai/helpers/zod";
const client = new OpenAI({
apiKey: process.env.TOQAN_API_KEY,
baseURL: "https://router.toqan.ai/eu/v3/router",
});
const UserInfoSchema = z.object({
name: z.string(),
age: z.number(),
email: z.string(),
occupation: z.string(),
});
const response = await client.chat.completions.parse({
model: "openai/gpt-5.6-sol",
messages: [
{
role: "user",
content: "Extract user information from: John Doe, 30 years old, john@example.com, Software Engineer",
},
],
response_format: zodResponseFormat(UserInfoSchema, "user_info"),
});
const user = response.choices[0].message.parsed;
console.log(`Name: ${user.name}`);
console.log(`Occupation: ${user.occupation}`);
from openai import OpenAI
from pydantic import BaseModel
import os
client = OpenAI(
api_key=os.environ.get("TOQAN_API_KEY"),
base_url="https://router.toqan.ai/eu/v3/router",
)
class UserInfo(BaseModel):
name: str
age: int
email: str
occupation: str
response = client.chat.completions.parse(
model="openai/gpt-5.6-sol",
messages=[
{
"role": "user",
"content": "Extract user information from: John Doe, 30 years old, john@example.com, Software Engineer",
}
],
response_format=UserInfo,
)
user = response.choices[0].message.parsed
print(f"Name: {user.name}")
print(f"Occupation: {user.occupation}")
Casos de uso comuns
Os exemplos desta seção usam o endpoint de Chat Completions. As saídas estruturadas funcionam da mesma forma com a Responses API: use
responses.create() com text: { format: { type: "json_schema", ... } } em vez de response_format.Extração de dados
from openai import OpenAI
from pydantic import BaseModel
from typing import List
import os
client = OpenAI(
api_key=os.environ.get("TOQAN_API_KEY"),
base_url="https://router.toqan.ai/eu/v3/router",
)
class LineItem(BaseModel):
description: str
quantity: int
unit_price: float
total: float
class InvoiceData(BaseModel):
invoice_number: str
date: str
vendor: str
total_amount: float
line_items: List[LineItem]
response = client.chat.completions.parse(
model="openai/gpt-5.6-sol",
messages=[{
"role": "user",
"content": "Extract invoice data from this text: [invoice text]"
}],
response_format=InvoiceData
)
Análise de conteúdo
import OpenAI from "openai";
import { z } from "zod";
import { zodResponseFormat } from "openai/helpers/zod";
const client = new OpenAI({
apiKey: process.env.TOQAN_API_KEY,
baseURL: "https://router.toqan.ai/eu/v3/router",
});
const SentimentSchema = z.object({
sentiment: z.enum(["positive", "negative", "neutral"]),
confidence: z.number().min(0).max(1),
key_phrases: z.array(z.string()),
summary: z.string(),
});
const response = await client.chat.completions.parse({
model: "openai/gpt-5.6-sol",
messages: [
{
role: "user",
content: "Analyze sentiment of this review: [review text]",
},
],
response_format: zodResponseFormat(SentimentSchema, "sentiment_analysis"),
});
Geração de formulários
from openai import OpenAI
from pydantic import BaseModel, Field
from typing import List
import os
client = OpenAI(
api_key=os.environ.get("TOQAN_API_KEY"),
base_url="https://router.toqan.ai/eu/v3/router",
)
class SurveyQuestion(BaseModel):
question: str
type: str
options: List[str]
class SurveyForm(BaseModel):
title: str
description: str
questions: List[SurveyQuestion] = Field(
...,
description="List of survey questions with type and options"
)
estimated_duration: int = Field(description="Minutes to complete")
response = client.chat.completions.parse(
model="openai/gpt-5.6-sol",
messages=[{
"role": "user",
"content": "Create a customer satisfaction survey for a restaurant"
}],
response_format=SurveyForm
)
Padrões avançados
Schemas condicionais
import { z } from "zod";
const ResponseSchema = z.discriminatedUnion("type", [
z.object({
type: z.literal("success"),
data: z.object({
result: z.string(),
metadata: z.record(z.any()),
}),
}),
z.object({
type: z.literal("error"),
error: z.object({
code: z.string(),
message: z.string(),
}),
}),
]);
Geração dinâmica de schemas
from typing import List
def create_schema_for_fields(fields: List[str]):
properties = {}
for field in fields:
properties[field] = {"type": "string"}
return {
"type": "object",
"properties": properties,
"required": fields
}
# Generate schema based on user input
fields = ["name", "email", "department"]
schema = create_schema_for_fields(fields)
Validação e tratamento de erros
from openai import OpenAI
from pydantic import BaseModel
import os
client = OpenAI(
api_key=os.environ.get("TOQAN_API_KEY"),
base_url="https://router.toqan.ai/eu/v3/router",
)
prompt = "Extract the following information: John Doe is 30 years old."
class MySchema(BaseModel):
name: str
age: int
try:
response = client.chat.completions.parse(
model="openai/gpt-5.6-sol",
messages=[{"role": "user", "content": prompt}],
response_format=MySchema
)
if response.choices[0].message.parsed:
data = response.choices[0].message.parsed
# Process validated data
else:
# Handle parsing failure
print("Failed to parse response")
except Exception as e:
print(f"Error: {e}")
# Fallback to regular completion
Boas práticas
Design do schema:- Use nomes de campo descritivos.
- Adicione descrições aos campos para obter melhores resultados.
- Marque os campos essenciais como obrigatórios.
- Use tipos de dados e restrições adequados.
import OpenAI from "openai";
import { z } from "zod";
import { zodResponseFormat } from "openai/helpers/zod";
const client = new OpenAI({
apiKey: process.env.TOQAN_API_KEY,
baseURL: "https://router.toqan.ai/eu/v3/router",
});
const parseWithFallback = async (prompt: string, schema: z.ZodTypeAny) => {
try {
const response = await client.chat.completions.parse({
model: "openai/gpt-5.6-sol",
messages: [{ role: "user", content: prompt }],
response_format: zodResponseFormat(schema, "data"),
});
return response.choices[0].message.parsed;
} catch (error) {
console.warn("Structured parsing failed, trying JSON mode");
// Fallback to basic JSON mode
const fallback = await client.chat.completions.create({
model: "openai/gpt-5.6-sol",
messages: [
{
role: "user",
content: `${prompt}\n\nRespond with valid JSON only.`,
},
],
response_format: { type: "json_object" },
});
const content = fallback.choices[0].message.content;
if (!content) throw new Error("Empty fallback response");
return JSON.parse(content);
}
};
# Cache schemas for reuse
schema_cache = {}
def create_schema(schema_name): ... # replace with your schema factory
def get_cached_schema(schema_name):
if schema_name not in schema_cache:
schema_cache[schema_name] = create_schema(schema_name)
return schema_cache[schema_name]
Solução de problemas
A validação do schema falha- Simplifique estruturas aninhadas complexas.
- Garanta que os campos obrigatórios estejam claramente especificados.
- Verifique se os tipos dos campos correspondem aos dados esperados.
- Adicione descrições aos campos para dar mais clareza.
- Use prompts mais específicos.
- Adicione exemplos no prompt.
- Reduza a temperatura (de 0 a 0,3) para obter saídas mais consistentes.
- Troque para um modelo mais capaz.
- Reduza a complexidade do schema.
- Armazene as definições de schema em cache.
- Use modelos adequados à complexidade da tarefa.
- Considere dividir schemas grandes em schemas menores.
Limitações
| Limitação | Impacto | Alternativa |
|---|---|---|
| Complexidade do schema | Schemas grandes podem falhar | Divida em schemas menores |
| Suporte dos modelos | Nem todos os modelos são compatíveis com schemas | Use o modo JSON como fallback |
| Profundidade de aninhamento | Aninhamentos profundos podem causar problemas | Achate as estruturas sempre que possível |
| Validação de arrays | Itens de array complexos são desafiadores | Simplifique os schemas dos itens |
| Custo de desempenho | A validação de schema adiciona latência | Armazene em cache e otimize os schemas |
Exemplos de integração
Integração com banco de dados
from openai import OpenAI
from pydantic import BaseModel
from typing import Optional
from datetime import datetime
import os
client = OpenAI(
api_key=os.environ.get("TOQAN_API_KEY"),
base_url="https://router.toqan.ai/eu/v3/router",
)
class DatabaseRecord(BaseModel):
id: Optional[int] = None
name: str
email: str
created_at: Optional[datetime] = None
# Generate structured data
response = client.chat.completions.parse(
model="openai/gpt-5.6-sol",
messages=[{"role": "user", "content": "Create user record"}],
response_format=DatabaseRecord
)
# Direct database insertion (example using SQLAlchemy)
record = response.choices[0].message.parsed
# session.add(record)
# session.commit()
Integração com API
import OpenAI from "openai";
import { z } from "zod";
import { zodResponseFormat } from "openai/helpers/zod";
const client = new OpenAI({
apiKey: process.env.TOQAN_API_KEY,
baseURL: "https://router.toqan.ai/eu/v3/router",
});
const ApiResponseSchema = z.object({
status: z.enum(["success", "error"]),
data: z.string(),
message: z.string().nullable().optional(),
});
const generateApiResponse = async (query) => {
const response = await client.chat.completions.parse({
model: "openai/gpt-5.6-sol",
messages: [{ role: "user", content: query }],
response_format: zodResponseFormat(ApiResponseSchema, "api_response"),
});
// Return structured API response
return response.choices[0].message.parsed;
};

