Chain of thought : faire raisonner le modèle étape par étape
Quand une tâche demande plusieurs étapes de calcul ou de déduction, obliger le modèle à poser son raisonnement avant de répondre réduit fortement les erreurs.
Temps de lecture : 12 min | Niveau : Intermédiaire
Ce que tu sauras faire après
- Reconnaître les tâches où le raisonnement étape par étape change vraiment le résultat.
- Écrire un chain of thought libre, guidé ou structuré, selon le besoin.
- Séparer proprement le raisonnement de la réponse finale, pour pouvoir l'ignorer dans ton code.
- Debugger une requête SQL fausse en forçant le modèle à vérifier avant de conclure.
- Éviter de payer du raisonnement inutile sur des tâches simples.
1. Le principe en une phrase
Chain of thought (souvent abrégé CoT, littéralement "chaîne de pensée") veut dire : tu demandes au modèle d'écrire son raisonnement avant d'écrire sa réponse.
Pourquoi ça marche ? Un modèle de langage produit du texte mot par mot. Quand il répond directement, il doit "trouver" la bonne réponse d'un coup. Quand il écrit d'abord son raisonnement, chaque étape intermédiaire devient du texte qu'il peut relire pour produire la suivante. Il se donne un brouillon.
C'est exactement ce que tu fais toi devant un calcul de marge un peu tordu : tu poses les chiffres sur un papier.
2. Attention : en 2026, le contexte a changé
C'est le point que beaucoup de tutoriels ratent.
Sur les modèles Claude récents, la réflexion est intégrée au modèle (adaptive thinking). La documentation Anthropic est explicite : le chain of thought écrit à la main est présenté comme un repli ("Manual chain-of-thought (CoT) prompting as a fallback"), utile surtout quand la réflexion interne est désactivée.
Concrètement :
- Si tu travailles dans Claude Code, l'application Claude, ou via l'API sur un modèle récent : le modèle réfléchit déjà tout seul. Tu n'as pas besoin d'écrire "réfléchis étape par étape" à chaque fois.
- Si tu travailles sur un modèle sans réflexion activée, ou sur un autre fournisseur : le CoT manuel reste une technique de base, et elle marche.
- Dans tous les cas, le CoT guidé (celui où tu imposes les étapes) reste utile, parce qu'il ne sert pas à déclencher le raisonnement mais à imposer ta méthode métier.
La doc ajoute un avertissement pratique : "Prefer general instructions over prescriptive steps". Une consigne comme "réfléchis à fond" produit souvent un meilleur raisonnement qu'un plan que tu aurais écrit toi-même. Garde ça en tête : impose des étapes seulement quand ces étapes sont une règle métier, pas quand tu essaies d'apprendre à réfléchir au modèle.
Détail utile : la doc note que sur Claude Opus 4.5, quand la réflexion est désactivée, le modèle est particulièrement sensible au mot "think" et à ses variantes. Si tu obtiens un comportement bizarre, remplace "think" par "consider", "evaluate" ou "reason through".
3. Quand ça aide vraiment
Utilise le CoT quand la tâche a plusieurs étapes dépendantes et qu'une erreur au milieu casse tout.
| Situation | CoT utile ? | Pourquoi |
|---|---|---|
| Calcul de KPI avec plusieurs filtres et une règle métier | Oui | Chaque filtre dépend du précédent |
| Debug d'une requête SQL qui renvoie un mauvais total | Oui | Il faut isoler la cause parmi plusieurs candidats |
| Choix d'une stratégie de partitionnement BigQuery | Oui | Arbitrage entre plusieurs critères |
| Relecture d'un modèle dbt pour trouver une jointure fan-out | Oui | Il faut suivre la cardinalité table par table |
| Reformater 200 lignes de JSON en CSV | Non | Transformation mécanique, aucune déduction |
| Traduire un commentaire de code en anglais | Non | Une seule étape |
| Classer un ticket en "bug" / "évolution" | Non | Décision atomique |
| Générer un docstring pour une fonction courte | Non | Une seule étape |
La règle simple : si tu es capable de répondre toi-même sans poser de brouillon, le modèle aussi. Pas de CoT.
4. Quand c'est du gaspillage
Le raisonnement n'est pas gratuit. Il est facturé comme des tokens de sortie et il ajoute de la latence.
Trois cas où tu perds de l'argent et du temps :
- Tâches mécaniques. Reformatage, extraction, traduction, renommage. Le modèle va écrire trois paragraphes de réflexion pour appliquer une regexp.
- Tâches à haut volume. Si tu classes 50 000 lignes de logs, multiplier chaque appel par 300 tokens de raisonnement, c'est 15 millions de tokens en plus. Voir le fichier
08-cout-cache-et-performance.md. - Quand tu veux une sortie JSON stricte. Le raisonnement pollue la sortie si tu ne le sépares pas proprement (section 6 de ce fichier). Mieux vaut utiliser les sorties structurées, voir
06-prefill-et-controle.md.
La doc Anthropic donne d'ailleurs un prompt tout fait pour réduire le déclenchement de la réflexion quand elle se déclenche trop souvent :
Thinking adds latency and should only be used when it will meaningfully improve
answer quality - typically for problems that require multistep reasoning. When in
doubt, respond directly.Version française que tu peux coller dans ton prompt système :
Reflechir ajoute de la latence. Ne le fais que si cela ameliore reellement la
qualite de la reponse, typiquement sur des problemes a plusieurs etapes.
En cas de doute, reponds directement.5. Les trois niveaux de CoT
Niveau 1 : CoT libre
Tu laisses le modèle choisir sa méthode.
Analyse cette requete et explique ton raisonnement avant de donner ta conclusion.Quand : exploration, tu ne connais pas encore la bonne méthode. Limite : le raisonnement part parfois dans une direction qui ne t'intéresse pas.
Niveau 2 : CoT guidé
Tu imposes les étapes. C'est le niveau le plus utile au quotidien en data, parce que tes étapes sont souvent des règles métier.
Procede dans cet ordre :
1. Liste les tables utilisees et leur grain (une ligne = quoi ?).
2. Pour chaque jointure, dis si elle est 1-1, 1-n ou n-n.
3. Identifie la jointure qui duplique des lignes.
4. Donne la correction.Quand : tu sais comment il faut raisonner, et tu veux que ce soit fait pareil à chaque fois. Limite : si tes étapes sont mauvaises, le résultat est mauvais. Ne prescris que ce que tu maîtrises.
Niveau 3 : CoT structuré
Tu imposes les étapes et tu encadres le raisonnement dans des balises, pour pouvoir le séparer ensuite.
Ecris ton raisonnement dans <raisonnement>. Ecris uniquement la requete corrigee
dans <sql>. Ne mets aucun commentaire hors de ces deux balises.Quand : ta sortie part dans un script, un pipeline, un fichier. C'est le niveau que tu dois viser dès que le résultat est consommé par du code.
6. Séparer le raisonnement de la réponse finale
C'est le point le plus rentable de ce fichier.
Si tu mets la réponse dans une balise dédiée, tu peux l'extraire en trois lignes de Python sans jamais parser du texte libre.
import re
def extraire(bloc: str, texte: str) -> str:
"""Recupere le contenu d'une balise XML simple dans la reponse du modele."""
motif = rf"<{bloc}>(.*?)</{bloc}>"
trouve = re.search(motif, texte, re.DOTALL)
return trouve.group(1).strip() if trouve else ""
sql_corrige = extraire("sql", reponse_du_modele)
explication = extraire("raisonnement", reponse_du_modele) # pour tes logsTu logges explication pour comprendre plus tard, et tu exécutes sql_corrige. Le raisonnement ne pollue jamais ton pipeline.
Les balises XML sont recommandées par Anthropic pour structurer un prompt : "XML tags help Claude parse complex prompts unambiguously". Le nom de la balise est libre. Choisis des noms descriptifs et garde les mêmes dans tous tes prompts.
7. Exemple 1 : calcul de KPI complexe
Contexte : tu dois calculer un taux de rétention à 30 jours, avec une règle métier maison.
Avant (mauvais prompt)
Calcule le taux de retention a 30 jours sur ma table commandes.Résultat : le modèle invente une définition de la rétention, choisit une fenêtre arbitraire, et te sort un chiffre que tu ne peux pas vérifier.
Après (prompt amélioré)
Tu es data analyst. Calcule le taux de retention a 30 jours.
<regles_metier>
- Un client est "actif au mois M" s'il a au moins 1 commande payee dans M.
- Les commandes annulees (statut = 'CANCELLED') ne comptent pas.
- La cohorte d'un client est le mois de sa PREMIERE commande payee.
- Retention a 30 jours = clients de la cohorte M actifs en M+1 / clients de la cohorte M.
</regles_metier>
<schema>
commandes(commande_id, client_id, date_commande DATE, statut STRING, montant_ht NUMERIC)
</schema>
Procede dans cet ordre, dans <raisonnement> :
1. Ecris la definition de la cohorte en une phrase.
2. Dis quels filtres s'appliquent a quelle etape (cohorte ? activite ? les deux ?).
3. Signale tout piege : doublons, fuseaux horaires, mois incomplets.
Puis donne UNIQUEMENT la requete BigQuery dans <sql>.Pourquoi c'est mieux
- Les règles métier sont explicites, donc le modèle n'invente plus la définition.
- L'étape 2 force le modèle à se poser la question qui fait le plus de dégâts : "le filtre
statuts'applique-t-il au calcul de la cohorte aussi ?". Neuf erreurs sur dix viennent de là. - L'étape 3 fait remonter les pièges avant que tu lances la requête sur 200 Go.
- La sortie est séparée : tu récupères
<sql>directement.
8. Exemple 2 : debugger une requête SQL fausse
Contexte classique : ton total de chiffre d'affaires a doublé depuis hier.
Avant (mauvais prompt)
Cette requete donne un mauvais resultat, corrige-la.
SELECT c.client_id, SUM(l.montant) AS ca
FROM clients c
JOIN commandes o ON o.client_id = c.client_id
JOIN lignes_commande l ON l.commande_id = o.commande_id
JOIN adresses a ON a.client_id = c.client_id
GROUP BY c.client_id;Résultat : le modèle réécrit la requête à sa façon. Tu ne sais toujours pas pourquoi c'était faux, donc tu referas l'erreur.
Après (prompt amélioré)
Cette requete BigQuery renvoie un chiffre d'affaires environ 2x trop eleve.
Je veux comprendre la cause, pas seulement une requete de remplacement.
<requete>
SELECT c.client_id, SUM(l.montant) AS ca
FROM clients c
JOIN commandes o ON o.client_id = c.client_id
JOIN lignes_commande l ON l.commande_id = o.commande_id
JOIN adresses a ON a.client_id = c.client_id
GROUP BY c.client_id;
</requete>
<grains>
clients : 1 ligne = 1 client
commandes : 1 ligne = 1 commande
lignes_commande : 1 ligne = 1 ligne de commande
adresses : 1 ligne = 1 adresse, un client peut en avoir plusieurs
</grains>
Dans <raisonnement>, procede dans cet ordre :
1. Pour chaque jointure, donne la cardinalite (1-1, 1-n, n-n).
2. Dis a quelle jointure le grain se duplique.
3. Ecris la requete de controle qui PROUVE la duplication (un COUNT qui doit
renvoyer plus d'une ligne pour un client donne).
4. Propose deux corrections possibles et dis laquelle tu recommandes.
Puis, dans <sql>, donne uniquement la requete corrigee recommandee.Pourquoi c'est mieux
- Tu donnes le grain de chaque table. C'est l'information sans laquelle personne, humain ou modèle, ne peut diagnostiquer un fan-out.
- L'étape 3 est le cœur du prompt : tu exiges une requête de preuve. Tu ne crois pas le modèle sur parole, tu vérifies en 10 secondes.
- L'étape 4 te laisse la décision finale. C'est toi le responsable du pipeline.
Réflexe à garder : ajoute toujours une étape de vérification. La doc le recommande explicitement : "Ask Claude to self-check. Append something like 'Before you finish, verify your answer against [test criteria].'"
9. Ton template prêt à copier
Template A - CoT structuré générique
Tu es [TON_ROLE, ex: data engineer senior sur BigQuery].
Tache : [DECRIS_LA_TACHE_EN_UNE_PHRASE].
<contexte>
[SCHEMA_DES_TABLES_OU_EXTRAIT_DE_CODE]
</contexte>
<contraintes>
- [REGLE_METIER_1]
- [REGLE_METIER_2]
- [CE_QUI_EST_INTERDIT]
</contraintes>
Dans <raisonnement>, procede dans cet ordre :
1. [ETAPE_1]
2. [ETAPE_2]
3. [ETAPE_3]
4. Verifie ta reponse contre : [CRITERE_DE_VERIFICATION].
Puis donne UNIQUEMENT [LE_LIVRABLE, ex: la requete SQL] dans <resultat>.
N'ecris rien en dehors de ces deux balises.Template B - Diagnostic d'un résultat faux
[LE_CODE_OU_LA_REQUETE] produit [LE_SYMPTOME_OBSERVE, ex: un total 2x trop grand].
Attendu : [LE_RESULTAT_ATTENDU].
<code>
[COLLE_TON_CODE_ICI]
</code>
<contexte_technique>
[GRAIN_DES_TABLES / VERSIONS / VOLUMES]
</contexte_technique>
Dans <raisonnement> :
1. Liste les 3 causes possibles les plus probables, de la plus probable a la moins probable.
2. Pour chaque cause, donne le test qui permet de la confirmer ou de l'ecarter.
3. Dis quelle cause tu retiens et pourquoi.
Dans <test>, donne la requete ou le bout de code qui prouve le diagnostic.
Dans <correction>, donne uniquement la version corrigee.Template C - Désactiver le raisonnement sur une tâche simple
Tache mecanique, pas de raisonnement necessaire.
Reponds directement, sans preambule et sans explication.
[TA_TACHE, ex: convertis ce bloc JSON en CSV avec les colonnes id, date, montant]
<donnees>
[TES_DONNEES]
</donnees>À retenir
- Le CoT sert quand la tâche a plusieurs étapes dépendantes. Sinon c'est du gaspillage de tokens et de latence.
- Sur les modèles Claude récents, la réflexion est déjà intégrée : le CoT manuel est un repli, mais le CoT guidé garde sa valeur parce qu'il impose tes règles métier.
- Trois niveaux : libre, guidé, structuré. Dès que ta sortie part dans du code, utilise le niveau structuré avec des balises XML.
- Sépare toujours
<raisonnement>et<resultat>: tu logges le premier, tu exécutes le second. - Ajoute une étape de vérification explicite. C'est le meilleur rapport effort / erreurs évitées.
- En data, l'information qui débloque tout, c'est le grain de chaque table. Donne-la systématiquement.
Sources
- Prompting best practices - Anthropic
- Thinking - Anthropic
- Steering thinking - Anthropic
- Prompt engineering overview - Anthropic
- Overview of prompting strategies - Google Cloud / Vertex AI (page sommaire : elle renvoie vers "Break down complex tasks" et "Instruct the model to explain its reasoning")
- Chain of thought prompting - Microsoft Learn (.NET) : la même technique, expliquée côté Microsoft. Leur phrase résume bien le principe : "models make more reasoning errors when they try to answer right away rather than taking time to work out an answer".