Aller au contenu principal

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_turns contrô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