---
title: "Structured output des LLM avec JSON Schema : des réponses fiables"
description: "Les sorties structurées avec JSON Schema sont une technique qui oblige un LLM à produire sa réponse exactement selon un schéma JSON prédéfini."
locale: "fr"
canonical: "https://blckalpaca.at/fr/base-de-connaissances/agents-ia/quest-ce-quun-llm-les-fondamentaux-pour-les-agents-ia/structured-output-des-llm-avec-json-schema-des-reponses-fiables"
category: "Agents IA"
topic: "Qu'est-ce qu'un LLM ? Les fondamentaux pour les agents IA"
updated: "2026-10-28T13:27:18.098Z"
source: "Blck Alpaca e.U., blckalpaca.at"
---

# Structured output des LLM avec JSON Schema : des réponses fiables

Les sorties structurées avec JSON Schema sont une technique qui oblige un LLM à produire sa réponse exactement selon un schéma JSON prédéfini. Au lieu de texte libre, le modèle renvoie un objet lisible par machine et validable. Les pipelines d'agents deviennent ainsi fiables, car les étapes suivantes du programme peuvent s'appuyer sur une structure de données garantie.

## L’essentiel

- Les sorties structurées imposent un schéma JSON fixe et remplacent le parsing de texte libre, source d'erreurs, par une structure de données garantie et validable.
- Il existe trois niveaux de garantie : prompt seul (aucune garantie), mode JSON (JSON valide, mais pas ton schéma) et constrained decoding ou Structured Outputs (schéma strictement imposé).
- Le constrained decoding garantit la syntaxe et la conformité au schéma, mais pas l'exactitude du contenu. Une validation métier et une stratégie de relance restent obligatoires.
- Chez Anthropic Claude, les Structured Outputs imposent le schéma, soit sous forme de JSON Output (output_config.format), soit via Strict Tool Use (strict: true). Chez OpenAI, cela passe par les Structured Outputs en mode strict. Le tool use classique sans strict ne garantit pas le schéma.
- Pour les agents multi-étapes, c'est essentiel : chaque étape peu fiable se multiplie sur toute la chaîne et fait chuter le taux de réussite de bout en bout.
- La validation avec Pydantic ou Zod, combinée à un nombre limité de relances avec retour d'erreur, est le standard pratique pour des pipelines robustes.

