Aller au contenu
2.12Intermédiaire8 min

Function Calling vs Tool Use : définitions et implémentations

Sebastian KarallMis à jour le 28 octobre 2026
Définition

Function Calling et Tool Use désignent la même fonctionnalité de base : au lieu de produire du texte libre, un LLM génère un appel structuré, conforme à un schéma, vers une fonction définie en externe. OpenAI a forgé le terme « Function Calling », Anthropic parle de « Tool Use ». Techniquement, les deux reposent sur JSON Schema et se recouvrent presque entièrement, avec des différences dans les noms de champs et la mécanique de l'API.

L’essentiel

  • Function Calling (OpenAI) et Tool Use (Anthropic) sont en grande partie synonymes : dans les deux cas, le LLM génère du JSON structuré au lieu de texte libre, que du code déterministe exécute ensuite.
  • La différence d'implémentation la plus visible tient au nommage des champs : OpenAI utilise 'parameters' dans le schéma d'outil, Anthropic 'input_schema'. Les deux s'appuient en dessous sur JSON Schema. Le format des réponses et le format de retour des appels d'outils diffèrent également.
  • Le LLM n'exécute rien lui-même : il fournit un appel d'outil, ton code l'exécute et renvoie le résultat. Chez Anthropic, le stop_reason 'tool_use' signale qu'un appel est en attente.
  • Les appels d'outils parallèles sont activés par défaut et peuvent être désactivés (Anthropic : disable_parallel_tool_use). Les erreurs doivent revenir au modèle sous forme de tool_result structuré avec is_error, et non sous forme d'exception.
  • La sélection d'outils ne passe pas à l'échelle indéfiniment : quelques outils bien délimités sont plus fiables que de nombreux outils qui se chevauchent. Les définitions d'outils consomment du budget de prompt et servent en même temps de cible de cache.
  • Règle pratique : toujours lire les entrées d'outils avec un parseur JSON, jamais par correspondance de chaînes, car l'échappement peut varier d'une version de modèle à l'autre.

Function Calling et Tool Use désignent au fond la même capacité : à un moment donné, un grand modèle de langage ne produit pas de texte libre, mais un appel structuré, conforme à un schéma, vers une fonction définie en externe, avec les arguments adéquats. OpenAI a introduit le terme « Function Calling », Anthropic parle de « Tool Use ». Techniquement, les deux reposent sur JSON Schema et se recouvrent presque entièrement. Les différences tiennent au nommage des champs du schéma et à certaines mécaniques de l'API, pas au principe de base.

Cet article fait partie du cluster consacré à l'article pilier « Les bases des LLM pour les agents » et approfondit ce qui est esquissé dans l'article complémentaire sur les bases du tool calling. Toutes les informations techniques correspondent à la situation de 2026.

  • Synonymes, avec une nuance : « Tool Use » est le terme un peu plus large, car chez Anthropic, un outil peut aussi être un service côté serveur (recherche web, exécution de code) ou un serveur MCP. « Function Calling » désigne au sens strict l'appel d'une simple fonction.
  • Le modèle n'exécute rien : il fournit uniquement l'appel. Ton code valide les arguments, exécute la fonction et renvoie le résultat. Ce n'est qu'ensuite que le LLM formule la réponse.
  • Différence d'implémentation la plus visible : dans le schéma d'outil, OpenAI utilise le champ parameters, Anthropic input_schema. Les deux s'appuient en dessous sur JSON Schema.

Comment un LLM génère des appels d'outils structurés

Le mécanisme est construit de la même façon dans les deux écosystèmes. Tu transmets au modèle une liste de définitions d'outils en plus de la requête de l'utilisateur proprement dite. Chaque définition comporte un nom, une description (quand utiliser l'outil et quand ne pas l'utiliser) et un schéma d'entrée avec des paramètres typés, dont certains sont obligatoires.

À partir des définitions d'outils, de la configuration des outils et de ton prompt système, l'API d'Anthropic construit son propre prompt de Tool Use. Selon la documentation d'Anthropic, il suit à peu près ce modèle :

