À la fin de ce guide, vous saurez définir un outil, l’envoyer à OpenAI, lire l’appel d’outil renvoyé par le modèle, parser ses arguments JSON, puis exécuter votre propre fonction côté application. Vous activerez aussi le mode strict, configurerez les appels parallèles, puis validerez et simulerez le côté API avec Apidog avant la mise en production. Gardez la documentation d’appel de fonction d’OpenAI ouverte comme référence, et consultez aussi notre guide sur la création d’agents avec le SDK OpenAI Agents pour une vue plus globale.
Ce dont vous avez besoin avant de commencer
L’appel de fonction, aussi appelé appel d’outil, permet à un modèle OpenAI de demander à votre application d’exécuter une action structurée.
Le modèle ne lance pas directement votre code. Il fait trois choses :
- Il lit le message utilisateur.
- Il choisit un outil parmi ceux que vous avez exposés.
- Il retourne un nom de fonction et des arguments JSON.
Votre application garde le contrôle de l’exécution.
Par exemple, au lieu de recevoir un texte à analyser comme :
L’utilisateur veut connaître la météo à Paris.
Vous recevez un appel structuré :
{
"name": "get_weather",
"arguments": "{\"location\":\"Paris, France\"}"
}
Pour suivre ce guide, vous avez besoin de :
- une clé API OpenAI ;
- une fonction dans votre application, par exemple
get_weather; - un schéma JSON décrivant les arguments attendus ;
- idéalement, un moyen de valider et simuler l’API appelée par cette fonction.
La fonctionnalité existe dans deux API OpenAI :
-
Chat Completions, avec une structure historique basée sur
toolsettool_calls; - Responses API, avec une structure plus plate et unifiée.
Les deux approches sont couvertes ci-dessous.
Étape 1 : Définissez votre outil
Un outil est une fonction que vous décrivez au modèle. Cette définition contient :
- un
name; - une
description; - un schéma JSON pour les
parameters.
La description est importante : elle aide le modèle à décider quand utiliser l’outil. Écrivez-la comme une instruction claire.
Exemple avec l’API Chat Completions :
{
"type": "function",
"function": {
"name": "get_weather",
"description": "Get the current weather for a city. Use when the user asks about temperature or conditions.",
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "City and country, e.g. Bogotá, Colombia"
},
"unit": {
"type": "string",
"enum": ["celsius", "fahrenheit"]
}
},
"required": ["location"],
"additionalProperties": false
}
}
}
Dans l’API Responses, la définition est plus directe. Les champs name, description, parameters et strict sont placés au niveau de l’objet outil, sans clé function imbriquée.
Si vous maintenez déjà une spécification OpenAPI pour votre service, vous pouvez réutiliser une grande partie de ce travail de schéma. Notre guide sur la génération de collections de tests à partir de spécifications OpenAPI montre comment rentabiliser ce travail côté tests.
Étape 2 : Envoyez l’outil à OpenAI
Envoyez le message utilisateur et la liste des outils disponibles dans la même requête.
Exemple avec Chat Completions :
curl https://api.openai.com/v1/chat/completions \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-4.1",
"messages": [
{
"role": "user",
"content": "What is the weather in Paris right now?"
}
],
"tools": [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "Get the current weather for a city.",
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string"
}
},
"required": ["location"],
"additionalProperties": false
}
}
}
]
}'
Le tableau tools contient toutes les fonctions que le modèle peut utiliser pendant cette interaction.
Si un outil correspond à l’intention de l’utilisateur, le modèle ne renvoie pas une réponse finale en langage naturel. Il renvoie un appel d’outil à exécuter côté application.
Étape 3 : Lisez l’appel d’outil renvoyé par le modèle
Dans Chat Completions, les appels d’outils sont disponibles dans tool_calls.
Exemple de réponse partielle :
{
"id": "call_12345xyz",
"type": "function",
"function": {
"name": "get_weather",
"arguments": "{\"location\":\"Paris, France\"}"
}
}
Dans l’API Responses, la forme est plus plate :
{
"type": "function_call",
"call_id": "call_12345xyz",
"name": "get_weather",
"arguments": "{\"location\":\"Paris, France\"}"
}
Point important : arguments est une chaîne encodée en JSON, pas un objet déjà parsé.
Vous devez donc l’analyser explicitement avant de l’utiliser.
Exemple en JavaScript :
const toolCall = response.choices[0].message.tool_calls[0];
const functionName = toolCall.function.name;
const args = JSON.parse(toolCall.function.arguments);
console.log(functionName); // get_weather
console.log(args); // { location: "Paris, France" }
Ajoutez toujours une validation après le JSON.parse, surtout si ces arguments déclenchent une action réelle.
Étape 4 : Exécutez votre fonction
Une fois les arguments extraits, mappez le nom de fonction vers votre propre code.
Exemple minimal :
async function getWeather({ location, unit = "celsius" }) {
// Exemple : appel à votre API météo interne ou externe
return {
location,
unit,
temperature: 18,
condition: "cloudy"
};
}
const availableFunctions = {
get_weather: getWeather
};
const fn = availableFunctions[functionName];
if (!fn) {
throw new Error(`Fonction inconnue : ${functionName}`);
}
const result = await fn(args);
Le modèle ne fait qu’émettre une demande structurée. Votre application décide :
- quelle fonction appeler ;
- quelles validations appliquer ;
- comment gérer les erreurs ;
- quelles données retourner au modèle.
Étape 5 : Retournez le résultat au modèle
Après exécution, renvoyez le résultat à OpenAI pour que le modèle produise une réponse finale.
Avec Chat Completions, ajoutez un message de rôle tool associé à l’id de l’appel :
{
"role": "tool",
"tool_call_id": "call_12345xyz",
"content": "{\"location\":\"Paris, France\",\"temperature\":18,\"condition\":\"cloudy\"}"
}
La boucle complète est donc :
- l’utilisateur pose une question ;
- le modèle demande un appel d’outil ;
- votre application exécute la fonction ;
- votre application renvoie le résultat ;
- le modèle formule la réponse finale.
Étape 6 : Activez le mode strict
Le mode strict force les arguments produits par le modèle à respecter votre schéma JSON.
OpenAI recommande de l’activer pour obtenir des sorties plus prévisibles.
Exemple :
{
"type": "function",
"function": {
"name": "get_weather",
"description": "Get the current weather for a city.",
"strict": true,
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string"
},
"unit": {
"type": ["string", "null"],
"enum": ["celsius", "fahrenheit", null]
}
},
"required": ["location", "unit"],
"additionalProperties": false
}
}
}
Deux règles sont importantes en mode strict :
- chaque objet doit définir
additionalProperties: false; - chaque champ présent dans
propertiesdoit aussi être présent dansrequired.
Pour rendre un champ optionnel, ne le retirez pas de required. Rendez-le nullable avec null.
Exemple :
"unit": {
"type": ["string", "null"],
"enum": ["celsius", "fahrenheit", null]
}
Votre code peut alors toujours s’attendre à recevoir la clé unit, même si sa valeur est null.
Étape 7 : Configurez les appels parallèles
Par défaut, le modèle peut renvoyer plusieurs appels d’outils en une seule réponse.
Exemple : si l’utilisateur demande la météo à Paris, Bogotá et Montréal, vous pouvez recevoir trois appels get_weather.
Cela permet d’exécuter les appels en parallèle :
const results = await Promise.all(
toolCalls.map(async (call) => {
const name = call.function.name;
const args = JSON.parse(call.function.arguments);
return {
tool_call_id: call.id,
result: await availableFunctions[name](args)
};
})
);
Si vos appels doivent s’exécuter dans un ordre précis, désactivez les appels parallèles :
{
"parallel_tool_calls": false
}
| Paramètre | Ce qu’il contrôle | Valeur par défaut | Quand le modifier |
|---|---|---|---|
parallel_tool_calls |
Autorise plusieurs appels d’outils en une seule réponse | true |
Passez à false si les appels dépendent les uns des autres |
strict |
Force les arguments à respecter le schéma JSON | Meilleur effort sauf configuration explicite | Activez-le pour des arguments plus prévisibles |
tool_choice |
Contrôle si et quelle fonction peut être appelée | auto |
Utilisez required, none ou ciblez une fonction précise |
Le mode strict améliore la structure des arguments, mais il ne valide pas votre logique métier. Une ville peut être valide selon le schéma, mais non prise en charge par votre service. Votre application doit continuer à vérifier les valeurs et gérer les erreurs.
Comment le tester dans Apidog
Le modèle vous donne un appel d’outil. Avant de le brancher à une fonction réelle, vous devez vérifier deux choses :
- les arguments respectent le format attendu ;
- l’API appelée par votre fonction se comporte comme prévu.
Apidog vous aide sur ces deux aspects côté contrat API.
Apidog n’exécute pas les fonctions internes de votre application. Votre code reste responsable de l’exécution.
En revanche, Apidog peut vous aider à :
- valider la structure des arguments ;
- tester les contrats JSON ;
- simuler les APIs en aval ;
- reproduire les cas d’erreur.
Valider les arguments produits par le modèle
Prenez la chaîne arguments renvoyée par OpenAI et traitez-la comme un corps de requête.
Exemple :
{
"location": "Paris, France",
"unit": "celsius"
}
Dans Apidog, vous pouvez vérifier que :
-
locationexiste ; -
locationest une chaîne ; -
unitvaut uniquementcelsius,fahrenheitounull; - aucun champ inattendu n’est présent.
Les expressions JSONPath permettent d’extraire des champs spécifiques. Pour des contrôles plus complets, utilisez la validation par schéma JSON, avec le même schéma que celui fourni à OpenAI.
Cette approche réduit le risque de connecter votre fonction à une charge utile invalide.
Simuler l’API appelée par votre fonction
Votre fonction get_weather appelle probablement un service météo externe ou interne.
Pendant le développement, ce service peut être :
- payant ;
- limité en débit ;
- instable ;
- pas encore disponible ;
- difficile à forcer en erreur.
Vous pouvez créer une API de simulation dans Apidog et pointer votre fonction vers cette simulation.
Exemple de réponse simulée :
{
"location": "Paris, France",
"temperature": 18,
"unit": "celsius",
"condition": "cloudy"
}
Vous pouvez aussi simuler des erreurs :
{
"error": "rate_limit_exceeded",
"message": "Too many requests"
}
Cela vous permet de tester votre logique avant d’envoyer du trafic vers l’API réelle.
Le workflow complet devient :
- capturez un appel d’outil OpenAI ;
- parsez la chaîne
arguments; - validez les arguments dans Apidog ;
- exécutez votre fonction ;
- pointez la fonction vers une API simulée Apidog ;
- testez les réponses nominales et les erreurs ;
- branchez ensuite l’API réelle.
Questions fréquemment posées
L’appel de fonction fonctionne-t-il avec Chat Completions et Responses API ?
Oui. Les deux points de terminaison le prennent en charge.
La différence principale est la forme des données :
- Chat Completions imbrique la fonction sous
functionet renvoietool_calls; - Responses API utilise une définition plus plate et renvoie des éléments
function_calldansoutput.
Pourquoi arguments est-il une chaîne et non un objet ?
arguments est du JSON encodé sous forme de texte. Vous devez le parser vous-même.
Exemple :
const args = JSON.parse(toolCall.function.arguments);
Ne l’utilisez pas directement sans validation. Vous pouvez ensuite passer l’objet obtenu dans une validation de schéma JSON avant d’appeler votre fonction.
Le mode strict garantit-il que ma fonction va réussir ?
Non.
Le mode strict garantit que la structure des arguments correspond au schéma JSON. Il ne garantit pas que les valeurs sont correctes pour votre métier.
Vous devez toujours vérifier :
- les valeurs autorisées ;
- les permissions ;
- les limites métier ;
- les erreurs de l’API appelée ;
- les timeouts ;
- les réponses inattendues.
Apidog peut-il exécuter ma fonction réelle ?
Non. Apidog ne remplace pas votre runtime applicatif.
Votre application exécute toujours ses propres fonctions. Apidog sert à valider les contrats et à simuler les APIs dont ces fonctions dépendent.
Conclusion
Vous avez maintenant la boucle complète d’un appel d’outil OpenAI :
- définir un outil avec un schéma JSON ;
- l’envoyer au modèle ;
- lire
tool_callsoufunction_call; - parser les
arguments; - exécuter votre fonction ;
- retourner le résultat au modèle ;
- activer le mode strict ;
- décider si les appels parallèles sont adaptés ;
- valider et simuler les dépendances API avant la production.
Pour tester cette partie plus efficacement, téléchargez Apidog afin de valider les arguments d’appel d’outil par rapport à votre schéma et simuler les APIs dont vos fonctions dépendent.

Top comments (0)