Votre premier outil
Dans la lecon precedente, nous avons vu le workflow du Tool Use. Passons maintenant a l’implementation concrete d’un exemple simple.
Le probleme : Claude et les mathematiques
Les LLM ont des limites en calcul mental. Demandons a Claude de multiplier deux grands nombres :
from anthropic import Anthropic
client = Anthropic()
response = client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=1000,
messages=[{"role": "user", "content": "Multiplie 1984135 par 9343116"}]
)
print(response.content[0].text)
Claude pourrait repondre 18593367726060, alors que la bonne reponse est 18538003464660. L’ecart est de 55 milliards !
La solution : un outil calculatrice
1. Ecrire la fonction
def calculator(operation, operand1, operand2):
if operation == "add":
return operand1 + operand2
elif operation == "subtract":
return operand1 - operand2
elif operation == "multiply":
return operand1 * operand2
elif operation == "divide":
if operand2 == 0:
return "Erreur : division par zero"
return operand1 / operand2
2. Definir l’outil pour Claude
Chaque definition d’outil comprend :
name: le nom de l’outil (alphanumerique, tirets, underscores)description: ce que fait l’outil, quand l’utiliserinput_schema: un schema JSON definissant les parametres attendus
tools = [
{
"name": "calculator",
"description": "Effectue des operations arithmetiques de base. Utilisez cet outil pour tout calcul mathematique.",
"input_schema": {
"type": "object",
"properties": {
"operation": {
"type": "string",
"enum": ["add", "subtract", "multiply", "divide"],
"description": "L'operation a effectuer"
},
"operand1": {
"type": "number",
"description": "Le premier operande"
},
"operand2": {
"type": "number",
"description": "Le second operande"
}
},
"required": ["operation", "operand1", "operand2"]
}
}
]
3. Envoyer la requete avec l’outil
response = client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=1000,
tools=tools,
messages=[{"role": "user", "content": "Multiplie 1984135 par 9343116"}]
)
4. Inspecter la reponse
La reponse contient un ToolUseBlock au lieu du texte habituel :
print(response.stop_reason) # "tool_use"
print(response.content)
# [ToolUseBlock(
# id='toolu_xxx',
# input={'operand1': 1984135, 'operand2': 9343116, 'operation': 'multiply'},
# name='calculator',
# type='tool_use'
# )]
5. Executer l’outil et obtenir le resultat
tool_use = response.content[0]
tool_name = tool_use.name
tool_input = tool_use.input
result = calculator(
tool_input["operation"],
tool_input["operand1"],
tool_input["operand2"]
)
print(result) # 18538003464660 (la bonne reponse !)
Eviter les appels d’outils inutiles
Parfois Claude veut utiliser un outil meme quand ce n’est pas pertinent. Pour eviter cela, ajoutez une instruction dans le prompt ou le system prompt :
response = client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=1000,
tools=tools,
system="Vous avez acces a des outils, mais ne les utilisez que quand c'est necessaire. Si un outil n'est pas requis, repondez normalement.",
messages=[{"role": "user", "content": "De quelle couleur sont les emeraudes ?"}]
)
# Claude repond normalement : "Les emeraudes sont vertes."
# stop_reason = "end_turn" (pas "tool_use")
Exercice
Ecrivez une definition d’outil pour cette fonction :
def inventory_lookup(product_name, max_results=5):
"""Recherche des produits dans l'inventaire par nom."""
# ...
La fonction attend :
product_name(string, requis) : le nom du produit a cherchermax_results(integer, optionnel, defaut 5) : nombre max de resultats
Voir la solution
tools = [{
"name": "inventory_lookup",
"description": "Recherche des produits dans l'inventaire par nom et retourne les resultats correspondants.",
"input_schema": {
"type": "object",
"properties": {
"product_name": {
"type": "string",
"description": "Le nom du produit a rechercher"
},
"max_results": {
"type": "integer",
"description": "Nombre maximum de resultats a retourner (defaut : 5)"
}
},
"required": ["product_name"]
}
}]