Pourquoi les agents IA ont encore plus besoin de JSON après l’Agents API : Harness, Tool Calling, JSON Schema

Au 18 septembre 2026 : la bêta publique de l’Agents API héberge le Codex harness. Une fois la boucle hors de vos mains, presque tout ce qui vous reste est du JSON — Schema d’outil, arguments, tool_result, MCP, événements de session. Un contrat lâche ne fait qu’accélérer les mauvais paramètres.

D’emblée : l’Agents API héberge la boucle. Elle n’héberge pas le contrat. Le 10 septembre 2026, OpenAI a mis devant les développeurs, en public beta, l’Agent Harness qui pilote Codex. L’ordonnancement du modèle, la compaction de contexte, les subagents et la durée de vie du sandbox ont quitté votre processus pour beta.agents.sessions. Ce que vous tenez encore est presque tout du JSON : le JSON Schema de chaque outil function, arguments, la chaîne dans tool_result, le inputSchema MCP, et le flux d’événements de session. Un harness hébergé qui fait tourner la boucle n’est pas quelqu’un d’autre qui valide vos champs. Relâchez le contrat, et la boucle hébergée ne fait que faire tourner plus souvent de mauvais paramètres.

Rédigé au 18 septembre 2026. Ce site a déjà pourquoi les agents ne peuvent pas vivre sans JSON, pourquoi le Tool Calling dépend de JSON Schema, si JSON Schema devient le contrat standard, MCP / Skills / Tools / Subagents et ce qu’est MCP. Cet article répond seulement à pourquoi le JSON compte davantage après l’Agents API, pas moins.

Ce qui a vraiment été publié le 10 septembre

La formule d’OpenAI : le même harness et la même infrastructure qui alimentent Codex, en agent cloud hébergé pour les développeurs. La doc publique le place sous l’espace de noms beta.agents ; les requêtes portent OpenAI-Beta: agents=v1. Le harness n’a pas de tarif séparé. Vous payez les tokens modèle, les outils et le temps de sandbox.

Créer une session, c’est soumettre un document JSON : modèle, instructions, liste d’outils, environnement, entrée. Les exemples officiels utilisent gpt-6-astra. Les outils peuvent être MCP, des functions personnalisées, ou de la retrieval intégrée. L’environnement peut être none, openai_hosted, ou un sandbox que vous apportez — Blaxel, Cloudflare, Daytona, E2B, Modal, Vercel, et assimilés. Le multi-agent est un flag : multi_agent.enabled plus max_concurrent_subagents.

Ce n’est pas un autre endpoint de chat qui dit « veuillez sortir du JSON ». La Responses API est toujours là. L’Agents SDK est toujours là. Ce que l’Agents API prend, c’est la boucle elle-même : qui choisit le saut suivant, quand le contexte est compacté, quand un subagent est lancé. Les noms de champs peuvent encore bouger pendant la beta. La coupure est déjà stable : OpenAI fait tourner le harness ; vous fournissez le contrat d’outil et le résultat métier.

Trois portes : Responses, Agents SDK, Agents API

En septembre 2026, OpenAI laisse trois façons de construire un agent côte à côte. Avant de les mélanger, demandez où tourne la boucle :

PorteOù tourne la boucleOù vit l’étatCe que vous écrivez encore
Responses APIVotre applicationL’historique que vous assemblez / ConversationsAppels modèle, retours d’outils, toute la boucle
Agents SDKVotre processusSessions SDK plus votre stockageApprobations, déploiement, et vous pouvez encore changer la boucle
Agents APILe Codex harness hébergé par OpenAIsession / turn / item côté serveurDéfinitions d’outils, résultats function, choix d’environnement ; vous ne pouvez pas changer la boucle

Une complétion unique reste sur Responses. Si vous devez posséder les approbations et la persistance, utilisez le SDK. Si vous voulez du travail sur plusieurs jours, la compaction, les subagents et un sandbox opéré pour vous, utilisez l’Agents API. Les trois décrivent encore les paramètres d’outil avec JSON Schema. La différence : les deux premières vous laissent encore patcher la boucle ; la troisième ne vous laisse patcher que le contrat et la charge de retour.

Ce qu’est un Agent Harness — et ce qu’il ne signera pas

