Développement IA

Comment migrer le JSON Tool Calling après la mise à jour API d’OpenAI DevDay 2026 ?

Environ 16 min

Changez l’écriture en retour avant l’identifiant du modèle. Si la cible est gpt-6-astra ou gpt-6.1-sol, le tool calling quitte Chat Completions et utilise l’API Responses. Un saut qui ne fait que classer ou router peut passer à l’API Decisions, bêta publique depuis le 6 octobre. La consultation reste lookup_order. Le modèle ne remplit que du JSON. L’hôte exécute.

Avant de lire

Objet Fait officiel Ce qui change dans la migration
Point d’entrée Les appels d’outils d’Astra et de GPT-6.1 Sol passent par Responses. Sol et Luna n’appellent une fonction sur Chat Completions que si reasoning_effort vaut none Passer à POST /v1/responses, ou garder none exprès
Objet outil Sur Responses, name est au même niveau que type. Omettre strict tente le mode strict, puis revient en arrière et marque strict: false Écrire strict explicitement. L’hôte vérifie encore
Écriture en retour function_call et function_call_output partagent call_id. async: true ne fait pas exécuter l’outil par le modèle Remplacer role:tool par function_call_output
Routage Decisions est en bêta publique depuis le 2026-10-06. Seulement gpt-6-luna. Un choice n’exécute pas d’outil Ne déplacer que le saut qui choisit une énumération

Faits des docs officielles au 2026-10-08 : Using GPT-6, Migrate to the Responses API, Decisions, Async tool calling. La commande A-1042 est fictive. Les probabilités de l’exemple Decisions sont illustratives.

Changer d’abord la forme de l’écriture en retour, puis l’identifiant du modèle

Après DevDay, la migration est un changement de champs. Ce n’est pas un nouveau texte sur ce qu’est un agent. Les notes officielles tiennent en quatre lignes. D’abord, si le modèle cible est gpt-6-astra ou gpt-6.1-sol, le tool calling passe à Responses. Ces deux modèles peuvent encore envoyer des requêtes Chat Completions sans outils. gpt-6-sol et gpt-6-luna n’appellent une fonction sur Chat Completions que si reasoning_effort vaut none. Le raisonnement avec des outils passe par Responses. Ensuite, le nom sort de l’objet imbriqué function et se place à côté de type. Puis l’identifiant de retour passe de tool_calls[].id à call_id. Enfin, un saut qui ne fait que classer ou router peut aller vers Decisions. Decisions n’exécute pas d’outil.

  • Astra / GPT-6.1 Sol : le tool calling quitte /v1/chat/completions. Sur Responses, le champ d’effort est reasoning.effort.
  • Aplatir la définition et écrire strict. Chat Completions est non strict par défaut. Responses tente le mode strict si strict est omis.
  • Séparer le routage de la consultation. Un choice renvoie une énumération. La consultation reste lookup_order.

Ce qui a été livré le 29 septembre : ce que DevDay 2026 a livré. Comment Responses et l’API Agents diffèrent comme points d’entrée : comment l’API Agents et Responses diffèrent. Ce texte ne réécrit pas ces deux articles. Il ne mappe que les champs d’une boucle JSON Tool Calling déjà en place.

Nommez l’appel que le code lit aujourd’hui

Dans une réponse Chat Completions, un appel ressemble à ceci. L’id est à l’extérieur. Le name est dans function. arguments est une chaîne. Commande fictive, pas de vrai secret :

{
  "id": "call_3c91",
  "type": "function",
  "function": {
    "name": "lookup_order",
    "arguments": "{\"order_id\":\"A-1042\"}"
  }
}

Un outil Responses place name à côté de type. N’omettez pas strict. Sinon Responses tente le mode strict. Un schema incompatible revient en arrière, et l’outil renvoyé affiche strict: false. Pour garder le comportement non strict, écrivez false. L’hôte vérifie quand même arguments avant d’exécuter :

