Exercices Projets guidés Le dispatcher d'outils
🎉

Bravo!

Intermédiaire 🧠 Fondamentaux 20 XP 0 personnes ont réussi

Le dispatcher d'outils

Tu as maintenant quatre outils : lire un fichier, lister les fichiers, ecrire dans un fichier, et chercher du texte. Mais le LLM ne peut pas les appeler directement. Il envoie une demande structuree (un "tool call") et ton programme doit comprendre quel outil lancer, avec quels arguments.

C'est le role du dispatcher d'outils. C'est le chef d'orchestre qui recoit les instructions du LLM et les traduit en actions concretes. Le vrai Claude Code a exactement ce systeme : quand le modele veut lire un fichier, il genere un JSON du type {"tool": "read_file", "arguments": {"path": "app.py"}} et le dispatcher execute la bonne fonction.

Cree une classe OutilsDispatcher qui enregistre des outils et les execute.

La classe doit avoir ces methodes :

enregistrer(nom, fonction, description) : ajoute un outil au registre.

lister_outils() : renvoie la liste des outils disponibles (nom + description).

executer(nom_outil, arguments) : execute l'outil avec les arguments fournis et renvoie le resultat. Si l'outil n'existe pas, renvoie une erreur. Si l'execution echoue, renvoie l'erreur sans planter.

obtenir_schemas() : renvoie les outils au format attendu par l'API OpenAI pour le function calling (on verra ca en detail).

Le format des schemas pour l'API OpenAI :

[
{"type": "function", "function": {
"name": "lire_fichier",
"description": "Lire le contenu d'un fichier"
}}
]

Exemple :

dispatcher = OutilsDispatcher()

def additionner(a, b):
return a + b

dispatcher.enregistrer("addition", additionner, "Additionner deux nombres")

dispatcher.executer("addition", {"a": 3, "b": 5})
renvoie {"succes": True, "resultat": 8}

dispatcher.executer("inexistant", {})
renvoie {"succes": False, "erreur": "Outil inconnu : inexistant"}

dispatcher.lister_outils()
renvoie [{"nom": "addition", "description": "Additionner deux nombres"}]

Tests (4/5)

Enregistrer et executer un outil
dispatcher = OutilsDispatcher()
dispatcher.enregistrer("double", lambda x: x * 2, "Doubler un nombre")
r = dispatcher.executer("double", {"x": 5})
assert r["succes"] == True
assert r["resultat"] == 10, f"Attendu 10, obtenu {r['resultat']}"
Outil inexistant
dispatcher = OutilsDispatcher()
r = dispatcher.executer("fantome", {"a": 1})
assert r["succes"] == False
assert "fantome" in r["erreur"], "L'erreur doit mentionner le nom de l'outil"
Lister les outils
dispatcher = OutilsDispatcher()
dispatcher.enregistrer("outil_a", lambda: 1, "Premier outil")
dispatcher.enregistrer("outil_b", lambda: 2, "Second outil")
outils = dispatcher.lister_outils()
assert len(outils) == 2, f"Attendu 2 outils, obtenu {len(outils)}"
noms = [o["nom"] for o in outils]
assert "outil_a" in noms and "outil_b" in noms
Schemas au format OpenAI
dispatcher = OutilsDispatcher()
dispatcher.enregistrer("lire", lambda path: path, "Lire un fichier")
schemas = dispatcher.obtenir_schemas()
assert len(schemas) == 1
assert schemas[0]["type"] == "function"
assert schemas[0]["function"]["name"] == "lire"
assert schemas[0]["function"]["description"] == "Lire un fichier"

+ 0 tests cachés

Indices (3 disponibles)

solution.py