> ## 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.

# Reparación de salida estructurada

> Reparación de salida estructurada por API Key: repara JSON con errores (truncamiento, comas, bloques de código) en Chat Completions, Responses, Claude y Gemini.

En escenarios de [salida estructurada](/es/api/Structured-Output), el JSON que devuelve el modelo a veces no se puede parsear: la salida se trunca por `max_tokens`, incluye comas finales o el contenido viene envuelto en un bloque de código Markdown. Por lo general, la aplicación tiene que escribir lógica de reintento o de reparación manual para estos casos.

La **reparación de salida estructurada** (Structured Output Repair) es una capacidad a **nivel de Key**, desactivada por defecto. Una vez activada, para las solicitudes **no en streaming** que declaran una salida JSON estructurada, cuando el JSON devuelto por el modelo presenta errores de formato, la pasarela de AIHubMix lo repara automáticamente a un JSON válido y parseable antes de devolverlo; el código del cliente no necesita ningún cambio.

<Note>
  Este interruptor está desactivado por defecto; mientras no se active, todas las respuestas se devuelven tal cual. El interruptor se configura de forma independiente por Key y surte efecto de inmediato tras activarlo.
</Note>

<Card title="Ir a la página de gestión de Keys para configurarlo" icon="key" href="https://console.aihubmix.com/token" horizontal>
  Cree o edite una Key y active el interruptor «Reparación de salida estructurada» (Structured Output Repair).
</Card>

<Frame>
  <img src="https://mintcdn.com/aihubmix/qSKYuy2NVPUOModZ/images/api/structured-output-repair/create-key-json-repair.png?fit=max&auto=format&n=qSKYuy2NVPUOModZ&q=85&s=119802fb4114c18581c6e47c1543620a" alt="Activar el interruptor de reparación de salida estructurada en el panel de edición de Key de AIHubMix" width="2886" height="1974" data-path="images/api/structured-output-repair/create-key-json-repair.png" />
</Frame>

***

## 1. Condiciones de aplicación

La reparación solo se produce cuando se cumplen **todas** las condiciones siguientes:

1. La Key usada en la solicitud tiene activada la «Reparación de salida estructurada».
2. La solicitud es **no en streaming** (no tiene `stream: true`).
3. La solicitud declara una salida JSON estructurada (los campos de declaración de cada protocolo se indican en la tabla siguiente).
4. El contenido de texto devuelto por el modelo no se puede parsear como JSON.

| Protocolo        | Endpoint                                        | Campo de declaración de salida estructurada                                                   |
| ---------------- | ----------------------------------------------- | --------------------------------------------------------------------------------------------- |
| Chat Completions | `/v1/chat/completions`                          | `response_format.type` con valor `json_object` o `json_schema`                                |
| Responses        | `/v1/responses`                                 | `text.format.type` con valor `json_schema` o `json_object`                                    |
| Claude Messages  | `/v1/messages`                                  | `output_config.format.type` con valor `json_schema`                                           |
| Gemini           | `/gemini/v1beta/models/{model}:generateContent` | `generationConfig.responseMimeType` con valor `application/json`, o `responseSchema` definido |

Cuando el contenido ya es JSON válido no se realiza ningún cambio y se devuelve tal cual.

***

## 2. Errores de formato reparables

**Truncamiento de la salida que deja paréntesis / comillas sin cerrar** (por ejemplo, `finish_reason` con valor `length`):

```text Antes theme={null}
{"items": [{"name": "Widget", "price": 9.99}, {"name": "Gad
```

```json Después theme={null}
{"items": [{"name": "Widget", "price": 9.99}, {"name": "Gad"}]}
```

**Envoltura en un bloque de código Markdown**:

````text Antes theme={null}
```json
{"status": "ok", "count": 3}
```
````

```json Después theme={null}
{"status": "ok", "count": 3}
```

**Comas finales**:

```text Antes theme={null}
{"a": 1, "b": 2,}
```

```json Después theme={null}
{"a": 1, "b": 2}
```

**Comillas simples**:

```text Antes theme={null}
{'name': 'Widget'}
```

```json Después theme={null}
{"name": "Widget"}
```

**Nombres de clave sin comillas**:

```text Antes theme={null}
{name: "Widget", price: 9.99}
```

```json Después theme={null}
{"name": "Widget", "price": 9.99}
```

**Texto y JSON mezclados** (JSON con texto explicativo antes o después):

```text Antes theme={null}
Here is the JSON you requested: {"name": "Widget", "price": 9.99}
```

```json Después theme={null}
{"name": "Widget", "price": 9.99}
```

La reparación adopta una estrategia conservadora:

* La reparación solo completa o normaliza la sintaxis JSON; **el contenido de los valores y las cadenas se mantiene tal cual, sin pérdida de precisión ni reescritura**.
* El resultado de la reparación debe ser un objeto o un array JSON válido y con una diferencia razonable respecto al original; si no se cumple alguna de estas condiciones, se descarta la reparación y se devuelve el contenido original tal cual.

***

## 3. Cómo saber si una respuesta ha sido reparada

Cuando se produce una reparación, hay dos señales programables / consultables:

