
Appel d’outils, expliqué : comment les agents d’IA décident quoi faire ensuite
Dans mon dernier article, comment obtenir des sorties structurées et lisibles par machine en réponse à un LLM, en utilisant le mode JSON, les appels de fonction et les sorties structurées. Dans cet article, nous avons brièvement abordé l’idée de l’appel de fonction, en l’abordant comme une méthode permettant d’obtenir des réponses structurées. Néanmoins, l’appel de fonction va bien au-delà de la simple récupération de données structurées à partir d’un modèle, puisqu’il constitue essentiellement l’épine dorsale de workflows d’IA agentique. Ainsi, dans l’article d’aujourd’hui, nous allons examiner de plus près ce sujet précisément.
Dans tous les exemples que nous avons abordés jusqu’à présent, le LLM est simplement utilisé comme un répondeur passif, ce qui signifie qu’il reçoit une question puis génère une réponse, et c’est tout. Mais que se passe-t-il si nous voulons que le LLM ne se contente pas de répondre par quelque chose, mais plutôt de faire quelque chose? Ou pour le dire plus précisément, que se passe-t-il si nous voulons qu’une action soit déclenchée en fonction de la réponse du modèle ? Cette action peut être n’importe quoi : rechercher des données en direct, envoyer un message, interroger une base de données, appeler une API externe, etc.
Ceci est rendu possible avec appel d’outil. L’appel d’outils est ce qui transforme un LLM d’un générateur de texte très intelligent en quelque chose qui peut réellement déclencher des actions et interagir avec le monde qui l’entoure.
Alors, jetons un coup d’œil !
Qu’est-ce que l’appel d’outils ?
Appel d’outil (aussi appelé appel de fonction) est le mécanisme par lequel un LLM peut demander l’exécution de fonctions externes ou d’API dans le cadre de la génération de sa réponse. En d’autres termes, au lieu de simplement renvoyer du texte, le modèle peut exécuter une fonction spécifique avec des arguments spécifiques, en réponse à la demande de l’utilisateur.
La chose clé à comprendre ici est que le modèle lui-même n’exécute pas l’outil. C’est seulement décide quel outil appeler et avec quels arguments. L’exécution réelle de l’outil sélectionné se produit dans notre propre code, dans lequel la requête au modèle d’IA est incluse. Nous transmettons ensuite le résultat de l’outil au modèle d’IA, qui l’utilise pour générer une réponse finale à l’utilisateur.
Il s’agit de la boucle d’appel de l’outil, qui comprend les étapes suivantes :
- L’utilisateur soumet un message
- Le modèle d’IA prend le message en entrée et produit un résultat, qui est essentiellement une décision sur l’outil à utiliser et avec quels arguments.
- La réponse du modèle contenant la sélection d’outils et les arguments respectifs à utiliser est renvoyée au code. Le code – sans implication du modèle d’IA – exécute l’outil sélectionné avec les arguments sélectionnés. Cette exécution produit une sorte de résultat (par exemple, un calcul, des informations obtenues à partir d’une API, etc.), et ce résultat est ensuite renvoyé au modèle d’IA.
- Le modèle d’IA prend en entrée le résultat de l’outil et produit une réponse finale à l’utilisateur sur cette base.

