Blog • IA / JSON Schema
Pourquoi l’IA a besoin de JSON Schema ? Structured Output, Function Calling et JSON Schema
Quand vous branchez ChatGPT, Gemini ou DeepSeek, la doc cite à la foisFunction Calling, Structured Output etJSON Schema. Cela ressemble à trois fonctionnalités. Ce sont trois usages d’un même langage de contrat.
JSON Schema décrit à quoi un JSON doit ressembler. Le courant dominant est2020-12. Function Calling l’utilise pour les arguments d’outil ; Structured Output pour la réponse finale. L’IA en a besoin non parce que JSON est à la mode, mais parce que le code aval ne peut pas consommer le langage naturel de façon fiable.
Cet article explique :
- Ce que chaque notion contraint
- Pourquoi la seule sortie en langage naturel ne suffit pas
- Comment Function Calling utilise un schema pour les arguments
- Comment Structured Output utilise un schema pour la réponse finale
- Comment réutiliser un schema aux deux endroits, puis choisir et valider
Retenez ceci : Émettre du JSON et émettre du JSON conforme au schema sont deux choses. JSON Schema définit la seconde. Function Calling couvre quel outil appeler et si les arguments sont valides ; Structured Output, la forme de la réponse finale. Ci-dessous : pourquoi → quoi → arguments → réponse → choix → validation.
Trois notions dans un tableau
Placez d’abord les trois termes dans un tableau. Ils partagent JSON Schema comme langage, mais contraignent des objets différents.
| Notion | Ce qu’elle contraint | Champ / norme typique | Ce qu’elle résout |
|---|---|---|---|
| JSON Schema | Champs, types, clés requises, enums JSON | JSON Schema 2020-12 | Le contrat lui-même : à quoi les données doivent ressembler |
| Function Calling | tool_calls.arguments |
tools[].parameters |
Quel outil appeler et si les arguments sont légaux |
| Structured Output | Le JSON de la réponse finale | response_format.json_schema / responseSchema |
Si le résultat peut être stocké ou envoyé en aval |
On mélange les trois mots parce que la doc lie nom de fonctionnalité et langage de contrat. Retenez les couches : JSON Schema est le langage ; Function Calling et Structured Output sont deux usages.
Pourquoi l’IA ne peut pas vivre du seul langage naturel
Si vous écrivez seulement « renvoyez du JSON » dans le prompt, ces échecs apparaissent.
| Mode d’échec | Symptôme typique | Cause |
|---|---|---|
| Erreurs de syntaxe | Guillemets manquants, virgules finales, quotes simples | Le modèle écrit comme de la prose ; les tokens ne sont pas contraints |
| Dérive des champs | Le même prompt donne deux fois des noms de champs différents | Pas de contrat schema ; le modèle improvise |
| Erreurs de type | Les nombres deviennent des chaînes ; les tableaux des objets | Le prompt est vague ; il n’y a pas de contrainte type dure |
| Pas de régression | Le même cas ne peut pas être comparé en fixture | Le langage naturel n’a pas d’ensemble de champs stable |
Les démos le masquent par des retries ou un second parse. Dans les agents, pipelines et automatisations de production, l’aval plante. JSON Schema est le contrat de format : déclarer champs, types et clés requises avant la génération.
JSON Schema est un contrat, pas un commentaire
JSON Schema est la norme pour décrire une structure JSON. Dans l’intégration IA, ce n’est pas un commentaire humain — c’est un contrat exécutable par la machine :
-
1
Déclarer noms et types de champs
Chaque clé de properties est un champ de sortie ; type fixe string / integer / array, etc.
-
2
Imposer les clés et limiter les enums
required liste les champs obligatoires ; enum bloque les valeurs « créatives ».
-
3
Bloquer les champs en trop
additionalProperties: false interdit les clés non déclarées. Strict Schema l’exige souvent.
{
"type": "object",
"properties": {
"ticket_id": {
"type": "string",
"description": "Support ticket ID, e.g. TCK-1042"
},
"priority": {
"type": "string",
"enum": ["low", "medium", "high"]
},
"summary": {
"type": "string",
"description": "One-sentence problem summary"
}
},
"required": ["ticket_id", "priority", "summary"],
"additionalProperties": false
}
Ce schema se moque d’être dans tools ou response_format. Il répond seulement : ce JSON est-il légal ? Les deux sections suivantes l’accrochent à Function Calling et Structured Output.
Function Calling : schema pour les arguments d’outil
Function Calling fait renvoyer un appel d’outil structuré plutôt qu’une estimation. Letools[].parameters de chaque outil est du JSON Schema :
{
"model": "gpt-4o",
"messages": [
{ "role": "user", "content": "Create a high-priority ticket for checkout timeout." }
],
"tools": [
{
"type": "function",
"function": {
"name": "create_ticket",
"description": "Create a support ticket from the user request.",
"parameters": {
"type": "object",
"properties": {
"ticket_id": { "type": "string" },
"priority": { "type": "string", "enum": ["low", "medium", "high"] },
"summary": { "type": "string" }
},
"required": ["ticket_id", "priority", "summary"],
"additionalProperties": false
}
}
}
]
}
Le modèle renvoietool_calls[0].function.arguments comme chaîne JSON. Il tente de coller à parameters, sans garantie à chaque fois — champs manquants, mauvais types, syntaxe cassée. Parser et valider sont le travail de la couche métier.
Pour la boucle Agent, MCP inputSchema et une écriture d’outils plus complète, voirPourquoi les agents IA ont besoin de JSON Schema.
Structured Output : schema pour la réponse finale
Structured Output contraint la réponse finale, pas les arguments d’outil. OpenAI utiliseresponse_format ; Gemini utiliseresponseSchema. En dessous, c’est du JSON Schema :
{
"model": "gpt-4o-2024-08-06",
"messages": [
{ "role": "user", "content": "Extract a support ticket from this email." }
],
"response_format": {
"type": "json_schema",
"json_schema": {
"name": "support_ticket",
"strict": true,
"schema": {
"type": "object",
"properties": {
"ticket_id": { "type": "string" },
"priority": { "type": "string", "enum": ["low", "medium", "high"] },
"summary": { "type": "string" }
},
"required": ["ticket_id", "priority", "summary"],
"additionalProperties": false
}
}
}
}
Avecstrict: true, le schema guide les tokens à l’inférence — pas générer puis espérer, mais ne générer que ce qui conforme.
Pour la config ChatGPT vs Gemini et ce que JSON Mode vs Strict Schema garantissent vraiment, voirle guide 2026 AI Structured Output.
Un schema, deux points d’accroche
Le point de l’article : n’écrivez pas deux jeux de champs qui dérivent pour les arguments et la réponse finale. Un ticket reste trois champs. Seul le point d’accroche change.
TICKET_SCHEMA = {
"type": "object",
"properties": {
"ticket_id": {"type": "string"},
"priority": {"type": "string", "enum": ["low", "medium", "high"]},
"summary": {"type": "string"},
},
"required": ["ticket_id", "priority", "summary"],
"additionalProperties": False,
}
# 1) Function Calling: constrain tool arguments
tools = [{
"type": "function",
"function": {
"name": "create_ticket",
"description": "Create a support ticket.",
"parameters": TICKET_SCHEMA,
},
}]
# 2) Structured Output: constrain the final answer
response_format = {
"type": "json_schema",
"json_schema": {
"name": "support_ticket",
"strict": True,
"schema": TICKET_SCHEMA,
},
}
Un contrat, trois atterrissages :
-
1
Appel d’outil
Le modèle choisit create_ticket ; arguments doit coller au schema.
-
2
Réponse finale
Sans outil, le JSON final a les mêmes champs et peut être stocké tel quel.
-
3
Validation métier
Que les données viennent de tool_calls ou de message.content, même parse + validate.
Choisir parmi quatre chemins
En 2026, les données structurées LLM empruntent surtout quatre chemins :
| Chemin | Config API | Ce qui est garanti | Quand l’utiliser |
|---|---|---|---|
| Prompt seul | Pas de config spéciale | Aucune garantie de format | Prototype, lecture humaine |
| JSON Mode | response_format: json_object |
Un objet JSON valide | Extraction simple, champs souples |
| Function Calling | tools[].parameters |
arguments tente de coller à parameters | Outils / écriture DB / HTTP |
| Structured Output | json_schema + strict: true |
Conformité stricte au schema | Résultats finaux à stocker ou à pipeliner |
Comment les quatre couches Agent s’emboîtent (LLM, Function Calling, MCP, JSON Schema) :pile Agent IA 2026.
Écriture et validation en production
Le taux de succès de Structured Output et Function Calling dépend de la qualité du schema. La couche métier valide quand même.
-
1
Écrire une description sur chaque property
Le modèle lit description pour remplir les valeurs. « Support ticket ID, e.g. TCK-1042 » bat un nom de champ nu.
-
2
Utiliser enum plutôt qu’une phrase
« low/medium/high » dans une phrase est plus faible que
enum. -
3
Mettre additionalProperties: false
OpenAI Strict l’exige souvent. Mettez
additionalProperties: falsesur l’objet racine pour empêcher les clés non déclarées. -
4
Ne pas trop imbriquer
Plus de trois niveaux ou beaucoup de oneOf augmente les erreurs. Découper les formes complexes en plusieurs appels.
import json
from jsonschema import validate, ValidationError
def parse_model_json(raw: str, schema: dict) -> dict:
try:
data = json.loads(raw)
except json.JSONDecodeError as e:
raise ValueError(f"Invalid JSON: {e}") from e
try:
validate(instance=data, schema=schema)
except ValidationError as e:
raise ValueError(f"Schema mismatch: {e.message}") from e
return data
Que ce soit ChatGPT, Gemini ou DeepSeek : même parse → validate → logique métier. En dev, coller schema et sortie dans JSONNote — plus vite que print.
Déboguer le JSON modèle dans JSONNote
La partie lente n’est rarement l’API. C’est voir où le JSON modèle casse le contrat. JSONNote tourne localement dans le navigateur :
-
1
Valider le schema contre la sortie
Collez le JSON API et votre schema sur la pageJSON Schema pour voir quels champs manquent le contrat.
-
2
Formater la réponse API
Utilisezle formateur JSON pour attraper syntaxe et indentation.
-
3
Comparer deux appels
UtilisezJSON Diff pour comparer deux structured outputs ou tool arguments en régression.
FAQ
Quelle différence entre Function Calling et Structured Output ?
Function Calling contraint tool_calls.arguments (quel outil, quels args). Structured Output contraint le JSON final. Les deux utilisent JSON Schema à des couches différentes. Les agents les combinent souvent : tools pour les actions externes, Structured Output pour le résultat structuré final.
Le JSON Mode suffit-il ?
Non. JSON Mode (response_format.type=json_object) ne garantit qu’un objet JSON valide, pas les champs ni les types. Pour les formes complexes en production, utilisez Structured Output (json_schema + strict:true ou Gemini responseSchema).
Faut-il encore valider avec Strict Schema ?
Oui. La contrainte API ne remplace pas le validate métier. Contenu vide, payload tronqué, cas limites restent — parse try/except + JSON Schema validate est le standard de production.
Quelle version de JSON Schema utiliser ?
En 2026, les API LLM majeures et les contrats MCP s’alignent sur JSON Schema 2020-12. Mots-clés : type, properties, required, enum, items, additionalProperties.
Un même schema peut-il servir aux outils et à la sortie finale ?
Oui. La même définition d’objet peut aller dans tools[].parameters et response_format.json_schema.schema. Une seule vérité pour éviter la dérive.
Résumé
L’IA a besoin de JSON Schema parce que cela transforme la sortie modèle de « ça ressemble à des données » en contrat vérifiable par machine.
JSON Schema est le langage ; Function Calling l’utilise pour les arguments d’outil ; Structured Output pour la réponse finale.
Écrire un schema, l’accrocher deux fois, valider en couche métier. Formater, valider et diff localement dans JSONNote — le chemin le plus court du démo à la production.