Un harness est le runtime entre le modèle et les effets de bord : lire les événements, choisir les outils, renvoyer les résultats, compacter le contexte, garder un long travail en vie. Le harness Codex est open source. L’Agents API, c’est OpenAI qui opère la même logique et la versionne avec les modèles. La note de lancement cite la compaction automatique, Tool search, Programmatic Tool Calling et les subagents parallèles.

Il ne signera aucun de ceci :

  • qu’un customer_id doive exister, ou doive être un UUID ;
  • que votre fonction puisse accepter des clés en trop ;
  • que le inputSchema d’un serveur MCP soit serré ou lâche ;
  • que le output que vous renvoyez soit un objet, une chaîne, ou un paragraphe de chat.

Cela reste JSON Schema plus une vérif que vous lancez vous-même. Un harness hébergé augmente la durée possible d’une boucle et le degré de parallélisation. Il n’augmente pas la légalité des paramètres de ce saut. Traiter les deux comme la même chose, c’est le premier mélange que cet article sépare.

Pourquoi une boucle hébergée produit plus de sauts JSON

Quand vous écrivez la boucle, le mauvais JSON meurt en général de votre côté : le parse échoue, les champs ne correspondent pas, vous vous arrêtez. Une fois la boucle hébergée, l’échec est différé, recopié, et envoyé dans plus de canaux :

SautChargeQui le produitQui doit valider
Créer la sessionagent / tools / environment JSONVotre applicationVous, avant de soumettre
Définition functionJSON Schema (parameters)Votre applicationVous : serrez required / additionalProperties
Le modèle lance un appelobjet argumentsHarness hébergé + modèleVous : validez encore avant d’exécuter
Renvoyer un résultatchaîne tool_result.outputVotre applicationVous : stringify une valeur légale
MCPJSON-RPC + inputSchemaServer / harnessLe serveur et votre allow list
Flux d’événementsévénements JSON agent.session.*Le service hébergéVous : branchez sur type ; ne le parsez pas comme de la prose de chat

Ajoutez Tool search qui charge les définitions à la demande, Programmatic Tool Calling qui enchaîne les appels dans du code, et des subagents qui portent chacun leur propre contexte — une tâche utilisateur fait maintenant plus d’allers-retours JSON qu’un seul saut Function Calling. L’hébergement cache ces sauts. Caché n’est pas facultatif à valider. Pour une carte saut par saut, voir du Tool Calling au MCP.

Tool Calling : les outils function restent du JSON Schema

Les outils function de l’Agents API réutilisent la forme de la Responses API. Ce que vous mettez sur agent.tools n’est pas un paragraphe. C’est un nom, une description et un JSON Schema :

{
  "type": "function",
  "name": "get_customer",
  "description": "Look up a customer by ID.",
  "parameters": {
    "type": "object",
    "properties": { "customer_id": { "type": "string" } },
    "required": ["customer_id"],
    "additionalProperties": false
  }
}

L’exemple officiel remplit required et met additionalProperties à false. Ce n’est pas une habitude de formatage. Si l’agent peut ajouter une clé en trop, cette clé peut devenir un chemin, un fragment SQL, ou une suppression. Le schema est le contrat que le modèle voit au décodage, et le contrat que vous devriez relancer avant d’exécuter. Pour le mode strict, ajv, et une pipeline en second passage, voir pourquoi le Tool Calling dépend de JSON Schema.

La description aide encore le modèle à choisir un outil. Elle ne remplace pas les types, les enums et les champs required. Plus le harness est malin, plus il choisit volontiers un outil « assez proche » dans une longue liste. Assez proche, c’est ce que le schema est là pour rejeter.

requires_action et tool_result : le chemin retour est aussi du JSON

Quand le modèle a besoin de votre fonction, la session s’arrête sur agent.session.requires_action. Le travail en attente vit dans required_actions. Un item function_call dans l’historique ne suffit pas à lui seul. Un appel pending typique ressemble à ceci :

{
  "type": "function_call",
  "turn_id": "turn_123",
  "call_id": "call_123",
  "name": "get_customer",
  "arguments": { "customer_id": "123" }
}

