← Articles

Tool Use : Comment Claude execute vos fonctions Python et TypeScript

Decouvrez comment transformer Claude en assistant capable d'executer vos propres fonctions. Guide complet avec exemples concrets en Python et TypeScript.

Tool Use : Comment Claude execute vos fonctions Python et TypeScript

Vous utilisez peut-etre Claude pour analyser du texte ou generer du code. Mais saviez-vous qu’il peut aussi appeler vos propres fonctions ? Avec Tool Use, Claude devient un orchestrateur qui decide quand et comment utiliser vos outils. Je vais vous montrer comment ca marche concretement.

Le concept : Claude comme chef d’orchestre

Tool Use, c’est l’API qui permet a Claude de demander l’execution de fonctions que vous definissez. Le flow est simple :

  1. Vous envoyez une requete avec la liste des outils disponibles
  2. Claude analyse et decide s’il doit utiliser un outil
  3. Il vous renvoie une demande d’execution (tool_use)
  4. Vous executez la fonction cote serveur
  5. Vous renvoyez le resultat a Claude
  6. Claude integre le resultat dans sa reponse finale

C’est different des simple prompts ou vous collez des donnees. Ici, Claude prend des decisions : “J’ai besoin de cette info, je vais appeler cet outil”.

Votre premier outil en Python

Commencons par un exemple simple : un outil qui recupere la meteo.

import anthropic
import json

client = anthropic.Anthropic(api_key="votre_cle")

# Definition de l'outil
tools = [
    {
        "name": "get_weather",
        "description": "Recupere la meteo actuelle pour une ville donnee",
        "input_schema": {
            "type": "object",
            "properties": {
                "city": {
                    "type": "string",
                    "description": "Le nom de la ville"
                },
                "unit": {
                    "type": "string",
                    "enum": ["celsius", "fahrenheit"],
                    "description": "L'unite de temperature"
                }
            },
            "required": ["city"]
        }
    }
]

# Fonction reelle qui sera executee
def get_weather(city, unit="celsius"):
    # Ici vous appelleriez une vraie API meteo
    return {"city": city, "temperature": 22, "unit": unit, "condition": "ensoleille"}

# Requete initiale
message = client.messages.create(
    model="claude-3-5-sonnet-20241022",
    max_tokens=1024,
    tools=tools,
    messages=[{"role": "user", "content": "Quel temps fait-il a Paris ?"}]
)

print(f"Stop reason: {message.stop_reason}")

Si Claude decide d’utiliser l’outil, stop_reason sera tool_use au lieu de end_turn. Le message contiendra un bloc tool_use avec les parametres.

Gerer la boucle d’execution

Le vrai travail commence maintenant : gerer la boucle requete/reponse.

def process_tool_calls(message):
    """Execute les outils demandes par Claude"""
    tool_results = []
    
    for block in message.content:
        if block.type == "tool_use":
            tool_name = block.name
            tool_input = block.input
            
            # Execution de la fonction
            if tool_name == "get_weather":
                result = get_weather(**tool_input)
            
            tool_results.append({
                "type": "tool_result",
                "tool_use_id": block.id,
                "content": json.dumps(result)
            })
    
    return tool_results

# Boucle complete
messages = [{"role": "user", "content": "Quel temps fait-il a Paris ?"}]

while True:
    message = client.messages.create(
        model="claude-3-5-sonnet-20241022",
        max_tokens=1024,
        tools=tools,
        messages=messages
    )
    
    if message.stop_reason == "tool_use":
        # Claude veut utiliser un outil
        messages.append({"role": "assistant", "content": message.content})
        
        tool_results = process_tool_calls(message)
        messages.append({"role": "user", "content": tool_results})
    else:
        # Claude a fini
        print(message.content[0].text)
        break

Ce pattern de boucle est essentiel. Claude peut enchainer plusieurs appels d’outils avant de repondre.

Version TypeScript avec le SDK officiel

Le SDK TypeScript offre une API similaire. Voici le meme exemple :

import Anthropic from '@anthropic-ai/sdk';

const client = new Anthropic({
  apiKey: process.env.ANTHROPIC_API_KEY,
});

