Appels d’outils

Les appels d'outils (function calling) permettent au modèle de demander l'exécution de vos fonctions : consulter une base, appeler une API, déclencher une action. Le modèle ne les exécute jamais lui-même : il vous dit quoi appeler, avec quels arguments.

Le cycle complet#

1. Vous envoyez  : messages + description des outils
2. Le modèle répond : finish_reason = "tool_calls" + arguments JSON
3. VOUS exécutez la fonction dans votre code
4. Vous renvoyez  : messages + tool_calls + résultat (role: "tool")
5. Le modèle répond en langage naturel

Exemple de bout en bout avec des données fictives#

import json
from openai import OpenAI

client = OpenAI(api_key="zir_ai_...", base_url="https://api.cloudzir.com/v1")

# 1. Décrire les outils disponibles
outils = [
    {
        "type": "function",
        "function": {
            "name": "stock_produit",
            "description": "Retourne le stock disponible d'un produit dans un entrepôt.",
            "parameters": {
                "type": "object",
                "properties": {
                    "reference": {"type": "string", "description": "Référence du produit, ex. DEMO-001"},
                    "entrepot": {"type": "string", "enum": ["alger", "oran", "constantine"]},
                },
                "required": ["reference"],
            },
        },
    }
]

# 2. Exemple local avec données fictives
def stock_produit(reference: str, entrepot: str = "alger") -> dict:
    return {"reference": reference, "entrepot": entrepot, "disponible": 42}

messages = [{"role": "user", "content": "Combien de DEMO-001 reste-t-il à Oran ?"}]

reponse = client.chat.completions.create(
    model="mina-full", messages=messages, tools=outils
)
message = reponse.choices[0].message

# 3. Exécuter ce que le modèle demande
if message.tool_calls:
    messages.append(message)                       # garder la demande dans l'historique
    for appel in message.tool_calls:
        arguments = json.loads(appel.function.arguments)
        resultat = stock_produit(**arguments)
        messages.append({
            "role": "tool",
            "tool_call_id": appel.id,
            "content": json.dumps(resultat, ensure_ascii=False),
        })

    # 4. Redemander la réponse finale
    finale = client.chat.completions.create(
        model="mina-full", messages=messages, tools=outils
    )
    print(finale.choices[0].message.content)
    # → « Il reste 42 unités de DEMO-001 à l'entrepôt d'Oran. »

Réponse du modèle lors d'un appel d'outil#

{
  "choices": [{
    "index": 0,
    "message": {
      "role": "assistant",
      "content": null,
      "tool_calls": [{
        "id": "call_a1b2c3",
        "type": "function",
        "function": {
          "name": "stock_produit",
          "arguments": "{\"reference\":\"DEMO-001\",\"entrepot\":\"oran\"}"
        }
      }]
    },
    "finish_reason": "tool_calls"
  }]
}

arguments est une chaîne JSON, pas un objet : il faut la parser.

Contrôler le déclenchement#

tool_choiceComportement
"auto" (défaut)Le modèle décide : outil ou texte.
"none"Interdit les outils pour cet appel.
"required"Force l'usage d'un outil (au choix du modèle).
{"type":"function","function":{"name":"x"}}Force cet outil précis.

Écrire de bonnes descriptions#

La qualité des appels dépend presque entièrement de vos descriptions :

  • Description de la fonction : dites quand l'utiliser, pas seulement ce qu'elle fait. « Utiliser quand l'utilisateur demande une disponibilité produit » vaut mieux que « Renvoie le stock ».
  • Chaque paramètre mérite sa description et, si possible, un enum : cela supprime les valeurs inventées.
  • Marquez required ce qui l'est vraiment : sinon le modèle omettra des champs.
  • Peu d'outils à la fois : au-delà d'une dizaine, la précision baisse et le prompt coûte cher (les définitions sont facturées à chaque appel).

Sécurité#

Le modèle n'est pas une autorisation

Un appel d'outil est une suggestion. Contrôlez toujours, dans votre code : l'identité de l'utilisateur, ses droits, et la validité des arguments. Ne câblez jamais directement un tool_call sur une action destructive (suppression, paiement, envoi) sans confirmation explicite.

  • Validez les arguments contre un schéma avant exécution : le modèle peut produire des valeurs hors bornes.
  • Limitez le nombre d'allers-retours (par exemple 5 maximum) pour éviter les boucles.
  • Renvoyez des messages d'erreur d'outil en clair : le modèle sait souvent corriger son appel au tour suivant.

Modèles recommandés#

ModèleAppels d'outils
mina-fullRecommandé : enchaînements complexes, plusieurs outils.
mina-lowBon pour 1 à 3 outils simples.
mina-flashPossible sur un outil unique et bien décrit.

Format Anthropic#

Sur /anthropic, les mêmes capacités passent par tools avec input_schema, les blocs tool_use et tool_result. Voir Utilisation de l'API Anthropic.

Paramètres

Réponse API