29 points par GN⁺ 2025-09-24 | 3 commentaires | Partager sur WhatsApp
  • Un article qui présente des principes de context engineering et un workflow pratique pour obtenir des résultats avec les modèles de langage récents dans de vastes bases de code de production
  • Le cœur de l’approche est la Frequent Intentional Compaction, qui consiste à structurer et compresser le contexte tout au long du développement afin de stabiliser la qualité de jugement de l’agent et sa trajectoire
  • Le processus en 3 étapes — recherche → planification → implémentation — produit des livrables de recherche en amont et des documents de planification, avec une revue humaine placée aux points à plus fort effet de levier pour réduire le slop et les retouches
  • L’approche a été validée dans BAML, une base Rust de 300 000 LOC, avec des tâches complexes menées rapidement comme des corrections de bugs et le support de l’annulation/WASM, montrant son efficacité même en environnement brownfield
  • En conclusion, le AI coding n’est pas un gadget mais un travail d’ingénierie artisanal sophistiqué, et l’avantage concurrentiel dépend d’une transformation des processus et de la culture à l’échelle de l’équipe

Contexte : limites de l’IA dans les bases de code complexes et constat de départ

  • La plupart des développeurs savent bien que les outils de AI coding ne fonctionnent pas aussi bien qu’espéré dans de vraies bases de code de production
  • Des recherches montrent que les outils de AI coding peuvent réduire la productivité sur de grandes bases de code et des tâches complexes
    • Selon une étude de Stanford, une part importante du code ajouté par les outils d’IA consiste à retravailler du code insuffisant qu’une IA avait déjà généré auparavant, ce qui provoque du travail répétitif
    • Les agents de AI coding sont efficaces sur des projets neufs ou de petites modifications, mais peuvent au contraire réduire la productivité des développeurs sur de grandes bases de code
    • D’où une réaction souvent prudente sur le terrain : « c’est difficile pour l’instant, quand les modèles seront plus intelligents »
  • Pourtant, l’application du context engineering sur une grande base Rust de 300 000 LOC a montré qu’avec les modèles existants, il était déjà possible de dépasser le niveau du marché à la fois en productivité et en qualité
    • Le point clé est la frequent intentional compaction, c’est-à-dire le fait de garder tout au long du développement un contexte donné à l’IA sous une forme structurée et maîtrisée
    • En fin de compte, le « AI coding » est un domaine qui exige un véritable artisanat technique

Fondements : « Specs are the new code » et recherches sur la productivité

  • Deux présentations à AI Engineer 2025 ont provoqué un changement de perspective
  • Dans la présentation Sean Grove, "Specs are the new code", il est expliqué qu’il faut abandonner les prompts conversationnels et conserver les spécifications comme du code
    • Jeter les prompts et ne committer que le code produit est comparé au fait de versionner uniquement des binaires sans le source
  • L’étude de Stanford sur l’impact de l’IA sur la productivité des développeurs suggère que même si l’IA augmente la production à court terme, la baisse de qualité et les retouches peuvent réduire le gain net
    • L’analyse des commits de 100 000 développeurs a observé que les outils d’IA augmentaient les retouches au point de compenser les gains de productivité
    • L’étude montre une bonne efficacité en greenfield, mais des effets inverses fréquents en brownfield et sur les tâches difficiles

Principe : le concept de Frequent Intentional Compaction

  • L’idée est de maintenir la fenêtre de contexte en permanence entre 40 et 60 %, avec une stratégie de compression continue visant à minimiser surcharge, omissions et informations erronées
    • Ce qu’il faut compresser, ce sont les bruits comme les logs de recherche de fichiers, traces de flux de code, historiques de modifications, logs de test/build, gros JSON, etc.
  • Les livrables de chaque étape sont conservés comme des artefacts structurés afin de garantir la qualité des entrées au tour suivant
    • Exemple : création d’un document de progression consignant le résumé d’avancement, les objectifs et l’approche, les étapes terminées et le point d’échec actuel

