FrameworksAgents.com Logo

Agent Planning : Comment Structurer les Tâches d'un Agent IA (2026)

Guidecalendar_todayPublié le 8 juin 2026schedule12 min de lectureagent ia planningagent task decomposition

Maîtrisez le planning d'un agent IA en 2026. ReAct, Chain of Thought, Tree of Thought : patterns de décomposition avec code Python.

Agent Planning : Comment Structurer les Tâches d'un Agent IA (2026)

Introduction

Un agent IA sans planning, c'est un navigateur sans carte. Il peut avancer quelques pas, mais il ne sait pas où il va, ni comment atteindre une destination complexe.

Le planning est la capacité à décomposer une tâche complexe en sous-actions ordonnées, les exécuter, puis s'adapter quand le contexte change.

En 2026, le planning distingue un agent utile d'un agent inutilement limité. Les LLMs sont de puissants moteurs de raisonnement, mais ils ne planifient pas naturellement. Sans technique explicite, un LLM oscille entre l'hallucination et l'impasse.

Cet article couvre les patterns opérationnels — ReAct, Chain of Thought, Tree of Thought et décomposition de tâches — avec du code Python en LangChain et CrewAI.

Résumé rapide

PatternPrincipeQuand l'utiliser
ReActBoucle think → act → observe → repeatAgents avec outils (tool-calling)
Chain of Thought (CoT)Raisonnement step-by-step forcéTâches logiques, multi-étapes
Tree of Thought (ToT)Exploration d'arbres de solutionsProblèmes complexes avec branchement
Task DecompositionGénération de sous-tâches par le LLMTâches longues, multi-phases

Le problème de la planification pour les LLMs

Pourquoi les LLMs ne planifient pas naturellement

Un LLM prédit le prochain token. Il n'a pas de modèle interne de ses objectifs à long terme, pas de mémoire de travail persistante au-delà du contexte, et pas de mécanisme de décomposition intégré.

Quand on lui demande "organise ma inbox email", il génère du texte plausible — pas un plan d'action exécutable.

Trois limitations expliquent ce comportement :

  1. Pas de décomposition native : le LLM ne segmente pas spontanément une tâche complexe en sous-objectifs.
  2. Hallucination sur les étapes intermédiaires : en raisonnant sur une séquence d'actions futures, il peut inventer des étapes impossibles.
  3. Pas de feedback loop : un LLM standard n'observe pas le résultat de ses actions. Il ne sait pas qu'une étape a échoué.

Ce que les techniques de planning apportent

Les techniques de planning structurent la manière dont on utilise le LLM — son prompting, sa boucle d'exécution, son interface avec des outils. Elles permettent de :

  • Décomposer une tâche complexe en étapes atomiques
  • Ordonner ces étapes dans un plan cohérent
  • Exécuter chaque étape avec un mécanisme de feedback
  • Réviser le plan quand une étape échoue ou que le contexte change

ReAct (Reasoning + Acting)

Le pattern