{
  "type": "function",
  "name": "lookup_order",
  "strict": true,
  "parameters": {
    "type": "object",
    "properties": {
      "order_id": { "type": "string", "pattern": "^[A-Z]-\\d{4}$" }
    },
    "required": ["order_id"],
    "additionalProperties": false
  }
}

L’écriture en retour ne reconnaît que call_id

Le modèle émet un item function_call, pas un tableau tool_calls. Le parseur lit ces quatre champs :

{
  "type": "function_call",
  "call_id": "call_3c91",
  "name": "lookup_order",
  "arguments": "{\"order_id\":\"A-1042\"}"
}

L’hôte analyse arguments, passe le Schema, exécute lookup_order et réécrit sur le même call_id. Un échec est aussi un objet dans la chaîne. Si vous rejouez l’historique à la main, renvoyez les items de raisonnement du tour précédent et le function_call avec le résultat. Ne renvoyez pas le résultat seul. Le chemin plus court est previous_response_id :

{
  "type": "function_call_output",
  "call_id": "call_3c91",
  "output": "{\"order_id\":\"A-1042\",\"status\":\"paid\"}"
}

Un outil lent peut poser async: true sur la définition. Les docs : le modèle peut continuer à raisonner, ou répondre aux parties qui ne dépendent pas de ce résultat. L’item d’appel porte async: true. Vous envoyez plus tard function_call_output avec le call_id d’origine. L’hôte exécute toujours l’outil. Les outils intégrés et le programmatic tool calling ne peuvent pas utiliser async. En mode multi-agent, ne combinez pas les outils async avec des appels parallèles. Les docs citent GPT-6 Astra et les modèles suivants.

Cinq boucles. Ne les fondez pas en une seule mise à niveau

Migrez selon l’écriture en retour que vous avez déjà. Des noms d’objets différents demandent des parseurs différents :

Boucle actuelle Où elle va
Chat Completions + outils, cible Astra ou GPT-6.1 Sol Passer à POST /v1/responses. tool_calls[].id devient call_id. Sortir name de function.
Chat Completions + outils, rester sur gpt-6-sol ou gpt-6-luna Vous ne restez que si reasoning_effort vaut none. Raisonnement plus outils : Responses.
Déjà un function_call Responses Garder la boucle. Changer l’identifiant du modèle. Astra et GPT-6.1 Sol ne prennent pas none ; utilisez low. Si l’effort n’est pas none, retirez temperature, top_p et top_logprobs.
Un outil qui ne renvoie que lookup / hold / escalate Ce saut va vers POST /v1/decisions sur gpt-6-luna. La consultation reste un function_call.
Une session Agents API Rester sur Agents si vous voulez le harness géré. L’écriture en retour reste turn_id, pas function_call_output.

Le saut de routage utilise un choice Decisions. La requête suit la forme de la bêta publique du 6 octobre. La commande est fictive. Ne POSTEZ pas vers /v1/decisions le contrat de réponses inventé dans le texte du 30 septembre :

{
  "model": "gpt-6-luna",
  "input": "Order A-1042 is paid. What should the host do next?",
  "questions": [{
    "type": "choice",
    "name": "next_step",
    "instructions": "Pick the next host action. Do not invent a tool name.",
    "choices": [
      { "value": "lookup", "description": "Read the order. No refund." },
      { "value": "hold", "description": "Stop and wait." },
      { "value": "escalate", "description": "Hand the case to a person." }
    ]
  }]
}

La réponse d’exemple reprend les noms de champs officiels d’un choice. Les probabilités sont fictives. L’hôte n’envoie lookup_order que si choice vaut lookup. hold s’arrête. escalate va vers une personne. Un refusal n’appelle pas l’outil. Vous choisissez le seuil. Les images doivent être des data URL base64 en ligne. Les URL https et file_id ne sont pas acceptés sur ce point d’entrée :