1. **Cabecera de respuesta** `X-JSON-Repaired: true` (esta cabecera no aparece cuando no ha habido reparación).
2. **Nota en el registro de llamadas**: en la [página de registros de llamadas](https://console.aihubmix.com/logs), la columna de notas de la solicitud correspondiente muestra `This request gateway automatically corrected the JSON format issue in the model output.`

El consumo de tokens y la facturación se calculan según la salida original del modelo; la reparación no altera el resultado de la facturación.

***

## 4. Ejemplo completo

Tomando como ejemplo la generación de información de un producto, la solicitud usa `json_schema` para declarar la salida estructurada; con el interruptor activado, aunque la salida del modelo presente los errores de formato anteriores, el `content` obtenido se puede parsear directamente:

<CodeGroup>
  ```python Python theme={null}
  import json
  import os
  import requests

  response = requests.post(
      "https://aihubmix.com/v1/chat/completions",
      headers={
          "Authorization": f"Bearer {os.environ['AIHUBMIX_API_KEY']}",
          "Content-Type": "application/json",
      },
      json={
          "model": "gpt-5.2",
          "messages": [
              {"role": "user", "content": "Generate a product listing for a wireless keyboard."}
          ],
          "response_format": {
              "type": "json_schema",
              "json_schema": {
                  "name": "product",
                  "schema": {
                      "type": "object",
                      "properties": {
                          "name": {"type": "string"},
                          "price": {"type": "number"},
                          "description": {"type": "string"},
                      },
                      "required": ["name", "price"],
                      "additionalProperties": False,
                  },
              },
          },
      },
  )

  repaired = response.headers.get("X-JSON-Repaired") == "true"
  product = json.loads(response.json()["choices"][0]["message"]["content"])
  print(product, "repaired:", repaired)
  ```

  ```typescript TypeScript theme={null}
  const response = await fetch("https://aihubmix.com/v1/chat/completions", {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.AIHUBMIX_API_KEY}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      model: "gpt-5.2",
      messages: [
        { role: "user", content: "Generate a product listing for a wireless keyboard." },
      ],
      response_format: {
        type: "json_schema",
        json_schema: {
          name: "product",
          schema: {
            type: "object",
            properties: {
              name: { type: "string" },
              price: { type: "number" },
              description: { type: "string" },
            },
            required: ["name", "price"],
            additionalProperties: false,
          },
        },
      },
    }),
  });

  const repaired = response.headers.get("X-JSON-Repaired") === "true";
  const data = await response.json();
  const product = JSON.parse(data.choices[0].message.content);
  console.log(product, "repaired:", repaired);
  ```

  ```shell curl theme={null}
  curl -sD - https://aihubmix.com/v1/chat/completions \
    -H "Authorization: Bearer $AIHUBMIX_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "model": "gpt-5.2",
      "messages": [
        {"role": "user", "content": "Generate a product listing for a wireless keyboard."}
      ],
      "response_format": {
        "type": "json_schema",
        "json_schema": {
          "name": "product",
          "schema": {
            "type": "object",
            "properties": {
              "name": {"type": "string"},
              "price": {"type": "number"},
              "description": {"type": "string"}
            },
            "required": ["name", "price"],
            "additionalProperties": false
          }
        }
      }
    }'
  ```
</CodeGroup>

Si quiere observar una reparación de forma activa, puede fijar `max_tokens` en un valor pequeño (por ejemplo, `80`) para que la salida se trunque: el `finish_reason` de la respuesta será `length`, el `content` será el JSON válido ya reparado y la cabecera de respuesta incluirá `X-JSON-Repaired: true`.

***

## 5. Límites y notas

<Warning>
  Las solicitudes en streaming (`stream: true`) no se reparan y se reenvían tal cual. Cuando necesite la capacidad de reparación, use solicitudes no en streaming.
</Warning>

<Warning>
  La reparación garantiza que el contenido se pueda parsear como JSON; los datos que falten por truncamiento no se pueden recuperar. Se recomienda comprobar también `finish_reason` / `stop_reason` y, cuando la salida esté truncada, aumentar `max_tokens` según sea necesario y reintentar.
</Warning>

* **Reparación de sintaxis**: si los nombres y tipos de los campos se ajustan a su schema es algo que la aplicación aún debe validar.
* **Los parámetros de llamada a herramientas quedan fuera del alcance de la reparación**: el JSON de los parámetros de `tool_calls` / `function_call` no se repara; los parámetros de las herramientas deben ser siempre validados por la aplicación antes de su ejecución.
* **Las salidas con varios bloques de texto no se reparan**: cuando la salida del modelo incluye varios bloques de texto (por ejemplo, cuando Gemini devuelve varios `parts`), se devuelve tal cual.
* **El contenido de razonamiento no se ve afectado**: el texto de razonamiento como `reasoning_content` o la parte thought de Gemini no participa en la reparación.

***

## Preguntas frecuentes (FAQ)

**¿La reparación modifica los valores numéricos o el texto del contenido devuelto?**

No. La reparación solo completa o normaliza la sintaxis JSON (cierra paréntesis, elimina comas finales, normaliza comillas, retira las marcas de bloque de código); el contenido de los valores y las cadenas se mantiene tal cual lo produjo el modelo.

**¿Activar el interruptor afecta a las solicitudes normales que no declaran salida estructurada?**

No. Las solicitudes que no declaran campos de salida estructurada como `response_format`, así como todas las solicitudes en streaming, devuelven su respuesta tal cual.

**¿La reparación genera facturación adicional o altera el consumo de tokens?**

No. El consumo de tokens y la facturación se calculan según la salida original del modelo; el proceso de reparación no genera ningún coste adicional.

**¿El JSON reparado cumple siempre el schema que definí?**

La reparación garantiza que el contenido se pueda parsear como JSON; que los nombres y tipos de los campos cumplan el schema depende de la propia salida del modelo, por lo que se recomienda que la aplicación conserve la validación del schema.