ReAct combine raisonnement et action dans une boucle itérative. À chaque tour, l'agent :

  1. Think : le LLM réfléchit sur l'état actuel et décide de l'action suivante
  2. Act : l'agent exécute l'action (appel d'outil, requête API...)
  3. Observe : le résultat est réinjecté dans le contexte
  4. Repeat : retour à l'étape 1 jusqu'à l'objectif atteint

Ce pattern est adapté aux agents qui utilisent des outils — le LLM interagit avec un environnement, il ne se contente pas de générer du texte.

Implémentation avec LangChain

from langchain.agents import AgentType, initialize_agent
from langchain_openai import ChatOpenAI
from langchain_core.tools import tool

llm = ChatOpenAI(model="gpt-4o", temperature=0)

@tool
def search_database(query: str) -> str:
    """Recherche dans la base de données clients."""
    return f"Résultat pour '{query}': 3 enregistrements trouvés"

@tool
def send_email(recipient: str, body: str) -> str:
    """Envoie un email."""
    return f"Email envoyé à {recipient}"

tools = [search_database, send_email]

agent = initialize_agent(
    tools,
    llm,
    agent=AgentType.STRUCTURED_CHAT_ZERO_SHOT_REACT_DESCRIPTION,
    verbose=True
)

result = agent.run(
    "Recherche les clients du secteur healthcare et envoie-leur un récapitulatif"
)

Implémentation avec CrewAI

from crewai import Agent, Task, Crew

researcher = Agent(
    role="Researcher",
    goal="Trouver les clients du secteur healthcare",
    backstory="Spécialiste de la recherche B2B",
    tools=[search_database]
)

sender = Agent(
    role="Sender",
    goal="Envoyer un récapitulatif aux clients identifiés",
    backstory="Expert marketing automation",
    tools=[send_email]
)

crew = Crew(agents=[researcher, sender], tasks=[...])
result = crew.kickoff()

Quand utiliser ReAct : tâches nécessitant des appels d'outils successifs, scénarios où l'agent doit s'adapter à des résultats intermédiaires.

Quand éviter : tâches purement analytiques sans interaction avec un environnement — un CoT sera plus efficace.

Chain of Thought (CoT)

Le principe

Chain of Thought force le LLM à exposer son raisonnement étape par étape, plutôt que de sauter directement à la réponse.

Variantes

Zero-shot CoT : on ajoute simplement "Think step by step" dans le prompt. Pas d'exemples nécessaires.

prompt = """
Un client a un panier de 450€. La remise est de 15% puis une remise supplémentaire de 10€.
Quel est le prix final ? Réfléchis étape par étape.
"""

response = llm.invoke(prompt)

Few-shot CoT : on fournit des exemples de raisonnement avant la question cible.

prompt = """
Exemple : Un produit à 200€ avec 20% de remise puis 5€ de frais.
Raisonnement : 200 * 0.80 = 160. 160 + 5 = 165€.
Réponse : 165€.

--- Question ---
Un produit à 350€ avec 12% de remise puis 8€ de frais.
Raisonnement :
"""

response = llm.invoke(prompt)

CoT auto-catalyqué : le LLM génère d'abord ses étapes de raisonnement, puis les valide avant de produire la réponse finale.

from langchain_core.prompts import PromptTemplate

cot_prompt = PromptTemplate.from_template(
    """Tu es un assistant de planification. Pour chaque tâche :
    1. Identifie le goal principal
    2. Décompose en 3-5 sous-tâches
    3. Estime l'ordre de dépendance
    4. Identifie les risques potentiels

    Tâche : {task}

    Raisonnement :""")

decomposition = llm.invoke(cot_prompt.format(
    task="Lancer une campagne email pour 500 prospects"
))

Quand utiliser CoT : tâches logiques, calculs, debugging de code, analyse de documents.

Limite : CoT ne fait pas d'actions. Le raisonnement reste dans le domaine textuel.

Tree of Thought (ToT)

Le pattern

Tree of Thought explore plusieurs branches de solutions en parallèle. L'agent évalue plusieurs chemins et sélectionne le plus prometteur.

from langchain_core.messages import HumanMessage
from langchain_openai import ChatOpenAI

llm = ChatOpenAI(model="gpt-4o", temperature=0.7)

def tree_of_thought(task: str, depth: int = 3) -> dict:
    """Exploration ToT simplifiée."""
    branches = []

    # Génération des branches initiales
    initial_prompt = f"Problème : {task}. Génère 3 approches alternatives distinctes."
    response = llm.invoke(initial_prompt)
    approaches = response.content.split("\n")[:3]

    for i, approach in enumerate(approaches):
        # Évaluation de chaque branche
        eval_prompt = f"Évalue cette approche : {approach}\nCritères : faisabilité, risque, temps. Réponds en 2 phrases."
        eval = llm.invoke(eval_prompt)
        branches.append({"approach": approach, "evaluation": eval.content})

    return {"branches": branches, "selected": branches[0]["approach"]}

result = tree_of_thought("Réduire le churn de notre SaaS de 8% à 3%")

Quand utiliser ToT : problèmes métier complexes avec plusieurs voies de résolution, décisions stratégiques multi-critères.

Limite : coût en tokens élevé et complexité de gestion.

Task Decomposition

Le concept

La décomposition de tâches utilise le LLM lui-même comme générateur de sous-tâches. Au lieu de définir manuellement chaque étape, on demande au LLM de diviser la tâche principale en un plan structuré.

Trois patterns de décomposition

Pattern 1 — Récursif : le LLM décompose chaque sous-tâche jusqu'à un niveau atomique.

def recursive_decompose(task: str, llm, depth: int = 0, max_depth: int = 4) -> list:
    """Décomposition récursive : chaque tâche est décomposée jusqu'au niveau atomique."""
    if depth >= max_depth:
        return [task]

    prompt = f"Décompose cette tâche en 2-4 sous-tâches plus petites et concrètes.\nTâche : {task}\n\nListe les sous-tâches :"
    response = llm.invoke(prompt)

    subtasks = extract_subtasks(response.content)
    result = []
    for subtask in subtasks:
        result.extend(recursive_decompose(subtask, llm, depth + 1, max_depth))

    return result

tasks = recursive_decompose("Préparer un rapport trimestriel complet", llm)
# ['Collecter les données ventes Q1', 'Collecter les données ventes Q2', ...]

Pattern 2 — Linéaire : décomposition en une séquence fixe d'étapes.

def linear_decompose(task: str, llm) -> list:
    """Décomposition linéaire : une séquence ordonnée d'étapes."""
    prompt = f"Décompose cette tâche en une séquence ordonnée de 4 à 6 étapes.\nTâche : {task}\n\nFormat : 1. [étape] 2. [étape] ..."
    response = llm.invoke(prompt)
    steps = extract_ordered_steps(response.content)
    return steps

plan = linear_decompose("Déployer un agent IA sur un VPS", llm)
# ['Vérifier les prérequis système', 'Installer Python 3.11+', ...]

Pattern 3 — Asynchrone : décomposition en tâches indépendantes exécutables en parallèle.

import asyncio
from concurrent.futures import ThreadPoolExecutor


def async_decompose(task: str, llm) -> list:
    """Décomposition pour exécution parallèle de sous-tâches indépendantes."""
    prompt = f"Identifie les sous-tâches qui peuvent être exécutées EN PARALLÈLE.\nTâche : {task}\n\nTâches parallélisables :"
    response = llm.invoke(prompt)
    parallel_tasks = extract_parallel_tasks(response.content)
    return parallel_tasks

parallel_tasks = async_decompose("Préparer un audit complet du système", llm)
# ['Audit sécurité', 'Audit performance', 'Audit données']

# Exécution parallèle
with ThreadPoolExecutor(max_workers=3) as executor:
    results = list(executor.map(run_audit_task, parallel_tasks))

Plan Execution et Adaptation

Moteur d'exécution

Un moteur de plan execution gère :

  • L'ordonnancement : quelle tâche dépend de quelle autre
  • Le monitoring : suivi de l'état de chaque étape (pending, running, done, failed)
  • La reprise sur erreur : si une étape échoue, décider de retenter, sauter ou replanifier
from enum import Enum
from dataclasses import dataclass, field
from typing import Callable

class TaskStatus(Enum):
    PENDING = "pending"
    RUNNING = "running"
    DONE = "done"
    FAILED = "failed"

@dataclass
class TaskStep:
    id: str
    description: str
    status: TaskStatus = TaskStatus.PENDING
    result: any = None
    error: str = None
    action: Callable = None

class PlanExecutor:
    def __init__(self, plan: list[TaskStep]):
        self.plan = plan
        self.results = {}

    def run(self) -> dict:
        for step in self.plan:
            step.status = TaskStatus.RUNNING
            try:
                if step.action:
                    step.result = step.action()
                step.status = TaskStatus.DONE
                self.results[step.id] = step.result
            except Exception as e:
                step.status = TaskStatus.FAILED
                step.error = str(e)
                if self.is_critical_error(step):
                    break
        return self.results

    def is_critical_error(self, step: TaskStep) -> bool:
        return step.id in ["validate_input", "authenticate"]

Replanification dynamique

Un plan statique est fragile. Un agent robuste détecte les écarts et ajuste :

def should_replan(current_state: dict, planned_steps: list, llm) -> bool:
    """Détecte si le plan doit être ajusté."""
    failed_steps = [s for s in planned_steps if s.status == TaskStatus.FAILED]
    unexpected_results = current_state.get("anomalies", [])

    if failed_steps or unexpected_results:
        return True
    return False

def replan(context: dict, llm) -> list:
    """Génère un nouveau plan basé sur le contexte actuel."""
    prompt = f"Contexte actuel : {context}\nLe plan précédent a échoué sur certaines étapes. Génère un nouveau plan adapté."
    response = llm.invoke(prompt)
    return extract_plan(response.content)

Exemple concret : Agent SEO de veille concurrentielle

Contexte : construire un agent qui surveille les mouvements SEO de 3 concurrents et génère un rapport hebdomadaire.

Architecture ReAct + Task Decomposition :

from langchain.agents import AgentType, initialize_agent
from langchain_openai import ChatOpenAI
from langchain_core.tools import tool
from datetime import datetime

llm = ChatOpenAI(model="gpt-4o", temperature=0)

@tool
def scrape_competitor(competitor_url: str) -> str:
    """Scrappe les nouvelles pages d'un concurrent."""
    return f"Pages récentes pour {competitor_url}: 4 nouvelles pages détectées"

@tool
def check_serp(keyword: str) -> str:
    """Vérifie le ranking SERP pour un mot-clé."""
    return f"Position pour '{keyword}':排名第5, en hausse de 2 places"

@tool
def generate_report(data: str) -> str:
    """Génère un rapport structuré."""
    return f"Rapport généré le {datetime.now().date()}\n\n{data}"


tools = [scrape_competitor, check_serp, generate_report]

agent = initialize_agent(
    tools,
    llm,
    agent=AgentType.STRUCTURED_CHAT_ZERO_SHOT_REACT_DESCRIPTION,
    verbose=True
)

task = """
Pour les 3 concurrents (site-a.com, site-b.com, site-c.com) :
1. Identifie leurs 5 dernières pages publiées
2. Vérifie le ranking SERP pour 3 mots-clés cibles
3. Génère un rapport de veille SEO hebdomadaire
"""

result = agent.run(task)
print(result)

L'agent exécute la boucle ReAct — il scrape chaque concurrent, vérifie les positions SERP, puis compile le rapport. Si un scrape échoue, il détecte l'erreur et réessaie ou ajuste le plan.

Bonnes pratiques

  • Commencer simple, ajouter de la complexité au besoin. Un agent avec ReAct basique + décomposition linéaire couvre 80% des cas d'usage. Introduisez ToT uniquement quand le problème présente un branchement réel.

  • Mesurer le nombre d'étapes. Plus le plan a d'étapes, plus le risque d'erreur cumulative augmente. Visez des sous-tâches de 5 à 10 minutes maximum chacune.

  • Définir des points de validation. Entre chaque phase significative, insérez une étape de validation. Si le résultat ne correspond pas aux attentes, déclenchez la replanification.

  • Protéger les étapes critiques. Certaines étapes (authentification, validation d'entrée) ne doivent jamais être skippées. Identifiez-les dès la conception.

  • Limiter la profondeur de décomposition. Une décomposition récursive qui va trop loin produit des micro-tâches inutiles. Fixez un max_depth et un seuil de granularité minimale.

  • Prévoir le timeout par étape. Chaque sous-tâche devrait avoir un temps d'exécution estimé. Si une étape dépasse ce seuil, c'est un signal d'alerte.

Questions fréquentes

Qu'est-ce que le agent planning ?

Le agent planning désigne la capacité d'un agent IA à décomposer une tâche complexe en sous-tâches ordonnées, à les exécuter dans un ordre cohérent, et à s'adapter quand le contexte change.

ReAct vs Chain of Thought : quelle différence ?

ReAct combine raisonnement et action — l'agent pense, exécute, observe le résultat, puis recommence. Chain of Thought se limite au raisonnement textuel. ReAct est adapté aux agents avec outils ; CoT aux tâches analytiques pures.

Comment implémenter un agent ReAct en Python ?

Avec LangChain, utilisez initialize_agent avec AgentType.STRUCTURED_CHAT_ZERO_SHOT_REACT_DESCRIPTION et vos outils personnalisés décorés avec @tool. Avec CrewAI, définissez des agents avec des rôles et des tools, puis orchestrez-les dans un Crew.

Quand utiliser Tree of Thought plutôt que ReAct ?

Tree of Thought est pertinent quand le problème présente plusieurs branches de résolution également valides et qu'il est difficile de déterminer la bonne approche a priori. Pour des tâches linéaires avec une voie évidente, ReAct est plus léger et plus rapide.

La task decomposition peut-elle être automatique ?

Oui. Le LLM peut être utilisé comme générateur de sous-tâches. Des patterns comme le recursive decompose ou le linear decompose exploitent cette capacité. Des frameworks comme LangGraph et CrewAI intègrent nativement cette décomposition.


Prêt à implémenter ces patterns ? Consultez les guides LangChain et CrewAI pour approfondir l'implémentation, ou explorez l'architecture d'un agent IA dans son ensemble pour comprendre où le planning s'insère dans le cycle de vie complet.

Articles liés

Restez informé sur les agents IA

Nouveaux tutoriels, comparatifs et guides pratiques directement dans votre boîte mail.

homeAccueilcodeFrameworkssmart_toyAgentsmenu_bookTutorielsTwitter