unlazy : méthode Depth Tree pour agents de code
Découvrez comment unlazy évite qu’un agent déclare le travail terminé trop tôt avec le Depth Tree, les fichiers gates, le contrat PLAN.md et son coût en profondeur.
Ce que fait la skill unlazy
La skill unlazy est une skill d’agent conçue pour empêcher un échec précis : un agent de programmation qui déclare le travail terminé avant qu’il le soit réellement. Son principe repose sur le Depth Tree, une méthode qui découpe une tâche selon ses limites réelles et attribue à chaque feuille ses propres critères d’acceptation. La version 2 déplace 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. Il n’existe aucune release marquée à utiliser comme référence : au 2026-10-11, les listes de tags et de releases du dépôt sont toutes deux vides. Ce guide a d’abord été rédigé à partir du milestone source 2.0.0 daté du 2026-08-10. Le 2026-10-11, nous l’avons vérifié à nouveau avec le code source actuel de la branche main. Le CHANGELOG qualifie ce code de « Unreleased, target 2.1.0 » et précise qu’il ne revendique ni tag Git ni GitHub Release pour la version 2.1.0. Exécuter aujourd’hui la commande d’installation vous procure ce code source plus récent, et non la version 2.0.0. Les skills de ce domaine évoluent rapidement. Consultez donc le CHANGELOG du dépôt avant de copier ces éléments dans une installation que vous laissez en fonctionnement.
Ici, une skill désigne le concept 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 est nouveau pour vous, commencez par ce qu’est une skill d’agent et comment un harness en charge une. unlazy est composé de markdown standard et de quelques scripts Node. Il n’a donc besoin ni d’un serveur ni de sa propre clé API.
Pourquoi les agents s’arrêtent à 80 % et ignorent votre troisième instruction
Ce comportement suit un schéma identifiable. Vous demandez quatre choses. La réponse traite la première, la deuxième et la quatrième. Le résumé final indique que les quatre sont terminées. Aucune erreur n’a été signalée, donc rien ne l’a détecté, et vous découvrez l’omission une semaine plus tard.
Le README d’unlazy s’appuie sur des travaux publiés consacrés à la tendance des modèles à produire des réponses incomplètes. Il cite arXiv 2512.20662, qui montre que « les prompts détaillés comportant plusieurs éléments restent sujets à une exécution partielle et à une troncature prématurée avec les modèles testés ». L’état de référence des gates expose clairement le principe de conception : « Les règles ci-dessus sont en prose, et la prose est la couche que ce projet considère déjà comme la plus fragile. » Demander à un agent de faire davantage d’efforts ajoute simplement de la prose au même contexte que celui qui a produit l’omission.
C’est pourquoi la version 2 conserve son état dans des fichiers. Une case à cocher dans GATES.md échappe à la discrétion du modèle. Soit la gate contient des éléments justificatifs, soit elle n’en contient pas. Un script peut vous l’indiquer sans interroger l’agent.
L’arbre de profondeur, couche par couche
L’arbre de profondeur décompose le travail en appliquant une règle sur l’emplacement autorisé des divisions. Extrait de la référence de méthode :
Divisez uniquement aux véritables limites de domaine, de composant ou de vérification. Les divisions binaires sont facultatives.
Faites de la couche 1 la tâche demandée.
Les feuilles portent les livrables. Chaque couche supérieure intègre et vérifie les éléments renvoyés par ses enfants.
Une feuille est plus importante qu’un élément de liste. La référence la dimensionne selon le résultat, et non selon la durée :
Faites de chaque feuille un livrable cohérent.
Fusionnez les petites feuilles adjacentes ; divisez une feuille qui dissimule plusieurs résultats indépendants.
Cette règle empêche un arbre profond de se transformer en travail de façade. Si une feuille indique « renommer la variable », elle ne passe pas le test et la division précédente est allée une couche trop loin.
Chaque feuille passe ensuite par quatre étapes : implémentez-la complètement, sans placeholder ; relisez-la comme le ferait un expert du domaine ; recherchez les défauts ; puis appliquez les améliorations peu coûteuses. Répétez jusqu’à ce qu’un passage d’amélioration complet ne trouve plus rien. Ces étapes expliquent aussi pourquoi il faut fusionner les feuilles trop petites. Effectuer quatre passages sur une modification de deux minutes relève de la mise en scène.
Vous choisissez la profondeur lorsque vous appelez la skill :
/unlazy tree 5 refactor the payment moduleLe langage courant convient également, car la description de la skill fait correspondre l’intention plutôt qu’une slash command :
tree 3 build the landing page and do not stop until every gate is checkedLes versions précédentes de ce guide associaient des fourchettes de profondeur à un nombre de feuilles pour chaque profondeur. La référence de méthode actuelle ne contient aucun nombre de feuilles et indique : « Ne considérez pas la profondeur comme une promesse arithmétique concernant l’effort ou le nombre de tokens. » Il ne reste que les indications qualitatives : « Utilisez un arbre peu profond ou un registre solo pour une fonctionnalité, une recherche de bug limitée ou un document. » Un arbre orchestré convient aux cas où plusieurs livrables cohérents bénéficient de contextes vierges ou d’une prise en charge indépendante. Un arbre plus profond n’est justifié que lorsque ses branches supplémentaires correspondent à de véritables limites d’intégration.
Si vous n’indiquez aucune profondeur, la référence demande de « choisir le plus petit arbre qui expose chaque livrable indépendant et chaque point d’intégration ». Si vous indiquez un nombre inadapté au travail, elle demande à l’agent de le signaler au lieu de remplir l’arbre artificiellement : « Si la profondeur demandée crée des feuilles de remplissage, indiquez cette inadéquation et utilisez la décomposition honnête la plus proche. » La profondeur décrit le travail ; augmenter artificiellement le nombre de couches n’améliore donc 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 est la commande. EXPECT est la sortie qui valide le contrôle, et la commande doit également se terminer avec le code 0. EVIDENCE commence à pending. Après une exécution réussie, le checker le remplit avec une empreinte de sortie au lieu de la sortie brute. Une gate manuelle n’a pas de commande : vous devez donc y consigner le fait minimal qui prouve le résultat. La skill fournit scripts/gate-check.mjs pour cela. Avec --status, elle indique quelles gates sont encore ouvertes sans exécuter de commande ni modifier de fichier. Vous pouvez ainsi auditer une exécution sans lire la transcription. Elle n’exécute les commandes du ledger que si vous passez --approve. Lisez donc chaque commande et chaque script appelé avant de le passer. Un scripts/gate-lint.mjs distinct vérifie la qualité d’un ledger sans rien exécuter.
La règle de reporting de SKILL.md tient en une ligne :
Ne composez pas de rapport de fin tant qu’une gate requise n’est pas satisfaite, a été abandonnée, différée ou reste en attente d’une décision du responsable.
L’agent reçoit également l’instruction suivante : « remesurez chaque nombre et chaque affirmation de complétude immédiatement avant le reporting ». Une gate ne peut pas être fermée parce que l’agent estime avoir terminé. Sa fermeture exige une exécution dont la sortie correspond à EXPECT ou n’y correspond pas.
Écrivez des gates qu’une personne extérieure pourrait exécuter. « Ça semble correct » n’est pas un contrôle. test -s dist/index.html && echo ok qui affiche ok est un contrôle, car il échoue explicitement si le fichier est vide ou absent.
Le contrat du PLAN.md avant tout travail en parallèle
Lorsque l’arborescence devient suffisamment large pour que les feuilles s’exécutent dans des contextes distincts, ces feuilles ne partagent plus les mêmes hypothèses. La référence de méthode place un contrat avant la répartition du travail : « Fix contracts before fan-out. » Le plan répertorie chaque résultat requis dans PLAN.md, « puis consigne les interfaces, les formats, les hypothèses partagées, les conventions d’erreur, les règles de nommage et la propriété avant le démarrage d’une feuille ».
La raison est concrète. Deux subagents auxquels on demande chacun « d’ajouter la gestion des erreurs » vont inventer deux formats d’erreur différents. Leurs feuilles passent toutes deux leurs propres contrôles, car chacune est correcte localement. L’échec n’apparaît qu’au moment où elles interagissent. Ce point d’interaction relève de la couche supérieure. La référence de l’orchestration l’indique clairement : « Reverify the children, then run interface, end-to-end, and regression checks. »
En mode orchestré, il est demandé au pilote de « Give each leaf only the shared contract, its exact ownership and dependencies, its own ledger » et de « not leak unrelated leaf histories ». Le ledger de chaque feuille déclare les chemins qu’elle peut modifier. Ces chemins OWNS ne doivent chevaucher aucun chemin d’une autre feuille exécutée au même moment. Lorsqu’un subagent revient, le pilote doit « re-run the returned leaf's runnable gates, including already checked gates », car --status seul ne constitue pas une nouvelle vérification. Une feuille dont les cases ont été cochées sans preuve réelle ne passe pas cette nouvelle exécution.
L’orchestration a une limite minimale. La référence de l’orchestration indique : « Stay solo when one focused context can implement and verify the task without hiding independent deliverables. » Chaque subagent doit reconstruire seul sa compréhension de la tâche. Pour une petite tâche, cette préparation coûte donc plus qu’elle ne rapporte en attention supplémentaire.
Comment installer la skill unlazy ?
La méthode prise en charge utilise la CLI skills :
npx skills add Leonxlnx/unlazyAjoutez -g pour une installation au niveau utilisateur, ou --all pour l’installer pour tous les agents détectés par la CLI. Cette commande installe le contenu présent sur main à ce jour. Il n’existe aucune release taguée. Le README vous recommande donc d’épingler un commit précis si vous avez besoin d’une installation qui ne changera pas sans avertissement.
L’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é installé :
ls ~/.claude/skills/unlazy/SKILL.mdLe chemin affiché confirme que le fichier se trouve 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 attendu et que git en a créé un nouveau. Ne vous fiez pas non plus à la réponse de l’agent. Un agent qui indique que la skill est installée ne vous a pas montré le fichier. Le checker et le hook optionnel nécessitent Node 16 ou une version ultérieure. Ils n’utilisent aucun package runtime tiers.
Au 2026-10-11, le README documente deux harnesses : Claude Code, avec lequel vous appelez la skill à l’aide de /unlazy, et Codex CLI, avec lequel vous utilisez $unlazy. Il ne documente aucune méthode pour les harnesses sans skill loader. Coller SKILL.md dans le fichier de règles d’un autre outil n’est donc pas testé. Pour comprendre ce qui permet à un SKILL.md d’être chargé de manière fiable, consultez écrire votre propre skill d’agent. Cette section explique le frontmatter et la correspondance de description qui déterminent si la skill est déclenchée.
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 de contrôle structurel est un hook Stop, 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 le ledger de la session en cours et l’état de dispatch, puis 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 n’exécute pas les contrôles et n’effectue aucun appel de modèle de son côté. Il n’est toutefois pas gratuit. La documentation de référence sur l’économie de tokens précise que « A block causes another agent continuation, which does consume model work. » Pour comprendre 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. Le README vous demande d’installer le hook uniquement avec l’accord de l’utilisateur. Il vous demande également d’ajouter .claude/settings.local.json, .unlazy/ et .unlazy-hook-state.json à vos règles d’exclusion.
Il dispose d’une soupape de sécurité, dont l’importance est réelle. Si l’agent ne fait aucun progrès sur les gates pendant six arrêts bloqués consécutifs, le hook le laisse continuer au lieu de le piéger. Les modifications qui concernent uniquement les métadonnées ne réinitialisent pas ce compteur. Une ligne ABANDON: <gate> <reason> permet également de terminer la session, mais sous la forme d’un transfert visible plutôt que d’une validation. La gate abandonnée est signalée comme un résultat non réussi, et non comme un travail terminé. Sans ces deux mécanismes de sortie, une gate impossible à satisfaire dans votre environnement consommerait des tokens jusqu’à ce que vous arrêtiez vous-même la session.
Dans Codex ou dans tout autre harness, install-hooks.mjs n’a rien dans lequel s’installer, car il écrit uniquement des fichiers de paramètres Claude. Vous disposez tout de même du fichier des gates et des contrôles exécutables. En revanche, aucun mécanisme structurel n’empêche le modèle de terminer prématurément son tour. Dans ce cas, le fichier des gates est un document que vous devez lire.
unlazy ou ponytail : lequel voulez-vous ?
Ces deux skills ont connu un engouement 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à validé et pousse l’effort jusqu’à ce que chaque partie soit terminée et vérifiée.
Choisissez donc en fonction du problème que vous rencontrez réellement. Si votre agent transforme une petite fonctionnalité en framework, vous voulez le skill ponytail et son persona de développeur senior adepte de la simplicité. Si votre agent laisse inachevé le troisième élément d’une demande en quatre parties, puis signale la réussite, 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 le périmètre validé aux gates d’unlazy. Dans l’autre sens, vous construisez un arbre de feuilles pour du travail que ponytail aurait supprimé, puis vous payez l’effort supplémentaire pour 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 ?
L’effort se mesure en tokens et, sur un VPS qui exécute un agent avec votre propre clé API, les tokens coûtent de l’argent. Le projet ne donne désormais plus de chiffre pour indiquer combien unlazy en ajoute.
Les versions précédentes de ce guide présentaient des multiplicateurs de tokens de sortie et de coût issus de la comparaison en six exécutions réalisée par les auteurs. Ceux-ci ont depuis retiré ces chiffres. Le fichier references/token-economy.md indique maintenant que les prompts bruts, les traces, les sorties et les enregistrements d’évaluation qui les étayaient ne sont plus présents dans le dépôt, « so those numbers are not reproducible here », puis ajoute : « Do not use them as product guarantees. » La référence méthodologique va plus loin : « Do not treat depth as an arithmetic promise about effort or tokens. » Nous avons supprimé ces chiffres plutôt que de répéter des valeurs que leurs propres auteurs ne cautionnent plus.
Ce que la référence indique encore sur le coût reste de l’ordre de grandeur. Son conseil initial est le suivant : « Move repeated, deterministic verification into commands and keep orchestration context narrow. » Le mode solo consomme des tokens de sortie supplémentaires dans un même contexte. Le mode orchestré ajoute des contextes, et chaque nouveau contexte lit le contrat et son propre ledger avant d’effectuer une tâche utile. La référence met en garde dans les deux sens : « Do not orchestrate a task that one focused session can implement and verify cleanly. » Elle déconseille également de conserver une build entière dans un seul contexte uniquement pour éviter le coût des subagents lorsque les feuilles et les contrats sont clairs.
Quatre paramètres en découlent :
- Choisissez la profondeur minimale dont les feuilles correspondent à de véritables unités de travail, puis arrêtez-vous. Une profondeur inutile est une dépense inutile.
- Restez en mode solo lorsqu’une session ciblée peut construire et vérifier la tâche, car la configuration du subagent coûte alors plus cher que ce que le nouveau contexte apporte.
- Installez le hook Stop si vous utilisez Claude Code. Le hook n’effectue aucun appel au modèle, mais chaque blocage renvoie l’agent au travail, qui est facturé.
- 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 skill conçue pour refuser les arrêts prématurés est, par conception, une skill qui continue à travailler. La définition des budgets et des alertes est 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 publiait autrefois son propre test, ce qui est plus rare que cela ne devrait l’être. Les auteurs ont depuis retiré ce test, ce qui est encore plus rare. Le README indique désormais seulement que « les versions précédentes du README citaient également une comparaison interne menée sur six exécutions » et que « les artefacts bruts nécessaires pour reproduire ces ratios et ces décomptes exacts ne se trouvent pas dans ce dépôt ». Il recommande de « considérer ces résultats comme des éléments historiques ayant orienté la conception, et non comme une garantie de benchmark ».
La configuration est toujours décrite dans research/validation-protocol.md : deux tâches de build, trois conditions pour chacune (sans skill, tree 3, tree 6), ainsi qu’un dossier et une session vierges pour chaque exécution. Le protocole parle d’une « comparaison exploratoire exécutée par les mainteneurs ». Il précise que les ratios de tokens, les décomptes de défauts trouvés par le modèle, les échecs en direct et les erreurs dans les numéros des rapports qu’elle a produits ne peuvent pas être reproduits ni audités à partir du dépôt. Il précise également que cette comparaison ne doit pas être présentée comme la preuve qu’unlazy entraîne une amélioration précise ou un multiplicateur de coût donné. Les versions précédentes de ce guide présentaient les décomptes de chaque exécution de ce test. Après le retrait des résultats par les auteurs, nous les avons supprimés.
Une leçon de conception a survécu aux chiffres. La règle consistant à « remesurer chaque chiffre et chaque affirmation de complétion immédiatement avant de les présenter » figure toujours dans SKILL.md, et le template des gates déconseille de copier un chiffre fourni dans EXPECT pour en faire sa propre preuve. Un résumé affirmatif fondé sur un build défaillant correspond exactement au problème que les gates doivent détecter.
Passons maintenant aux limites. Au 2026-10-11, il ne reste aucun résultat publié à évaluer, seulement la méthode et un protocole permettant de refaire correctement le test. Testez plutôt cette méthode sur votre propre travail : exécutez deux fois la même tâche, d’abord sans configuration particulière, puis avec un fichier de gates, et comptez les gates qui se sont fermées avec des preuves que vous pouvez vous-même réexécuter. Ce décompte est le seul chiffre de ce domaine qui vous appartient.
FAQ
Qu’est-ce que l’arbre de profondeur dans la skill unlazy ?
C’est une méthode de décomposition. Une tâche se divise uniquement à de véritables limites de domaine, de composant ou de vérification. Le niveau 1 correspond à la tâche demandée, et chaque feuille constitue un livrable cohérent avec ses propres gates. Les petites feuilles adjacentes sont fusionnées. Une feuille qui dissimule plusieurs résultats indépendants est à nouveau divisée. Chaque niveau situé au-dessus des feuilles intègre et vérifie : il contrôle de nouveau les éléments enfants, puis exécute les vérifications d’interface, de bout en bout et de non-régression. Vous choisissez la profondeur lors de l’appel, par exemple tree 5. Si aucune profondeur n’est indiquée, la skill choisit l’arbre le plus petit qui expose chaque livrable et chaque point d’intégration indépendant.
La skill unlazy fonctionne-t-elle en dehors de Claude Code ?
Partiellement. La skill est en markdown simple, et le README documente Codex CLI en plus de Claude Code. L’arbre de profondeur, le fichier de gates, les vérifications exécutables et les quatre passes par feuille fonctionnent donc également avec Codex CLI. La documentation actuelle ne couvre pas les autres harnesses. Le mécanisme d’application stricte est différent. Le hook Stop, qui empêche 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 de lire le fichier de gates et de le renvoyer à l’agent.
Quel coût la skill unlazy ajoute-t-elle à ma consommation de tokens ?
Personne ne peut aujourd’hui vous donner un chiffre fiable. Les anciens ratios de tokens des auteurs provenaient de six exécutions qui ne peuvent pas être reproduites. La documentation actuelle indique de ne pas les considérer comme des garanties produit, ni de traiter la profondeur comme une promesse arithmétique concernant l’effort ou le nombre de tokens. La tendance reste toutefois claire. Le mode solo ajoute de la sortie dans un même contexte. Le mode orchestré crée un nouveau contexte pour chaque feuille, lequel lit le contrat et son ledger avant de travailler. Le hook Stop n’effectue aucun appel de modèle de lui-même, mais chaque blocage renvoie l’agent au travail. Mesurez le coût sur votre propre tâche, avec votre propre facturation.
Dois-je utiliser unlazy ou ponytail ?
Choisissez la skill en fonction du problème rencontré. ponytail convient à un agent qui écrit trop de code : elle 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 convient à un agent qui ne termine pas suffisamment ce que vous avez demandé : elle impose une 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 n’appliquerez ainsi jamais un multiplicateur d’effort à 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 éléments. Commencez par confirmer que la skill est présente sur le disque avec ls ~/.claude/skills/unlazy/SKILL.md, car le cas le plus fréquent est un clone vers un répertoire qui n’existait pas. Confirmez ensuite qu’un fichier de gates a été écrit avant le début du travail, car le hook analyse le ledger de la session et un fichier GATES.md absent ne lui fournit rien à bloquer. Vérifiez également où le hook a été installé : l’exécution simple de install-hooks.mjs écrit uniquement dans le settings.local.json de ce projet. Un autre projet nécessite donc --global. Enfin, rappelez-vous que le mécanisme de sortie fonctionne comme prévu. Six arrêts consécutifs bloqués sans progression d’une gate libèrent l’agent. Une ligne ABANDON: <gate> <reason> termine volontairement la tentative comme une transmission visible, qui ne constitue pas un succès.