Pourquoi l'IA a besoin de JSON Schema ? Structured Output, Function Calling et le contrat
Depuis 2024, les pages produit écrivent JSON Schema, Function Calling et Structured Outputs comme une seule fonction. Ce n'est pas le cas. Le Schema est la langue du contrat. Function Calling veut dire « veuillez exécuter ». Structured Outputs veut dire « le modèle doit émettre cette forme ». Cet article sépare les trois mots, puis explique pourquoi un modèle probabiliste doit s'asseoir derrière un Schema validable — pas derrière la phrase « veuillez renvoyer du JSON ».
Aperçu rapide
| Idée | Une ligne | Où ça vit |
|---|---|---|
| JSON Schema | Le contrat des champs, types, clés requises et enums — pas une fonction du modèle | Un fichier .json dans git ; un validateur en CI |
| Function Calling | Le modèle propose un appel ; l'hôte l'exécute ; les effets de bord sont ici | tools[] / arguments |
| Structured Output | La réponse finale doit matcher cette forme ; en général sans effet de bord | json_schema / output_type |
Retenir la découpe : le Schema est le diamètre, Function Calling est la main tendue, Structured Outputs est l'objet rendu. Les aplatir en « faire émettre du JSON au modèle » et le saut suivant parse de la prose.
Pourquoi les trois mots sont-ils toujours mélangés ?
Docs, extraits SDK et posts aiment les empiler en une phrase : donnez un Schema au modèle, il émettra du JSON légal. Les démos réussissent souvent. Les incidents de prod commencent en général après que vous croyez être « déjà structurés ».
Le mélange cache trois métiers différents :
- Les
argumentsde Function Calling sont encore souvent une chaîne. L'hôte doit refaire unJSON.parse. Types, enums et champs en trop n'ont pas encore été arrêtés. - Structured Outputs ne gouvernent que la réponse finale. Ils ne consultent pas une commande, ne bougent pas d'argent, n'écrivent pas une base. Les effets de bord passent encore par Function Calling.
- Un Schema qui ne vit que dans le prompt ne peut pas échouer en CI. « Veuillez renvoyer du JSON » n'échoue jamais. Un Schema dans git, si.
La question n'est donc pas « l'IA sait-elle faire du JSON ? » C'est : qui, à quel moment, avec quel contrat, arrête un objet illégal. Les trois mots nomment trois qui différents.
Ce qu'est JSON Schema (ce n'est pas une fonction du modèle)
JSON Schema est un document qui décrit une forme JSON : quelles clés, quels types, ce qui est requis, quelles valeurs d'enum, si des champs en trop sont autorisés. C'est plus strict que « ça ressemble à du JSON », et les API de modèles le citent plus souvent qu'un type TypeScript ou un protobuf.
Le travail Agent / Structured Output n'utilise en pratique que ces mots-clés :
type/properties: à quoi ressemble l'objet.required: quelle clé manquante fait échouer le contrôle.enum/pattern/ bornes numériques : transformer « à peu près » en ensemble fini.additionalProperties: false: les clés en trop échouent — y compris celles glissées par injection de prompt.
Le détail des mots-clés est dans le tutoriel JSON Schema. Ici : le Schema existe d'abord pour les validateurs et les tests. Une description claire aide le modèle à choisir un outil ; elle ne remplace pas enum et required.
{
"$id": "https://example.com/schemas/order.json",
"type": "object",
"properties": {
"order_id": { "type": "string", "pattern": "^A-[0-9]{4,}$" },
"amount": { "type": "number", "exclusiveMinimum": 0 },
"status": { "type": "string", "enum": ["paid", "refunded", "pending"] }
},
"required": ["order_id", "amount", "status"],
"additionalProperties": false
}
Le contrat de commande ci-dessus peut alimenter les parameters de Function Calling, le json_schema de Structured Outputs, et ajv côté hôte. On change un champ à un seul endroit.
Qu'est-ce que Function Calling ?
Function Calling (et Tool Calling au sens large) n'est pas « le modèle exécute une fonction ». Le modèle n'émet qu'un nom et des arguments. L'hôte parse, valide, exécute, et replace le résultat dans la conversation. Consultations de stock, remboursements, tickets — les effets de bord vivent ici.
Les éditeurs écrivent les outils en tools[]. L'objet parameters est un sous-ensemble de Schema :
{
"type": "function",
"function": {
"name": "lookup_order",
"description": "Look up an order by ID",
"parameters": {
"type": "object",
"properties": {
"order_id": {
"type": "string",
"pattern": "^A-[0-9]{4,}$"
}
},
"required": ["order_id"],
"additionalProperties": false
},
"strict": true
}
}
le guide agent IA place ce saut dans la boucle complète. MCP Tool Schema vs Function Calling montre que le inputSchema MCP et les parameters éditeur sont deux graphies du même dictionnaire.
Ça a déjà l'air structuré. Les trous : arguments est souvent encore une chaîne ; les résultats d'outil n'ont souvent pas de Schema ; strict ne lie que le côté modèle. Sans contrôle hôte, savoir si amount est un nombre ou une chaîne dépend encore du snapshot du jour.
Que sont les Structured Outputs ?
Les Structured Outputs (forme stricte du JSON mode) contraignent le message final du modèle lui-même. Classification, extraction, objet de résumé, handoff d'agent — pas d'effet de bord externe, mais le saut suivant a besoin d'une forme fixe.
Les noms de champs diffèrent : response_format, text.format.json_schema, output_type. Le cœur est le même : donner un Schema au décodeur et couper les chemins de tokens illégaux.
{
"type": "json_schema",
"json_schema": {
"name": "order",
"strict": true,
"schema": {
"$id": "https://example.com/schemas/order.json",
"type": "object",
"properties": {
"order_id": { "type": "string" },
"amount": { "type": "number" },
"status": {
"type": "string",
"enum": ["paid", "refunded", "pending"]
}
},
"required": ["order_id", "amount", "status"],
"additionalProperties": false
}
}
}
les prévisions DevDay 2026 a écrit cette couche, Function Calling et le runtime agent comme un seul tuyau JSON. Le diamètre reste le Schema : le définir d'abord, puis brancher les protocoles.
Avec strict: true, champs manquants, mauvais enums et clés en trop sont souvent arrêtés côté modèle. Ça remplace le prompt « répondez en JSON ». Ça ne remplace pas un second contrôle hôte, ni Function Calling.
Comment les trois s'empilent-ils ?
Les aplatir en « faire émettre du JSON au modèle » et on perd les métiers. Séparés :
- JSON Schema est le diamètre partagé : dictionnaire de champs, clés requises, enums. Il n'appelle rien et n'engendre rien. Il dit seulement à quoi ressemble « légal ».
- Function Calling est la main vers l'extérieur. Le modèle demande un effet de bord. Les arguments doivent passer le Schema ; les résultats aussi.
- Structured Outputs est l'objet rendu. Quand le saut se termine, la réponse elle-même doit être cette forme.
Un tableau pour qu'ils cessent d'être traités comme des synonymes :
| Couche | Ce que fait le modèle | Sans Schema |
|---|---|---|
| Function Calling | Proposer un appel, attendre l'hôte | Les arguments sont de la prose ; des clés en trop peuvent atteindre la facturation |
| Structured Output | Émettre l'objet final directement | L'aval extrait des champs d'un paragraphe |
| JSON Schema | Rien — ce n'est que la règle | Une règle qui ne vit que dans le prompt ne se mesure pas en CI |
Un agent multi-étapes utilise les deux : Structured Outputs pour l'objet de triage, Function Calling pour la consultation et le remboursement. agents IA et workflows JSON Schema ordonne les portes. Cet article ne fait que nommer les trois blocs.
Pourquoi l'IA ne peut-elle pas se passer de JSON Schema ?
Parce qu'un modèle et un programme ne sont pas le même genre de chose. Le modèle continue des tokens par probabilité ; le programme lit un objet par règles. Si la jointure n'est que « ça ressemblait à du JSON aujourd'hui », un champ oublié, un nombre-en-chaîne, un enum écrit "Paid", un note en trop — chacun peut devenir un fait pour le saut suivant.
Avant 2024 la chaîne était courte : un chat, une fonction, un humain voyait l'échec. En 2026 elle est plus longue : classer → consulter → rembourser ou passer à un humain → donner un objet à un autre agent. Si un saut n'est que « en forme de JSON », les étapes suivantes figent l'erreur.
Pour la même commande, le modèle peut à tout moment émettre cet objet « qui a l'air légal » :
{
"order_id": "A-1042",
"amount": "99.00",
"status": "Paid",
"note": "please hurry"
}
amount est une chaîne, status a la mauvaise casse, et note est apparu. Sans Schema, l'aval peut concaténer 99.00 dans du SQL comme texte, ou traiter Paid comme un état inconnu et réessayer. Pour déboguer, formater en local, puis JSON Diff contre l'objet de la semaine dernière. Ne collez pas de réponses portant des données utilisateur sur un site JSON public.
Le Schema n'est pas là pour « apprendre au modèle à parler ». Il est là pour arrêter les objets illégaux à la porte de l'hôte. Une fois avant l'appel, une fois après la réponse, une fois encore dans les evals. Plus la fenêtre est grande et plus il y a de sauts, plus vite les erreurs de prose deviennent des faits dans le système.
Un Schema, deux projections
N'écrivez pas à la main une définition « assez proche » pour Function Calling et une autre pour Structured Outputs. La forme est un fichier source, deux exportateurs :
- Garder
schemas/order.jsondans le dépôt avec un$idstable et une version. - Exporter Function Calling : couper en
function.parameterset activerstrict. Un outil de consultation n'a souvent besoin que deorder_id— ne pas fourrer toute la commande dans les arguments. - Exporter Structured Outputs : le même objet en
json_schema/output_typepour l'extraction, le triage et la réponse finale.
Attention aux sous-ensembles : le strict éditeur exige souvent chaque property dans required et désactive certains oneOf / $ref. La source peut être plus riche ; l'exportateur coupe par cible. La CI fait un Diff structurel « source vs projection » pour que personne n'édite un côté à la main.
L'hôte doit encore valider
strict: true ne lie que le décodage modèle. Un changement de snapshot, un éditeur qui coupe strict, un second parse de arguments, un outil qui renvoie un objet ouvert — tout peut contourner le côté modèle. Faire tourner le même Schema à trois endroits côté hôte :
- Avant d'exécuter un outil. parse → validate → execute. En cas d'échec, renvoyer une erreur structurée. Ne pas passer la chaîne brute en aval.
- Après avoir accepté l'objet final du modèle. Un succès Structured Outputs n'est pas votre règle métier (plafonds, devise, auth).
- En écrivant l'état ou les fixtures d'eval. Checkpoints et evals doivent être du JSON légal. Ne pas deviner la progression dans un journal de chat.
Contraintes côté modèle et validation côté hôte sont deux métiers. Si strict est coupé ou que vous changez d'API, un Schema qui ne vit que dans le prompt disparaît.
Livrer en 2026 (les fichiers d'abord, puis le prompt)
- Créer
schemas/tools/,schemas/extract/etschemas/state/. Chaque fichier a un$idet une version. - Écrire le Schema avant « veuillez renvoyer du JSON ». Une phrase de prompt ne peut pas échouer en CI.
- Les effets de bord (requête, paiement, e-mail) passent par Function Calling. Classification, extraction et handoff passent par Structured Outputs.
- Par défaut,
additionalProperties: falseet unenumexplicite. Pour étendre, ajouter un objetmetadataséparé — ne pas relâcher la racine. - Au-delà de dix outils, d'abord retrouver puis appeler. Ne pas verser le catalogue dans une requête.
- Inspecter secrets et champs utilisateur seulement dans le navigateur : formater, JSON Diff, zéro envoi.
Le répertoire peut être mince. Ce qui compte, c'est les fichiers avant les prompts. Les modèles changeront, des protocoles s'ajouteront. Le diamètre doit se stabiliser d'abord.
Pièges fréquents
- Prendre Structured Outputs pour Function Calling. Le premier n'exécute pas de code. Consultations et remboursements ont encore besoin d'une couche d'outils.
- N'écrire « veuillez renvoyer du JSON » que dans le prompt. Pas de Schema dans git, pas de test qui puisse échouer.
- Valider seulement les entrées d'outil, pas l'objet final. Les incidents d'extraction et de triage arrivent sur des réponses qui « ressemblent déjà à du JSON ».
- Écrire à la main un Schema assez proche par protocole. Ils divergent à la troisième semaine. Exporter ; ne pas copier.
- Utiliser un large
type: objectpour éviter le design. Un objet ouvert n'est pas une porte. Versionner, ou ajouter unmetadataexplicite.
FAQ
Les Structured Outputs peuvent-ils remplacer Function Calling ?
Non. Structured Outputs contraignent la forme de la réponse finale. Function Calling demande à l'hôte un effet de bord. Extraire les champs d'une commande avec les premiers ; consulter le stock ou rembourser avec le second. Ils doivent citer le même Schema, pas se remplacer.
Function Calling a déjà parameters — faut-il encore un fichier Schema ?
Oui. parameters est une projection, pas la source. Un fichier séparé alimente Structured Outputs, MCP, evals et ajv hôte. N'éditer que la copie dans tools[] et elle dérive du Schema d'extraction d'ici trois semaines.
Pas d'agent — juste une extraction. Faut-il encore un Schema ?
Encore plus. Si le résultat va droit dans une base ou une feuille, il n'y a pas de saut suivant pour « le comprendre encore ». Structured Outputs plus un contrôle hôte sont l'ensemble minimal complet.
J'ai activé strict: true. Faut-il encore valider côté hôte ?
Oui. strict gouverne le décodage. L'hôte gouverne les règles métier, le second parse, et le repli si un éditeur coupe strict. Deux portes bon marché ; en enlever une et un changement de modèle le montrera.
Comment inspecter un JSON rejeté en local ?
Le formater, chercher dans le Schema un required manquant ou un mauvais enum, puis Diff contre la dernière version qui passait. JSONSort le fait dans le navigateur et n'envoie rien. Ne collez pas de réponses portant des secrets sur un site public.
Conclusion
L'IA a besoin de JSON Schema non parce que les modèles ne savent plus lire le langage naturel, mais parce que une sortie probabiliste doit rencontrer une porte déterministe. Function Calling dit « fais ceci ». Structured Outputs dit « rends cet objet ». Le Schema est le diamètre qu'ils partagent.
Commencer aujourd'hui par schemas/extract_order.json, puis choisir une API. Les modèles changeront. Les protocoles bougeront. Le diamètre doit se stabiliser d'abord.
Pour aller plus loin
- Pourquoi les agents IA ont désormais besoin de JSON Schema Les portes du Tool Calling au workflow structuré
- Qu'est-ce qu'un agent IA ? Tool Calling et JSON Runtime, appels d'outils et contrat JSON
- MCP Tool Schema vs Function Calling La frontière de protocole du JSON d'outil
- Qu'est-ce que JSON Schema ? required, enum, additionalProperties
- Boîte à outils locale JSONSort Formater, valider, Diff
- Tous les articles D'autres notes JSON et IA
Journal : première publication