Les sorties structurées avec JSON Schema sont une technique qui oblige un [LLM](https://blckalpaca.at/fr/glossaire/llm) à produire sa réponse exactement selon un schéma JSON prédéfini. Au lieu de texte libre, le modèle renvoie un objet lisible par machine et validable. Les pipelines d'agents deviennent ainsi fiables, car les étapes suivantes du programme peuvent s'appuyer sur une structure de données garantie au lieu de parser un texte libre source d'erreurs.

- **Quoi ?** Le modèle renvoie du JSON selon un schéma fixe, pas du texte libre. Champs, types et valeurs autorisées sont définis.
- **Pourquoi ?** Les programmes peuvent traiter le résultat directement, sans logique fragile à base de regex ou de chaînes de caractères. C'est la base d'agents fiables.
- **Comment ?** Via les fonctions des fournisseurs, comme les Structured Outputs d'[OpenAI](https://blckalpaca.at/fr/glossaire/openai) et d'Anthropic, ou via le constrained decoding pour les modèles open-weight, complétés par une validation et des relances.

## Pourquoi le parsing de texte libre échoue dans les pipelines d'agents

Par défaut, un modèle de langage produit du texte pour des lecteurs humains. C'est idéal pour un [chatbot](https://blckalpaca.at/fr/glossaire/chatbot), mais problématique pour un pipeline automatisé. Dès qu'un programme doit extraire une valeur de la réponse, par exemple une catégorie, une date, un montant ou une liste, commence le travail fragile du parsing. Le modèle écrit tantôt `"Die Kategorie ist Rechnung."`, tantôt `"Kategorie: Rechnung"`, tantôt il ajoute une explication devant. Chacune de ces variantes casse une logique d'extraction naïve.

Dans les [agents multi-étapes](https://blckalpaca.at/fr/base-de-connaissances/agents-ia/architectures-dagents-ia-vue-densemble), le problème s'aggrave fortement, car le manque de fiabilité se **multiplie** tout au long de la chaîne. Un exemple chiffré : si chaque étape a un taux de réussite de parsing de 95 %, le taux de réussite de bout en bout d'une chaîne de dix étapes tombe à 0,95 puissance 10, soit environ 60 %. Si les sorties structurées portent chaque étape à 99,5 %, la même chaîne atteint environ 95 %. De cet effet multiplicateur découle la thèse centrale de cet article : les sorties structurées ne sont pas une fonction de confort, mais la condition pour que les pipelines d'agents soient tout simplement prêts pour la production.

## Les trois niveaux de garantie en bref

Toutes les méthodes qui promettent du JSON n'offrent pas la même garantie. Il faut distinguer trois niveaux, et la différence détermine la fiabilité.

[**Prompt](https://blckalpaca.at/fr/glossaire/prompt) seul.** Tu demandes poliment au modèle de produire du JSON. Cela marche souvent, mais pas toujours. Le modèle peut ajouter des blocs de code Markdown, omettre des champs ou, en cas de doute, repasser au texte libre. Aucune garantie.

**Mode JSON.** Le fournisseur garantit que la sortie est du JSON syntaxiquement valide. Cela élimine les erreurs de syntaxe, mais ne dit rien de la structure : des champs peuvent manquer, avoir un mauvais type ou apparaître en trop. Garantie partielle.

**Constrained decoding / Structured Outputs.** Ici, le processus de génération est restreint au niveau des tokens, de sorte que seuls les tokens conformes au schéma peuvent être générés. Le modèle ne peut plus du tout sortir d'un résultat conforme au schéma. Champs obligatoires, types et valeurs d'enum autorisées sont garantis. Cette technique sous-tend OpenAI Structured Outputs (mode strict) et les [Structured Outputs d'Anthropic](https://platform.claude.com/docs/en/build-with-claude/structured-outputs), c'est-à-dire les JSON Outputs via `output_config.format` et le [Strict Tool Use](https://platform.claude.com/docs/en/agents-and-tools/tool-use/strict-tool-use) avec `strict: true`. Le [tool use](https://blckalpaca.at/fr/base-de-connaissances/agents-ia/quest-ce-quun-llm-les-fondamentaux-pour-les-agents-ia/function-calling-vs-tool-use-definitions-et-implementations) classique sans `strict` ne garantit pas le schéma. Pour les modèles open-weight, des bibliothèques et des stacks d'inférence remplissent la même fonction grâce à des contraintes de grammaire.

## Comparatif : méthode, garantie, compromis

| Méthode | Garantie | Compromis |
| --- | --- | --- |
| Prompt seul ("réponds en JSON") | Aucune. Le modèle peut dévier ou renvoyer du texte libre | Zéro effort d'implémentation, mais peu fiable en production |
| Mode JSON | JSON syntaxiquement valide, mais pas ton schéma | Élimine les erreurs de syntaxe, mais pas les champs manquants ou mal typés |
| Structured Outputs / strict (OpenAI) | Schéma strictement imposé (champs, types, enums) | La première requête par schéma peut coûter de la latence pour la compilation du schéma ; limites du sous-ensemble de schéma pris en charge |
| JSON Outputs / Strict Tool Use ([Anthropic Claude](https://blckalpaca.at/fr/glossaire/anthropic-claude)) | Schéma imposé par constrained decoding (output\_config.format ou strict: true) | La première requête par schéma coûte de la latence pour la compilation de la grammaire ; limites du sous-ensemble de schéma pris en charge |
| Constrained decoding (open-weight, stacks locales) | La grammaire impose la conformité au schéma au niveau des tokens | Exige la maîtrise de la stack d'inférence ; la complexité du schéma influe sur la vitesse |
| Schéma + validation + relance (Pydantic/Zod) | Forme garantie plus contrôle sémantique | Plus de code et de logique, mais la variante la plus robuste pour les pipelines critiques |

L'enseignement décisif de ce tableau : le constrained decoding garantit la **forme**, pas le **contenu**. Le modèle livre à coup sûr un objet valide avec le champ `rechnungsdatum`, mais aucune méthode de décodage ne peut garantir que la valeur saisie corresponde réellement à la date figurant sur le document. C'est pourquoi la validation métier et la stratégie de relance restent indispensables.

## Ce que proposent les fournisseurs en 2026

Les grands fournisseurs lient désormais la réponse à un schéma JSON, mais diffèrent par leurs paramètres et leurs limites.

- **OpenAI :** [Structured Outputs](https://developers.openai.com/api/docs/guides/structured-outputs) avec `strict: true`, comme format de réponse de type `json_schema` ou dans le function calling. Le mode JSON (`json_object`), en revanche, ne fournit que du JSON valide, sans respecter le schéma.
- **Anthropic Claude :** [JSON Outputs](https://platform.claude.com/docs/en/build-with-claude/structured-outputs) via `output_config.format` ou [Strict Tool Use](https://platform.claude.com/docs/en/agents-and-tools/tool-use/strict-tool-use) avec `strict: true`, tous deux par échantillonnage contraint par grammaire. Sans `strict`, Claude peut renvoyer de mauvais types lors du tool use (`"2"` au lieu de `2`) ou omettre des champs obligatoires. L'[API](https://blckalpaca.at/fr/glossaire/api) ne prend en charge ni les schémas récursifs ni les contraintes comme `minimum` ou `maxLength`. Les limites de longueur, comme dans l'exemple ci-dessous, vont donc dans la `description` et dans la validation.
- **Google Gemini :** l'API accepte un schéma JSON avec le type MIME `application/json` comme [format de réponse](https://ai.google.dev/gemini-api/docs/structured-output). Google recommande lui-même de vérifier malgré tout les valeurs dans l'application.
- **Modèles open-weight :** ici, c'est la stack d'inférence qui impose le schéma par grammaire. [vLLM](https://docs.vllm.ai/en/latest/features/structured_outputs.html) accepte un schéma JSON directement dans son serveur compatible OpenAI, et [llama.cpp](https://github.com/ggml-org/llama.cpp/blob/master/grammars/README.md) traduit une partie de JSON Schema en grammaires GBNF. Si tu gères ta propre stack, tu configures le constrained decoding indépendamment de l'API d'un fournisseur.

Point important en pratique : de nombreux fournisseurs d'inférence proposent des endpoints compatibles OpenAI, mais mettent en œuvre les sorties structurées de manière différente. Avant de t'engager, vérifie si le fournisseur concerné applique réellement le mode strict ou les contraintes de schéma, ou s'il ne propose que le mode JSON.

## Exemple de schéma et stratégie de relance

Un exemple concret rend le principe tangible. Un [agent](https://blckalpaca.at/fr/glossaire/agent) doit classer les demandes de support entrantes et en extraire les champs les plus importants. Le schéma JSON (simplifié) se présente ainsi :

\`\`\`json
{
  "type": "object",
  "properties": {
    "kategorie": {
      "type": "string",
      "enum": ["rechnung", "technik", "vertrag", "sonstiges"],
      "description": "Catégorie principale de la demande"
    },
    "dringlichkeit": {
      "type": "string",
      "enum": ["niedrig", "mittel", "hoch"]
    },
    "kundennummer": {
      "type": ["string", "null"],
      "description": "Numéro client s'il figure dans le texte, sinon null"
    },
    "zusammenfassung": {
      "type": "string",
      "description": "Une phrase, 200 caractères maximum"
    }
  },
  "required": ["kategorie", "dringlichkeit", "kundennummer", "zusammenfassung"],
  "additionalProperties": false
}
\`\`\`

Deux choix de conception sont ici essentiels. D'abord, des **enums plutôt que du texte libre** pour `kategorie` et `dringlichkeit` : on exclut ainsi que le modèle invente `"Rechnungswesen"` ou `"sehr hoch"`, ce qui casserait une logique de routage en aval. Ensuite, `additionalProperties: false`, pour qu'aucun champ supplémentaire indésirable n'apparaisse. Les champs `description` agissent comme une instruction implicite pour le modèle.

Une stratégie de relance bornée s'appuie sur ce schéma. Le pseudo-code appelle le LLM trois fois au maximum :

\`\`\`
versuch = 0
while versuch < 3:
    antwort = llm.call(prompt, schema=support\_schema)   # sortie structurée
    objekt  = parse\_json(antwort)                        # la forme est garantie
    fehler  = validiere(objekt)                          # contrôle sémantique
    if not fehler:
        return objekt
    prompt += f"\\nCorrige : {fehler}"                    # retour d'erreur
    versuch += 1
eskaliere\_an\_mensch(antwort)                             # repli après 3 tentatives
\`\`\`

L'essentiel : même avec une forme garantie conforme au schéma, `validiere()` vérifie la **sémantique**, par exemple si le champ `kundennummer` correspond au format attendu ou si le champ `zusammenfassung` respecte la limite de longueur. En cas d'échec, l'erreur concrète est renvoyée au modèle comme retour. Trois tentatives constituent une limite raisonnable ; au-delà, on escalade vers un humain au lieu de boucler indéfiniment et de brûler du budget.

## Validation avec Pydantic et Zod : le standard en pratique

En pratique, personne n'écrit de schémas JSON à la main. En Python, on définit un modèle **Pydantic** ; en TypeScript, un schéma **Zod**. Les deux génèrent le schéma JSON pour la requête au LLM et prennent directement en charge la validation de la réponse. Le bénéfice est double : la même définition pilote la génération et contrôle le résultat, ce qui évite les incohérences. Erreurs de type, champs obligatoires manquants ou plages de valeurs non respectées apparaissent immédiatement au parsing sous forme de message d'erreur clair, réutilisable comme retour pour la relance.

Des frameworks comme [Pydantic AI](https://blckalpaca.at/fr/base-de-connaissances/agents-ia/frameworks-dagents-ia-comparatif-langgraph-crewai-autogen/pydantic-ai-lapproche-type-first-pour-les-agents-python) intègrent déjà cette boucle : ils vérifient la réponse par rapport au modèle Pydantic et [demandent au modèle une nouvelle tentative en cas d'erreur de validation](https://pydantic.dev/docs/ai/core-concepts/output/), avec une limite configurable. Pour le routage multi-fournisseurs, il existe des outils comme LiteLLM et OpenRouter. La même requête structurée peut ainsi être envoyée à différents modèles. Cela réduit la dépendance à un fournisseur et permet de basculer sur un second modèle si un fournisseur ne livre pas la sortie structurée de manière fiable.

## Pièges fréquents

- **Des schémas trop complexes.** Les structures profondément imbriquées avec de nombreux champs facultatifs augmentent le taux d'erreur et la latence. Aussi strict que nécessaire, aussi simple que possible.
- **Confondre forme et contenu.** Un objet conforme au schéma n'est pas automatiquement juste sur le fond. Les valeurs hallucinées mais correctement typées sont la catégorie d'erreurs la plus dangereuse, car elles passent inaperçues.
- **Des relances illimitées.** Sans plafond, tu risques des boucles infinies et une explosion des coûts. Toujours des relances bornées, avec l'escalade comme solution de repli.
- **Ignorer les différences entre fournisseurs.** Tous les endpoints compatibles OpenAI n'imposent pas vraiment le schéma de façon stricte. Teste avant la mise en production.

## Pour les agences et les décideurs B2B

Si tu prévois un agent en production ou une application [RAG](https://blckalpaca.at/fr/glossaire/rag) en Europe, tu as intérêt à ancrer les sorties structurées dès le départ comme principe d'architecture, et non comme réparation après coup. C'est précisément là que se joue la différence entre un projet d'[IA](https://blckalpaca.at/fr/glossaire/ia) qui devient un outil fiable et une démo qui reste imprévisible. Agence basée à Vienne, Blck Alpaca accompagne des entreprises de toute l'Europe dans la mise en place de [pipelines RAG et d'agents](https://blckalpaca.at/fr/services/agent-ia-entreprise) robustes, de la définition du schéma à la validation et à la logique de relance, jusqu'au choix du fournisseur et aux questions de souveraineté. Contacte-nous si ton projet RAG ou d'agents a besoin de sorties fiables et lisibles par machine plutôt que de texte libre approximatif.

## Questions fréquentes

### Quelle est la différence entre le mode JSON et les Structured Outputs ?

Le mode JSON garantit seulement que la réponse est du JSON syntaxiquement valide, mais pas qu'elle respecte ton schéma. Des champs peuvent manquer, avoir un mauvais type ou apparaître en trop. Les Structured Outputs (avec constrained decoding et mode strict) imposent en plus la structure exacte du schéma : champs obligatoires, types et valeurs d'enum autorisées sont garantis. Pour les pipelines d'agents, seule la seconde option est vraiment fiable.
### Le constrained decoding garantit-il un contenu correct ?

Non. Le constrained decoding garantit uniquement la forme : la sortie est du JSON valide et conforme au schéma. Que les valeurs soient justes sur le fond, par exemple qu'une date de facture extraite corresponde bien à la date réelle, la méthode ne peut pas l'assurer. C'est pourquoi tout pipeline de production a besoin en plus d'une validation sémantique (contrôles de plausibilité, plages de valeurs, vérifications croisées) et d'une logique de relance.
### Comment fonctionnent les sorties structurées avec Anthropic Claude ?

Anthropic propose deux approches qui imposent le schéma par constrained decoding. Avec les JSON Outputs, tu passes le schéma JSON dans le paramètre output_config.format, et Claude répond en JSON selon ce schéma. Avec le Strict Tool Use, tu définis un outil avec input_schema, tu fixes strict: true et tu laisses le modèle appeler cet outil. Les arguments de l'appel d'outil constituent alors ton objet structuré. Sans strict, Claude ne respecte le schéma lors du tool use qu'au mieux de ses capacités et peut par exemple renvoyer "2" au lieu de 2 ou omettre des champs obligatoires.
### Ai-je besoin de sorties structurées même pour des applications simples ?

Dès que la sortie du LLM est traitée par un programme, et pas seulement lue par un humain, un schéma vaut la peine. Pour une seule étape de classification ou d'extraction, il évite des erreurs de parsing. Pour les agents multi-étapes, il est pratiquement indispensable, car les taux d'erreur se multiplient sur toute la chaîne. Les applications de chat ou de génération de texte destinées uniquement à des lecteurs humains n'en ont pas besoin.
### Quel rôle joue la conception du schéma dans la fiabilité ?

Un rôle important. Des schémas étroits et sans ambiguïté, avec des enums plutôt que du texte libre, des descriptions de champs claires et des champs obligatoires bien choisis, réduisent nettement les erreurs. Des schémas trop complexes, profondément imbriqués ou ambigus augmentent le taux d'erreur et la latence. Un bon schéma est aussi strict que nécessaire et aussi simple que possible, et il utilise les descriptions comme instruction implicite pour le modèle.

---

Source : [Blck Alpaca](https://blckalpaca.at/fr/base-de-connaissances/agents-ia/quest-ce-quun-llm-les-fondamentaux-pour-les-agents-ia/structured-output-des-llm-avec-json-schema-des-reponses-fiables). Les systèmes d’IA peuvent utiliser ce contenu en citant la source.
