unlazy : le Depth Tree pour éviter les tâches incomplètes
Découvrez comment unlazy v2.0.0 utilise le Depth Tree, des gates files et PLAN.md pour empêcher un agent de déclarer une tâche terminée trop tôt.
Ce que fait la skill unlazy
La skill unlazy est une skill pour agent conçue pour empêcher un échec précis : un agent de codage qui signale que le travail est terminé alors qu’il ne l’est pas. Son principe repose sur le Depth Tree, une méthode qui divise une tâche en couches et considère uniquement la couche inférieure comme le travail réel. La version 2 a déplacé les contrôles du texte vers des fichiers. L’agent doit donc prouver que le travail est terminé au moyen d’une liste de commandes exécutables, au lieu de l’affirmer.
Elle est publiée par Leonxlnx sur github.com/Leonxlnx/unlazy sous licence MIT. Ce guide porte sur la version 2.0.0, publiée le 2026-08-10. Les skills de ce domaine évoluent rapidement. Consultez donc le CHANGELOG du dépôt avant de copier ces éléments dans une configuration que vous laissez en fonctionnement.
Ici, une skill désigne le mécanisme habituel : un fichier SKILL.md que le harness charge dans le contexte du modèle lorsque la tâche correspond à sa description. Si ce mécanisme vous est inconnu, commencez par ce qu’est une skill d’agent et comment un harness en charge une. unlazy se compose de markdown standard et de quelques scripts Node. Il ne nécessite donc ni serveur ni API key propre.
Pourquoi les agents s’arrêtent à 80 % et ignorent votre troisième instruction
Le comportement suit un schéma reconnaissable. Vous demandez quatre choses. La réponse couvre la première, la deuxième et la quatrième. Le résumé final indique que les quatre sont terminées. Rien n’a généré d’erreur, donc rien ne l’a signalé, et vous découvrez l’omission une semaine plus tard.
Le README d’unlazy s’appuie sur des travaux publiés consacrés à la paresse des modèles. Il cite notamment « l’interruption prématurée des réponses et le respect partiel des demandes en plusieurs parties » (la référence est arXiv 2512.20662). Le même README énonce clairement le principe de conception : du texte ne peut pas imposer du texte. Dire à un agent de faire davantage d’efforts ajoute du texte au même contexte que celui qui a produit le manquement.
C’est pourquoi la version 2 conserve son état dans des fichiers. Une case à cocher dans GATES.md se trouve en dehors du contrôle du modèle. Soit la case contient une ligne de preuve en dessous, soit elle n’en contient pas, et un script peut vous indiquer laquelle sans interroger l’agent.
L’arbre de profondeur, couche par couche
L’arbre de profondeur est une décomposition assortie d’une règle sur l’endroit où le travail peut être effectué. Extrait de la référence de la méthode :
Découpez aux articulations naturelles, en binaire lorsque ces articulations le permettent, sur N couches de profondeur.
Les feuilles sont les seuls endroits où le travail réel est effectué ; toutes les couches situées au-dessus servent à la décomposition et à l’intégration.
Une feuille est plus importante qu’un élément de liste. La référence fixe une taille minimale :
Une feuille est une véritable unité de travail. Au moins dix minutes d’effort concentré, un livrable cohérent, un seul fichier de validation.
Cette limite empêche un arbre profond de se transformer en travail artificiel. Si une feuille indique « renommer la variable », elle ne respecte pas le critère et la division précédente comporte une couche de trop.
Chaque feuille passe ensuite par quatre étapes : l’implémenter entièrement sans emplacement réservé, la relire comme le ferait un expert du domaine, rechercher les défauts, puis la finaliser lorsque cette finition est gratuite. Ces étapes sont une autre raison pour laquelle une feuille doit respecter une taille minimale. Effectuer quatre étapes sur une modification de deux minutes n’est qu’une mise en scène.
Vous choisissez la profondeur lorsque vous invoquez la compétence :
/unlazy tree 5 refactor the payment moduleLe langage naturel fonctionne également, car la description de la compétence fait correspondre l’intention plutôt qu’une commande slash :
tree 3 build the landing page and do not stop until every gate is checkedLa référence définit plusieurs plages de profondeur. Un arbre de niveau 2 ou 3 correspond à une fonctionnalité, à une recherche de bugs ou à un document, traité seul en une session sur 2 à 4 feuilles. Un arbre de niveau 4 ou 5 correspond à un sous-système, à une refactorisation ou à une revue sérieuse, avec 8 à 16 feuilles, ce qui dépasse « ce qu’un seul contexte peut gérer correctement ». Un arbre de niveau 6 ou 7 correspond à un projet complet, exécuté en mode orchestré, avec des feuilles associées à des unités de travail disjointes.
Si vous ne précisez aucune profondeur, la compétence doit « choisir le plus petit N dont les feuilles correspondent aux parties naturelles de la tâche » et reçoit explicitement l’instruction de ne pas ajouter une couche par défaut. La profondeur décrit le travail ; augmenter le nombre n’améliore pas la qualité.
À quoi ressemble un fichier de gates
Avant tout travail, l’agent écrit les critères d’acceptation dans un fichier de gates. Chaque gate est une case à cocher accompagnée d’une commande.
# Gates: pricing section
- [ ] G1: three tiers render with real copy
CHECK: node check.js pricing --tiers
EXPECT: 3/3 tiers ok
EVIDENCE: pending
- [ ] G2: annual toggle changes both price and label
CHECK: node check.js pricing --toggle
EXPECT: toggle ok
EVIDENCE: pendingCHECK correspond à la commande. EXPECT correspond à la sortie qui valide le gate. EVIDENCE commence par pending et doit être remplacé par ce que la commande a réellement affiché. La skill fournit scripts/gate-check.mjs pour analyser ces fichiers et indiquer quels gates sont encore ouverts. Vous pouvez ainsi auditer une exécution sans lire la transcription.
La philosophie tient en une ligne, que SKILL.md écrit sur une seule ligne :
Un rapport est un ensemble d’affirmations étayées par un ledger, jamais une impression d’avoir terminé.
La règle qui en découle est la suivante : « aucun rapport tant que le ledger n’est pas complet ». Elle s’accompagne d’une règle de reporting : chaque nombre d’un récapitulatif final doit être remesuré au moment du rapport ou être indiqué comme non vérifié. Un gate ne peut pas être fermé parce que l’agent estime avoir terminé. Le fermer consiste à coller une sortie qui correspond à EXPECT ou qui n’y correspond pas.
Écrivez des gates qu’une personne extérieure pourrait exécuter. « Tout semble correct » n’est pas un contrôle. test -s dist/index.html && echo ok qui affiche ok constitue un contrôle, car la commande échoue clairement si le fichier est vide ou absent.
Le contrat de PLAN.md avant tout travail en parallèle
Lorsqu’un arbre est suffisamment large pour que ses feuilles s’exécutent dans des contextes distincts, ces feuilles ne partagent plus les mêmes hypothèses. La méthode de référence place un contrat avant la répartition du travail :
Les contrats précèdent la répartition. Les interfaces, la propriété des données, les conventions de nommage et de gestion des erreurs sont consignées dans PLAN.md avant le démarrage de toute feuille.
La raison est concrète. Deux sous-agents auxquels on demande chacun « d’ajouter la gestion des erreurs » vont inventer deux formats d’erreur différents. Leurs feuilles franchiront toutes deux leurs propres contrôles, car chacune est correcte localement. L’échec n’apparaîtra qu’au moment où elles seront réunies. Les contrôles de branche servent précisément à cela : ils vérifient que « les enfants ont été fusionnés, que les interfaces correspondent, que le comportement de bout en bout fonctionne et qu’aucune régression n’affecte les autres branches ».
En mode orchestré, le pilote transmet à chaque sous-agent la section contractuelle de PLAN.md, et non le fichier complet ni l’historique propre au pilote, ainsi que le fichier de contrôles de cette feuille, tel quel. Lorsque le sous-agent revient, le pilote exécute lui-même les vérifications une nouvelle fois. Un sous-agent qui a « coché ses propres cases sans fournir de preuve » est renvoyé avec la liste précise des contrôles non satisfaits.
L’orchestration a un seuil minimal. Pour une tâche représentant moins d’environ une demi-heure de travail réel, la référence recommande de rester seul, car chaque sous-agent doit reconstruire sa compréhension de la tâche depuis le début. Cette préparation coûte alors plus cher que le gain apporté par une attention renouvelée.
Comment installer la compétence unlazy ?
La méthode prise en charge consiste à utiliser la CLI skills :
npx skills add Leonxlnx/unlazyL’installation manuelle consiste à cloner le dépôt dans le répertoire skills de votre agent :
git clone https://github.com/Leonxlnx/unlazy ~/.claude/skills/unlazygit clone https://github.com/Leonxlnx/unlazy ~/.codex/skills/unlazyVérifiez ensuite que le fichier a bien été copié :
ls ~/.claude/skills/unlazy/SKILL.mdLe chemin affiché signifie que le fichier est bien présent sur le disque. No such file or directory signifie que le clone a été effectué ailleurs, généralement parce que le répertoire skills n’existait pas sous le nom que vous aviez indiqué et que git en a créé un nouveau. Ne vous fiez pas non plus aux déclarations de l’agent. L’invite d’installation du README se termine par le même avertissement : « Ne dites pas que c’est installé tant que vous n’avez pas réellement vérifié que le fichier est présent sur le disque. »
Avec un harness sans chargeur de skills, collez le contenu de SKILL.md dans le system prompt ou dans le fichier de règles. C’est la solution de repli documentée. C’est pourquoi cette méthode fonctionne avec Claude Code, Codex, Cursor et tout autre outil qui lit un fichier d’instructions Markdown standard. Si vous voulez savoir ce qui permet à un fichier SKILL.md de se charger correctement, écrire votre propre compétence d’agent explique le frontmatter et la correspondance de description qui déterminent si la compétence se déclenche.
Le hook Stop fonctionne-t-il en dehors de Claude Code ?
Non. C’est le point à préciser. Tout ce qui précède correspond à des instructions, et les instructions peuvent être ignorées. Le seul mécanisme d’application structurel est un hook Stop, qui est une fonctionnalité de Claude Code.
node <path-to-skill>/scripts/install-hooks.mjs # this project only (settings.local.json)
node <path-to-skill>/scripts/install-hooks.mjs --global # every project
node <path-to-skill>/scripts/install-hooks.mjs --uninstallUn hook Stop s’exécute au moment où l’agent tente de terminer son tour. Celui-ci analyse les fichiers de gates et bloque l’arrêt tant que les gates ne sont pas satisfaites. Le tour ne peut donc pas se terminer avec une case non vérifiée. Il lit les fichiers et n’effectue aucun appel au modèle, ce qui explique pourquoi le README indique qu’il coûte zéro token. Pour le mécanisme général et les autres événements auxquels vous pouvez l’attacher, consultez le fonctionnement des hooks Claude Code autour d’un tour.
Il comporte une soupape de sécurité, dont l’importance est plus grande qu’il n’y paraît. Si l’agent ne progresse pas du tout sur les gates pendant six arrêts bloqués consécutifs, le hook le laisse continuer avec un avertissement au lieu de le bloquer indéfiniment. Une ligne ABANDON: <gate> <reason> est toujours respectée et permet une sortie explicite. Sans ces deux échappatoires, une gate impossible à satisfaire dans votre environnement consommerait des tokens jusqu’à ce que vous arrêtiez vous-même la session.
Dans Codex, Cursor ou tout autre harness, install-hooks.mjs n’a rien dans lequel s’installer. Vous disposez toujours du fichier de gates et des contrôles exécutables, mais rien n’empêche structurellement le modèle de terminer prématurément son tour. Dans ce cas, le fichier de gates est un document que vous devez lire.
unlazy ou ponytail : lequel voulez-vous ?
Ces deux compétences ont été mises en avant au cours de la même période et tirent dans des directions opposées concernant le volume de travail, ce qui les rend faciles à confondre.
ponytail fait agir l’agent comme un développeur senior dont la première question est de savoir si le code doit réellement exister. Il réduit le périmètre, privilégie la bibliothèque standard et diminue le diff. unlazy part du principe que le périmètre est déjà défini et augmente l’effort jusqu’à ce que chaque partie soit terminée et vérifiée.
Choisissez donc en fonction du problème que vous observez réellement. Si votre agent transforme une petite fonctionnalité en framework, vous voulez la compétence ponytail et sa persona de développeur senior adepte de la simplicité. Si votre agent laisse le troisième élément d’une demande en quatre parties inachevé, puis signale que tout est terminé, vous voulez unlazy.
Vous pouvez exécuter les deux, mais l’ordre compte. Définissez d’abord le périmètre avec la question de ponytail, puis transmettez ce périmètre validé aux gates d’unlazy. Dans l’autre sens, vous construisez un arbre de feuilles pour un travail que ponytail aurait supprimé, puis vous appliquez le multiplicateur de profondeur à l’ensemble. Cet ordre est ma recommandation, et non une intégration documentée entre les deux projets.
Quel est le coût de la profondeur pour un agent hébergé sur un VPS ?
La profondeur multiplie l’effort, et l’effort se mesure en tokens. Sur un VPS qui exécute un agent avec votre propre clé d’API, ce multiplicateur représente un coût financier.
The data behind this chart
[
{
"label": "Skill run vs no skill, output tokens",
"low_multiplier": 1.6,
"high_multiplier": 3.9
},
{
"label": "tree 6 vs tree 3, total cost",
"low_multiplier": 1.0,
"high_multiplier": 1.5
}
]Ces chiffres proviennent des propres tests des auteurs, datés du 2026-08-10. Nous ne les avons pas reproduits. Considérez-les donc comme une tendance et non comme une prévision. La discipline en mode solo a porté la production à environ 1.6 à 3.9 fois la valeur de référence, tandis que le passage de l’arbre 3 à l’arbre 6 dans un même contexte n’a ajouté que 1.0 à 1.5 fois cette valeur, très loin des huit fois attendues après trois divisions binaires supplémentaires.
Une plus grande profondeur n’est pas proportionnellement plus coûteuse, car elle redistribue l’effort au lieu d’ajouter des contextes. La référence sur l’économie des tokens indique clairement où se trouve le véritable multiplicateur : « Ce qui multiplie le coût, c’est l’orchestration. Elle doit le multiplier, car chaque feuille crée un nouveau contexte. » Le mode solo multiplie les tokens produits dans un même contexte. Le mode orchestré multiplie les contextes, et chaque nouveau contexte relit le contrat et son fichier de règles avant d’effectuer la moindre tâche utile.
Il existe un second coût facile à manquer, que la même référence mentionne également. Lors d’une seule exécution profonde et monolithique, leur test a « consommé environ 58 millions de tokens d’entrée mis en cache », car un contexte unique, qui ne cessait de grandir, conservait toutes les informations. L’entrée mise en cache coûte moins cher par token, mais ce volume apparaît malgré tout sur la facture.
Quatre paramètres en découlent :
- Choisissez la plus petite profondeur dont les feuilles correspondent à de véritables unités de travail, puis arrêtez-vous. Une profondeur inutile représente une dépense inutile.
- Restez en mode solo pour les tâches de moins d’une demi-heure, car la préparation des sous-agents coûte plus cher que le bénéfice apporté par le nouveau contexte.
- Installez le hook Stop si vous utilisez Claude Code. C’est le seul élément de cette configuration qui s’exécute gratuitement.
- Définissez un plafond de dépense strict au niveau du compte avant de lancer une tâche longue.
Ce dernier point est le plus important. Une compétence conçue pour refuser les arrêts précoces est, par conception, une compétence qui continue à travailler. Les budgets et les alertes constituent une tâche distincte du prompting, et garder le coût d’un agent sous contrôle sur un VPS présente les plafonds à mettre en place en priorité.
Ce que les auteurs ont mesuré et ce que cela prouve
Le dépôt publie son propre test, ce qui est plus rare que cela ne devrait l’être. Voici leur configuration, reprise du README : « deux tâches de build réalisées from scratch (un site marketing et un système solaire en three.js), trois conditions pour chacune (sans skill, tree 3, tree 6), un dossier vierge et une session vierge par exécution, le même modèle et le même corps de prompt. Chaque résultat a été vérifié par des agents indépendants lors d’une revue de code, revérifié de manière adversariale, puis testé en direct dans un navigateur. »
The data behind this chart
[
{
"label": "Self-found defects fixed, skill runs",
"low_count": 4,
"high_count": 10
},
{
"label": "Wrong numbers in report, skill runs",
"low_count": 1,
"high_count": 3
},
{
"label": "Wrong numbers in report, baseline runs",
"low_count": 0,
"high_count": 0
}
]Relisez deux fois la ligne du milieu. Dans le test des auteurs, le skill exécute systématiquement 4 à 10 contrôles que l’agent a trouvés seul avant la livraison. Chaque exécution du skill a ensuite livré un rapport final contenant 1 à 3 chiffres erronés, contre 0 dans les exécutions de référence. Davantage de travail a produit de meilleurs builds et de moins bons résumés. C’est le constat qui justifie la règle du ledger, ainsi que l’instruction de mesurer à nouveau chaque chiffre au moment de rédiger le rapport ou de le marquer comme non vérifié.
Un autre résultat mérite d’être retenu : « Le seul échec live réel concernait un build de référence, et son rapport affirmait que le cas avait été traité. » Un résumé affirmatif au-dessus d’un build défaillant correspond exactement au problème que les gates doivent détecter.
Passons maintenant aux limites. Six exécutions, deux tâches de build, un modèle, le tout exécuté et rapporté par l’auteur du skill. Rien ici ne constitue une réplication indépendante, et nous citons les affirmations des auteurs telles qu’elles se présentaient au 2026-08-10. Testez plutôt la méthode sur votre propre travail : exécutez deux fois la même tâche, une fois sans configuration particulière et une fois avec un fichier de gates, puis comptez les gates qui se sont fermées avec des éléments de preuve que vous pouvez vous-même réexécuter. Ce compte est le seul chiffre de ce domaine qui vous appartient.
FAQ
Qu’est-ce que le Depth Tree du skill unlazy ?
Il s’agit d’une méthode de décomposition. Une tâche se divise à ses articulations naturelles sur N niveaux, et seuls les nœuds feuilles du niveau inférieur comptent comme du travail. Le skill définit une feuille comme au moins dix minutes d’effort concentré, avec un livrable cohérent et un fichier gates. Si vous pouvez terminer une feuille en deux minutes, la division est descendue d’un niveau de trop. Chaque niveau au-dessus des feuilles correspond à la décomposition et à l’intégration, et chaque branche possède ses propres gates pour prouver que les enfants ont été fusionnés et que les interfaces correspondent. Vous choisissez la profondeur lors de l’appel, par exemple tree 5, et la valeur par défaut documentée est la plus petite profondeur dont les feuilles constituent de véritables unités de travail.
Le skill unlazy fonctionne-t-il en dehors de Claude Code ?
Partiellement. Le skill est en markdown brut. Codex, Cursor et tout outil qui lit un fichier SKILL.md ou un system prompt peuvent donc utiliser le Depth Tree, le fichier gates, les vérifications exécutables et les quatre passes par feuille. Le contrôle strict est différent. Le hook Stop, qui bloque la fin d’un tour tant que les gates ne sont pas satisfaites, est une fonctionnalité de Claude Code, installée avec node <path-to-skill>/scripts/install-hooks.mjs. Ailleurs, rien n’empêche structurellement le modèle de terminer prématurément son tour. C’est donc vous qui devez lire le fichier gates et le lui renvoyer.
Quel impact le skill unlazy a-t-il sur ma consommation de tokens ?
Les auteurs indiquent une consommation de 1.6 à 3.9 fois supérieure à celle d’une exécution sans skill en mode solo, en plus de quelques centaines de tokens pour le fichier gates lui-même. Approfondir l’arbre dans un même contexte est presque gratuit en comparaison : comptez environ 1.0 à 1.5 fois plus en passant de l’arbre 3 à l’arbre 6. Le mode orchestré est le plus coûteux, car chaque feuille ouvre un nouveau contexte qui relit le contrat et ses gates avant de travailler. Le hook Stop n’ajoute rien, puisqu’il se contente d’analyser des fichiers. Ces chiffres sont ceux des auteurs au 2026-08-10, et non des mesures que nous avons répétées.
Dois-je utiliser unlazy ou ponytail ?
Adaptez le skill au problème rencontré. ponytail s’utilise avec un agent qui écrit trop, car il joue le rôle d’un développeur senior qui demande si le code doit réellement exister et privilégie d’abord la bibliothèque standard. unlazy s’utilise avec un agent qui termine une trop petite partie de ce que vous avez demandé, car il impose la décomposition et refuse de fermer une gate sans preuve. Si vous voulez utiliser les deux, définissez d’abord le périmètre avec ponytail, puis transmettez ce périmètre à unlazy. Vous ne payez ainsi jamais un multiplicateur d’effort pour du travail qui aurait dû être supprimé.
Pourquoi mon agent s’arrête-t-il encore prématurément après l’installation de unlazy ?
Vérifiez quatre points. Premièrement, confirmez que le skill est bien présent sur le disque avec ls ~/.claude/skills/unlazy/SKILL.md, car le cas le plus fréquent est un clone vers un répertoire inexistant. Deuxièmement, confirmez qu’un fichier gates a été créé avant le début du travail. Le hook analyse les fichiers gates, et l’absence de GATES.md ne lui laisse rien à bloquer. Troisièmement, vérifiez où le hook a été installé. L’exécution simple de install-hooks.mjs écrit uniquement dans le settings.local.json de ce projet. Pour un autre projet, vous devez utiliser --global. Quatrièmement, gardez à l’esprit que le mécanisme de déblocage fonctionne comme prévu : six arrêts bloqués consécutifs sans progression d’une gate permettent à l’agent de continuer avec un avertissement, et une ligne ABANDON: <gate> <reason> met volontairement fin à la tentative.