Quarante-huit agents. Un millier de sections de connaissance. Douze compétences auto-apprises. Et un seul problème de fond qui m'a pris du temps à diagnostiquer : mes agents étaient en train de devenir des monolithes.
Au départ, tout allait bien. Un agent, un rôle, quelques instructions dans un fichier .md. Puis les agents ont grandi : des règles de style, des exemples, des cas limites, des références d'API, des conventions de commit. Chaque ajout semblait raisonnable. Résultat, au bout de quelques mois : des fichiers .md de 300, parfois 400 lignes, chargés intégralement dans le contexte à chaque appel.
Le coût était invisible, mais réel : en tokens système, en latence, en fenêtre de contexte brûlée avant même que l'agent ait commencé à travailler.
La solution n'était pas de supprimer du contenu. C'était de le déplacer.
Avant de continuer de lire la suite de l'article, je vous invite à vous inscrire à ma newsletter, pour connaître en avant première les futurs sujets traités chaque semaine.
Le problème des agents monolithiques
Imaginons une architecture naïve : chaque agent stocke ses instructions directement dans son fichier .md. Un agent de révision de code peut avoir : son rôle (20 lignes), ses critères de qualité (50 lignes), ses exemples de bonnes pratiques (80 lignes), ses règles de sécurité (60 lignes), ses références OWASP (40 lignes). Total : 250 lignes par agent.
Multipliez par 48 agents, même partiellement chargés en parallèle, et vous obtenez un problème structurel.
Voici le calcul concret issu de l'audit :
| Approche | Calcul | Coût tokens |
|---|---|---|
| Naïf (inline) | 48 agents × 5 Ko par fichier | ~240 Ko constants |
| RAG-First | 48 × 1,5 Ko bootstrap + 5-15 Ko on-demand | ~72 Ko réel |
| Économie | -70 % |
Ces 70 % ne sont pas théoriques. Ce sont des tokens système qui étaient consommés à chaque adoption d'agent, qu'il y en ait besoin ou non. Un agent de migration de base de données chargé pour une tâche d'écriture d'article. Des exemples de requêtes SQL dans le contexte d'un générateur de posts LinkedIn. Du bruit permanent.
L'architecture RAG-First résout ce problème à la racine : le fichier .md devient un bootstrap léger, et le contenu riche vit dans pgvector, chargé uniquement quand l'agent en a besoin.
Le principe RAG-First
L'idée est simple : séparer ce qui est nécessaire au routage de ce qui est nécessaire à l'exécution.
Le fichier .md (≤ 70 lignes) contient uniquement :
- Les métadonnées YAML pour le routage (nom, description, exemples, model, tools)
- Une ligne de rôle
- Un snippet SQL pour charger les instructions détaillées depuis RAG
pgvector contient tout le reste : les processus pas à pas, les cas limites, les formats de sortie, les tableaux de référence, les bonnes pratiques. Ce contenu est illimité en taille et chargé à la demande.
Voici à quoi ressemble un fichier .md dans cette architecture :
--- name: mgrr-agent-code-reviewer description: Review code changes for quality, security, and maintainability model: sonnet tools: [Read, Grep, Bash] --- You are a senior code reviewer specializing in quality, security, and maintainability. ## Dynamic Instructions (RAG) \```bash echo "SELECT section_type, content FROM rag_agent_instructions WHERE agent_name = 'mgrr-agent-code-reviewer' AND active = true ORDER BY section_type, id" | docker exec -i grepai-pgvector psql -U grepai -d grepai \```
L'agent charge ses instructions complètes en une seule requête SQL au démarrage. Si pgvector est indisponible, il fonctionne quand même avec son rôle minimal. Dégradation gracieuse, pas de panne.
Les couches de l'architecture
L'audit a inventorié 1 047 sections RAG actives réparties sur 215 entités distinctes (agents + skills + learned-skills). Voici la distribution par type de section :
| Type de section | Nombre | Contenu |
|---|---|---|
| process | 201 | Procédures pas à pas |
| reference | 177 | Tables de référence, APIs, SQL views |
| edge_cases | 173 | Cas limites, erreurs connues, gotchas |
| role | 128 | Description détaillée du rôle |
| output_format | 63 | Templates, structures de sortie |
| best_practices | 58 | Principes et patterns recommandés |
| invocation | 50 | Contexte d'utilisation, triggers |
| responsibilities | 48 | Responsabilités spécifiques |
| extended | 40 | Connaissances domaine approfondies |
| examples | 34 | Exemples étendus |
| skills_used | 27 | Références aux skills réutilisables |
| parameters | 22 | Paramètres configurables |
| other | 15 | Contenu divers |
| search_priority | 11 | Priorités de recherche sémantique |
Cette granularité est intentionnelle. Quand un agent exécute une tâche de révision de code, il charge process, edge_cases et output_format. Il ne charge pas reference ni extended si ce n'est pas pertinent. Le chargement est ciblé, pas exhaustif.
Les skills (535 sections) sont des procédures réutilisables partagées entre plusieurs agents. Un skill french-typography est utilisé par le rédacteur, le planificateur et le réviseur de contenu. Il est stocké une seule fois dans RAG, associé à plusieurs agents. Pas de duplication, une seule source de vérité.
Les agents (461 sections) contiennent les instructions spécifiques à chaque rôle. Les learned-skills (49 sections, 12 entités) sont une catégorie à part : ils n'existent pas au moment du développement. Ils sont créés automatiquement pendant l'exécution.
Le cycle d'apprentissage automatique
C'est la partie de l'architecture qui me fascine le plus, parce qu'elle change fondamentalement la relation entre un agent et le travail qu'il fait.
Le principe : après chaque tâche non triviale, l'agent évalue ce qu'il vient d'apprendre et décide s'il faut le capturer pour la prochaine fois.
Phase 1 : le notepad pendant l'exécution
Pendant qu'un agent travaille, il note ses découvertes en temps réel :
echo "[gotcha] Windows .env a des CRLF — utiliser split(/\r?\n/) pas split('\n')" >> /tmp/learning-notes.md
echo "[api] OpenProject v3 utilise HAL+JSON, pagination offset 1-based" >> /tmp/learning-notes.md
echo "[efficiency] 12 requêtes SQL pour l'audit RAG → 1 appel rag_audit() suffit" >> /tmp/learning-notes.md
Les catégories (api, gotcha, pattern, library, workaround, efficiency) permettent de qualifier chaque note. La note [efficiency] est particulièrement puissante : elle déclenche automatiquement la création d'un artefact de réduction d'étapes.
Phase 2 : l'évaluation post-tâche
Après completion, l'agent lit le notepad et cherche dans RAG :
SELECT agent_name, section_title, LEFT(content, 150)
FROM rag_agent_instructions
WHERE metadata->>'type' IN ('skill', 'learned-skill')
AND active = true
AND (
section_title ILIKE '%docker%'
OR content ILIKE '%vhdx%'
)
ORDER BY created_at DESC LIMIT 10;
Selon les résultats, il prend une décision parmi quatre :
| Décision | Condition | Action |
|---|---|---|
| NEW | Aucun skill correspondant + critères remplis | Crée un SKILL.md + seed pgvector |
| IMPROVE | Skill existant mais incomplet | UPDATE du contenu RAG |
| OPTIMIZE | Note [efficiency] dans le notepad | Crée artefact PgSQL/Bun + skill |
| NONE | Tâche triviale ou skill existant couvre tout | Rien, avec justification |
Phase 3 : la création du skill
Quand la décision est NEW, l'agent génère un fichier SKILL.md temporaire et le seed dans pgvector :
bun ~/.claude/scripts/rag-history/seed-single-agent.ts \ --skill learned-build-error-docker-vhdx-compact \ --project global \ --learned-from mgrr-agent-build-error-resolver
Le skill est ensuite disponible pour tous les agents lors du recall au démarrage. La prochaine fois qu'un agent rencontre un problème de compaction VHDX Docker, il retrouve la procédure exacte sans devoir la redécouvrir.
Les douze learned-skills actifs
L'audit a révélé douze skills auto-capturés couvrant des domaines très variés :
- learned-docker-vhdx-compact : compaction manuelle d'un disque virtuel Docker sur Windows
- learned-svelte5-effect-untrack-write : workaround Svelte 5 pour les effets réactifs avec untrack()
- learned-xtts-cosyvoice2-eu-windows : configuration de la synthèse vocale CosyVoice2 sur Windows
- learned-gmail-rag-sync : synchronisation incrémentale Gmail vers pgvector
- learned-rag-opt-action-history : optimisation de l'historique d'actions dans RAG
- learned-disk-pgvector-scanner : diagnostic d'espace disque pgvector
Ces skills n'auraient jamais été écrits manuellement. Ils existent parce que l'agent a rencontré le problème, l'a résolu, et a décidé que ça valait la peine d'être mémorisé.
Les résultats de l'audit
L'audit a porté sur trois axes de vérification :
Inventaire global :
- 48 fichiers .md agents, tous sous les 70 lignes (conformité 100 %, maximum observé : 67 lignes)
- 1 047 sections RAG actives
- ~449 Ko de contenu indexé dans pgvector
- Économie effective de -70 % de tokens système
Distribution des types :
skill : 535 sections (procédures réutilisables) agent : 461 sections (instructions par agent) learned-skill: 49 sections (12 skills auto-capturés)
Trois points de contrôle vérifiés :
- ✅ Agents sans couverture RAG : 0 (100 % des agents ont leurs sections RAG complètes)
- ✅ Recall tracking : bug corrigé (voir section suivante)
- ✅ TTL 30 jours : pruning automatique ajouté
Ces chiffres sont la photographie d'un système qui tourne depuis plusieurs mois. La croissance est organique : chaque tâche complexe est susceptible d'ajouter un learned-skill. Le contenu RAG s'enrichit sans intervention manuelle.
Conclusion : une architecture qui vieillit mieux
Ce qui me plaît dans cette architecture, c'est qu'elle répond à un problème commun à toutes les équipes qui industrialisent des agents IA : la maintenance.
Les agents monolithiques dégradent vite. Plus on ajoute d'instructions, plus le coût token augmente, plus les agents deviennent lents et imprévisibles. La tentation de « juste ajouter une ligne » finit par créer des fichiers de configuration impossibles à maintenir.
L'approche RAG-First inverse cette dynamique :
- Le fichier .md reste petit et stable. On ne le touche presque jamais.
- Les instructions détaillées vivent dans pgvector, versionnées, auditables, accessibles via SQL.
- Les learned-skills s'accumulent organiquement sans effort de documentation.
- Le TTL fait le ménage automatiquement.
Ce n'est pas une solution parfaite. La dépendance à pgvector introduit un composant d'infrastructure supplémentaire. La requête SQL au démarrage ajoute quelques dizaines de millisecondes. Et il faut s'astreindre à une discipline : tout contenu substantiel va dans RAG, pas dans le .md.
Mais pour une infrastructure de 48 agents qui évolue quotidiennement, le gain est structurel. -70 % de tokens système, 12 skills auto-appris, 0 agent sans couverture RAG. Ce sont des chiffres qui tiennent dans le temps.
La prochaine étape : implémenter la recherche sémantique sur les learned-skills au démarrage, plutôt que la recherche par mots-clés. Quand un agent adopté pour du débogage TypeScript peut automatiquement retrouver un learned-skill sur un bug similaire rencontré il y a trois semaines par un autre agent, l'architecture commence vraiment à ressembler à une mémoire collective.
Qui suis je ?
Je suis Mathieu GRENIER, CTO d'Easystrat une startup de Montpellier, en France. Je manage une équipe d'une dizaine d'ingénieurs (Graphistes, IA, frontend, backend, devOps, AWS) en remote depuis le Japon.
J'ai aussi mon activité de freelance, où je conseille des entrepreneurs dans leurs projets d'application.
Avec mon expérience personnelle de plus de 15 ans en ESN, j'ai pu travailler pour un large panel d'entreprises de différentes tailles. Ma compréhension des problèmes métiers est une de mes grandes forces et permet à mes clients de pouvoir se projeter plus facilement.
L'essentiel de mon travail consiste à canaliser l'énergie des entrepreneurs sur l'essence même de leur projet.
La technologie, les méthodes, le management sont le cœur de mes compétences.
Vous pouvez me faire confiance sur ces points là.
Si vous voulez me parler d'un de vos projets, n'hésitez pas à m'envoyer un email avec vos disponibilités à : contact@mathieugrenier.fr
Tous les articles de ce blog sont écrits par moi, même si je peux m'aider de l'IA pour illustrer mes propos. Mais jamais je ne fournis d'articles 100% IA.
Architecture RAG-First : comment mes agents Claude apprennent seuls