CrewAI tools : équiper vos agents
Guide pratique pour créer, intégrer et optimiser des tools dans CrewAI. Code Python commenté, erreurs courantes et bonnes pratiques.
CrewAI tools : équiper vos agents
Introduction
Un agent sans outil, c'est un navigateur sans connexion — du potentiel, mais aucune action possible. Les tool sont le pont entre vos agents et le monde réel : recherche web, appels API, lecture de fichiers, requêtes base de données.
Ce tutoriel couvre la création d'un tool personnalisé, son association à un agent, et la gestion des erreurs en production.
Résumé rapide
| Critère | Détail |
|---|---|
| Type | Outil (@tool decorator ou classe Tool) |
| Dépendance | crewai[tools] |
| Association | via le paramètre tools= de l'agent |
| Erreurs fréquentes | timeout, rate limit, schéma de retour invalide |
| Debug | verbose=True, dry_run, examen du résultat |
Qu'est-ce qu'un tool dans CrewAI ?
Un tool est une fonction Python annotée qu'un agent peut invoquer pendant son raisonnement. Il expose :
- Un nom — utilisé par l'agent pour décider quand appeler le tool.
- Une description — c'est elle que le modèle lit pour comprendre quand déclencher l'appel (tool calling).
- Un schéma d'entrée — paramètres attendus, typés et documentés.
- Une fonction sous-jacente — le code qui s'exécute réellement.
Deux interfaces de définition :
# Méthode 1 : @tool (recommandée pour les cas simples)
from crewai import Tool
@Tool(name="recherche_web", description="Recherche des informations sur le web")
def recherche_web(query: str):
# ... logique
pass
# Méthode 2 : classe Tool (pour plus de contrôle)
from crewai.tools import Tool
recherche_tool = Tool(
name="recherche_web",
description="Recherche des informations sur le web",
func=ma_fonction_recherche,
)
Point critique : la description. Floue = agent qui n'appelle jamais son tool, ou qui l'appelle mal.
Créer un tool simple
import json
from crewai import Tool
@Tool(name="recherche_web", description="""Recherche des informations récentes sur le web.
Accepte une requête en français ou en anglais.
Retourne un résumé des 5 premiers résultats avec titre et URL.""")
def recherche_web(query: str) -> str:
"""
Tool de recherche web simulé.
En production : remplacez par SerpAPI, Tavily ou DuckDuckGo.
"""
try:
if not query or len(query.strip()) < 3:
return json.dumps({"erreur": "Requête trop courte (min 3 caractères)."})
query = query.strip()
resultats = [
{"titre": f"Résultat pour '{query}' — article 1", "url": "https://exemple.com/1"},
{"titre": f"Résultat pour '{query}' — article 2", "url": "https://exemple.com/2"},
]
return json.dumps({"requete": query, "resultats": resultats}, ensure_ascii=False)
except Exception as e:
return json.dumps({"erreur": f"Échec de la recherche : {str(e)}"})
| Élément | Rôle |
|---|---|
@Tool | Enregistre la fonction comme tool CrewAI |
name | Identifiant unique pour le tool calling |
description | Instructions pour le modèle — être précis |
| Validation entrée | Évite les appels vides ou malformed |
try/except | Retourne un message structuré même en cas d'erreur |
Associer un tool à un agent
Un tool n'a de valeur que relié à un agent. CrewAI utilise le paramètre tools= :
from crewai import Agent, Task, Crew
# 1. Définir l'agent avec son tool
chercheur = Agent(
role="Chercheur web",
goal="Trouver les informations les plus pertinentes sur le sujet demandé.",
backstory="""Tu es un chercheur rigoureux. Tu utilises toujours tes outils de recherche
pour obtenir des informations à jour avant de formuler tes conclusions.""",
tools=[recherche_web],
verbose=True,
)
# 2. Définir la task
tache_recherche = Task(
description="Recherche les dernières avancées sur les frameworks d'agents IA en 2026.",
agent=chercheur,
expected_output="Un résumé de 5 résultats avec titre, source et date.",
)
# 3. Orchestrer dans un crew
crew = Crew(
agents=[chercheur],
tasks=[tache_recherche],
process="sequential",
verbose=True,
)
resultat = crew.kickoff()
print(resultat)
L'agent décide seul quand invoquer recherche_web — en fonction de sa description et de son goal.
Exemple concret : agent de veille IA
Deux tools complémentaires : recherche web + stockage fichier.
from crewai import Agent, Task, Crew
import json
@Tool(name="recherche_web", description="Recherche des informations sur le web.")
def recherche_web(query: str) -> str:
return json.dumps({"resultats": [{"titre": "IA Act adopté", "url": "https://example.com"}]})
@Tool(name="sauvegarder_fichier", description="Écrit du contenu dans un fichier texte local.")
def sauvegarder_fichier(nom_fichier: str, contenu: str) -> str:
try:
with open(nom_fichier, "w", encoding="utf-8") as f:
f.write(contenu)
return f"Fichier {nom_fichier} créé avec succès."
except Exception as e:
return f"Erreur d'écriture : {e}"
veilleur = Agent(
role="Veilleur IA",
goal="Surveiller les évolutions du secteur de l'IA et produire un rapport synthétique.",
backstory="Tu es un veilleur technologique. Tu effectues des recherches ciblées, compiles les résultats et les stockes.",
tools=[recherche_web, sauvegarder_fichier],
verbose=True,
)
tache = Task(
description="Fais une veille sur l'IA agents en 2026 et sauvegarde un rapport dans veille_ia.txt.",
agent=veilleur,
expected_output="Un fichier veille_ia.txt contenant 3 actualités majeures.",
)
crew = Crew(agents=[veilleur], tasks=[tache], process="sequential")
resultat = crew.kickoff()
L'agent invoque recherche_web pourgather les informations, puis sauvegarder_fichier pour les persister.
Gérer erreurs, timeouts et rate limits
Trois causes principales d'échec : timeout, rate limit, schema de retour invalide.
Timeout
import requests
def recherche_web(query: str) -> str:
try:
response = requests.get(
"https://api.exemple.com/search",
params={"q": query},
timeout=10, # délai max en secondes
)
response.raise_for_status()
return response.text
except requests.Timeout:
return json.dumps({"erreur": "Délai dépassé (10s). Réessayez."})
except requests.RequestException as e:
return json.dumps({"erreur": f"Échec requête : {str(e)}"})
Rate limit
import time
_appels_recent = []
def recherche_web_rate_limited(query: str) -> str:
global _appels_recent
maintenant = time.time()
_appels_recent = [t for t in _appels_recent if maintenant - t < 60]
if len(_appels_recent) >= 10:
return json.dumps({"erreur": "Rate limit atteint (10req/min). Patience."})
_appels_recent.append(maintenant)
# ... logique de recherche
Schema invalide
Retournez toujours un format cohérent. Si l'agent attend du JSON structuré et que votre tool renvoie du texte brut, le raisonnement déraille. Documentez le format de retour dans la description du tool.
Bonnes pratiques
1. Une responsabilité par tool. Un tool qui fait recherche + traitement + stockage fait mal une seule chose.
2. Descriptions précises et actionnables. Pas "Outil de recherche" — mais "Recherche des articles récents sur [sujet]. Retourne une liste de 5 résultats avec titre, URL et date."
3. Validation des entrées en premier. Vérifiez les paramètres avant toute logique coûteuse. Un tool qui échoue élégamment vaut mieux qu'un tool qui crash.
4. Naming : verbes pour les actions (recherche_web, lit_fichier) — noms pour les données (scrape_page, appelle_api).
5. Limitez le nombre de tools par agent. 2 à 5 tools maximum. Au-delà, l'agent disperse son attention.
6. Documentez dans le code ET dans la description. Le premier est lu par le modèle, le second par les développeurs.
FAQ
Comment créer un tool personnalisé ?
Utilisez @tool en important Tool depuis crewai. Définissez un nom unique, une description précise, et votre fonction Python. Associez via tools=[mon_tool].
Peut-on utiliser plusieurs tools avec un seul agent ?
Oui. Passez une liste au paramètre tools=. L'agent choisit lequel invoquer selon la tâche. Gardez 2-5 tools par agent.
Un tool n'est jamais appelé — comment debugger ?
Activez verbose=True, vérifiez la description (le modèle doit comprendre quand l'appeler), et testez le tool isolément avec des entrées variées.
Les tools supportent-ils les appels asynchrones ?
Oui. Définissez votre fonction en async def — CrewAI gère l'appel non-bloquant. Idéal pour les HTTP parallelisés.
Comment gérer les rate limits ? Implémentez un throttling simple (compteur par minute) avec message d'erreur structuré. Prévoyez un retry avec backoff exponentiel.
Aller plus loin
Les tools sont un pilier de l'architecture agentique. Consultez le guide complet de CrewAI pour comprendre comment ils s'intègrent dans une architecture multi-agents. Pour installer votre premier environnement, le guide d'installation vous donne un setup prêt en 10 minutes. Et pour une vision large de l'outillage agentique, notre article sur les agent tools fait le tour des approches et bonnes pratiques.
Restez informé sur les agents IA
Nouveaux tutoriels, comparatifs et guides pratiques directement dans votre boîte mail.