> ## Documentation Index
> Fetch the complete documentation index at: https://docs.aihubmix.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Salidas Estructuradas (Structured Outputs)

> Controla el formato de salida del modelo mediante JSON Schema (Structured Outputs). Compatible con response_format y output_config.format de OpenAI, Anthropic Claude, Gemini y otros modelos, con degradación automática y conversión entre protocolos.

## Descripcion general

Las salidas estructuradas (Structured Outputs) hacen que la respuesta del modelo se ajuste estrictamente al JSON Schema que definas, asegurando que el valor de retorno pueda ser parseado directamente por tu programa, sin necesidad de expresiones regulares ni post-procesamiento.

A diferencia de pedirle al modelo en el prompt que "devuelva JSON", las salidas estructuradas se basan en la **decodificacion restringida (Constrained Decoding)**: el proveedor upstream compila el JSON Schema en reglas gramaticales y restringe la generacion token a token durante la inferencia, haciendo **imposible** que el modelo produzca contenido que viole el Schema.

Escenarios tipicos:

* Extraccion de entidades y campos a partir de texto no estructurado
* Clasificacion / etiquetado / analisis de sentimiento
* Transferencia estandarizada de resultados intermedios en razonamientos de multiples pasos
* Restricciones de tipado fuerte en parametros de llamadas a herramientas de Agents

## Comparacion de parametros por protocolo

<Note>
  Los nombres de parametros difieren entre los tres protocolos, pero el mecanismo subyacente es el mismo: la salida del modelo coincide estrictamente con el JSON Schema que proporcionas.
</Note>

| Protocolo                          | Parametro                                  | Modelos compatibles                                  |
| ---------------------------------- | ------------------------------------------ | ---------------------------------------------------- |
| OpenAI Chat `/v1/chat/completions` | `response_format.type: "json_schema"`      | Claude 4.5+, GPT-4o / serie GPT-5, serie Gemini      |
| Anthropic Messages `/v1/messages`  | `output_config.format.type: "json_schema"` | Claude 4.5+ (directo / Vertex); Bedrock solo 4.5-4.6 |
| OpenAI Responses `/v1/responses`   | `text.format.type: "json_schema"`          | Segun capacidad del modelo upstream                  |

### Limitaciones de AWS Bedrock