Workflow : Research → Plan → Implement

  • À l’étape Research, on examine les fichiers concernés, les flux et les hypothèses sur la cause afin de produire un document de recherche synthétique
    • Si nécessaire, des sous-agents explorent le périmètre et résument leurs résultats dans un contexte neuf
  • À l’étape Plan, on rédige un plan d’implémentation décrivant en détail les fichiers à modifier, la manière de les changer, ainsi que les procédures de validation et de test
    • Le plan devient un point de revue à fort effet de levier, plus utile qu’une revue de code classique
  • À l’étape Implement, le plan est exécuté progressivement et, après validation de chaque étape, l’état est recompresé dans le document de plan pour s’accumuler proprement
    • Pour les tâches complexes, un réalignement du contexte est effectué à chaque point de jonction entre étapes

Anti-patterns et montée en maturité progressive

  • L’approche naïve révèle que, dans un flux de chat, le contexte se dégrade et mène à des boucles d’excuses ou à des dérives
    • Une méthode un peu meilleure consiste à réinitialiser la session et à ajouter des « prompts d’instruction », mais cela reste insuffisant pour un contrôle fondamental du bruit
  • La compression intentionnelle est une meilleure méthode pour reconstruire le contexte à l’aide de résumés d’avancement (fichiers) et de messages de commit
    • L’article propose un format type pour un livrable de compression idéal, avec comme objectifs l’optimisation de la précision / exhaustivité / taille / trajectoire

Regard technique sur l’optimisation du contexte

  • Les LLM étant des fonctions sans état, leur qualité dépend entièrement du contexte d’entrée
    • L’ordre du pire au moins pire est : désinformation > omission > excès de bruit
  • Comme un contexte plus petit est préférable, l’enjeu clé est une compression qui obtienne une cohérence maximale avec une entrée minimale
    • D’autres points de vue sont aussi évoqués, comme des stratégies d’exécution d’agent en boucle simple (par exemple le processus « Ralph »)

Rôle des sous-agents : non pas jouer des rôles humains, mais contrôler le contexte

  • Les sous-agents effectuent recherche / résumé / organisation dans un contexte indépendant afin de garder la fenêtre du main agent propre
    • La réponse idéale revient sous la forme d’un livrable compressé structuré autour de l’objectif / l’état actuel / le chemin à suivre
  • Les sous-agents permettent de localiser le coût d’exploration et d’augmenter la concentration du contexte de travail principal

Cas 1 : correction de bug BAML validée du premier coup

  • Dans BAML, base Rust de 300 000 LOC, un nouvel arrivant a pu soumettre puis faire approuver en quelques heures une PR de correction de bug
    • En itérant plusieurs fois sur le document de recherche pour en améliorer la qualité, puis en implémentant à partir du plan final, l’équipe a obtenu une réussite dès la première passe
  • L’expérience répond à plusieurs objectifs : adéquation au brownfield, élimination du slop et maintien de l’alignement

Cas 2 : ajout du support annulation/WASM à BAML sur 35k LOC

  • Deux personnes ont démontré en 7 heures une modification d’ampleur ajoutant la fonction d’annulation et la compilation WASM
    • Selon l’estimation de l’équipe, cela représentait 3 à 5 jours de travail par personne, réduits grâce au pipeline recherche / planification / implémentation
  • Certaines PR ont été fusionnées immédiatement, d’autres sont restées ouvertes au stade de démo fonctionnelle, prouvant la possibilité de résoudre des problèmes difficiles

Limites et apprentissages tirés des échecs

  • Une tentative de suppression de la dépendance Hadoop dans Parquet Java est restée un échec, faute d’avoir suffisamment creusé l’arbre des dépendances
    • Conclusion : tous les problèmes ne se résolvent pas avec 7 heures de prompting, et la participation d’un expert métier reste nécessaire
  • L’effet de levier de la revue humaine augmente dans l’ordre recherche > plan > code, et une seule ligne erronée dans la recherche peut se propager en milliers de lignes d’erreurs

Priorité aux documents pour aligner l’équipe

  • L’article défend l’idée que l’essence d’une revue de code est de maintenir un alignement mental
    • Une succession de grosses PR peut faire perdre à l’équipe sa compréhension du produit et générer de l’anxiété ; les specs / plans / recherches réduisent ce coût d’alignement
  • Un ingénieur peut lire plus souvent et plus précisément un document de plan de 200 lignes que 2 000 lignes de code
    • Même pour traiter un problème dans une zone inconnue, un prompt de recherche peut jouer un rôle d’orientation rapide

