Outil bash
Permettez à Claude de demander des commandes shell que votre application exécute dans une session bash persistante et renvoie sous forme de résultats d'outils.
L'outil bash est un outil client : Claude n'exécute pas lui-même les commandes. Lorsque vous incluez l'outil dans une requête, Claude répond avec un bloc tool_use qui indique la commande à exécuter. Votre application exécute cette commande dans une session bash qu'elle possède et renvoie la sortie dans un bloc tool_result.
Votre application maintient un seul processus bash actif d'un appel d'outil à l'autre, de sorte que l'état persiste entre les commandes. Le répertoire de travail, les variables d'environnement et tous les fichiers créés par une commande sont toujours présents pour la commande suivante.
La version actuelle de l'outil est bash_20250124. Pour la prise en charge des modèles, les en-têtes bêta et la version antérieure, consultez Versions de l'outil. Pour tous les outils fournis par Anthropic, consultez la Référence des outils.
Cas d'utilisation
- Flux de travail de développement : exécuter des commandes de build, des tests et des outils de développement
- Automatisation système : exécuter des scripts, gérer des fichiers, automatiser des tâches
- Traitement de données : traiter des fichiers, exécuter des scripts d'analyse, gérer des jeux de données
- Configuration d'environnement : installer des paquets, configurer des environnements
Démarrage rapide
client = anthropic.Anthropic()
response = client.messages.create(
model="claude-opus-5-5",
max_tokens=1024,
tools=[{"type": "bash_20250124", "name": "bash"}],
messages=[
{"role": "user", "content": "List all Python files in the current directory."}
],
)
print(response)Claude répond avec stop_reason: "tool_use" et un bloc tool_use qui contient la commande que votre application doit exécuter :
{
"id": "msg_01XAbCDeFgHiJkLmNoPQrStU",
"model": "claude-opus-5-5",
"stop_reason": "tool_use",
"role": "assistant",
"content": [
{
"type": "text",
"text": "I'll list all Python files in the current directory for you."
},
{
"type": "tool_use",
"id": "toolu_01A09q90qw90lq917835lq9",
"name": "bash",
"input": {
"command": "ls *.py"
}
}
]
}Exécutez input.command dans votre session bash et renvoyez la sortie sous forme de tool_result. Consultez Implémenter l'outil bash pour l'aller-retour complet.
Fonctionnement
Chaque appel d'outil correspond à un aller-retour entre Claude et votre application :
- Claude renvoie un bloc
tool_usecontenant lacommandà exécuter. - Votre application exécute la commande dans sa session bash.
- Votre application renvoie la sortie de la commande, stdout et stderr ensemble, à Claude dans un bloc
tool_result. - Claude demande une autre commande dans la même session ou répond avec du texte.
Claude peut également renvoyer plusieurs blocs tool_use dans une seule réponse. Exécutez-les dans l'ordre dans la même session et renvoyez tous les résultats dans un seul message user. Consultez Utilisation d'outils en parallèle.
L'API est sans état. Rien concernant votre session shell ne transite entre les requêtes ; c'est donc votre application qui décide quand la session démarre, combien de temps elle vit et quand la redémarrer. Pour le cycle complet de requête et de réponse, consultez Gérer les appels d'outils.
Paramètres
Une définition de l'outil bash comporte deux champs obligatoires, type et name, et name doit être bash. L'outil est sans schéma : vous ne fournissez pas d'input_schema, car le schéma est intégré au modèle de Claude et ne peut pas être modifié. Le tableau suivant répertorie les champs d'entrée que Claude définit lorsqu'il appelle l'outil.
| Paramètre | Obligatoire | Description |
|---|---|---|
command | Oui* | La commande bash à exécuter |
restart | Non | Définir sur true pour redémarrer la session bash |
*Obligatoire sauf si restart est utilisé
Pour gérer restart: true, tuez le processus shell, démarrez-en un nouveau et renvoyez un tool_result qui confirme le redémarrage. Une session redémarrée repart de zéro : le répertoire de travail, les variables d'environnement et tous les processus en cours d'exécution ont disparu.
Exécuter une commande :
{
"command": "ls -la *.py"
}Redémarrer la session :
{
"restart": true
}Versions de l'outil
bash_20250124 est la version actuelle de l'outil et ne nécessite aucun en-tête bêta. Tous les modèles à partir de Claude Sonnet 3.7 (retiré) l'acceptent, y compris tous les modèles Claude actuels.
La version d'origine bash_20241022 fonctionne uniquement avec le modèle Claude Sonnet 3.5 d'octobre 2024 (retiré). Les requêtes qui l'utilisent nécessitent l'en-tête anthropic-beta: computer-use-2024-10-22, et le SDK ne l'expose que dans son espace de noms bêta. Les nouvelles intégrations doivent utiliser bash_20250124.
Exemple : automatisation en plusieurs étapes
Claude peut enchaîner des commandes sur plusieurs appels d'outils pour accomplir une tâche en plusieurs étapes :
User request:
"Install the requests library and create a simple Python script that
fetches a joke from an API, then run it."
Claude's tool uses:
1. Install package
{"command": "pip install requests"}
2. Create script
{"command": "cat > fetch_joke.py << 'EOF'\nimport requests\nresponse = requests.get('https://official-joke-api.appspot.com/random_joke')\njoke = response.json()\nprint(f\"Setup: {joke['setup']}\")\nprint(f\"Punchline: {joke['punchline']}\")\nEOF"}
3. Run script
{"command": "python fetch_joke.py"}La session conserve l'état entre les commandes, de sorte que les fichiers créés à l'étape 2 sont disponibles à l'étape 3.
Implémenter l'outil bash
Claude détermine quelle commande exécuter. Votre application est responsable de tout le reste : le processus shell, le délai d'expiration et les contrôles de sécurité. Les étapes suivantes présentent une implémentation minimale.
Créer une session bash persistante
Démarrez un processus bash de longue durée et exécutez chaque commande à l'intérieur de celui-ci. Comme un pipe vers un processus actif ne signale jamais de fin de fichier, la session affiche une ligne sentinelle unique après chaque commande pour marquer l'endroit où se termine la sortie de cette commande :
Pythonimport subprocess import uuid class BashSession: """A bash process that stays alive between commands so state persists.""" def __init__(self): self.process = subprocess.Popen( ["/bin/bash"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, # interleave errors with output, in order start_new_session=True, # own process group: a timeout can kill every child text=True, ) def execute_command(self, command): """Run a command in the session and return its output.""" sentinel = f"__CLAUDE_BASH_DONE_{uuid.uuid4().hex}__" # unique per call self.process.stdin.write(f"{command}\necho {sentinel}\n") self.process.stdin.flush() output = [] for line in self.process.stdout: if sentinel in line: # this command's output is complete break output.append(line) return "".join(output) def restart(self): self.process.kill() self.process.wait() self.__init__() bash_session = BashSession() print(bash_session.execute_command("cd /tmp && pwd")) print(bash_session.execute_command("pwd")) # still /tmp: the session kept its stateLa session entrelace stderr avec stdout, de sorte que les messages d'erreur apparaissent là où ils se sont produits. L'exemple omet ce dont une implémentation complète a également besoin : un délai d'expiration qui tue le shell et tous les processus qu'il a lancés lorsqu'une commande se bloque, puis redémarre la session. La bonne pratique Utiliser des délais d'expiration pour les commandes montre une façon de l'ajouter.
Traiter les appels d'outils de Claude
Extrayez et exécutez les commandes à partir des réponses de Claude :
Pythontool_results = [] for content in response.content: if content.type == "tool_use" and content.name == "bash": if content.input.get("restart"): bash_session.restart() result = "Bash session restarted" else: command = content.input.get("command") result = bash_session.execute_command(command) # Un tool_result par bloc tool_use, tous renvoyés dans le message utilisateur suivant tool_results.append( {"type": "tool_result", "tool_use_id": content.id, "content": result} )