Pipeline multi-outils
Orchestrer des outils en séquence
L’agent météo de la leçon précédente utilisait des outils indépendants. Dans un pipeline multi-outils, les résultats d’un outil alimentent l’appel suivant. Le modèle orchestre la séquence automatiquement — votre rôle est de fournir les outils et d’exécuter les appels.
Architecture d’un pipeline
Un pipeline typique suit ce schéma :
Recherche → Analyse → Action → Notification
Chaque étape produit des données consommées par la suivante. Le modèle gère cette orchestration naturellement grâce au contexte de conversation.
Exemple : pipeline de veille concurrentielle
Imaginons un pipeline qui surveille les prix des concurrents et génère un rapport :
tools = [
{
"type": "function",
"function": {
"name": "scrape_competitor_prices",
"description": "Récupérer les prix actuels d'un concurrent "
"pour une liste de produits. Retourne un tableau "
"de {produit, prix, disponibilité}.",
"parameters": {
"type": "object",
"properties": {
"competitor": {
"type": "string",
"description": "Nom du concurrent"
},
"products": {
"type": "array",
"items": {"type": "string"},
"description": "Liste des produits à vérifier"
}
},
"required": ["competitor", "products"]
}
}
},
{
"type": "function",
"function": {
"name": "compare_with_our_prices",
"description": "Comparer les prix concurrents avec nos prix. "
"Retourne les écarts en pourcentage et les "
"recommandations d'ajustement.",
"parameters": {
"type": "object",
"properties": {
"competitor_prices": {
"type": "array",
"items": {
"type": "object",
"properties": {
"product": {"type": "string"},
"price": {"type": "number"}
}
}
}
},
"required": ["competitor_prices"]
}
}
},
{
"type": "function",
"function": {
"name": "generate_report",
"description": "Générer un rapport PDF avec les résultats de "
"l'analyse comparative. Retourne l'URL du rapport.",
"parameters": {
"type": "object",
"properties": {
"title": {"type": "string"},
"data": {"type": "object"},
"format": {
"type": "string",
"enum": ["pdf", "csv", "json"]
}
},
"required": ["title", "data"]
}
}
},
{
"type": "function",
"function": {
"name": "send_notification",
"description": "Envoyer une notification par email ou Slack "
"avec un résumé et un lien vers le rapport.",
"parameters": {
"type": "object",
"properties": {
"channel": {
"type": "string",
"enum": ["email", "slack"]
},
"recipient": {"type": "string"},
"message": {"type": "string"},
"attachment_url": {"type": "string"}
},
"required": ["channel", "recipient", "message"]
}
}
}
]
Exécution du pipeline
Quand l’utilisateur demande « Analyse les prix de ConcurrentX pour nos 5 produits phares et envoie le rapport à l’équipe commerciale », le modèle orchestre :
Tour 1 : scrape_competitor_prices(competitor="ConcurrentX", products=[...])
Tour 2 : compare_with_our_prices(competitor_prices=[résultats du tour 1])
Tour 3 : generate_report(title="Veille prix ConcurrentX", data={...})
Tour 4 : send_notification(channel="slack", recipient="#commercial", ...)
Chaque tour utilise les résultats du précédent. Le modèle passe naturellement les données d’un outil au suivant.
Combinaison outils serveur + client dans un pipeline
Les pipelines les plus puissants combinent outils serveur et client :
tools = [
{"type": "web_search"}, # Serveur : recherche web
{
"type": "function",
"function": {
"name": "extract_data",
"description": "Extraire des données structurées d'un texte brut",
"parameters": { ... }
}
},
{
"type": "function",
"function": {
"name": "save_to_crm",
"description": "Sauvegarder les données extraites dans le CRM",
"parameters": { ... }
}
}
]
Flux : le modèle fait une recherche web (automatique côté serveur), puis appelle votre fonction d’extraction (côté client), puis sauvegarde dans le CRM (côté client).
Pattern : fan-out / fan-in
Certains pipelines nécessitent un pattern fan-out (plusieurs appels parallèles) suivi d’un fan-in (agrégation des résultats) :
┌→ scrape_site_A ─┐
Requête ─┤→ scrape_site_B ─┤→ aggregate_results → generate_report
└→ scrape_site_C ─┘
Le modèle gère cela naturellement avec les appels parallèles :
Tour 1 : [scrape_site_A, scrape_site_B, scrape_site_C] (parallèle)
Tour 2 : aggregate_results(data=[résultat_A, résultat_B, résultat_C])
Tour 3 : generate_report(aggregated_data={...})
Gestion des échecs dans un pipeline
Un pipeline robuste gère les échecs à chaque étape :
def execute_with_retry(name, args, max_retries=2):
for attempt in range(max_retries + 1):
try:
result = execute_function(name, args)
if "error" not in result:
return result
except Exception:
pass
if attempt < max_retries:
time.sleep(1) # Attente avant réessai
return {
"error": f"Échec après {max_retries + 1} tentatives",
"function": name,
"partial_data": None
}
Quand une étape échoue, le modèle peut :
- Réessayer avec des paramètres ajustés
- Sauter l’étape et continuer avec des données partielles
- Informer l’utilisateur et demander des instructions
Points clés à retenir
- Un pipeline multi-outils enchaîne les résultats d’un outil au suivant
- Le modèle orchestre la séquence automatiquement grâce au contexte
- Le pattern fan-out/fan-in combine appels parallèles et agrégation
- Combinez outils serveur (web_search) et client (vos fonctions) pour des pipelines hybrides
- Gérez les échecs à chaque étape avec retry et fallback
- Chaque outil du pipeline doit avoir une responsabilité claire et unique