Aller au contenu

S'exercerNiveau 3, Construire20 minutes

L'appel d'outils

Donner au modèle des fonctions qu'il peut demander : il ne les exécute pas, il demande ; votre programme décide, exécute et lui rend le résultat. Le mécanisme de tout agent, sur un exemple métier, chez quatre éditeurs.

Écrit le 7 octobre 2026 · Vérifié le 7 octobre 2026

Vous saurez

  • Décrire une fonction pour qu'un modèle sache quand la demander
  • Recevoir sa demande, exécuter la fonction et lui rendre le résultat
  • Savoir ce qui reste sous votre contrôle, et pourquoi
  • Commencer par des outils qui lisent, avant ceux qui écrivent

Dans le parcours

Premiers pas en développement

Étape 5 sur 8

Sur cette page
  1. L'essentiel
  2. Objectif
  3. Données fournies
  4. Consignes
  5. Critères de réussite
  6. Indications
  7. Correction commentée
  8. Extensions
  9. Lectures suivantes
L'essentiel
  1. Le modèle n'exécute jamais une fonction : il demande à l'appeler, avec des arguments ; votre programme décide.
  2. Une fonction se décrit par un nom, une phrase qui dit à quoi elle sert, et ses paramètres en schéma JSON.
  3. Le résultat repart au modèle, qui s'en sert pour répondre, ou demande un autre appel.
  4. Tout ce qu'un outil rapporte est une donnée, jamais une consigne : une page lue peut contenir un piège.
  5. Un outil qui écrit, paie ou envoie demande l'accord d'une personne avant d'agir.
1

Objectif

Donner à un modèle une fonction qui lit le statut d'une facture, le laisser demander l'appel, exécuter la fonction dans votre programme, et obtenir sa réponse finale. Les cinq temps sont les mêmes chez les quatre éditeurs : la demande avec les outils, la demande d'appel, l'exécution par votre code, le renvoi du résultat, la réponse.

Les factures sont fabriquées. Les appels au modèle suivent la documentation de chaque éditeur, lue le 7 octobre 2026, et n'ont pas encore été exécutés par Meridal ; la fonction locale, elle, a tourné.

2

Données fournies

Une fonction qui lit le statut d'une facture dans un tableau fabriqué, à la place de votre logiciel de facturation. Elle ne fait que lire.

outils.py
FACTURES = {  # données fabriquées : à la place, votre logiciel de facturation
    "2026-0412": {"statut": "payée", "le": "2026-10-02"},
    "2026-0413": {"statut": "en attente", "échéance": "2026-10-31"},
}

def statut_facture(numero):
    """Le statut de paiement d'une facture. Une lecture seulement : l'outil ne modifie rien."""
    f = FACTURES.get(numero)
    if f is None:
        return f"Aucune facture {numero}."
    return ", ".join(f"{cle} : {valeur}" for cle, valeur in f.items())
essai_outil.py
from outils import statut_facture

for numero in ("2026-0412", "2026-0413", "2026-9999"):
    print(numero, "→", statut_facture(numero))
La sortieuv run essai_outil.py
2026-0412 → statut : payée, le : 2026-10-022026-0413 → statut : en attente, échéance : 2026-10-312026-9999 → Aucune facture 2026-9999.

Essayé le 7 octobre 2026 avec Python 3.12.7.

3

Consignes

Votre programme envoie la question et les outils décrits ; le modèle demande l'appel de statut_facture avec le numéro 2026-0412 ; votre code décide, puis exécute ; le résultat, « statut : payée, le : 2026-10-02 », repart au modèle comme une donnée ; le modèle répond, ou demande un autre appel. Un outil qui écrit, paie ou envoie attend l'accord d'une personne.
Les cinq temps d'un appel d'outil, entre votre programme et le modèle.

La demande d'appel arrive comme un élément function_call ; le résultat repart en function_call_output, avec le même call_id. OpenAI conseille d'activer toujours le mode strict, qui exige que chaque objet refuse les champs en plus.

demander.py
from dotenv import load_dotenv
load_dotenv()

import json

from openai import OpenAI

from outils import statut_facture

client = OpenAI()
tools = [{
    "type": "function",
    "name": "statut_facture",
    "description": "Donne le statut de paiement d'une facture à partir de son numéro.",
    "parameters": {
        "type": "object",
        "properties": {
            "numero": {"type": "string", "description": "Numéro de la facture, par exemple 2026-0412"},
        },
        "required": ["numero"],
        "additionalProperties": False,
    },
    "strict": True,
}]
input_list = [{"role": "user", "content": "La facture 2026-0412 est-elle payée ?"}]