La doc présente arguments comme un objet. Ne l’emballez pas dans une réponse de chat pour le racler avec JSON.parse — c’est le mauvais canal, traité dans pourquoi JSON.parse échoue. Validez l’objet contre le même schema, exécutez la fonction, puis postez agent.session.input.tool_result sur l’endpoint d’événements de session avec les turn_id et call_id d’origine.

En succès, success: true et output en chaîne ou en tableau de contenu supporté. Les objets passent d’abord par JSON.stringify. En échec, success: false et une error que le modèle peut lire. N’envoyez pas de stacks, de secrets, ni une ligne de base entière. Si le processus meurt après l’exécution de la fonction mais avant que le résultat n’atteigne OpenAI, identifiez l’effet de bord par session / turn / call et restez idempotent : au redémarrage, lisez les actions pending avant de relancer.

Les handlers function tournent toujours dans votre application, même si la session a un sandbox. Le harness n’exécutera pas get_customer pour vous. Si vous êtes hors ligne, le saut reste bloqué. C’est l’un des rares points synchrones d’une boucle hébergée qui vous appartient encore entièrement — et le saut où le JSON doit être juste.

Tool search et Programmatic Tool Calling

Une longue liste d’outils brûle des tokens et casse le cache si chaque schema reste dans le contexte. L’Agents API charge les functions en eager par défaut. Les rares peuvent poser defer_loading: true, avec {"type": "tool_search"} sur agent.tools. Le modèle trouve la définition, puis l’appelle. Cela ajoute un saut où « la définition est aussi du JSON » : le schema que search renvoie doit correspondre à la fonction que vous avez vraiment implémentée. N’annoncez pas un contrat large pour exécuter un contrat étroit.

Programmatic Tool Calling laisse les modèles supportés écrire un court programme qui exécute les outils éligibles en parallèle ou en chaîne, puis ne ramène dans le contexte que les résultats filtrés. Cela coupe le coût de remplir la fenêtre à chaque saut. Cela relève l’exigence que le JSON intermédiaire soit légal. Si les types dérivent au milieu, les filtres et fusions suivants se trompent dans un harness que vous ne voyez pas. Le SDK a déjà un correctif qui encode les erreurs structurées en JSON. Ce chemin mange du schema, pas de la prose.

MCP et subagents : plus de schemas, plus de JSON

Ajoutez un serveur MCP à agent.tools et le harness découvre les outils, les appelle, et renvoie les résultats. Contrairement aux functions, ces appels ne passent pas par votre application. HTTP se connecte depuis OpenAI par défaut ; vous pouvez aussi connecter depuis l’environnement, ou lancer stdio dans le sandbox. Ce que vous contrôlez encore, c’est allowed_tools, si un init en échec fait échouer le turn (required: true), et à quel point le inputSchema du serveur est serré.

Les messages MCP restent du JSON-RPC. Un schema lâche signifie que le harness hébergé enverra plus de requêtes que vous ne verrez jamais. Ce n’est pas « le protocole vous a rendu sûr ». C’est « la boucle s’est éloignée ». Pour les couches du protocole, voir ce qu’est MCP ; pour la frontière avec Skills et Subagents, voir la pile agent 2026.

Chaque subagent garde son propre contexte ; le parent fusionne. Le travail parallèle coupe la latence et multiplie aussi beaucoup d’objets arguments. Si la fusion est encore un long texte sans schema, vous n’avez fait que reporter « parser le chat » au dernier saut. Les conclusions qui entrent dans un programme doivent encore passer par Structured Output ou un schema de résultat que vous définissez — pas un autre raclage de prose. Voir ce qu’est Structured Output.

Quatre choses à encore valider en local

Après que le harness est hébergé, la liste ne raccourcit pas. Elle se rétrécit :

  1. Schemas d’outils. Remplissez required, posez additionalProperties: false, serrez les enums. Ne vous appuyez pas sur la description pour arrêter les effets de bord.
  2. Les arguments avant exécution. Même si le vendor a déjà appliqué le schema, relancez le même document dans votre processus. Mauvais types, champs manquants, clés en trop s’arrêtent ici.
  3. L’output que vous renvoyez. Faites du JSON légal, puis stringify. Les erreurs sortent en success: false. Ne tendez pas au modèle une exception interne brute.
  4. Gardez événements et chat sur des canaux séparés. Branchez sur event.type. Ne traitez pas tout un flux SSE comme une seule valeur JSON. Les réponses structurées à l’utilisateur passent par Structured Output, pas par JSON.parse sur une phrase assistant.

