Aller au contenu principal

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

ValeurComportement
{"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

  1. Descriptions precises : plus la description de l’outil est detaillee, mieux Claude saura quand l’utiliser
  2. Noms explicites : utilisez des noms d’outils qui decrivent clairement leur fonction
  3. Schemas valides : assurez-vous que votre input_schema est un JSON Schema valide
  4. Gestion des erreurs : prevoyez le cas ou l’outil echoue et renvoyez un message d’erreur clair a Claude
  5. 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.