L'architecture modulaire avec Xavier Agapé
Dojo conceptuel avec Xavier Agapé (ingénieur, ex-directeur technique, No-Code France) consacré à l'architecture modulaire : pourquoi découper une application en modules autonomes communiquant par contrats d'interface permet de maîtriser la fenêtre de contexte des LLM, de réduire les hallucinations et le coût en tokens — illustré par un projet de mini-Slack pour la communauté No-Code France en React + Vite + Convex.
Stack technique
Outils utilisés
Résumé de la session
Pour ce dojo un peu différent, Alexis reçoit Xavier Agapé, ingénieur en système d'information et génie logiciel, ancien directeur technique et figure de la communauté No-Code France. Xavier explique d'emblée qu'il n'écrit quasiment plus de code et ne le relit presque plus, mais qu'il continue de lire tous les outputs de réflexion de l'IA. Le sujet du jour, réclamé plusieurs fois par les auditeurs, est l'architecture modulaire — un sujet d'ingénierie qui existe depuis longtemps mais qui prend tout son sens dans le contexte du vibe coding. Pour l'illustrer, Xavier lance en parallèle la construction d'un mini-Slack destiné à la communauté No-Code France.
Le live commence par un cours sur la fenêtre de contexte. Xavier rappelle que les gros modèles offrent environ un million de tokens, mais que la performance se concentre sur le premier tiers : passé ~50 % de remplissage, le taux de réussite chute autour de 75 % (soit un token sur quatre potentiellement faux), les hallucinations augmentent et le coût explose puisque chaque nouveau message réembarque toute la conversation — une croissance non linéaire. Il détaille ce qui remplit ce contexte (système prompt, entêtes de skills, MCP, fichiers de config type CLAUDE.md / AGENTS.md, thinking) et recommande de raisonner « une feature = une conversation », et de préférer repartir d'une discussion neuve plutôt que de laisser le contexte se compacter automatiquement.
Vient ensuite le cœur du sujet, expliqué au tableau. Par défaut, l'IA produit un monolithe : bien codé au début, il dérive vers du code spaghetti, avec duplication de fichiers et de routes d'API que le modèle peine ensuite à retrouver. À l'opposé, les microservices sont des applications indépendantes (langage, base de données, déploiement propres) qui scalent unitairement mais ajoutent une grande complexité et des appels API qui peuvent devenir « spaghetti » eux aussi. L'architecture modulaire est l'entre-deux : un monolithe modulaire qui reproduit, à l'intérieur d'une seule application déployable, le découpage en services autonomes communiquant par des contrats d'interface. Xavier file l'analogie de la mairie : chaque service (passeports, cantine) est en silo et ne peut obtenir une information d'un autre qu'en respectant un formalisme imposé, exactement comme une documentation d'API — mais en interne.
L'intérêt est direct pour le vibe coding : en plaçant un petit CLAUDE.md dans chaque dossier de feature, l'IA n'a plus besoin de parcourir tout le code pour intervenir, ce qui borne mécaniquement le nombre de tokens consommés. Xavier insiste sur le rôle du linter, premier rempart contre les bêtises de l'IA comme des humains : on peut lui interdire les imports entre services différents, lui imposer des conventions, et bloquer commit ou déploiement quand il ne passe pas. Il raconte avoir cassé le site de son livre à cause d'une variable non déclarée poussée en production alors qu'un linter non bloquant l'avait pourtant signalée.
La démonstration en direct consiste à demander à Claude (via l'IDE Antigravity, avec Opus 4.7) de proposer une architecture modulaire pour le mini-Slack. Le modèle découpe l'application en modules — authentification, channels, messages, membres — plus un dossier partagé (shared) pour les composants réutilisables. Xavier précise que Convex, la base de données choisie (qui gère aussi l'authentification), ne se prête pas aux schémas séparés et qu'on s'appuie alors sur des sous-dossiers ; il rappelle les trois niveaux possibles côté données (schéma classique, un schéma par module, une base par module) sans suroptimiser dès le premier jour. Claude, configuré en mode « be contrarian », joue systématiquement l'avocat du diable : il pousse au KISS (ne pas scinder un channel public et privé en deux features mais utiliser un simple indicateur privé/public) et suggère de séparer logiquement plutôt que physiquement, en ne refactorisant que « quand la douleur arrive ». Xavier, lui, assume de partir modulaire dès le départ même sur un petit projet, pour pouvoir empiler et interchanger des briques comme des Lego.
La discussion s'élargit à la méthode de travail. Xavier revendique un vibe coding « éclairé », proche de l'AI driven development : il prépare PRD, schéma et architecture en discutant avec le modèle avant de toucher aux outils, et profite de chaque réponse pour apprendre (React compiler vs useMemo/useCallback). Il partage un retour d'expérience marquant : sur une cohorte de 40 projets clients réels confiés à cinq développeurs ultra-seniors, l'architecture modulaire apporte environ 20 % de chances supplémentaires d'aboutir, faisant passer ces développeurs d'« un projet par personne » à la gestion d'un portfolio. Il décrit enfin son usage du fanout multi-agents (un agent par feature partageant le même contexte de départ, chaque agent devant produire un document de plan et cocher une checklist avant de coder) et le mode advisor pour rendre la méthode viable même sur des modèles plus faibles. L'application de démonstration n'aboutira pas — l'agent reste bloqué près de 50 minutes —, mais Xavier et Alexis concluent que l'essentiel était de transmettre des concepts fondamentaux, applicables avec n'importe quel LLM et durables face à l'évolution des outils.
Le live commence par un cours sur la fenêtre de contexte. Xavier rappelle que les gros modèles offrent environ un million de tokens, mais que la performance se concentre sur le premier tiers : passé ~50 % de remplissage, le taux de réussite chute autour de 75 % (soit un token sur quatre potentiellement faux), les hallucinations augmentent et le coût explose puisque chaque nouveau message réembarque toute la conversation — une croissance non linéaire. Il détaille ce qui remplit ce contexte (système prompt, entêtes de skills, MCP, fichiers de config type CLAUDE.md / AGENTS.md, thinking) et recommande de raisonner « une feature = une conversation », et de préférer repartir d'une discussion neuve plutôt que de laisser le contexte se compacter automatiquement.
Vient ensuite le cœur du sujet, expliqué au tableau. Par défaut, l'IA produit un monolithe : bien codé au début, il dérive vers du code spaghetti, avec duplication de fichiers et de routes d'API que le modèle peine ensuite à retrouver. À l'opposé, les microservices sont des applications indépendantes (langage, base de données, déploiement propres) qui scalent unitairement mais ajoutent une grande complexité et des appels API qui peuvent devenir « spaghetti » eux aussi. L'architecture modulaire est l'entre-deux : un monolithe modulaire qui reproduit, à l'intérieur d'une seule application déployable, le découpage en services autonomes communiquant par des contrats d'interface. Xavier file l'analogie de la mairie : chaque service (passeports, cantine) est en silo et ne peut obtenir une information d'un autre qu'en respectant un formalisme imposé, exactement comme une documentation d'API — mais en interne.
L'intérêt est direct pour le vibe coding : en plaçant un petit CLAUDE.md dans chaque dossier de feature, l'IA n'a plus besoin de parcourir tout le code pour intervenir, ce qui borne mécaniquement le nombre de tokens consommés. Xavier insiste sur le rôle du linter, premier rempart contre les bêtises de l'IA comme des humains : on peut lui interdire les imports entre services différents, lui imposer des conventions, et bloquer commit ou déploiement quand il ne passe pas. Il raconte avoir cassé le site de son livre à cause d'une variable non déclarée poussée en production alors qu'un linter non bloquant l'avait pourtant signalée.
La démonstration en direct consiste à demander à Claude (via l'IDE Antigravity, avec Opus 4.7) de proposer une architecture modulaire pour le mini-Slack. Le modèle découpe l'application en modules — authentification, channels, messages, membres — plus un dossier partagé (shared) pour les composants réutilisables. Xavier précise que Convex, la base de données choisie (qui gère aussi l'authentification), ne se prête pas aux schémas séparés et qu'on s'appuie alors sur des sous-dossiers ; il rappelle les trois niveaux possibles côté données (schéma classique, un schéma par module, une base par module) sans suroptimiser dès le premier jour. Claude, configuré en mode « be contrarian », joue systématiquement l'avocat du diable : il pousse au KISS (ne pas scinder un channel public et privé en deux features mais utiliser un simple indicateur privé/public) et suggère de séparer logiquement plutôt que physiquement, en ne refactorisant que « quand la douleur arrive ». Xavier, lui, assume de partir modulaire dès le départ même sur un petit projet, pour pouvoir empiler et interchanger des briques comme des Lego.
La discussion s'élargit à la méthode de travail. Xavier revendique un vibe coding « éclairé », proche de l'AI driven development : il prépare PRD, schéma et architecture en discutant avec le modèle avant de toucher aux outils, et profite de chaque réponse pour apprendre (React compiler vs useMemo/useCallback). Il partage un retour d'expérience marquant : sur une cohorte de 40 projets clients réels confiés à cinq développeurs ultra-seniors, l'architecture modulaire apporte environ 20 % de chances supplémentaires d'aboutir, faisant passer ces développeurs d'« un projet par personne » à la gestion d'un portfolio. Il décrit enfin son usage du fanout multi-agents (un agent par feature partageant le même contexte de départ, chaque agent devant produire un document de plan et cocher une checklist avant de coder) et le mode advisor pour rendre la méthode viable même sur des modèles plus faibles. L'application de démonstration n'aboutira pas — l'agent reste bloqué près de 50 minutes —, mais Xavier et Alexis concluent que l'essentiel était de transmettre des concepts fondamentaux, applicables avec n'importe quel LLM et durables face à l'évolution des outils.
Ce qu'on a appris
- Les gros modèles offrent environ 1 million de tokens, mais la performance se concentre sur le premier tiers. Au-delà de 50 % de remplissage, le taux de réussite tombe autour de 75 % : un token sur quatre peut être une bêtise.
- Le coût d'une conversation est non linéaire : chaque nouveau message réembarque tout l'historique. Une discussion longue dégrade les performances et fait atteindre les limites plus vite.
- Raisonner « une feature = une conversation ». Préférer une nouvelle discussion (clear) au compactage : si un compact automatique se déclenche, c'est que le contexte est déjà saturé.
- Le contexte ne contient pas que vos messages : le système prompt, les entêtes des skills, les MCP, les fichiers de configuration (CLAUDE.md côté Anthropic, AGENTS.md ailleurs) et le raisonnement du modèle s'y accumulent.
- Par défaut, l'IA produit un monolithe qui dérive vers du code spaghetti : duplication de fichiers, de dossiers et de routes d'API qu'elle finit par modifier au mauvais endroit.
- Les microservices sont des applications indépendantes (code, langage, base de données et déploiement propres) qui montent en charge unitairement, mais ajoutent une lourde complexité et des appels d'API qui peuvent eux aussi devenir spaghetti.
- L'architecture modulaire est un compromis : un monolithe modulaire qui reproduit le découpage en services autonomes à l'intérieur d'une seule application déployable. Plus simple à raisonner qu'une architecture hexagonale, et accessible à tous.
- Partir modulaire dès le début, même sur un petit projet : on peut alors empiler et interchanger des briques comme des Lego, là où repartir d'un monolithe classique impose de tout resegmenter.
- Les modules communiquent par des contrats d'interface, comme une documentation d'API mais en interne. Analogie de la mairie : chaque service est en silo et n'obtient une information qu'en respectant le formalisme imposé.
- Placer un petit CLAUDE.md dans chaque dossier de feature : l'IA n'a plus besoin de parcourir tout le code, ce qui borne mécaniquement le nombre de tokens consommés pour une modification.
- Côté base de données, trois niveaux sont possibles (schéma classique, un schéma par module, une base par module). Ne pas suroptimiser dès le premier jour : on optimise quand le problème arrive. Convex ne gère pas les schémas séparés, on passe alors par des sous-dossiers.
- Le linter agit comme un surveillant : on peut lui interdire les imports entre services différents (la dérive la plus fréquente, que l'IA fait aussi par fainéantise) et lui imposer des conventions de code.
- Bloquer le commit (via un pre-commit hook) ou le déploiement quand le linter ne passe pas. Anecdote : une variable non déclarée poussée en production a cassé le site du livre de Xavier, alors qu'un linter non bloquant l'avait pourtant signalée.
- Instruction « be contrarian » : demander au modèle de jouer systématiquement l'avocat du diable force à réfléchir et préserve le principe KISS (un simple indicateur privé/public plutôt que deux features distinctes). À double tranchant : un LLM trouve toujours des arguments pour et contre, ce qui peut faire perdre du temps.
- Préparer le PRD, le schéma et l'architecture en discutant avec le modèle avant de toucher aux outils. Ce travail amont coûte du temps mais en fait gagner énormément ensuite, en évitant de se demander après coup s'il a bien pensé à tout.
- Vibe coding « éclairé », proche de l'AI driven development : ne plus relire tout le code mais garder une granularité proche du code permet d'apprendre en continu et d'utiliser des modèles moins chers.
- Sur 40 projets clients réels confiés à 5 développeurs ultra-seniors, l'architecture modulaire apporte environ 20 % de chances supplémentaires d'aboutir — assez pour passer d'un projet par personne à la gestion d'un portfolio de projets.
- Fanout multi-agents : un agent par feature, tous partageant le même contexte de départ, chacun devant produire un document de plan et cocher une checklist avant de coder (imposé via le CLAUDE.md).
- La méthode fonctionne avec n'importe quel LLM : réduire le contexte et la complexité la rend accessible aux modèles plus faibles. Opus pour la préparation, Sonnet pour l'implémentation ; le mode advisor peut diviser les coûts par 5 à 10.