Agent multi-étapes avec boucle de raisonnement
Agent multi-étapes avec boucle de raisonnement
Les agents les plus puissants ne se contentent pas d’un seul appel de tool. Ils enchaînent plusieurs étapes de raisonnement, ajustent leur stratégie en fonction des résultats, et itèrent jusqu’à atteindre l’objectif. Dans cette leçon, vous apprendrez à construire ces agents multi-étapes.
Le pattern plan-execute
Un agent multi-étapes commence par élaborer un plan, puis exécute chaque étape :
from agents import Agent, Runner, function_tool
from pydantic import BaseModel
import json
class PlanAction(BaseModel):
etapes: list[str]
objectif: str
agent_planificateur = Agent(
name="Planificateur",
instructions="""Vous recevez une tâche complexe. Décomposez-la en étapes simples et ordonnées.
Chaque étape doit être une action concrète et réalisable.""",
model="o3-pro", # Le raisonnement avancé pour la planification
output_type=PlanAction,
)
@function_tool
def rechercher_dans_crm(requete: str) -> str:
"""Recherche dans le CRM des informations clients."""
return json.dumps({"clients": [
{"nom": "Acme Corp", "ca": 500000, "contrat": "Enterprise"},
{"nom": "TechStart", "ca": 50000, "contrat": "Starter"},
]})
@function_tool
def generer_rapport(titre: str, contenu: str) -> str:
"""Génère un rapport formaté."""
return f"Rapport '{titre}' généré avec succès ({len(contenu)} caractères)"
@function_tool
def envoyer_email(destinataire: str, sujet: str, corps: str) -> str:
"""Envoie un email."""
return f"Email envoyé à {destinataire} : {sujet}"
agent_executeur = Agent(
name="Exécuteur",
instructions="""Vous exécutez des tâches étape par étape.
Utilisez les outils disponibles pour accomplir chaque étape.
Si une étape échoue, tentez une approche alternative.""",
tools=[rechercher_dans_crm, generer_rapport, envoyer_email],
model="gpt-5.3",
)
async def traiter_tache_complexe(tache: str):
# Étape 1 : Planifier
plan = await Runner.run(agent_planificateur, tache)
print(f"Plan : {plan.final_output.etapes}")
# Étape 2 : Exécuter avec le plan comme contexte
instructions_execution = f"""Exécutez les étapes suivantes dans l'ordre :
{chr(10).join(f'{i+1}. {e}' for i, e in enumerate(plan.final_output.etapes))}
Objectif : {plan.final_output.objectif}"""
result = await Runner.run(agent_executeur, instructions_execution)
return result.final_output
Agent auto-correcteur
Un agent qui détecte ses erreurs et se corrige :
from agents import Agent, Runner, function_tool
@function_tool
def executer_requete_sql(sql: str) -> str:
"""Exécute une requête SQL sur la base de données."""
# Simulation : certaines requêtes échouent
if "DROP" in sql.upper():
return "ERREUR : Les requêtes destructives sont interdites."
if "SELECT" in sql.upper() and "FROM" not in sql.upper():
return "ERREUR : Syntaxe SQL invalide - FROM manquant."
return json.dumps({
"colonnes": ["nom", "ca_mensuel", "region"],
"lignes": [
["Acme Corp", 45000, "Île-de-France"],
["TechStart", 12000, "Rhône-Alpes"],
],
"nb_resultats": 2
})
agent_analyste = Agent(
name="Analyste de données",
instructions="""Vous analysez des données en exécutant des requêtes SQL.
Si une requête échoue :
1. Analysez le message d'erreur
2. Corrigez la requête
3. Réessayez
Maximum 3 tentatives par requête.
Ne jamais utiliser DROP, DELETE ou TRUNCATE.""",
tools=[executer_requete_sql],
model="gpt-5.3",
max_turns=10, # Assez de tours pour les corrections
)
result = Runner.run_sync(
agent_analyste,
"Quel est le chiffre d'affaires total par région ?"
)
Pattern : chaîne d’agents spécialisés
Pour les workflows complexes, enchaînez plusieurs agents spécialisés :
from agents import Agent, Runner
agent_collecte = Agent(
name="Collecteur de données",
instructions="Collectez toutes les données nécessaires à l'analyse.",
tools=[rechercher_dans_crm, executer_requete_sql],
model="gpt-5.3",
)
agent_analyse = Agent(
name="Analyste",
instructions="Analysez les données collectées et identifiez les tendances.",
model="o3-pro", # Raisonnement avancé pour l'analyse
)
agent_redaction = Agent(
name="Rédacteur",
instructions="""Rédigez un rapport clair et structuré en français
à partir de l'analyse fournie. Format : introduction, points clés, recommandations.""",
model="gpt-5.3",
)
async def pipeline_analyse(question: str):
# Étape 1 : Collecter les données
donnees = await Runner.run(agent_collecte, question)
# Étape 2 : Analyser
analyse = await Runner.run(
agent_analyse,
f"Analysez ces données : {donnees.final_output}"
)
# Étape 3 : Rédiger le rapport
rapport = await Runner.run(
agent_redaction,
f"Rédigez un rapport basé sur cette analyse : {analyse.final_output}"
)
return rapport.final_output
Contrôler la profondeur de raisonnement
Le paramètre max_turns est votre garde-fou principal :
# Agent prudent : peu de tours
agent_simple = Agent(
name="Agent simple",
instructions="Répondez en un seul tour si possible.",
model="gpt-5.3",
)
result = await Runner.run(agent_simple, "Question simple", max_turns=3)
# Agent complexe : beaucoup de tours
agent_recherche = Agent(
name="Chercheur approfondi",
instructions="Explorez toutes les pistes avant de conclure.",
tools=[rechercher_dans_crm, executer_requete_sql],
model="gpt-5.3",
)
result = await Runner.run(agent_recherche, "Analyse complète du Q1", max_turns=25)
Points clés à retenir
- Le pattern plan-execute sépare la planification (o3-pro) de l’exécution (gpt-5.3)
- Un agent auto-correcteur analyse ses erreurs et ajuste sa stratégie
- Les chaînes d’agents spécialisés permettent des workflows complexes et maintenables
max_turnscontrôle la profondeur de raisonnement et protège contre les boucles- Utilisez les modèles de raisonnement (o3-pro) pour la planification et l’analyse