Passer au contenu principal
Dans les scénarios de sortie structurée, le JSON renvoyé par le modèle ne peut parfois pas être analysé : la sortie est tronquée par max_tokens, comporte une virgule finale, ou le contenu est encadré par un bloc de code Markdown. Côté application, il faut généralement écrire une logique de nouvelle tentative ou de correction manuelle pour y remédier. La réparation de sortie structurée (Structured Output Repair) est une capacité au niveau de la clé, désactivée par défaut. Une fois activée, pour les requêtes non-streaming déclarant une sortie JSON structurée, lorsque le JSON renvoyé par le modèle présente des erreurs de format, la passerelle AIHubMix le répare automatiquement, avant le retour, en un JSON valide et analysable ; le code client n’a besoin d’aucune modification.
Cette option est désactivée par défaut ; lorsqu’elle n’est pas activée, toutes les réponses sont renvoyées telles quelles. L’option se configure indépendamment pour chaque clé et prend effet immédiatement après activation.

Accéder à la page de gestion des clés

Créez ou modifiez une clé, puis activez l’option « Réparation de sortie structurée » (Structured Output Repair).
Activation de l'option de réparation de sortie structurée dans le panneau d'édition de clé AIHubMix

1. Conditions de déclenchement

La réparation n’a lieu que lorsque toutes les conditions suivantes sont réunies :
  1. La clé utilisée par la requête a activé « Réparation de sortie structurée ».
  2. La requête est non-streaming (stream: true n’est pas défini).
  3. La requête déclare une sortie JSON structurée (voir le tableau ci-dessous pour les champs de déclaration de chaque protocole).
  4. Le contenu textuel renvoyé par le modèle ne peut pas être analysé en JSON.
ProtocolePoint de terminaisonChamp de déclaration de sortie structurée
Chat Completions/v1/chat/completionsresponse_format.type vaut json_object ou json_schema
Responses/v1/responsestext.format.type vaut json_schema ou json_object
Claude Messages/v1/messagesoutput_config.format.type vaut json_schema
Gemini/gemini/v1beta/models/{model}:generateContentgenerationConfig.responseMimeType vaut application/json, ou responseSchema est défini
Lorsque le contenu est déjà un JSON valide, aucune modification n’est apportée et il est renvoyé tel quel.

2. Erreurs de format réparables

Parenthèses / guillemets non fermés en raison d’une troncature de la sortie (par exemple lorsque finish_reason vaut length) :
Avant
{"items": [{"name": "Widget", "price": 9.99}, {"name": "Gad
Après
{"items": [{"name": "Widget", "price": 9.99}, {"name": "Gad"}]}
Encadrement par un bloc de code Markdown :
Avant
```json
{"status": "ok", "count": 3}
```
Après
{"status": "ok", "count": 3}
Virgule finale :
Avant
{"a": 1, "b": 2,}
Après
{"a": 1, "b": 2}
Guillemets simples :
Avant
{'name': 'Widget'}
Après
{"name": "Widget"}
Noms de clés sans guillemets :
Avant
{name: "Widget", price: 9.99}
Après
{"name": "Widget", "price": 9.99}
Texte et JSON mélangés (texte explicatif avant ou après le JSON) :
Avant
Here is the JSON you requested: {"name": "Widget", "price": 9.99}
Après
{"name": "Widget", "price": 9.99}
La réparation adopte une stratégie conservatrice :
  • La réparation se contente de compléter ou de normaliser la syntaxe JSON ; les valeurs numériques et le contenu des chaînes conservent leur texte d’origine, sans perte de précision ni réécriture.
  • Le produit de la réparation doit être un objet ou un tableau JSON valide, et l’écart avec le texte d’origine doit rester dans une plage raisonnable ; si l’une de ces conditions n’est pas remplie, la réparation est abandonnée et le contenu d’origine est renvoyé tel quel.

3. Comment déterminer qu’une réponse a été réparée

Lorsqu’une réparation a lieu, deux signaux sont disponibles, l’un exploitable par programme, l’autre consultable :
  1. En-tête de réponse X-JSON-Repaired: true (cet en-tête est absent lorsqu’aucune réparation n’a eu lieu).
  2. Note dans le journal d’appels : sur la page des journaux d’appels, la colonne des notes de la requête correspondante affiche This request gateway automatically corrected the JSON format issue in the model output.
La consommation de tokens et la facturation sont calculées sur la sortie d’origine du modèle ; la réparation ne modifie pas le résultat de la facturation.

4. Exemple complet

Prenons l’exemple de la génération d’informations sur un produit : la requête utilise json_schema pour déclarer une sortie structurée ; une fois l’option activée, même si la sortie du modèle présente les erreurs de format évoquées ci-dessus, le content obtenu peut être analysé directement :
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)
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);
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
        }
      }
    }
  }'
Pour observer volontairement une réparation, vous pouvez régler max_tokens sur une valeur faible (par exemple 80) afin de tronquer la sortie : le finish_reason de la réponse vaut length, le content est un JSON valide après réparation, et l’en-tête de réponse porte X-JSON-Repaired: true.

5. Limites et précisions

Les requêtes en streaming (stream: true) ne sont pas réparées et sont transmises telles quelles. Si vous avez besoin de la capacité de réparation, utilisez des requêtes non-streaming.
La réparation garantit que le contenu peut être analysé en JSON ; les données perdues à cause d’une troncature ne peuvent pas être restaurées. Il est recommandé de vérifier également finish_reason / stop_reason, et d’augmenter max_tokens au besoin puis de réessayer lorsque la sortie est tronquée.
  • Réparation syntaxique : la conformité des noms et des types de champs à votre schéma doit toujours être validée côté application.
  • Les paramètres d’appel d’outils ne sont pas concernés par la réparation : le JSON des paramètres de tool_calls / function_call n’est pas réparé ; les paramètres d’outils doivent toujours être validés côté application avant exécution.
  • Les sorties à blocs de texte multiples ne sont pas réparées : lorsque la sortie du modèle contient plusieurs blocs de texte (par exemple lorsque Gemini renvoie plusieurs parts), elle est renvoyée telle quelle.
  • Le contenu de raisonnement n’est pas affecté : les textes de raisonnement tels que reasoning_content ou la partie « thought » de Gemini ne participent pas à la réparation.

FAQ

La réparation modifie-t-elle les valeurs numériques ou le texte du contenu renvoyé ? Non. La réparation se contente de compléter ou de normaliser la syntaxe JSON (fermeture des parenthèses manquantes, suppression des virgules finales, normalisation des guillemets, retrait des marqueurs de bloc de code) ; les valeurs numériques et le contenu des chaînes conservent le texte d’origine de la sortie du modèle. Activer l’option affecte-t-il les requêtes ordinaires ne déclarant pas de sortie structurée ? Non. Les requêtes ne déclarant pas de champ de sortie structurée tel que response_format, ainsi que toutes les requêtes en streaming, voient leur réponse renvoyée telle quelle. La réparation entraîne-t-elle une facturation supplémentaire ou modifie-t-elle la consommation de tokens ? Non. La consommation de tokens et la facturation sont calculées sur la sortie d’origine du modèle ; le processus de réparation ne génère aucun coût supplémentaire. Le JSON réparé est-il forcément conforme au schéma que j’ai défini ? La réparation garantit que le contenu peut être analysé en JSON ; la conformité des noms et des types de champs au schéma dépend de la sortie du modèle elle-même. Il est recommandé de conserver une validation du schéma côté application.