Encore une fois, le modèle génère un appel d’outil, pas une exécution d’outil. Les deux sont des choses très différentes, et les confondre est l’une des sources de confusion les plus courantes.
Mais qu’est-ce qu’un appel d’outil exactement ? En pratique, cela signifie que le modèle renvoie une réponse structurée et lisible par machine en utilisant l’appel de fonction, comme nous l’avons vu dans l’article précédent. Dans cette réponse, le contenu est None; il n’y a pas de réponse en langage naturel, juste une instruction structurée indiquant quel outil appeler et avec quels arguments. Ce n’est qu’après avoir exécuté l’outil et renvoyé le résultat que le modèle génère une réponse textuelle réelle pour l’utilisateur.
Mais voyons cela en pratique !
Nous commencerons par un exemple simple utilisant un seul outil et un seul appel, puis nous passerons progressivement à des scénarios plus intéressants.
1. Un seul outil : l’API météo
Je pense que l’exemple le plus courant d’utilisation d’outils avec l’IA qui me vient à l’esprit est une API météo (la pierre angulaire des données personnalisées en direct), alors imaginons que nous construisions un assistant météo. En particulier, nous voulons créer un mécanisme dans lequel l’utilisateur pose des questions sur la météo, et au lieu de simplement laisser le modèle d’IA inventer quelque chose (ce que le modèle ferait très volontiers 🙃), nous voulons qu’il appelle une vraie fonction météo et obtienne des données réelles sur la météo ailleurs, en dehors du LLM. Pour obtenir les données météorologiques, j’utiliserai Ouvrir-Météoune API météo gratuite et open source qui ne nécessite heureusement aucune clé API.
Pour utiliser un outil, il faut d’abord le déclarer dans tools.
from openai import OpenAI
import json
client = OpenAI(api_key="your_api_key")
# Step 1: define the tool
tools = [
{
"type": "function",
"function": {
"name": "get_current_weather",
"description": "Get the current weather for a given city",
"parameters": {
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "The name of the city, e.g. Athens"
},
"unit": {
"type": "string",
"enum": ["celsius", "fahrenheit"],
"description": "The temperature unit to use"
}
},
"required": ["city"]
}
}
}
]
Remarquez que l’outil réel à utiliser (l’API météo) n’est mentionné nulle part jusqu’à présent. Au lieu de cela, le modèle décide quel outil appeler en fonction de trois éléments : la description de la fonction (« Obtenir la météo actuelle pour une ville donnée »), les descriptions des paramètres (« Le nom de la ville, par exemple Athènes »), et le schéma appliqué. C’est uniquement à partir de ces informations que le modèle détermine s’il s’agit du bon outil pour appeler un message utilisateur donné et avec quels arguments. Ainsi, rédiger des descriptions claires et précises lors de la définition de nos outils est d’une importance capitale pour que le modèle puisse identifier et appeler avec succès le bon outil en fonction des entrées de l’utilisateur.
Ainsi, après avoir défini la variable tools, nous pouvons alors faire une requête au modèle IA :
# Step 2: send the user message along with the tool definition
messages = [
{"role": "user", "content": "What's the weather like in Athens right now?"}
]
response = client.chat.completions.create(
model="gpt-4o-mini",
tools=tools,
messages=messages
)
print(response.choices[0].message)
Voici ce qui se passe lorsque nous faisons cette demande. Le modèle lit le message de l’utilisateur, « Quel temps fait-il à Athènes en ce moment ? »et comprend que l’outil disponible get_current_weather peut aider à répondre à cette requête avec des données réelles et en direct. Ainsi, plutôt que de générer directement une réponse textuelle, il décide d’appeler d’abord l’outil. Plus précisément, la réponse du modèle à ce stade ressemble à ceci :
ChatCompletionMessage(
content=None,
role='assistant',
tool_calls=[
ChatCompletionMessageToolCall(
id='call_abc123',
type='function',
function=Function(
name='get_current_weather',
arguments='{"city": "Athens", "unit": "celsius"}'
)
)
]
)
Remarquez comment le contenu est Noneparce que le modèle ne renvoie pas de réponse textuelle, mais un appel d’outil. Il nous appartient maintenant d’exécuter réellement l’outil, le modèle sélectionné, et de lui renvoyer le résultat. Dans notre cas, il s’agira de faire la requête API à l’API météo, en utilisant les arguments (c’est-à-dire la ville et l’unité de mesure) fournis dans la réponse du modèle d’IA :
# Step 3: execute the tool using the Open-Meteo API
import requests
def get_current_weather(city: str, unit: str = "celsius"):
# geocode the city name to coordinates
geo = requests.get(
"https://geocoding-api.open-meteo.com/v1/search",
params={"name": city, "count": 1}
).json()
lat = geo["results"][0]["latitude"]
lon = geo["results"][0]["longitude"]
# fetch current weather
weather = requests.get(
"https://api.open-meteo.com/v1/forecast",
params={
"latitude": lat,
"longitude": lon,
"current": "temperature_2m,weather_code",
"temperature_unit": unit
}
).json()
temp = weather["current"]["temperature_2m"]
return {"city": city, "temperature": temp, "unit": unit}
# extract the tool call from the response
tool_call = response.choices[0].message.tool_calls[0]
arguments = json.loads(tool_call.function.arguments)
# call the actual function
weather_result = get_current_weather(**arguments)
nous pouvons ensuite ajouter le résultat de l’outil à l’historique des messages, puis tout renvoyer au modèle :
# Step 4: add the assistant's tool call AND the tool result to the message history
messages.append(response.choices[0].message) # important: append the tool call first
messages.append({
"role": "tool",
"tool_call_id": tool_call.id, # links the result back to the specific tool call
"content": json.dumps(weather_result)
})
# Step 5: send everything back to the model for a final response
final_response = client.chat.completions.create(
model="gpt-4o-mini",
tools=tools,
messages=messages
)
print(final_response.choices[0].message.content)
Et maintenant, nous obtenons enfin une réponse textuelle appropriée :
It's currently 29°C in Athens. Sounds like a great day to be outside!
🍨 Crème de données est une newsletter proposant des histoires et des tutoriels sur l’IA, les données et la technologie. Si ces sujets vous intéressent, abonnez-vous ici!
2. Laisser le modèle choisir parmi plusieurs outils
Voyons maintenant un exemple plus réaliste. Dans une application agentique réelle, le modèle a généralement accès non pas à un, mais à multiple outils et, par conséquent, il doit déterminer lesquels (ou lesquels) doivent être utilisés en fonction de ce que demande l’utilisateur.
Étendons notre exemple initial d’API météo en ajoutant un outil supplémentaire pour les devises. Pour cela, nous utiliserons Saucisseune API de devises fournissant les taux quotidiens de la Banque centrale européenne, là encore sans exigence de clé API. Alors, mettons à jour notre tools variable en ajoutant un deuxième outil de conversion des devises :
tools = [
{
"type": "function",
"function": {
"name": "get_current_weather",
"description": "Get the current weather for a given city",
"parameters": {
"type": "object",
"properties": {
"city": {"type": "string", "description": "The name of the city"},
"unit": {"type": "string", "enum": ["celsius", "fahrenheit"]}
},
"required": ["city"]
}
}
},
{
"type": "function",
"function": {
"name": "convert_currency",
"description": "Convert an amount from one currency to another",
"parameters": {
"type": "object",
"properties": {
"amount": {"type": "number", "description": "The amount to convert"},
"from_currency": {"type": "string", "description": "The source currency code, e.g. USD"},
"to_currency": {"type": "string", "description": "The target currency code, e.g. EUR"}
},
"required": ["amount", "from_currency", "to_currency"]
}
}
}
]
Et également configurer le réel convert_currency fonction utilisant l’API Frankfurter :
def convert_currency(amount: float, from_currency: str, to_currency: str):
response = requests.get(
f"https://api.frankfurter.dev/v2/rate/{from_currency}/{to_currency}"
).json()
rate = response["rate"]
converted = round(amount * rate, 2)
return {
"amount": amount,
"from_currency": from_currency,
"to_currency": to_currency,
"converted_amount": converted,
"rate": rate
}
De cette manière, le modèle peut gérer un éventail beaucoup plus large de demandes d’utilisateurs ; il peut désormais également répondre sur les devises, en plus de la météo 😋. Maintenant, si l’utilisateur demande « Quel temps fait-il à Athènes ? »le modèle devrait appeler get_current_weather. S’ils demandent « Combien font 100 USD en EUR ? »il devrait appeler convert_currency. Et si nous demandons quelque chose qui n’a aucun rapport avec la météo et les devises et pour lequel aucun des outils disponibles ne peut aider, le modèle répondra simplement par texte sans appeler aucun outil.
Mais voyons ceci en action :
messages = [
{"role": "user", "content": "How much is 200 USD in EUR?"}
]
response = client.chat.completions.create(
model="gpt-4o-mini",
tools=tools,
messages=messages
)
tool_call = response.choices[0].message.tool_calls[0]
Jetons un coup d’œil à la réponse :
print(tool_call.function.name)
d’où nous obtenons convert_currency. Ainsi, le modèle a compris que la question « Combien font 200 USD en EUR ? » est pertinent pour le convert_currency outil. Jetons également un coup d’œil aux arguments :
print(tool_call.function.arguments)
d’où nous obtenons
'{"amount": 200, "from_currency": "USD", "to_currency": "EUR"}'
Le modèle identifie donc correctement convert_currency comme le bon outil et remplit les arguments appropriés, sans que nous fassions autre chose que fournir des descriptions d’outils appropriées et que l’utilisateur fournisse un message approprié. Ce mécanisme précis de prise de décision est ce qui fait de l’appel d’outils le fondement des systèmes agentiques.
3. Appeler plusieurs outils à la fois
Un autre scénario intéressant d’appel d’outils est que de nombreux modèles, comme gpt-4opeut appeler plusieurs outils en une seule réponse lorsque la demande de l’utilisateur l’exige. C’est ce qu’on appelle appel d’outil parallèle.
Par exemple, imaginons un scénario dans lequel l’utilisateur demande dans une seule requête quelque chose qui nécessite l’utilisation à la fois du get_current_weather et convert_currency outils pour obtenir les informations requises :
messages = [
{"role": "user", "content": "What's the weather in Athens and how much is 100 USD in EUR?"}
]
response = client.chat.completions.create(
model="gpt-4o-mini",
tools=tools,
messages=messages
)
for tool_call in response.choices[0].message.tool_calls:
print(tool_call.function.name)
print(tool_call.function.arguments)
Dans ce cas, la réponse que nous obtenons est la suivante :
get_current_weather
{"city": "Athens"}
convert_currency
{"amount": 100, "from_currency": "USD", "to_currency": "EUR"}
Remarquez comment les deux outils sont appelés dans une seule réponse de modèle. Nous pouvons ensuite exécuter les outils respectifs avec les arguments fournis et transmettre ensemble les résultats des outils au modèle. C’est beaucoup plus efficace que les appels séquentiels, et c’est ainsi que les agents plus avancés gèrent les requêtes en plusieurs parties.
Dans mon esprit : alors, qu’est-ce qui rend cet agent ?
Une chose qui m’a toujours énervé est le terme « agent » qui est appliqué sur tout. Agents, workflows agents, tout ce qui vient du mot agent est très sexy de nos jours, mais comme vous l’avez peut-être déjà découvert, tout ce qui est vendu comme agent ne l’est pas vraiment.
Prenons donc du recul et réfléchissons en premier lieu à ce qu’est réellement un agent. À la base, un agent est quelque chose qui perçoit son environnement, traite ces informations d’une manière ou d’une autre, a un objectif, puis décide quelle action entreprendre pour l’atteindre. Pensez à ce que fait notre mécanisme d’appel d’outils : il perçoit les outils disponibles, décide lequel est approprié pour répondre à la demande de l’utilisateur (le cas échéant) et transmet cette décision au reste du code pour exécution. C’est, dans sa forme la plus simple, l’agence.
Dans les applications agentiques du monde réel, la boucle d’appel d’outil s’exécute non pas une mais plusieurs fois, le modèle utilisant les résultats d’un appel d’outil pour décider si et lequel outil appeler ensuite. C’est ce qu’on appelle parfois un Boucle ReAct (Raison + Acte), et c’est ce qui permet aux agents de gérer des tâches complexes en plusieurs étapes qui ne peuvent pas être résolues en un seul appel.
En fin de compte, ce que je trouve le plus fascinant dans l’appel d’outils, c’est la façon dont il change la nature d’un LLM. Jusqu’à présent, un modèle de langage était essentiellement un très fonction d’entrée-sortie sophistiquée, qui prend du texte en entrée et génère du texte en sortie. Mais avec l’appel de l’outil, nous avons accès à une collection infinie de fonctionnalités supplémentaires, que nous pouvons combiner avec la puissance de raisonnement du LLM pour créer des systèmes bien plus performants que l’un ou l’autre seul.
✨ Merci d’avoir lu ! ✨
Si tu es arrivé jusqu’ici, les pialgorithmes pourraient vous être utiles — une plateforme que nous avons créée qui aide les équipes à gérer en toute sécurité les connaissances organisationnelles en un seul endroit.
Vous avez adoré cet article ? Rejoignez-moi sur 💌Sous-pile et 💼LinkedIn
Toutes les images sont de l’auteur, sauf mention contraire.