const tools: Anthropic.Tool[] = [
  {
    name: 'get_weather',
    description: 'Recupere la meteo actuelle pour une ville donnee',
    input_schema: {
      type: 'object',
      properties: {
        city: {
          type: 'string',
          description: 'Le nom de la ville',
        },
        unit: {
          type: 'string',
          enum: ['celsius', 'fahrenheit'],
          description: 'L\'unite de temperature',
        },
      },
      required: ['city'],
    },
  },
];

function getWeather(city: string, unit: string = 'celsius') {
  return { city, temperature: 22, unit, condition: 'ensoleille' };
}

async function runAssistant() {
  const messages: Anthropic.MessageParam[] = [
    { role: 'user', content: 'Quel temps fait-il a Paris et Londres ?' },
  ];

  while (true) {
    const message = await client.messages.create({
      model: 'claude-3-5-sonnet-20241022',
      max_tokens: 1024,
      tools,
      messages,
    });

    if (message.stop_reason === 'tool_use') {
      messages.push({ role: 'assistant', content: message.content });

      const toolResults = message.content
        .filter((block): block is Anthropic.ToolUseBlock => block.type === 'tool_use')
        .map((block) => {
          const result = getWeather(block.input.city, block.input.unit);
          return {
            type: 'tool_result' as const,
            tool_use_id: block.id,
            content: JSON.stringify(result),
          };
        });

      messages.push({ role: 'user', content: toolResults });
    } else {
      console.log(message.content[0].text);
      break;
    }
  }
}

runAssistant();

Notez comment Claude peut demander plusieurs villes en un seul appel. Il optimise automatiquement.

Cas d’usage avances

1. Recherche et synthese

Combinez un outil de recherche avec l’analyse de Claude :

tools = [
    {
        "name": "search_documentation",
        "description": "Recherche dans la documentation technique",
        "input_schema": {
            "type": "object",
            "properties": {
                "query": {"type": "string"},
                "source": {
                    "type": "string",
                    "enum": ["github", "stackoverflow", "docs"]
                }
            },
            "required": ["query"]
        }
    }
]

Claude peut enchainer : rechercher sur GitHub, puis StackOverflow, puis synthetiser.

2. Execution de code securisee

Creez un sandbox pour executer du code genere par Claude :

{
    "name": "execute_python",
    "description": "Execute du code Python dans un environnement securise",
    "input_schema": {
        "type": "object",
        "properties": {
            "code": {"type": "string"},
            "timeout": {"type": "number", "default": 5}
        },
        "required": ["code"]
    }
}

Attention : validez et sandboxez TOUJOURS le code avant execution.

3. Workflows multi-etapes

Claude peut orchestrer des workflows complexes :

const tools = [
  { name: 'read_file', /* ... */ },
  { name: 'analyze_code', /* ... */ },
  { name: 'run_tests', /* ... */ },
  { name: 'generate_report', /* ... */ },
];

Demandez “Analyse ce projet et genere un rapport de qualite”. Claude va :

  1. Lire les fichiers pertinents
  2. Analyser le code
  3. Lancer les tests
  4. Generer le rapport

Tout ca sans que vous ayez a coder la logique d’orchestration.

Conseils pour des outils efficaces

1. Descriptions precises Claude decide grace aux descriptions. Soyez specifique :

  • âś… “Recherche des utilisateurs dans la base PostgreSQL par email ou ID”
  • ❌ “Cherche des trucs”

2. Input schemas stricts Utilisez les enums, required, et descriptions pour chaque parametre. Claude respecte le schema.

3. Gestion d’erreurs Retournez des erreurs claires dans tool_result :

try:
    result = ma_fonction(**tool_input)
    content = json.dumps(result)
except Exception as e:
    content = json.dumps({"error": str(e)})
    is_error = True

4. Performance Si un outil est lent, indiquez-le dans la description. Claude peut decider de l’utiliser en dernier recours.

5. Composition Preferez plusieurs petits outils specialises qu’un gros outil generaliste. Claude orchestre mieux.

Conclusion

Tool Use transforme Claude en assistant capable d’interagir avec votre systeme. C’est la base de l’agentic AI : un modele qui prend des decisions et agit.

Commencez simple : un ou deux outils bien definis. Puis ajoutez progressivement. Vous verrez Claude devenir de plus en plus autonome dans la resolution de problemes complexes.

Le code complet de ces exemples est sur mon GitHub. N’hesitez pas a experimenter et a partager vos cas d’usage sur X en me taguant @askjeanclaude !