Salidas estructuradas
Las salidas estructuradas hacen que un modelo responda con JSON en lugar de texto libre: ya sea cualquier objeto JSON válido, o JSON que sigue un esquema que tú proporcionas. Es la forma confiable de extraer campos, clasificar texto o pasar una respuesta directamente a tu código.
Usa un modelo cuyo capabilities.json_mode sea true en la lista de modelos.
Esquema JSON
const completion = await client.chat.completions.create({
model: "gpt-5.5",
messages: [
{ role: "system", content: "Extract the event details." },
{ role: "user", content: "Team offsite on March 3rd at the Lisbon office, 10am." },
],
response_format: {
type: "json_schema",
json_schema: {
name: "event",
strict: true,
schema: {
type: "object",
properties: {
title: { type: "string" },
date: { type: "string" },
location: { type: "string" },
},
required: ["title", "date", "location"],
additionalProperties: false,
},
},
},
});
const event = JSON.parse(completion.choices[0].message.content);
Con strict: true, los modelos que admiten esquemas estrictos solo producen una salida válida. El modo estricto admite un subconjunto de JSON Schema: define additionalProperties: false en cada objeto y enumera cada propiedad en required (usa una unión con null para valores opcionales).
Modo JSON
Para obtener JSON válido sin un esquema fijo, usa json_object. Indica en el prompt que quieres JSON y describe la estructura, ya que el modelo no tiene otra referencia:
{
"model": "gemini-3.6-flash",
"response_format": { "type": "json_object" },
"messages": [
{ "role": "user", "content": "List three primary colours as JSON: {\"colours\": [...]}" }
]
}
En la API de Responses
El esquema va dentro de text.format:
{
"model": "gpt-5.5",
"input": "Team offsite on March 3rd at the Lisbon office, 10am.",
"text": {
"format": {
"type": "json_schema",
"name": "event",
"strict": true,
"schema": { "type": "object", "properties": { "title": { "type": "string" } }, "required": ["title"], "additionalProperties": false }
}
}
}
Los helpers del SDK para salidas estructuradas (client.chat.completions.parse con Zod o Pydantic, client.responses.parse) envían los mismos campos y funcionan sin cambios.
Qué revisar
- Un modelo que no admite un esquema devuelve un
400en lugar de ignorarlo en silencio. Elige otro modelo o recurre al modo JSON. - Una respuesta cortada por
max_tokens(finish_reason: "length") es JSON incompleto. Deja margen en el límite. - Un modelo aún puede rechazar una solicitud; verifica si hay un rechazo antes de parsear.
- Valida de todos modos el objeto parseado. Un esquema garantiza la estructura, no la veracidad.
- En el endpoint de Messages, que no tiene
response_format, el patrón habitual es una sola herramienta cuyoinput_schemaes tu esquema, contool_choiceforzando su uso.