Tool Choice et controle des outils
Objectifs
- Comprendre le parametre
tool_choice - Controler quand et comment Claude utilise les outils
Le parametre tool_choice
Par defaut, Claude decide librement s’il veut utiliser un outil ou non. Le parametre tool_choice permet de controler ce comportement :
Les options disponibles
| Valeur | Comportement |
|---|---|
{"type": "auto"} | Claude decide librement (defaut) |
{"type": "any"} | Claude doit utiliser un outil (n’importe lequel) |
{"type": "tool", "name": "nom_outil"} | Claude doit utiliser l’outil specifie |
Mode auto (defaut)
response = client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=1000,
tools=tools,
tool_choice={"type": "auto"}, # Optionnel, c'est le defaut
messages=[{"role": "user", "content": "Quelle est la capitale de la France ?"}]
)
# Claude repond directement sans outil (pas necessaire)
Forcer l’utilisation d’un outil
response = client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=1000,
tools=tools,
tool_choice={"type": "tool", "name": "calculator"},
messages=[{"role": "user", "content": "Combien font 245 * 873 ?"}]
)
# Claude DOIT utiliser la calculatrice
Forcer l’utilisation de n’importe quel outil
response = client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=1000,
tools=tools,
tool_choice={"type": "any"},
messages=[{"role": "user", "content": "J'ai besoin d'aide"}]
)
# Claude DOIT utiliser au moins un outil
Quand utiliser chaque mode ?
- auto : cas general, Claude gere intelligemment
- tool (specifique) : quand vous savez exactement quel outil est necessaire (par exemple, pour forcer du JSON structure)
- any : quand vous voulez garantir qu’un outil sera appele, sans savoir lequel
Appels d’outils multiples
Claude peut demander a utiliser plusieurs outils dans une seule reponse. La reponse contient alors plusieurs ToolUseBlock, et vous devez fournir un tool_result pour chacun :
# Claude peut repondre avec 2 demandes d'outils
# response.content = [
# TextBlock(text="Je vais chercher les infos..."),
# ToolUseBlock(id="toolu_1", name="get_weather", input={...}),
# ToolUseBlock(id="toolu_2", name="get_news", input={...})
# ]
# Vous devez renvoyer un resultat pour CHAQUE outil
tool_results = []
for block in response.content:
if block.type == "tool_use":
result = execute_tool(block.name, block.input)
tool_results.append({
"type": "tool_result",
"tool_use_id": block.id,
"content": str(result)
})
messages.append({"role": "user", "content": tool_results})
Bonnes pratiques
- Descriptions precises : plus la description de l’outil est detaillee, mieux Claude saura quand l’utiliser
- Noms explicites : utilisez des noms d’outils qui decrivent clairement leur fonction
- Schemas valides : assurez-vous que votre
input_schemaest un JSON Schema valide - Gestion des erreurs : prevoyez le cas ou l’outil echoue et renvoyez un message d’erreur clair a Claude
- Limiter le nombre d’outils : trop d’outils peuvent confondre Claude ; gardez une liste pertinente
Quiz
Que se passe-t-il si vous definissez tool_choice a {"type": "any"} mais que Claude n’a aucun outil pertinent pour la question ?
Voir la reponse
Claude sera force d’utiliser un outil, meme si aucun n’est pertinent. Il choisira l’outil le plus “proche” de la question et l’appellera avec des parametres qui peuvent ne pas avoir de sens. C’est pourquoi le mode any doit etre utilise avec precaution.