Côté sécurité : une chaîne dans arguments peut être une injection, pas « le type collait, donc exécutez ». Voir JSON malveillant et prompt injection. Si JSON Schema devient le contrat inter-fournisseurs, c’est le texte sur le contrat standard — l’Agents API n’affaiblit pas cette thèse. Elle la pousse sur la seule couche que vous pouvez encore changer.

Inspecter le contrat avec les outils JSON locaux

Avant de confier le travail à une session hébergée, regardez trois textes dans le navigateur : le schema d’outil, un objet arguments d’échantillon, et l’output que vous comptez renvoyer.

  • Validateur JSON — la grammaire est-elle légale ; si vous avez un schema, vérifiez ensemble champs, required et clés en trop.
  • Formateur JSON — déroulez un tool_result sur une ligne et voyez si vous avez sérialisé toute une ligne de base.
  • JSON Diff — comparez les arguments envoyés par le modèle avec le plus petit objet que le schema autorise.

Rien ne quitte le navigateur. C’est le bon endroit pour poser côte à côte une charge required_actions en échec, un document parameters, et un résultat stringifié. Stabilisez le contrat, puis laissez le harness hébergé tourner des jours.

FAQ

L’Agents API veut-elle dire que je peux arrêter d’écrire du JSON Schema ?

L’inverse. Une fois la boucle hébergée, le schema est le contrat principal que vous tenez encore. Les parameters des functions, l’inputSchema MCP, et l’output que vous renvoyez restent du JSON.

Comment choisir entre Agents API, Agents SDK et Responses ?

Les appels uniques vont sur Responses. Si vous devez posséder la boucle, les approbations et le stockage, utilisez le SDK. Si vous voulez de longs jobs, la compaction, les subagents et un sandbox opéré par OpenAI, utilisez l’Agents API. Les trois prennent encore JSON Schema pour les paramètres d’outil.

Arguments est déjà un objet. Dois-je encore appeler JSON.parse ?

Ne parsez pas à nouveau le chat autour. Traitez arguments comme un objet, comme la doc, et validez-le avec le même JSON Schema. Extraire arguments de la prose, c’est le mauvais canal.

Pourquoi tool_result doit-il être stringifié ?

La doc veut output en chaîne ou en tableau de contenu supporté. Faites du JSON légal, puis stringify, pour ne pas mélanger un second encodage avec « ça ressemble à un objet, c’est en fait une chaîne ».

Les outils MCP passent-ils par mon application ?

Pas par défaut. Le harness parle au serveur. Ce que vous serrez, c’est l’inputSchema du serveur lui-même, allowed_tools, et toute approbation pour les actions irréversibles dans ce serveur.

Les noms de champs changeront-ils pendant la beta ?

Peut-être. Cet article suit la doc publique au 18 septembre 2026. La coupure, non : le harness fait tourner la boucle ; vous fournissez le contrat JSON. Si un champ est renommé, le devoir de valider reste de votre côté.

Résumé

L’Agents API réduit le travail de « comment faire tourner un agent jusqu’au bout ». Elle relève le poids de « chaque saut JSON doit être juste ». Ce qui a été publié le 10 septembre, c’est le harness Codex : sessions, compaction, tool search, appels programmatiques, subagents, sandboxes. Il ne vérifiera pas à quoi un customer_id doit ressembler, et il ne transformera pas votre tool_result en chaîne légale pour vous.

Brancher un agent dans un programme en 2026 suit encore le même ordre : outils sur JSON Schema, réponses finales sur Structured Output, la prose de chat n’est pas une API. Ce qui a changé, c’est qu’une fois la boucle hébergée, le seul endroit où vous pouvez encore patcher, c’est le contrat. Vérifiez d’abord le schema, les arguments et la charge de retour dans un validateur local, puis confiez le travail à une session hébergée. Les modèles changeront. Le harness prendra de nouvelles versions. Votre contrat de champs ne devrait pas se relâcher avec eux.