En AWS Bedrock, las versiones de Claude 4.7 y superiores utilizan la ruta de inferencia Mantle, que actualmente no soporta `output_config.format`. El gateway elimina automaticamente el campo `format` para estos modelos y marca la degradacion en el encabezado de respuesta (ver [Mecanismo de degradacion](#mecanismo-de-degradacion-automatica) mas abajo); la solicitud no fallara por este motivo.

***

## Inicio rapido

### Protocolo OpenAI (recomendado)

Aplicable a todos los modelos que soportan salidas estructuradas, compatible entre proveedores.

<CodeGroup>
  ```python Python theme={null}
  from openai import OpenAI

  client = OpenAI(
      api_key="<AIHUBMIX_API_KEY>",
      base_url="https://aihubmix.com/v1",
  )

  response = client.chat.completions.create(
      model="claude-sonnet-5",
      messages=[
          {"role": "user", "content": "Extrae la siguiente informacion: Juan Garcia, 28 anos, Madrid Centro"}
      ],
      response_format={
          "type": "json_schema",
          "json_schema": {
              "name": "person_info",
              "strict": True,
              "schema": {
                  "type": "object",
                  "properties": {
                      "name": {"type": "string"},
                      "age": {"type": "integer"},
                      "city": {"type": "string"}
                  },
                  "required": ["name", "age", "city"],
                  "additionalProperties": False
              }
          }
      }
  )

  import json
  data = json.loads(response.choices[0].message.content)
  print(data)
  # {"name": "Juan Garcia", "age": 28, "city": "Madrid Centro"}
  ```

  ```typescript Node.js theme={null}
  import OpenAI from "openai";

  const client = new OpenAI({
    apiKey: "<AIHUBMIX_API_KEY>",
    baseURL: "https://aihubmix.com/v1",
  });

  const response = await client.chat.completions.create({
    model: "claude-sonnet-5",
    messages: [
      { role: "user", content: "Extrae la siguiente informacion: Juan Garcia, 28 anos, Madrid Centro" },
    ],
    response_format: {
      type: "json_schema",
      json_schema: {
        name: "person_info",
        strict: true,
        schema: {
          type: "object",
          properties: {
            name: { type: "string" },
            age: { type: "integer" },
            city: { type: "string" },
          },
          required: ["name", "age", "city"],
          additionalProperties: false,
        },
      },
    },
  });

  const data = JSON.parse(response.choices[0].message.content);
  console.log(data);
  ```

  ```bash cURL theme={null}
  curl https://aihubmix.com/v1/chat/completions \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer <AIHUBMIX_API_KEY>" \
    -d '{
      "model": "claude-sonnet-5",
      "messages": [
        {"role": "user", "content": "Extrae la siguiente informacion: Juan Garcia, 28 anos, Madrid Centro"}
      ],
      "response_format": {
        "type": "json_schema",
        "json_schema": {
          "name": "person_info",
          "strict": true,
          "schema": {
            "type": "object",
            "properties": {
              "name": {"type": "string"},
              "age": {"type": "integer"},
              "city": {"type": "string"}
            },
            "required": ["name", "age", "city"],
            "additionalProperties": false
          }
        }
      }
    }'
  ```
</CodeGroup>

### Uso con otros modelos (ejemplo GLM-5.2)

El mismo conjunto de parametros del protocolo OpenAI se aplica a todos los modelos que soportan salidas estructuradas; basta con cambiar el campo `model`.

```python Python theme={null}
from openai import OpenAI

client = OpenAI(
    api_key="<AIHUBMIX_API_KEY>",
    base_url="https://aihubmix.com/v1",
)

response = client.chat.completions.create(
    model="glm-5.2",
    messages=[
        {"role": "user", "content": "Extrae la siguiente informacion: Juan Garcia, 28 anos, Madrid Centro"}
    ],
    response_format={
        "type": "json_schema",
        "json_schema": {
            "name": "person_info",
            "strict": True,
            "schema": {
                "type": "object",
                "properties": {
                    "name": {"type": "string"},
                    "age": {"type": "integer"},
                    "city": {"type": "string"}
                },
                "required": ["name", "age", "city"],
                "additionalProperties": False
            }
        }
    }
)

import json
data = json.loads(response.choices[0].message.content)
print(data)
# {"name": "Juan Garcia", "age": 28, "city": "Madrid Centro"}
```

### Protocolo nativo de Claude

Llamada directa mediante el SDK de Anthropic, utilizando el parametro `output_config.format`.

<CodeGroup>
  ```python Python theme={null}
  import anthropic

  client = anthropic.Anthropic(
      api_key="<AIHUBMIX_API_KEY>",
      base_url="https://aihubmix.com",
  )

  response = client.messages.create(
      model="claude-sonnet-5",
      max_tokens=1024,
      messages=[
          {"role": "user", "content": "Extrae la siguiente informacion: Juan Garcia, 28 anos, Madrid Centro"}
      ],
      output_config={
          "format": {
              "type": "json_schema",
              "schema": {
                  "type": "object",
                  "properties": {
                      "name": {"type": "string"},
                      "age": {"type": "integer"},
                      "city": {"type": "string"}
                  },
                  "required": ["name", "age", "city"],
                  "additionalProperties": False
              }
          }
      }
  )

  import json
  data = json.loads(response.content[0].text)
  print(data)
  ```

  ```bash cURL theme={null}
  curl https://aihubmix.com/v1/messages \
    -H "Content-Type: application/json" \
    -H "x-api-key: <AIHUBMIX_API_KEY>" \
    -H "anthropic-version: 2023-06-01" \
    -d '{
      "model": "claude-sonnet-5",
      "max_tokens": 1024,
      "messages": [
        {"role": "user", "content": "Extrae la siguiente informacion: Juan Garcia, 28 anos, Madrid Centro"}
      ],
      "output_config": {
        "format": {
          "type": "json_schema",
          "schema": {
            "type": "object",
            "properties": {
              "name": {"type": "string"},
              "age": {"type": "integer"},
              "city": {"type": "string"}
            },
            "required": ["name", "age", "city"],
            "additionalProperties": false
          }
        }
      }
    }'
  ```
</CodeGroup>

***

## Puntos clave para escribir Schemas

### Campos obligatorios

Todos los tipos `object` deben declarar explicitamente `additionalProperties: false`; de lo contrario, algunos proveedores upstream rechazaran la solicitud.

```json theme={null}
{
  "type": "object",
  "properties": {
    "name": { "type": "string" },
    "score": { "type": "number" }
  },
  "required": ["name", "score"],
  "additionalProperties": false
}
```

### Objetos anidados

Los `object` anidados tambien requieren `additionalProperties: false`:

```json theme={null}
{
  "type": "object",
  "properties": {
    "user": {
      "type": "object",
      "properties": {
        "name": { "type": "string" },
        "email": { "type": "string" }
      },
      "required": ["name", "email"],
      "additionalProperties": false
    }
  },
  "required": ["user"],
  "additionalProperties": false
}
```

### Diferencias de Schema entre protocolos

| Caracteristica                                       | Protocolo OpenAI               | Protocolo Anthropic                                                                |
| ---------------------------------------------------- | ------------------------------ | ---------------------------------------------------------------------------------- |
| Campo `name`                                         | Obligatorio                    | No soportado (el gateway lo gestiona automaticamente en llamadas entre protocolos) |
| Campo `strict`                                       | Opcional, se recomienda `true` | No soportado                                                                       |
| Restricciones numericas (`minimum`, `maximum`, etc.) | Soportado                      | No soportado (el gateway las elimina automaticamente, sin afectar la solicitud)    |
| Restricciones de cadena (`minLength`, `maxLength`)   | Soportado                      | No soportado (el gateway las elimina automaticamente)                              |

<Tip>
  Al llamar a modelos Claude mediante el protocolo OpenAI, el gateway convierte automaticamente el formato del Schema y elimina las palabras clave incompatibles, sin necesidad de adaptacion manual.
</Tip>

***

## Mecanismo de degradacion automatica

El gateway habilita por defecto la proteccion de degradacion automatica de salidas estructuradas para todas las solicitudes. Cuando el modelo o la plataforma no lo soportan, el gateway **no devuelve un error**, sino que elimina automaticamente las restricciones del Schema y marca el motivo de la degradacion en el encabezado de respuesta. Tu solicitud seguira recibiendo una respuesta normal del modelo, solo que la salida no estara sujeta a las restricciones forzadas del Schema.

Esto significa que puedes habilitar con confianza las salidas estructuradas de forma uniforme en el cliente, sin necesidad de verificar la compatibilidad de cada modelo:

* **Cambio de modelos sin preocupaciones**: al alternar entre Claude, GPT, Gemini y GLM con el mismo codigo, incluso si el modelo de destino no soporta salidas estructuradas, la solicitud no fallara
* **Enrutamiento Fallback transparente**: cuando el canal principal no esta disponible y se activa el enrutamiento Fallback hacia un canal de respaldo, incluso si la version del modelo del canal de respaldo no soporta salidas estructuradas, la solicitud se completara normalmente
* **Logica del cliente simplificada**: no necesitas mantener una lista de "que modelos soportan salidas estructuradas", el gateway ya lo gestiona automaticamente; el cliente solo necesita verificar el encabezado de respuesta para decidir si se requiere un analisis adicional

### Encabezado de respuesta

```
X-Structured-Output-Degraded: <reason>
```

| reason                                 | Significado                                                                                  |
| -------------------------------------- | -------------------------------------------------------------------------------------------- |
| `model_unsupported`                    | El modelo (o el modelo en la plataforma actual) no soporta salidas estructuradas             |
| `json_object_unsupported_on_anthropic` | El modo `json_object` no puede convertirse al formato Anthropic                              |
| `json_schema_missing_schema`           | Se especifico el tipo `json_schema` pero falta el campo `schema`                             |
| `schema_keywords_stripped`             | Se eliminaron algunas palabras clave de restriccion del Schema (como `minimum`, `maxLength`) |

### Ejemplo de deteccion

```python Python theme={null}
import httpx

response = httpx.post(
    "https://aihubmix.com/v1/chat/completions",
    headers={
        "Authorization": "Bearer <AIHUBMIX_API_KEY>",
        "Content-Type": "application/json",
    },
    json={
        "model": "claude-sonnet-5",
        "messages": [{"role": "user", "content": "Extraer informacion: Juan Garcia, 28 anos"}],
        "response_format": {
            "type": "json_schema",
            "json_schema": {
                "name": "person",
                "strict": True,
                "schema": {
                    "type": "object",
                    "properties": {"name": {"type": "string"}, "age": {"type": "integer"}},
                    "required": ["name", "age"],
                    "additionalProperties": False,
                }
            }
        }
    }
)

# Verificar si ocurrio una degradacion (por ejemplo, cuando la solicitud se enruta a un canal Bedrock no compatible)
degraded = response.headers.get("X-Structured-Output-Degraded")
if degraded:
    print(f"Salida estructurada degradada: {degraded}")
    # La respuesta del modelo sigue siendo normal, pero la salida no esta sujeta a restricciones forzadas del Schema
else:
    import json
    data = json.loads(response.json()["choices"][0]["message"]["content"])
    print(data)  # {"name": "Juan Garcia", "age": 28}
```

***

## Diferencias con el modo `json_object`

|                        | `json_schema` (salidas estructuradas)                        | `json_object`                        |
| ---------------------- | ------------------------------------------------------------ | ------------------------------------ |
| Garantia de salida     | Coincidencia estricta con el Schema especificado             | Solo garantiza que sea JSON valido   |
| Control de campos      | Nombres, tipos y obligatoriedad de campos estan restringidos | Sin restricciones                    |
| Protocolos compatibles | OpenAI / Anthropic / Responses                               | Solo protocolo compatible con OpenAI |
| Soporte de Claude      | Mediante `output_config.format`                              | No soportado                         |

<Warning>
  El modo `json_object` no soporta la conversion al protocolo nativo de Claude. Si envias `response_format: {"type": "json_object"}` a Claude mediante el protocolo OpenAI, el encabezado de respuesta marcara la degradacion `json_object_unsupported_on_anthropic`. Se recomienda usar directamente el tipo `json_schema`.
</Warning>

***

## Preguntas frecuentes

<AccordionGroup>
  <Accordion title="Que modelos soportan Structured Outputs?">
    **Serie Claude** (mediante `output_config.format` de la API de Anthropic):

    * Opus / Sonnet / Haiku 4.5 y versiones superiores
    * Fable / Mythos 5 y versiones superiores
    * En la plataforma Bedrock solo 4.5-4.6; Vertex AI igual que la conexion directa

    **Serie OpenAI** (mediante `response_format`):

    * GPT-4o y superiores, serie GPT-5

    **Serie Gemini** (mediante `responseSchema`):

    * Gemini 2.5 y superiores

    Puedes consultar las etiquetas de capacidad de cada modelo en la [pagina de lista de modelos](https://aihubmix.com/models).
  </Accordion>

  <Accordion title="Por que algunos modelos de Claude en Bedrock no soportan salidas estructuradas?">
    En AWS Bedrock, Claude 4.7+ utiliza la nueva ruta de inferencia Mantle, que actualmente no acepta el parametro `output_config.format`. El gateway lo gestiona automaticamente: elimina el campo format y devuelve la respuesta normalmente, marcando al mismo tiempo el encabezado de degradacion `X-Structured-Output-Degraded: model_unsupported`. Claude 4.5-4.6 tiene soporte completo en Bedrock.
  </Accordion>

  <Accordion title="Se modifica el JSON Schema en llamadas entre protocolos?">
    Si. Al llamar a modelos Claude mediante el protocolo OpenAI, el gateway automaticamente:

    1. Convierte `response_format` a `output_config.format`
    2. Elimina las palabras clave del Schema no soportadas por Anthropic (`minimum`, `maxLength`, etc.)
    3. Si se eliminaron palabras clave, el encabezado de respuesta marca `schema_keywords_stripped`

    La conversion inversa (protocolo Claude llamando a modelos OpenAI) tambien se realiza automaticamente.
  </Accordion>

  <Accordion title="Se pueden usar Structured Outputs y Extended Thinking al mismo tiempo?">
    Si. El campo `format` (salidas estructuradas) dentro de `output_config` y el campo `effort` (intensidad de razonamiento) dentro de `reasoning` son parametros independientes que se pueden configurar simultaneamente:

    ```json theme={null}
    {
      "output_config": {
        "format": {
          "type": "json_schema",
          "schema": { ... }
        }
      },
      "reasoning": {
        "effort": "high"
      }
    }
    ```
  </Accordion>

  <Accordion title="En comparacion con otras plataformas de agregacion como OpenRouter, en que se diferencia el mecanismo de degradacion?">
    La mayoria de las plataformas de agregacion de API devuelven un error directamente cuando el modelo no soporta salidas estructuradas. AIHubMix adopta una estrategia de **degradacion elegante**: elimina automaticamente los parametros incompatibles, devuelve la respuesta del modelo normalmente e informa al cliente del motivo de la degradacion a traves del encabezado de respuesta `X-Structured-Output-Degraded`. Tu aplicacion no se interrumpira por este motivo.
  </Accordion>
</AccordionGroup>