{
  "answers": [{
    "type": "choice",
    "name": "next_step",
    "choice": "lookup",
    "probabilities": [
      { "value": "lookup", "probability": 0.91 },
      { "value": "hold", "probability": 0.05 },
      { "value": "escalate", "probability": 0.04 }
    ],
    "confidence": 0.88
  }]
}

Ultrafast est service_tier avec la valeur ultrafast sur gpt-6-astra. Il ne prend en charge que la résidence des données aux États-Unis et le traitement global, pas l’UE ni les autres points régionaux, et il ne change pas le JSON des outils. L’Ultrafast de GPT-6.1 Sol était encore annoncé comme à venir dans le récapitulatif du 29 septembre. Ce texte ne le donne pas pour livré. Le 29 septembre, l’API Agents a ajouté Computer Use dans un navigateur hébergé par OpenAI. Votre application gère toujours les approbations de site et la connexion. Ce n’est pas une raison de remplacer function_call_output sur Responses. La surveillance de désalignement peut alerter ou arrêter une conversation. Si un tour s’arrête, ne rejouez pas aveuglément le même appel d’outil.

Six étapes, puis basculez le trafic

Ne commencez pas par activer Ultrafast. Écrivez l’écriture en retour :

  1. Nommez l’écriture en retour actuelle. C’est role: tool plus tool_call_id, ou function_call_output, ou un turn_id Agents. Ne partagez pas un parseur entre les trois.
  2. Choisissez le point d’entrée. Les appels d’outils d’Astra et de GPT-6.1 Sol passent à POST /v1/responses. Sol et Luna ne restent sur Chat Completions que si reasoning_effort vaut none.
  3. Aplatissez l’outil et écrivez strict. Si le schema utilise une forme que le mode strict refuse, mettez strict: false et gardez la vérification de l’hôte. Une consultation n’accepte que order_id.
  4. Alignez call_id et retirez les paramètres d’échantillonnage. arguments reste une chaîne. Sur Astra et GPT-6.1 Sol, remplacez none par low. Si l’effort n’est pas none, retirez temperature, top_p et top_logprobs. Sur Chat Completions, retirez aussi logprobs. Sur Responses, retirez message.output_text.logprobs de include. En venant de GPT-5.5 ou d’avant, remplacez prompt_cache_retention par prompt_cache_options.ttl à 30m. Pour changer l’effort en cours de conversation, envoyez un item configuration_update et laissez reasoning.effort au niveau de la requête inchangé.
  5. Ne déplacez vers Decisions que le saut d’énumération. Le modèle est gpt-6-luna. L’hôte mappe lookup vers lookup_order. N’ajoutez async: true que pour un outil lent, et réécrivez sur le call_id d’origine.
  6. Faites le diff des deux JSON, puis basculez. Vérifiez arguments et answers[].choice avec le Schema. S’ils ne correspondent pas, ne changez pas l’identifiant du modèle.

Comment le Schema est une porte : API Agents + JSON Schema. Pourquoi cette porte ne peut pas vivre seulement dans le prompt : pourquoi l’IA a besoin de JSON Schema. La forme d’écriture en retour d’Agents : le JSON d’outils de l’API Agents.

Avant de basculer, étalez trois objets JSON

La plupart des échecs viennent d’un identifiant qui ne correspond pas, d’un name encore imbriqué sous function, ou d’un choice traité comme une commande déjà consultée.

  • formater l’ancien tool call à côté du nouveau function_call, puis validation Schema pour voir si arguments et answers[0].choice passent la porte.
  • Utilisez extraction JSONPath pour $.call_id, $.name et $.answers[0].choice.
  • JSON Diff la charge avant et après le déplacement. Corrigez call_id avant de réécrire le prompt.
  • Vérifiez que call_3c91 est le même identifiant sur l’appel et sur function_call_output.
  • Ne collez pas de commandes, de jetons ni de chemins de dépôt dans un formateur public. JSONSort tourne dans le navigateur.

