L'agent gère lui-même sa progression
« L'agent peut suivre sa propre progression — et je peux la voir. » Laissez le modèle dresser sa liste, puis un petit mécanisme lui rappelle de la tenir à jour.
La planification structurée de soi
Quand Claude Code travaille sur une tâche complexe — grep pour trouver des références, lire plusieurs fichiers, modifier le code, lancer les tests — si on le laisse « avancer au feeling », les premières étapes sont bonnes, puis il commence à oublier et finit par s'arrêter en chemin.
La solution de s03 : lui donner un outil liste de tâches. Le modèle appelle lui-même l'outil todo pour y ajouter des items ; TodoManager valide la structure, persiste l'état et retourne la vue courante. Deux bénéfices :
- Le modèle est obligé de rendre explicite ce qu'il doit faire — le seul fait de l'écrire clarifie déjà sa réflexion.
- L'humain peut voir ce qu'il pense. L'expérience de débogage est dix fois meilleure.
# Vue TODO — chaque item est structuré [ ] #1: grep "TODO" across src/ [>] #2: read src/app.py and list comments # en cours [ ] #3: generate summary markdown [ ] #4: write to TODO_LIST.md (0/4 completed)
Une règle stricte : un seul in_progress à la fois
TodoManager.update() inclut une validation :
if in_progress_count > 1: raise ValueError("Only one task can be in_progress at a time")
Cela semble strict, mais c'est en réalité une aide. Si plusieurs tâches peuvent être « en cours » simultanément, le modèle s'éparpille et n'en finit aucune. La contrainte d'une seule tâche active l'oblige à terminer chaque item avant de passer au suivant.
Le widget ci-dessous vous permet de jouer le rôle du modèle : soumettez différents payloads todo et observez lesquels passent la validation, lesquels sont rejetés.
Nag reminder : 3 tours sans mise à jour ? Une piqûre.
Même avec l'outil todo, le modèle « oublie » parfois de mettre à jour sa liste — il a accompli beaucoup de choses, mais le in_progress reste bloqué à l'item 2. La technique de s03 : un compteur tout simple.
rounds_since_todo = 0 while True: response = LLM(messages, tools) ... used_todo = any(b.name == "todo" for b in tool_uses) rounds_since_todo = 0 if used_todo else rounds_since_todo + 1 if rounds_since_todo >= 3: results.append({"type":"text", "text":"<reminder>Update your todos.</reminder>"})
Au bout de 3 tours, un reminder est glissé dans le prochain message utilisateur. Le modèle le voit et va instinctivement mettre à jour son todo. C'est une façon de transformer une contrainte douce (« pensez à mettre à jour ») en stimulus fort grâce à l'ingénierie.
Comment s'appelle cette technique ?
Dans la communauté agent, on parle de structured self-planning with soft nudges — fournir au modèle un état structuré qu'il doit maintenir, complété par des reminders opportuns. Le vrai code de Claude Code utilise un pattern similaire, mais plus discret (fréquence plus faible, formulation neutre).
Pourquoi ne pas simplement écrire « mettez à jour le todo à chaque étape » dans le system prompt ? On peut, mais l'obéissance du modèle aux instructions génériques du system prompt se dégrade au fur et à mesure que la conversation s'allonge. Fragmenter la directive en reminders injectés régulièrement donne un effet bien plus stable.