Aller au contenu principal

Batch Tool Use

Mis à jour le 30 juillet 2026

Claude peut nativement exécuter plusieurs outils en même temps — demander deux calculs dans une seule réponse — mais certaines versions n’exploitent pas toujours cette capacité, et préfèrent l’aller-retour prudent : un outil, un résultat, l’outil suivant. Vous pouvez augmenter considérablement les chances de parallélisation en implémentant un outil batch : une astuce de conception qui transforme la parallélisation en choix explicite proposé au modèle.

Le problème

Si vous demandez « Quelle est la date du 12 mars 2025 + 50 jours ? Et aussi + 100 jours ? », Claude pourrait théoriquement envoyer deux demandes d’outils séparées dans une seule réponse — ces opérations sont totalement parallélisables, car elles ne dépendent pas l’une de l’autre. Mais Claude les exécute souvent séquentiellement : deux tours complets de conversation, deux allers-retours API, pour deux calculs qui auraient tenu dans un seul. Sur deux opérations, l’écart est anecdotique ; sur dix requêtes météo ou dix recherches en base, il double ou triple la latence totale.

L’outil batch

L’idée : créer un outil qui peut invoquer plusieurs autres outils simultanément — un outil dont les arguments sont… des appels d’outils.

{
  "name": "batch_tool",
  "description": "Invoquer plusieurs appels d'outils simultanement",
  "input_schema": {
    "type": "object",
    "properties": {
      "invocations": {
        "type": "array",
        "description": "Les appels d'outils a invoquer",
        "items": {
          "type": "object",
          "properties": {
            "name": {
              "type": "string",
              "description": "Le nom de l'outil a invoquer"
            },
            "arguments": {
              "type": "string",
              "description": "Les arguments de l'outil, encodés en chaîne JSON"
            }
          },
          "required": ["name", "arguments"]
        }
      }
    },
    "required": ["invocations"]
  }
}

Le schéma se lit de l’intérieur : chaque invocation porte un nom d’outil et ses arguments — encodés en chaîne JSON, car un schéma ne peut pas prévoir la forme des arguments de tous les outils —, et invocations en accepte une liste. En présentant cet outil à Claude, on lui donne un moyen explicite de dire « fais tout cela d’un coup » : la parallélisation cesse d’être une initiative que le modèle ose ou n’ose pas, elle devient un outil comme un autre, décrit et disponible.

Implémentation

def run_batch(tool_input):
    batch_output = []
    for invocation in tool_input["invocations"]:
        tool_name = invocation["name"]
        args = json.loads(invocation["arguments"])

        tool_output = run_tool(tool_name, args)
        batch_output.append({"tool_name": tool_name, "output": tool_output})

    return batch_output

La fonction déballe chaque invocation — décodage de la chaîne JSON d’arguments compris — puis délègue à notre run_tool existant : le batch réutilise tout le routage déjà construit. Chaque sortie est étiquetée du nom de son outil, pour que Claude puisse rattacher les résultats aux demandes. Reste à enregistrer le batch lui-même dans le routeur :

elif tool_name == "batch_tool":
    return run_batch(tool_input)

Notez la différence avec les autres cas : on passe tool_input directement, sans l’opérateur de déploiement (**) — l’outil batch doit gérer la structure brute, puisque c’est lui qui itère sur les invocations qu’elle contient.

Résultat

Rejouez la question des deux dates : au lieu de voir deux appels d’outils séparés dans le journal des messages, vous verrez un seul appel à l’outil batch contenant les deux calculs comme sous-invocations — un seul tour de conversation au lieu de deux. L’outil batch est particulièrement utile quand vous avez plusieurs opérations indépendantes exécutables simultanément ; et si vous voulez aller plus loin, la boucle de run_batch peut elle-même paralléliser réellement les exécutions (threads, async) — le contrat vu de Claude ne change pas.

Points clés à retenir

  • Claude sait paralléliser les appels d’outils, mais ne le fait pas toujours spontanément
  • L’outil batch rend la parallélisation explicite : un outil dont les arguments sont des appels d’outils
  • Les arguments internes voyagent en chaînes JSON — décodés par run_batch avant délégation à run_tool
  • Cas particulier du routeur : tool_input passé brut, sans **
  • Gain : un tour de conversation au lieu de N pour des opérations indépendantes