Saltar al contenido

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 400 en 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 cuyo input_schema es tu esquema, con tool_choice forzando su uso.