# Sorties structurées JSON : extraire des données fiables d’un LLM

> Utiliser le mode JSON et les schémas de sortie d'une API de LLM pour obtenir des données exploitables directement, puis les valider côté PHP avant tout usage.

- Auteur : Clément Hadrot
- Publié le : 2024-05-10
- Mis à jour le : 2024-05-10
- Catégorie : IA &amp; MCP
- URL : https://wpmoderne.dev.wordpress-developpement.fr/ia-mcp/sorties-structurees-json-llm/

## L’essentiel

- Le mode JSON garantit un format, pas un contenu correct
- Un schéma précis réduit fortement les erreurs
- La validation PHP reste obligatoire après réception

Extraire des données structurées d'un texte libre avec un modèle de langage a longtemps reposé sur une méthode fragile : demander dans le prompt de répondre « au format JSON », puis espérer que la réponse soit effectivement un JSON valide, avant de tenter un `json_decode()` qui échouait une fois sur dix sur des cas limites. Les sorties structurées, apparues plus largement en 2024, changent la donne en contraignant réellement le format de la réponse au niveau de l'API elle-même.

Ce tutoriel ne traite pas le function calling, abordé séparément : il porte sur l'extraction directe de données structurées à partir d'un texte, sans notion d'appel de fonction ni d'exécution d'action.

## La différence entre demander du JSON et l'imposer

Demander « réponds en JSON » dans un prompt reste une instruction que le modèle peut mal suivre, en ajoutant du texte explicatif avant ou après l'objet JSON, ou en produisant une syntaxe légèrement invalide. Le mode de sortie structurée fonctionne différemment : il contraint techniquement la génération du modèle, token par token, pour qu'elle respecte un schéma JSON fourni dans la requête, rendant une sortie non conforme au schéma nettement moins probable.

## Définir un schéma précis pour l'extraction

Prenons un cas concret : extraire d'un communiqué de presse envoyé par un client les informations structurées nécessaires pour préremplir un formulaire d'article — titre suggéré, date d'événement, ville, et liste de personnes citées.

```
$schema = array(
    'type'       => 'object',
    'properties' => array(
        'titre_suggere' => array( 'type' => 'string' ),
        'date_evenement' => array( 'type' => 'string', 'description' => 'Format AAAA-MM-JJ' ),
        'ville'          => array( 'type' => 'string' ),
        'personnes_citees' => array(
            'type'  => 'array',
            'items' => array( 'type' => 'string' ),
        ),
    ),
    'required' => array( 'titre_suggere', 'date_evenement', 'ville', 'personnes_citees' ),
    'additionalProperties' => false,
);
```

> L'essentiel à retenir : Le mode JSON garantit un format, pas un contenu correct ; Un schéma précis réduit fortement les erreurs ; La validation PHP reste obligatoire après réception

## Envoyer le schéma dans la requête à l'API

Le schéma accompagne la requête dans un paramètre dédié au format de sortie, distinct du contenu du message. La structure exacte de ce paramètre varie selon le fournisseur, mais le principe reste le même : le schéma est transmis en même temps que le prompt, pas décrit uniquement en langage naturel dans le texte de l'instruction.

```
$reponse = wp_remote_post( 'https://api.openai.com/v1/chat/completions', array(
    'timeout' => 20,
    'headers' => array(
        'Authorization' => 'Bearer ' . WPM_LLM_API_KEY,
        'Content-Type'  => 'application/json',
    ),
    'body'    => wp_json_encode( array(
        'model'           => 'gpt-4o-mini',
        'messages'        => array(
            array( 'role' => 'user', 'content' => $texte_communique ),
        ),
        'response_format' => array(
            'type'        => 'json_schema',
            'json_schema' => array(
                'name'   => 'extraction_communique',
                'schema' => $schema,
                'strict' => true,
            ),
        ),
    ) ),
) );
```

## La validation PHP reste obligatoire malgré tout

Le mode structuré garantit que la réponse respecte la forme du schéma : les bons types, les bonnes clés. Il ne garantit en rien que le contenu est correct sur le fond. Une date d'événement peut être structurellement valide, au format attendu, tout en étant erronée parce que le modèle l'a mal extraite du texte source. La validation métier reste donc entièrement à la charge du code PHP.

```
function wpm_valider_extraction( $donnees ) {
    $erreurs = array();

    if ( ! empty( $donnees['date_evenement'] )
        && ! preg_match( '/^\d{4}-\d{2}-\d{2}$/', $donnees['date_evenement'] ) ) {
        $erreurs[] = 'Format de date invalide.';
    }

    if ( empty( $donnees['ville'] ) || mb_strlen( $donnees['ville'] ) > 100 ) {
        $erreurs[] = 'Ville manquante ou anormalement longue.';
    }

    return $erreurs;
}
```

### Le champ toujours prérempli, jamais publié directement

Les données extraites servent uniquement à préremplir le formulaire de création d'article dans l'administration, jamais à publier un article automatiquement. Une personne de la rédaction vérifie et corrige chaque champ avant l'enregistrement effectif, ce qui absorbe les erreurs d'extraction qui échapperaient à la validation technique.

## Ce que le mode structuré a changé concrètement

Avant l'usage des sorties structurées, environ une extraction sur dix nécessitait un nouvel appel à cause d'un JSON mal formé. Ce taux d'échec technique est tombé à un niveau négligeable avec le schéma imposé, ce qui a permis de retirer entièrement la logique de nouvelle tentative automatique que nous devions maintenir auparavant.

> Le format structuré résout un problème de forme. Il ne dispense jamais de vérifier le fond, particulièrement sur des données qui finiront dans un formulaire prérempli.

## Notre verdict

Pour toute extraction de données à partir d'un texte libre, les sorties structurées constituent désormais le point de départ par défaut plutôt qu'une instruction textuelle espérant un JSON bien formé. Elles réduisent fortement les erreurs de format, mais n'exemptent jamais de la validation métier appliquée ensuite côté PHP.