response = client.responses.create(model="gpt-6-luna", tools=tools, input=input_list)
input_list += response.output
for item in response.output:
    if item.type == "function_call" and item.name == "statut_facture":
        numero = json.loads(item.arguments)["numero"]
        input_list.append({"type": "function_call_output", "call_id": item.call_id,
                           "output": statut_facture(numero)})

response = client.responses.create(model="gpt-6-luna", tools=tools, input=input_list)
print(response.output_text)
La sortieuv run demander.py

Pas encore exécuté par Meridal. Ce qu'on attend : une phrase qui dit que la facture 2026-0412 est payée, le 2 octobre 2026.

4

Critères de réussite

5

Indications

Chez Anthropic, une erreur 400 avec tool_choice

CauseClaude Opus 5.5 et Sonnet 5.5 refusent tool_choice à any ou tool.

À faireLaissez auto, la valeur par défaut.

Le modèle répond sans appeler la fonction

CauseLa description ne dit pas assez quand s'en servir, ou la question ne la demande pas.

À faireRéécrivez la description comme une consigne : ce que fait la fonction, et quand l'appeler.

Plusieurs appels arrivent d'un coup

CauseLes modèles peuvent demander plusieurs fonctions dans la même réponse.

À faireRendez un résultat par appel, tous dans le message suivant ; ou interdisez les appels parallèles pour les outils qui ont des effets.

La fonction échoue

CauseUn numéro inconnu, un service indisponible.

À faireRendez l'erreur au modèle comme un résultat, en clair ; chez Anthropic, avec is_error à vrai.

6

Correction commentée

Ouvrir la correction

Ce qui se passePremier appel : le modèle lit la question et la description de la fonction, et répond par une demande d'appel, statut_facture avec numero à 2026-0412. Votre programme exécute la fonction et obtient « statut : payée, le : 2026-10-02 ». Second appel : le modèle reçoit ce résultat et rédige la réponse.

Ce qui change d'un éditeur à l'autreLes noms : parameters ou input_schema, function_call, tool_use ou tool_calls, et la façon de rattacher le résultat à la demande. Le mécanisme ne change pas.

Ce qui reste à vousLa décision d'exécuter. C'est ce qui permet de refuser un appel, de demander une confirmation, ou de journaliser chaque action.

7

Extensions

  • Les résultats sont des données : un outil qui lit une page web ou un courriel peut rapporter un texte qui se fait passer pour une consigne. Anthropic demande de traiter tout résultat d'outil comme non fiable ; OpenAI, de faire passer les contenus extérieurs par les messages de l'utilisateur, jamais par les consignes du développeur.
  • Un outil qui agit : avant de payer, d'écrire ou d'envoyer, une personne valide ; Google demande de confirmer avec l'utilisateur les appels lourds de conséquences, comme une commande.
  • Peu d'outils à la fois : moins de vingt pour OpenAI, dix à vingt pour Google ; chaque description se paie en tokens lus.
  • Valider avant d'exécuter : vérifier le numéro reçu, son format, et que la personne a le droit de le consulter, avant d'appeler le logiciel.
  • La suite : un agent qui enchaîne plusieurs outils, et les serveurs MCP qui les partagent entre assistants : serveurs MCP existants.
8

Lectures suivantes

↑ Plus général

Rien avant : c'est un point de départ.

Vous êtes ici

L'appel d'outils

→ EnsuiteUn RAG minimal en PythonS'exercer · Niveau 3 · 25 minutes

Premiers pas en développement · étape 6 sur 8

Tout le dossier « Construction et programmation »

Limites et sources

Les appels suivent la documentation des éditeurs du 7 octobre 2026 et n'ont pas encore été exécutés par Meridal ; la fonction locale a tourné avec Python 3.12.7.

Les factures et leurs statuts sont fabriqués.

  1. OpenAI, Function calling ; Anthropic, Tool use ; Google, Function calling ; Mistral, Function calling.
  2. Le relevé complet : apprendre/recherches/2026-10-07-dev-appels-modeles.json.

Écrit par Meridal, avec l'aide de l'IA ; chaque fait vérifié à sa source et relu avant publication. Texte et schémas sous licence CC BY 4.0 : reprenez-les en citant Meridal. Le code sous licence MIT.

Service correspondant

Ne plus recopier d'un logiciel à l'autre

1 100 € à 3 400 €, puis sur devis

Voir le service

Un premier échange de 30 minutes

En visio et sans frais : vous décrivez votre situation, nous vous indiquons ce qui est réalisable, avec quels outils et pour quel ordre de prix. Vous pouvez aussi nous écrire ; chaque message reçoit une réponse écrite.