Récapitulatif et structure de coûts

  • Tous les objectifs sont remplis : compatibilité brownfield, résolution de problèmes complexes, minimisation du slop et maintien de l’alignement d’équipe
    • En termes de coût d’exploitation, une équipe de 3 personnes fonctionne avec un coût mensuel en tokens Opus d’environ 12 000 $
  • Il existe des exceptions, mais l’ensemble est présenté comme une méthodologie qui fonctionne réellement

Changements à venir et produit

  • Les agents de code vont devenir une commodité, et le vrai défi portera sur la transformation des organisations et des workflows
    • Dans un monde où l’IA écrit 99 % du code, la refonte complète des modes de collaboration deviendra le point de bascule de la compétitivité
  • Pour soutenir cela, un outil « post-IDE » nommé CodeLayer a été lancé en bêta privée
    • Pensé comme un Superhuman for Claude Code, il accélère le développement agentique spec-first

3 commentaires

 
say8425 2025-09-25

Fin de la pub...

 
tested 2025-09-25

Conclusion avec la présentation d’un service appelé CodeLayer...

 
GN⁺ 2025-09-24
Avis Hacker News
  • C’était une lecture intéressante avec des idées originales. Mais je pense que ce type d’affirmation pose problème. Sean prédit que l’IA va progresser au point que, à l’avenir, les documents de spécification deviendront le véritable code. Selon lui, d’ici 2 ans, ouvrir un fichier Python dans un IDE sera aussi rare qu’ouvrir aujourd’hui un éditeur hexadécimal pour regarder de l’assembleur. Il dit qu’au début cela le mettait mal à l’aise, mais qu’il a fini par accepter une approche où l’on se concentre sur les tests au lieu de lire chaque ligne de code d’une PR, en considérant la spec comme la vraie source. Mais à cause du caractère non déterministe des LLM, même avec d’excellents prompts, on ne peut pas toujours s’attendre à une implémentation raisonnable. Un compilateur est déterministe et, même s’il a un bug, on peut le reproduire et le déboguer, ce qui n’est pas le cas d’un LLM

    • Même quand on travaille avec un développeur junior, l’implémentation reste déterministe jusqu’à un certain point. Avec un modèle d’IA, même en donnant des instructions claires, on obtient à répétition des implémentations complètement différentes

    • Ce qui est amusant, c’est qu’en réalité les documents de spec eux-mêmes sont déjà non déterministes. Si on essaie d’écrire des requirements en anglais de façon à ce qu’aucune interprétation erronée ne soit possible, on finit par créer un langage de programmation

    • Je suis d’accord avec l’inquiétude selon laquelle « le prompt peut être parfait, sans aucune garantie que le LLM le transforme en une implémentation raisonnable ». En fait, les prompts écrits en langage naturel sont souvent fondamentalement ambigus et incomplets. C’est utile quand on cherche des résultats créatifs, mais si le langage naturel avait été adapté à la définition des exigences logicielles, le génie logiciel aurait résolu ce problème il y a des décennies. J’ai été enthousiaste vis-à-vis des LLM, mais je pense qu’essayer d’en faire la solution à tous les problèmes va trop loin. Pour la spécification des exigences, cela ressemble aux anciens systèmes formels et aux tentatives de vérification mathématique, mais à l’opposé total. Même si cela se termine par un échec partiel, j’y vois une expérience qui peut apporter de nouveaux éclairages sur le développement logiciel. Dans certains domaines, cela créera une vraie valeur ; dans d’autres, ce sera peut-être totalement abandonné. Époque intéressante

    • En réalité, il est déjà très rare que les gens rédigent des specs techniques ou de la documentation de manière claire et détaillée. Et même si c’était le cas, je doute que cela se généralise d’ici 2 ans. Un rédacteur technique qui comprend vraiment en profondeur l’ingénierie logicielle serait-il satisfait de simplement bien prompter un agent IA sans regarder le code ? Je n’y crois pas. Cela ressemble beaucoup à la façon classique dont les ingénieurs considèrent les humains comme des machines

    • L’affirmation selon laquelle « grâce aux compilateurs, on n’a plus besoin de regarder l’assembleur dans un éditeur hexadécimal à chaque build » est vraie dans l’ensemble parce que les outils se sont améliorés, mais dans la recherche scientifique HPC, il arrivait souvent de disséquer directement l’assembleur avec Intel VTune et autres outils pour vérifier si le compilateur avait correctement vectorisé les boucles critiques

  • J’ai utilisé ce schéma sur deux codebases différentes. L’une était un gros repo monolithique Apache Airflow de 500 000 lignes, l’autre un side project personnel démarré de zéro avec Flutter. Je ne connaissais vraiment ni Flutter ni Dart. Malgré cela, j’ai senti que cette méthode fonctionnait. Sur un projet greenfield, on peut presque se contenter de lancer /create_plan, et exploiter toute l’aide de l’agent. L’essentiel est de relire attentivement les documents produits par l’IA. Il faut vérifier soi-même s’ils couvrent les edge cases qui nous préoccupent et si les choix techniques sont pertinents. Par exemple, on repère tout de suite une mauvaise décision comme recommander Postgres alors qu’il faudrait respecter un pattern basé sur SQLite. En général, on peut corriger le plan directement en discutant avec l’agent. Au travail, je dois utiliser GitHub Copilot, donc je rédige les prompts un peu différemment, mais je continue à faire des résumés intentionnels entre les étapes. Copilot ne prend pas en charge les sous-agents comme Claude Code, mais j’arrive quand même à conserver une bonne productivité.


    Je voudrais aussi partager une expérience personnelle. Juste avant l’ère des assistants de code IA, j’étais très déprimé à l’idée que mon travail devenait trop ennuyeux. Travailler sur de grosses codebases, avec plusieurs repos, équipes et personnalités, revenait toujours à faire une quantité absurde de tâches ingrates. Ce que j’ai préféré avec le code assisté par IA, c’est sa capacité à gérer en douceur tous ces petits travaux pénibles. J’éprouve beaucoup de satisfaction à construire quelque chose qui fonctionne bien, mais cette joie disparaissait sans cesse à cause de ces corvées. Maintenant, j’obtiens régulièrement de bons résultats et j’en suis fier

    • Merci d’avoir partagé ton expérience. Au début, c’était extrêmement inconfortable, puis une fois habitué, il devient impossible de revenir à l’ancienne façon de faire
  • J’ai créé un package que j’utilise quand je travaille sur de grandes codebases : [GitHub.com/iambateman/speedrun]. Je commence par entrer une description de fonctionnalité avec /feature, ce qui lance l’analyse de la codebase et pose des questions. Quand j’y réponds, il rédige un plan au format Markdown. Ce processus génère 8 à 10 fichiers Markdown contenant ce qu’il faut faire ainsi que du code d’exemple. Ensuite vient une étape de « code critic », censée détecter les erreurs, mais qui se trompe en réalité dans 60 % des cas. Je filtre donc dans ce feedback les erreurs absurdes. À ce stade, j’obtiens un dossier propre avec les changements souhaités et la description de la fonctionnalité. Je n’ai alors plus qu’à dire à Claude Code « vas-y », et le travail démarre étape par étape. Cette façon de faire m’aide à éviter de partir dans la mauvaise direction et me donne davantage confiance dans le résultat. J’utilise ce workflow plusieurs fois par jour pour les gros travaux, et pour les tâches relativement précises, j’utilise simplement Claude Code de façon plus classique. Je trouve ce workflow assez efficace

    • Je ne comprends absolument pas pourquoi on voudrait passer par un processus aussi compliqué. À mon avis, coder normalement avec juste un peu d’aide des LLM est plus productif que cette méthode

    • Le gros problème quand on utilise un LLM sur une grande codebase, c’est qu’il répète les mêmes erreurs. Je me demande comment tu fais, dans ce contexte, pour suivre d’une tâche à l’autre les décisions d’architecture

    • Ça a l’air vraiment excellent. Il y a une étape intermédiaire de pseudo-code ; je me demande si définir à l’avance le workflow ou le processus t’a réellement aidé. J’ai aussi entendu dire qu’il est important de garder chaque fichier sous les 100 lignes ; je serais curieux de savoir si tu as constaté la même chose

  • Cet article ressemble à une capsule temporelle du moment où j’ai complètement renoncé à gérer le contexte dans Claude Code. J’avais créé un dossier de specs séparé pour chaque partie du code, avec un journal par fonctionnalité. Je gérais en Python plusieurs sous-systèmes d’un serveur API, comme les comptes, les notifications, les abonnements, etc. À mesure que la situation se compliquait, Claude comprenait de moins en moins la logique métier, et la gestion du contexte devenait extrêmement difficile. Par exemple, pour mettre en place un simple système RBAC, je devais lui fournir un diagramme UML expliquant la relation compte-profil, avec des exemples, pour qu’il se comporte à peu près comme prévu

    • Je pense que c’est précisément pour cela que le fait de créer d’abord research_codebase.md a été décisif. La grande question était : « si on nous confie cette codebase, comment demander au modèle d’y travailler si nous n’en comprenons pas la structure ? » Dans le code principalement écrit par l’IA, il y a deux problèmes. 1) Si on ne connaît pas bien le code, il faut une phase de recherche pour comprendre rapidement les flux et les fonctionnalités 2) Les énormes revues de PR sont très pénibles, tandis qu’un plan structure ce qui a changé et pourquoi. Au passage, Mitchell a énormément vanté la fonctionnalité de partage de thread d’ampcode, et c’est une bonne solution au point n°2 [https://x.com/mitchellh/status/1963277478795026484]
  • On voit passer toutes sortes de déclarations et d’affirmations sur l’usage de l’IA, mais presque personne ne publie de processus ou de prompts concrets. Il est facile de tenir un discours séduisant dans l’abstrait ; pour être vraiment utile, il faudrait conserver des logs de prompts. Les commits générés par l’IA devraient inclure les prompts utilisés, de sorte qu’on puisse parcourir le journal des prompts comme on parcourt un historique de commits, et comprendre ainsi comment le code a été produit

  • L’auteur se vante d’avoir exploré et implémenté 35K lignes de code en 7 heures, alors qu’en réalité on voit 40 commits étalés sur 7 jours. On se demande s’il a travaillé une heure par jour. Et c’est assez drôle qu’un des commits les plus récents soit « ignorer certains tests »

    • En lisant davantage, on voit qu’il le reconnaît lui-même. « La PR sur l’annulation demandait un peu plus de travail, mais j’ai quand même fait d’énormes progrès en une journée »
  • Il y avait cette phrase : « Quelques semaines plus tard, avec @hellovai, nous avons ajouté 35k LOC à BAML pour introduire la prise en charge de l’annulation, la compilation WASM, etc. L’équipe existante estimait que chaque fonctionnalité prendrait 3 à 5 jours. » Donc ils pensaient vraiment qu’un ingénieur senior écrirait 4 à 6 KLOC par jour ? (avant la genAI ?)

    • Ce qui manque ici, c’est qu’un ingénieur senior l’aurait probablement résolu avec seulement 2 KLOC

    • Et en réalité, l’auteur reconnaît aussi ailleurs que ce travail a pris une semaine https://news.ycombinator.com/item?id=45351546

  • Je suis totalement d’accord avec le passage : « Au début c’était inconfortable, mais j’ai fini par renoncer à lire tout le code des PR et à ne plus vérifier que les tests en détail. La spec est devenue la vraie source. » J’ai le sentiment que notre rôle se déplace de l’écriture directe des détails d’implémentation vers la définition et la vérification du comportement. Récemment, il fallait ajouter un upload récursif à un opérateur Python S3-to-SFTP, avec beaucoup de flags de chemin complexes. Mon processus a été le suivant : 1) extraire le comportement existant sous forme d’une spec claire, c’est-à-dire en la faisant passer sous forme de tests unitaires 2) étendre la spec pour la nouvelle fonctionnalité 3) transmettre le problème et les tests à l’agent de code. Au final, j’ai compris que je n’avais pas du tout besoin de comprendre l’ancien code. Mon seul focus était de savoir si le nouveau code respectait correctement la spec. À l’avenir, notre valeur résidera dans la validation de la justesse, et le code concret deviendra un détail géré par les agents

    • Je suis d’accord avec l’idée que « notre rôle passe de l’écriture des détails d’implémentation à la définition et à la vérification du comportement ». On pourrait même dire que cela a toujours été l’essentiel du travail. Avec les langages de haut niveau, les compilateurs et d’autres abstractions, le temps passé à écrire les détails d’implémentation ne fait que diminuer

    • La phrase « mon focus était de savoir si le nouveau code fonctionnait conformément à la spec » me fait penser à la loi de Postel. Dans un système largement utilisé, le comportement observé devient de fait l’interface publique et la spec du système, y compris tous ses défauts et bugs d’implémentation. Il faut aussi tester si les clients du code respectent réellement bien la spec, et s’il existe des écarts, les détecter puis les gérer

    • Claude Plays Pokemon montrait la même chose. L’IA est faible pour juger si quelque chose fonctionne réellement ; elle a plutôt tendance à tourner en rond. Mais si un humain la recadre de temps en temps, cela peut devenir une combinaison très puissante

    • Si on essaie de définir tous les aspects du comportement, on finit en pratique par écrire presque tout le code. Si une ligne quelconque dans la PR n’est pas immédiatement compréhensible, c’est sans doute que le comportement global n’a pas été suffisamment défini

  • Il y avait aussi cette affirmation : « Dans quelques années, les documents de spec deviendront le vrai code, et on n’aura presque plus besoin d’ouvrir des fichiers Python. » Pour que cela arrive, la génération de code par IA doit être correcte à 99,9 % et les hallucinations doivent être quasiment inexistantes. Si nous faisons confiance aux compilateurs et ne regardons pas l’assembleur, c’est parce que nous sommes convaincus que le résultat est toujours le même et sans erreur majeure. Il y a parfois de rares bugs ou problèmes d’optimisation, mais ils sont presque toujours corrigés rapidement. Aujourd’hui encore, si le code généré par l’IA se comporte différemment de la spec, c’est forcément un humain qui doit revenir le corriger

  • J’ai été très marqué par le conseil consistant à découper l’implémentation en unités de travail, puis à les traiter ou les relire séparément.

    1. Décomposer une fonctionnalité ou un bug report en spec technique d’implémentation, en utilisant une décomposition logique (COT)
    2. Après validation de la spec d’implémentation, transmettre le feedback de review à l’agent de prompt initial pour corriger et intégrer
    3. Transformer la spec d’implémentation en véritable plan d’exécution, le découper logiquement par module, et vérifier aussi les dépendances
    4. Répéter build, tests et intégration avec l’agent de code
    5. Si nécessaire, squash l’ensemble de la fonctionnalité en un seul commit Ce processus m’a été utile sur des fonctionnalités nouvelles complexes. Si plus de validation est nécessaire, on peut faire intervenir un humain (HITL) à chaque étape. Sur les grandes codebases, je recommande de toujours maintenir un ARCHITECTURE.md, et pour les gros modules un DESIGN.md
    • Je ne l’ai pas encore essayé au travail, mais sur mes side projects je crée une branche pour la nouvelle fonctionnalité et je donne à CLAUDE un prompt aussi détaillé que possible. Il génère alors un CLAUDE-feature.md avec le plan d’implémentation et des informations utiles, comme les éléments accessibles dans la codebase. Si je vois qu’il manque des choses dans le fichier ou que certaines explications sont confuses, je complète avec des prompts supplémentaires. Entre des prompts relativement importants, j’utilise /reset, je lui fais à nouveau référencer les documents, puis j’itère pour améliorer le tout. Au moment de l’implémentation réelle, je refais aussi un /reset, puis je lui fais refaire /reset à chaque checkpoint du plan, tout en mettant à jour l’avancement dans le document. Globalement, ça fonctionne plutôt correctement, mais je ne suis pas sûr de lui faire autant confiance au travail