Si ces trois objets se reconstruisent contre le Schema, la migration est faite. Ultrafast ne remplace pas cette vérification.

Pièges fréquents

  • Prendre Decisions pour la nouvelle API de tool calling. Elle renvoie un choice, une probability ou un score. Les arguments d’outil restent le function calling de Responses. Un objet qui suit votre propre schema utilise les Structured Outputs de Responses.
  • Laisser l’objet function imbriqué. Responses ne lit pas l’ancien function.name. Le name est au même niveau que type.
  • Omettre strict en croyant rester non strict. Responses tente le mode strict, puis revient en arrière et marque strict: false si le schema ne suit pas. Écrivez le comportement voulu. Gardez la vérification de l’hôte.
  • Laisser none ou temperature sur Astra ou GPT-6.1 Sol. Ces modèles ne prennent pas none. GPT-6.1 Sol ne prend pas non plus minimal. Utilisez low. Si l’effort n’est pas none, retirez les paramètres d’échantillonnage.
  • Déplacer toute une boucle Responses vers l’API Agents pour Computer Use. L’ajout du 29 septembre est un navigateur hébergé. Les approbations restent dans l’application. L’écriture en retour d’Agents est turn_id.
  • Lire async: true comme une exécution par le modèle. L’hôte exécute l’outil et suit le travail en attente. Réécrivez plus tard sur le call_id d’origine.

FAQ

Faut-il quitter Chat Completions ?

Si la requête utilise des outils et que le modèle est gpt-6-astra ou gpt-6.1-sol, ces appels passent à Responses. Chat Completions peut encore porter des requêtes sans outils sur ces modèles. gpt-6-sol et gpt-6-luna n’appellent une fonction sur Chat Completions que si reasoning_effort vaut none. Le raisonnement avec des outils passe par Responses.

Decisions peut-il émettre un function_call ?

Non. Il renvoie une réponse typée : une probability de prédicat, un choice, ou un score. L’hôte mappe le choice vers une fonction que vous avez déjà. Le point d’entrée de la bêta publique est POST /v1/decisions, et le seul modèle aujourd’hui est gpt-6-luna. OpenAI le décrit comme environ 10 fois plus rapide que Responses. C’est une vitesse de classement, pas une consultation de commande.

Que se passe-t-il si j’omets strict ?

Chat Completions est non strict par défaut. Sur Responses, omettre strict tente le mode strict. Si le schema ne peut pas être rendu compatible, l’API revient en arrière et l’outil renvoyé affiche strict: false. Écrivez false explicitement pour garder le comportement non strict. L’hôte vérifie arguments dans les deux cas.

Faut-il changer l’écriture en retour d’une session Agents ?

Non. L’API Agents est encore en bêta publique. Gardez turn_id. Computer Use est une permission séparée sur un navigateur hébergé. L’application gère les approbations de site et la connexion. Si vous voulez posséder chaque saut, restez sur Responses et function_call_output.

Ultrafast change-t-il le JSON des outils ?

Non. C’est service_tier: ultrafast sur gpt-6-astra, avec résidence des données aux États-Unis et traitement global seulement. La définition d’outil, call_id et le Schema restent. N’écrivez pas l’Ultrafast de GPT-6.1 Sol comme déjà disponible.

Conclusion

Migrer le JSON Tool Calling après DevDay 2026, c’est changer l’écriture en retour. Les appels d’outils d’Astra et de GPT-6.1 Sol utilisent Responses. Le name est au même niveau que type. Les résultats reviennent sur call_id. Le saut qui ne choisit qu’une énumération peut passer à Decisions. L’hôte exécute toujours la consultation.

Écrivez si A-1042 entre dans les arguments de lookup_order ou dans un input Decisions. Pointez call_3c91 et answers[0].choice avant de basculer le trafic.

Pour aller plus loin

Historique : Première publication