Module 4 — Chaîne de pensée et décomposition des étapes
Demander au modèle « raisonne étape par étape » est devenu un réflexe. Comme tout réflexe, il aide dans certains cas et il nuit dans d'autres. Ce module explique quand cette technique paie, quand elle coûte inutilement, et ce qu'elle devient face aux modèles à raisonnement intégré.
Ce que fait la chaîne de pensée
Une chaîne de pensée (chain of thought) est une consigne qui demande au
modèle de produire son raisonnement avant sa réponse. La formulation
canonique tient en une phrase :
Réfléchis étape par étape, puis donne la réponse finale.
Le mécanisme est simple : générer les étapes intermédiaires en jetons condition la suite du texte sur ces étapes. Une réponse arithmétique qui apparaît immédiatement a été « devinée » ; la même réponse qui suit trois lignes de décomposition a été « déduite » — au sens où sa probabilité est calculée en tenant compte de la trace intermédiaire.
Quand la chaîne de pensée aide
Elle aide sur les tâches qui décomposent un problème en sous-étapes enchaînées dont chaque étape est fiable individuellement :
- Arithmétique en plusieurs opérations
- Raisonnement logique à plusieurs implications
- Analyse d'un document long où il faut d'abord extraire, puis comparer, puis conclure
- Rédaction d'une réponse qui doit citer les passages du document sur lesquels elle s'appuie
Sur notre fil rouge, un courriel qui mentionne « livraison retardée provoquant l'annulation d'un événement demain » demande implicitement deux étapes : identifier le motif (livraison) puis évaluer l'urgence (élevée à cause de la contrainte temporelle). Une chaîne de pensée courte améliore mesurablement la précision sur ce type de cas :
CONSIGNE = """
Tu extrais quatre champs d'un courriel de réclamation.
Procède ainsi :
1. Identifie le motif principal.
2. Repère les contraintes temporelles éventuelles pour évaluer l'urgence.
3. Décide de l'action demandée.
4. Rends un objet JSON final avec les clés motif, produit, urgence,
action_demandee, et rien d'autre.
""".strip()
Notez la contrainte finale : rends uniquement le JSON. Sans elle, le modèle rend son raisonnement suivi du JSON, ce qui casse la sortie consommable par un logiciel. C'est un piège classique traité au module 5.
Quand la chaîne de pensée nuit
Trois situations où elle dégrade la performance ou le coût :
Tâches de reconnaissance directe. Classer un courriel spam / non spam, détecter la langue d'un texte, extraire un montant en euros : le modèle « sait » la réponse en une passe. Forcer un raisonnement ajoute des jetons et augmente la variance sans améliorer la précision.
Tâches où le raisonnement est faux mais convaincant. Sur les puzzles logiques mal posés ou les questions à énoncé trompeur, le modèle produit une chaîne de pensée grammaticalement impeccable qui conduit à une réponse fausse — et l'auditeur humain croit d'autant plus à cette réponse qu'elle est « justifiée ». On mesure alors une régression de fiabilité.
Coût en jetons de sortie. Chaque étape de raisonnement est facturée en sortie, souvent au tarif le plus élevé. Sur un million d'appels par mois, une chaîne de pensée de 200 jetons ajoute deux ordres de grandeur au coût final.
Un modèle peut produire un raisonnement plausible et une réponse fausse ; c'est même la combinaison la plus dangereuse pour l'utilisateur, qui adhère d'autant plus à l'erreur qu'elle semble justifiée. Toujours évaluer la performance avec et sans, sur le même jeu de test, avant de décider.
Auto-cohérence : plusieurs raisonnements, un vote
Une extension classique : lancer la même consigne avec chaîne de pensée plusieurs fois en jouant sur la température, puis voter la réponse finale à la majorité.
def extraire_par_vote(courriel: str, k: int = 5) -> dict:
reponses = []
for _ in range(k):
r = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "system", "content": CONSIGNE},
{"role": "user", "content": courriel}],
temperature=0.7,
)
reponses.append(extraire_json(r.choices[0].message.content))
return vote_majoritaire(reponses)
Le gain de précision est mesurable sur les tâches où la chaîne de pensée aide déjà. Le coût est multiplié par . La question devient un compromis : sur une extraction courrielle, doubler le coût pour gagner deux points de précision n'est presque jamais justifié. Sur un diagnostic médical assisté, cela le devient.
Décomposition en sous-appels
Quand la tâche est vraiment complexe, une meilleure stratégie que « une consigne à tout faire avec chaîne de pensée » consiste à découper en plusieurs appels enchaînés, chacun avec sa propre consigne minimaliste :
def analyser(courriel: str) -> dict:
langue = detecter_langue(courriel) # appel 1
resume = resumer_pour_extraction(courriel, langue)# appel 2
champs = extraire_champs(resume) # appel 3
return champs
Trois avantages : chaque appel est testable isolément, les échecs sont localisés (« l'erreur vient de l'appel 2 »), et chaque consigne reste courte, donc bon marché et lisible. Le coût cumulé est parfois inférieur au coût d'une consigne unique très longue qui traite tout.
Trois inconvénients : la latence s'additionne, la logique de flux se déplace dans le code Python, et une erreur en amont se propage sans qu'un appel aval ne puisse la rattraper.
| Approche | Avantage principal | Coût typique |
|---|---|---|
| Consigne monolithique | 1 appel, 1 latence | jetons élevés en entrée |
| Chaîne de pensée | correction sur cas ambigus | jetons élevés en sortie |
| Auto-cohérence | précision maximale | multiplié par |
| Décomposition | testabilité, lisibilité | latence cumulée |
Les modèles à raisonnement intégré
Une génération de modèles récents — souvent identifiés par un « r » ou « reasoning » dans leur nom — produit un raisonnement caché avant de répondre, sans qu'il faille le demander. La chaîne de pensée manuelle devient alors non seulement inutile mais parfois contre-productive : le modèle raisonne déjà, l'ajout d'une consigne « réfléchis étape par étape » soit n'a aucun effet, soit interfère avec son processus interne.
Sur ces modèles, la bonne pratique est inversée : consignes courtes, directes, sans instruction de raisonnement. Le modèle décide seul de la profondeur d'analyse. Les tokens de raisonnement sont facturés séparément et n'apparaissent pas dans la sortie visible.
La chaîne de pensée est l'exemple parfait d'une technique dont l'efficacité varie selon le modèle, la tâche et le jeu de test. Avant de l'imposer en production, comparer sur au moins 50 cas la précision avec et sans, ainsi que la latence et le coût. Le résultat est parfois surprenant : sur une tâche que l'on croyait complexe, la version sans chaîne de pensée gagne par sa stabilité.
En résumé
- La chaîne de pensée conditionne la réponse sur les jetons de raisonnement, ce qui aide sur les tâches en plusieurs étapes.
- Elle nuit sur les tâches de reconnaissance directe, et elle rend les erreurs plus convaincantes qu'elles ne sont réellement.
- L'auto-cohérence multiplie le coût par pour gagner quelques points de précision ; à réserver aux enjeux qui le justifient.
- La décomposition en sous-appels est souvent supérieure à une chaîne de pensée dans une consigne monolithique, au prix de la latence.
Module suivant : les sorties structurées, où l'on force le modèle à ne produire qu'un JSON valide conforme à un schéma.