```
In this environment you have access to a set of tools you can use to answer the user's question.
{{ FORMATTING INSTRUCTIONS }}
String and scalar parameters should be specified as is, while lists and objects should use JSON format.
Here are the functions available in JSONSchema format:
{{ TOOL DEFINITIONS IN JSON SCHEMA }}
{{ USER SYSTEM PROMPT }}
{{ TOOL CONFIGURATION }}
```

Il en découle une conséquence économique souvent négligée : chaque outil coûte en permanence des tokens sous forme de schéma (généralement de l'ordre de 100–300 par outil, selon la complexité du schéma), car le modèle relit les définitions à chaque tour d'inférence. Un catalogue de dix outils représente donc en gros 1 000–3 000 tokens par appel. À 100 000 appels par mois, cela fait 100–300 millions de tokens de pure charge de schéma, ce qui n'est économiquement viable qu'avec le Prompt Caching.

Dans le cadre des 12-Factor Agents de Dex Horthy, le principe directeur est donc : les outils ne sont que des sorties structurées. Ce que produit le LLM, c'est du JSON conforme à un schéma ; ce qui est exécuté, c'est du code déterministe que tu possèdes et contrôles toi-même.

Définition du schéma : JSON Schema comme langage commun

Sous le capot, les deux fournisseurs misent sur JSON Schema comme lingua franca. Des outils code-first comme Pydantic (Python) ou Zod (TypeScript) génèrent ce schéma automatiquement à partir de définitions de types.

Une définition d'outil fiable repose sur sa description, au niveau de l'outil comme au niveau des champs. Un paramètre recipient_email décrit comme « adresse e-mail du destinataire conforme à la RFC 5321 ; doit correspondre à une fiche client existante » est nettement plus fiable que le même champ sans description. Une règle pratique éprouvée : la description ne doit pas seulement dire ce que fait un outil, mais surtout quand il doit être appelé et comment construire les arguments. C'est le contrat d'interface durable entre le modèle et l'API, et sur les modèles récents, plutôt réticents à recourir aux outils, son effet est mesurablement plus fort que celui d'une simple description de fonction.

Remarque pour les entreprises en Europe : garder les noms d'outils et les identifiants de paramètres en anglais (interopérabilité avec les bibliothèques, les logs, OpenAPI), mais rédiger les descriptions dans la langue d'exécution de l'agent. Les catalogues multilingues fonctionnent avec les modèles de pointe, mais restent une source d'incohérences évitable.

Différences d'implémentation : OpenAI vs Anthropic

Le tableau suivant résume les différences pertinentes en pratique (état 2026). Important : les points communs l'emportent. En production, de nombreuses équipes utilisent une couche d'abstraction (par exemple LiteLLM ou le Vercel AI SDK) pour encapsuler les différences de noms de champs.

Aspect

OpenAI (Function Calling)

Anthropic (Tool Use)

Terme

Function Calling

Tool Use

Champ de schéma pour les paramètres

parameters

input_schema

Standard de schéma

JSON Schema

JSON Schema

Signal d'appel d'outil

Entrée function_call dans l'output (Responses API) ou finish_reason: "tool_calls" (Chat Completions)

stop_reason: "tool_use"

Contrôle de la sélection

tool_choice : auto / required / none / fonction nommée

tool_choice : auto / any / tool / none

Appels parallèles

Activés par défaut

Activés par défaut

Désactiver le parallélisme

Paramètre parallel_tool_calls: false

disable_parallel_tool_use: true dans tool_choice

Retour du résultat

function_call_output avec call_id (Responses API) ou message avec role: "tool" et tool_call_id (Chat Completions)

Bloc tool_result avec le tool_use_id correspondant

Signaler une erreur

erreur structurée dans le résultat

tool_result avec is_error: true

Outils côté serveur

entre autres Code Interpreter, recherche web

Exécution de code, recherche et récupération web

Application stricte du schéma

Structured Outputs / strict: true

strict: true ou output_config.format

Chez Anthropic, tool_choice propose quatre modes : {"type": "auto"} (le modèle décide, valeur par défaut), {"type": "any"} (au moins un outil doit être utilisé), {"type": "tool", "name": "..."} (un outil précis est imposé) et {"type": "none"} (aucun outil). Avec auto, disable_parallel_tool_use: true limite la réponse à un appel au maximum, avec any et tool à exactement un. Selon la documentation d'Anthropic, Claude Opus 5.5, Sonnet 5.5, Fable 5.1 et Mythos 5.1 ne prennent en charge ni any ni tool. Il en va de même, selon la documentation Tool Use, lorsque l'Extended Thinking est activé manuellement. Dans les deux cas, seuls auto et none restent disponibles.

Appels d'outils parallèles et boucle d'agent

Les modèles de pointe peuvent demander plusieurs appels d'outils simultanés dans une seule réponse, par exemple « récupérer le profil », « charger les dernières commandes » et « vérifier le stock » en parallèle. Cela réduit sensiblement les allers-retours et la latence. Ton harness doit traiter tous les appels demandés et renvoyer les résultats regroupés dans un seul message de suivi.

La boucle d'agent manuelle chez Anthropic suit ce schéma : appeler l'API et examiner la réponse. Tant que stop_reason vaut tool_use, les blocs tool use sont exécutés, la réponse complète du modèle ainsi que les blocs tool_result (chacun avec le tool_use_id correspondant) sont ajoutés à l'historique des messages, puis l'appel API suivant est lancé. La boucle se termine lorsque stop_reason vaut end_turn. Les SDK officiels proposent aussi un « Tool Runner » automatique qui encapsule cette boucle ; on utilise la boucle manuelle pour un contrôle plus fin, par exemple des étapes de validation ou une journalisation personnalisée.

Gestion des erreurs : robuste plutôt que fragile

La deuxième cause la plus fréquente d'agents instables en production, après les définitions d'outils ambiguës, est une mauvaise gestion des erreurs. Trois principes valent dans tous les secteurs :

  • Renvoyer les erreurs sous forme de tool result structuré, plutôt que de lever une exception qui interrompt la boucle. Un { "error": "code", "message": "...", "retry_after_seconds": 30 } condensé laisse le modèle décider s'il corrige les arguments, choisit une autre stratégie ou fait remonter le problème. Chez Anthropic, tu définis en plus is_error: true dans le bloc tool_result.
  • Garder le contexte d'erreur compact. Ne déverse pas de stack traces brutes dans la fenêtre de contexte. Cela pollue le contexte et dégrade les réponses suivantes. Condense d'abord les stack traces.
  • Plafonner les nouvelles tentatives. Trois tentatives, c'est la norme. Distingue selon le type d'erreur : erreurs d'outil (500/timeout) à relancer avec backoff, erreurs de validation (400) avec des arguments ajustés, erreurs de permission (403) à escalader vers un humain sans nouvelle tentative, limites de débit (429) avec backoff et, le cas échéant, changement de modèle.

Un anti-pattern tenace est la suppression silencieuse des erreurs : les appels d'outils échouent, mais l'agent continue comme si tout allait bien. Renvoie toujours explicitement les erreurs au modèle.

Une deuxième règle pratique : toujours lire les entrées d'outils avec un parseur JSON, jamais par correspondance de chaînes sur l'entrée sérialisée. Les modèles Claude peuvent gérer l'échappement JSON différemment selon la version, par exemple pour l'échappement Unicode ou des barres obliques. Faire du string matching brut, c'est se fabriquer un bug difficile à repérer.

Exemple concret en pseudocode

L'exemple de pseudocode suivant montre une définition d'outil et une boucle manuelle dans la syntaxe d'Anthropic. Chez OpenAI, input_schema s'appellerait parameters. La boucle aurait aussi une autre forme : dans la Responses API, les arguments arrivent sous forme de chaîne JSON dans une entrée function_call avec call_id, et le résultat est renvoyé en function_call_output avec le même call_id, comme le montre le guide Function Calling d'OpenAI.

```
tool = {
"name": "fetch_recent_orders",
"description": "Charge les dernières commandes d'un client. "
"À utiliser si l'utilisateur demande l'historique, le statut "
"ou la livraison de ses commandes. NE PAS utiliser pour une "
"simple recherche de produits, utiliser search_products. "
"Returns: liste de {id, total, status, items}.",
"input_schema": {
"type": "object",
"properties": {
"user_id": {"type": "string", "description": "ID client interne"},
"limit": {"type": "integer", "description": "Nombre max. (par défaut 10)"}
},
"required": ["user_id"]
}
}

messages = [{"role": "user", "content": "Où est ma dernière commande ?"}]

while True:
response = client.messages.create(
model="claude-opus-5-5", # modèle d'exemple
max_tokens=1024,
tools=[tool],
messages=messages,
)
if response.stop_reason != "tool_use":
break # end_turn -> terminé

messages.append({"role": "assistant", "content": response.content})
results = []
for block in response.content:
if block.type == "tool_use": # év. plusieurs -> en parallèle
try:
data = run_tool(block.name, block.input) # ton propre code
results.append({
"type": "tool_result",
"tool_use_id": block.id,
"content": to_json(data),
})
except ToolError as e:
results.append({
"type": "tool_result",
"tool_use_id": block.id,
"content": str(e),
"is_error": True,
})
messages.append({"role": "user", "content": results})
```

Exemple de calcul de la charge des outils : supposons que cet agent fonctionne avec cinq outils de ~200 tokens de schéma chacun (1 000 tokens) plus 800 tokens de prompt système. À 100 000 appels par mois, le seul préfixe stable représente environ 180 millions de tokens d'entrée. Avec le Prompt Caching d'Anthropic, une lecture en cache coûte, pour la plupart des modèles, 10 % du tarif d'entrée standard, soit environ 0,30 au lieu de 3,00 dollars US par million de tokens avec Sonnet 4.6. Avec Opus 5.5 et Sonnet 5.5, c'est 5 %, et 2,5 % avec Fable 5.1 et Mythos 5.1. La condition préalable est un catalogue d'outils stable. Toute modification des définitions d'outils, même de leur seul ordre, invalide entièrement le cache. D'où le pattern de production : déployer les catalogues d'outils dans des releases planifiées, pas de hotfix sur les définitions d'outils.

Combien d'outils sont pertinents et pourquoi le chevauchement pose problème

La précision de sélection des outils ne passe pas à l'échelle indéfiniment. Une approche a fait ses preuves : ne charger en permanence qu'un petit noyau d'outils et charger les autres dynamiquement via un outil de recherche d'outils. Cela limite le contexte fixe et ménage le cache, car les schémas sont ajoutés au lieu d'être remplacés. Le véritable goulet d'étranglement n'est toutefois pas le nombre en soi, mais le chevauchement : une poignée d'outils bien délimités se gère sans difficulté, alors que quelques outils qui se chevauchent suffisent à pousser un modèle à deviner.

Deux outils qui pourraient plausiblement répondre à la même requête, par exemple search_documents et search_knowledge_base, constituent le problème qu'aucun prompt, aussi bon soit-il, ne résout. Face à « Trouve des informations sur X », le modèle devine. La contre-mesure la plus efficace, et la plus souvent oubliée, est la clause « quand ne pas l'utiliser » dans chaque description. Le Berkeley Function-Calling Leaderboard (BFCL) sert de référence publique de benchmark pour la précision de sélection ; ses valeurs fluctuent toutefois et devraient être revérifiées sur ton propre jeu d'évaluation, pas sur la foi d'un article de blog marketing.

Pour les agences et les décideurs B2B

Function Calling ou Tool Use, c'est le pont entre le modèle de langage et tes systèmes réels : CRM, comptabilité, expédition, base de connaissances. La confusion terminologique est sans conséquence ; la discipline d'implémentation, elle, en a. Qu'un agent tourne de façon fiable en production dépend de définitions d'outils bien délimitées, d'une gestion des erreurs solide sous forme de résultats structurés, de conditions d'arrêt maîtrisées et d'une stratégie de catalogue qui tient compte du cache, pas du choix entre OpenAI et Anthropic.

En tant qu'agence basée à Vienne et spécialisée dans les agents IA, nous accompagnons les entreprises en Europe, de la conception des schémas d'outils à une boucle d'agent auditable et prête pour la production, en passant par l'abstraction des fournisseurs. Si tu veux intégrer de manière fiable des appels d'outils structurés dans tes processus métier, contacte-nous.

Résumer avec l’IAChatGPTClaudePerplexity

Ouvre le chat avec un prompt prêt à l’emploi.

Questions fréquentes

Function Calling, est-ce la même chose que Tool Use ?
Sur le fond, oui. Les deux termes décrivent le même mécanisme : au lieu de texte libre, un LLM génère un appel structuré, conforme à un schéma, vers une fonction que tu as définie. 'Function Calling' est le terme d'OpenAI, 'Tool Use' celui d'Anthropic. La nuance : 'Tool Use' est un terme un peu plus large, car chez Anthropic, un outil peut aussi être un service côté serveur (par exemple la recherche web ou l'exécution de code) ou un serveur MCP, et pas seulement une fonction côté client. En pratique, les deux termes s'emploient comme synonymes.
En quoi OpenAI et Anthropic diffèrent-ils sur le plan technique ?
La différence la plus visible est le nommage des champs dans le schéma d'outil. OpenAI définit les paramètres sous la clé 'parameters', Anthropic sous 'input_schema'. Les deux utilisent JSON Schema en dessous, si bien que l'objet de paramètres lui-même est presque identique. Ils diffèrent aussi par la signalisation (Anthropic : stop_reason 'tool_use') et par le format de retour des résultats (Anthropic : un bloc tool_result avec le tool_use_id correspondant). C'est pourquoi la boucle d'agent n'a pas la même forme chez les deux fournisseurs.
Le LLM exécute-t-il lui-même la fonction ?
Non, pas avec les outils classiques côté client. Le modèle fournit uniquement l'appel structuré, arguments compris. Ton code (le 'harness') valide les arguments, exécute la fonction et renvoie le résultat sous forme de tool_result. Ce n'est qu'ensuite que le LLM formule la réponse finale. Les outils côté serveur (par exemple l'exécution de code ou la recherche web d'Anthropic), qui tournent sur l'infrastructure du fournisseur, font exception.
Comment fonctionnent les appels d'outils parallèles ?
Les modèles de pointe peuvent demander plusieurs appels d'outils simultanés dans une seule réponse, par exemple pour interroger trois sources de données indépendantes. Cela économise des allers-retours et réduit la latence. Tu dois exécuter tous les appels demandés et renvoyer les résultats regroupés. Si tu veux au maximum un appel par réponse, tu peux désactiver ce comportement, chez Anthropic via disable_parallel_tool_use dans le paramètre tool_choice.
Comment gérer correctement les erreurs lors des appels d'outils ?
Les erreurs doivent revenir au modèle sous forme de résultat structuré, et non sous forme d'exception levée qui interrompt la boucle d'agent. Renvoie un tool_result avec is_error à true et un message d'erreur court et compréhensible. Le modèle peut alors décider s'il corrige les arguments, choisit une autre stratégie ou fait remonter le problème. Mieux vaut condenser les stack traces plutôt que de les transmettre brutes, pour ne pas polluer la fenêtre de contexte.
Combien d'outils un agent devrait-il avoir ?
Moins, c'est souvent mieux. Un petit noyau chargé en permanence, complété par un chargement dynamique via un outil de recherche d'outils, est plus fiable qu'un grand catalogue statique. Le vrai problème n'est pas le nombre en soi, mais le chevauchement : deux outils qui pourraient plausiblement répondre à la même requête, aucun prompt ne parvient à les séparer proprement. Ce qui compte, ce sont des descriptions propres et sans ambiguïté, avec une clause claire « quand ne pas l'utiliser ».

Envie d’aller plus loin ?

Reçois les nouvelles analyses directement dans ta boîte mail ou découvre comment nous mettons ce savoir au service des entreprises.