Aller au contenu principal

Définir des outils en JSON

De la théorie à la pratique

Vous connaissez maintenant le concept du function calling et la structure des schémas JSON. Il est temps de passer à l’implémentation concrète. Dans cette leçon, vous allez apprendre à construire une requête complète avec des définitions d’outils et à traiter la réponse du modèle.

Definition doutils pour le function calling

Structure d’une requête avec outils

Voici une requête complète à l’API Grok avec un outil défini :

from openai import OpenAI

client = OpenAI(
    api_key="votre-cle-api",
    base_url="https://api.x.ai/v1"
)

tools = [
    {
        "type": "function",
        "function": {
            "name": "get_weather",
            "description": "Obtenir la météo actuelle d'une ville",
            "parameters": {
                "type": "object",
                "properties": {
                    "city": {
                        "type": "string",
                        "description": "Nom de la ville"
                    },
                    "unit": {
                        "type": "string",
                        "enum": ["celsius", "fahrenheit"],
                        "default": "celsius"
                    }
                },
                "required": ["city"]
            }
        }
    }
]

response = client.chat.completions.create(
    model="grok-3",
    messages=[
        {"role": "user", "content": "Quel temps fait-il à Paris ?"}
    ],
    tools=tools
)

Notez la structure imbriquée : l’objet tools contient un tableau, chaque élément ayant un type et un objet function avec les détails.

Chiffres clés de l’implémentation

200
Outils max par requête
6
Types JSON supportés
3
SDKs compatibles
1
Requête = tout le flux

Traiter la réponse tool_call

Quand le modèle décide d’appeler une fonction, la réponse contient un tableau tool_calls :

message = response.choices[0].message

if message.tool_calls:
    for tool_call in message.tool_calls:
        print(f"Fonction : {tool_call.function.name}")
        print(f"Arguments : {tool_call.function.arguments}")
        print(f"ID : {tool_call.id}")

Le champ tool_call.function.arguments est une chaîne JSON (pas un objet Python). Vous devez le parser :

import json

args = json.loads(tool_call.function.arguments)
city = args["city"]
unit = args.get("unit", "celsius")

Exécuter et renvoyer le résultat

Une fois la fonction exécutée, vous renvoyez le résultat au modèle dans un second appel :

import json

# 1. Exécuter la fonction
weather_data = get_weather(city="Paris", unit="celsius")

# 2. Construire les messages avec le résultat
messages = [
    {"role": "user", "content": "Quel temps fait-il à Paris ?"},
    message,  # La réponse du modèle avec tool_calls
    {
        "role": "tool",
        "tool_call_id": tool_call.id,
        "content": json.dumps(weather_data)
    }
]

# 3. Rappeler le modèle avec le résultat
final_response = client.chat.completions.create(
    model="grok-3",
    messages=messages,
    tools=tools
)

print(final_response.choices[0].message.content)

Le message de rôle tool doit contenir :

  • tool_call_id : l’identifiant unique du tool_call (pour le lier à la demande)
  • content : le résultat sous forme de chaîne JSON

Définir plusieurs outils

Vous pouvez déclarer autant d’outils que nécessaire dans le tableau tools :

tools = [
    {
        "type": "function",
        "function": {
            "name": "get_weather",
            "description": "Obtenir la météo actuelle d'une ville",
            "parameters": { ... }
        }
    },
    {
        "type": "function",
        "function": {
            "name": "search_restaurants",
            "description": "Rechercher des restaurants par ville et type de cuisine",
            "parameters": { ... }
        }
    },
    {
        "type": "function",
        "function": {
            "name": "book_table",
            "description": "Réserver une table dans un restaurant",
            "parameters": { ... }
        }
    }
]

Le modèle choisira automatiquement le ou les outils pertinents en fonction de la requête utilisateur.

Vérifier le finish_reason

Le champ finish_reason de la réponse vous indique si le modèle a terminé sa réponse ou s’il attend un résultat d’outil :

finish_reason = response.choices[0].finish_reason

if finish_reason == "tool_calls":
    # Le modèle attend le résultat d'un ou plusieurs outils
    handle_tool_calls(response)
elif finish_reason == "stop":
    # Le modèle a terminé sa réponse
    print(response.choices[0].message.content)

Points clés à retenir

  • La requête contient les messages et les tools (définitions)
  • Les arguments du tool_call sont une chaîne JSON à parser
  • Le résultat se renvoie dans un message de rôle tool avec le tool_call_id
  • Vérifiez finish_reason pour savoir si le modèle attend un résultat
  • Vous pouvez déclarer plusieurs outils — le modèle choisit automatiquement