Aller au contenu principal
Comment Code Buddy gère 200K tokens sans perdre la mémoire
Retour au blog
IA

Comment Code Buddy gère 200K tokens sans perdre la mémoire

Patrice Huetz2 avril 202611 min

Il est 16h. Tu travailles avec un agent IA depuis ce matin sur un refactoring massif. L'agent a lu 47 fichiers, exécuté 112 commandes, analysé 23 résultats de tests. Ton historique de conversation fait 180 000 tokens. Il reste 20 000 tokens de fenêtre — et l'agent commence à oublier des décisions prises ce matin.

Tu as deux options : relancer une session fraîche (et perdre tout le contexte de la journée) ou continuer avec un agent qui hallucine. Les deux sont mauvaises.

Code Buddy propose une troisième option : un Context Engine à 7 hooks qui orchestre 6 stratégies de compression et 9 types de mémoire. Le résultat ? Des sessions de plusieurs heures sur des codebases de millions de lignes, sans dégradation.

Voici comment ça fonctionne sous le capot.

Le problème universel : la fenêtre qui se remplit

Tous les agents IA souffrent du même problème fondamental. La fenêtre de contexte est finie. Chaque fichier lu, chaque commande exécutée, chaque message échangé consomme des tokens. Et quand la fenêtre est pleine, il faut choisir quoi garder et quoi jeter.

Les solutions classiques sont toutes insatisfaisantes :

  • Résumer — on perd des détails critiques (quel était le message d'erreur exact ? quelle ligne posait problème ?)
  • Tronquer — on supprime l'historique le plus ancien, qui contient souvent les décisions architecturales fondamentales
  • Ignorer — on espère que le modèle se débrouille, et il finit par halluciner
ℹ️
Code Buddy (github.com/phuetz/code-buddy) n'est pas un prototype académique. C'est un agent de développement en production : environ 500 000 lignes de TypeScript, 110+ outils intégrés, 15 providers LLM supportés. C'est le terrain d'épreuve où la théorie de la compression de contexte rencontre la réalité.

Le problème est d'autant plus aigu que les agents de code sont gourmands. Un simple cat fichier.ts sur un fichier de 500 lignes consomme ~2 000 tokens. Un résultat de npm test avec 40 tests peut facilement faire 5 000 tokens. En une heure de travail intensif, un agent consomme facilement 100 000 tokens de résultats d'outils — la moitié de sa fenêtre.

Les 7 hooks du cycle de vie

Le cœur du Context Engine est une interface TypeScript à 7 hooks. Chaque hook correspond à un moment précis dans le cycle requête-réponse de l'agent :

Hook 1 : `bootstrap()` — l'initialisation

Au démarrage de la session, le système charge les instructions projet (CLAUDE.md, AGENTS.md), récupère les mémoires persistantes de la base SQLite, configure les budgets token par catégorie, et initialise les indices de recherche sémantique.

Le point clé ici, c'est le budget token :

typescript
this.budget = TokenBudget.forModel(config.model, {
  system:       0.08,  // 8% pour le prompt système
  instructions: 0.03,  // 3% pour les instructions projet
  code:         0.18,  // 18% pour le code source
  tools:        0.13,  // 13% pour les résultats d'outils
  conversation: 0.53,  // 53% pour la conversation
  memory:       0.04,  // 4% pour la mémoire persistante
  margin:       0.01,  // 1% de marge de sécurité
});

Chaque catégorie a un budget fixe. Quand une catégorie déborde, elle déclenche la compression — pas la suppression.

Hook 2 : `ingest()` — le tri à l'entrée

Chaque message entrant passe par trois opérations : classification (type, importance, catégorie), scoring d'importance (0.0 à 1.0), et transformation optionnelle. Un résultat d'outil volumineux peut être immédiatement compressé de façon réversible avant même d'entrer dans le contexte.

Hook 3 : `assemble()` — la construction du prompt

L'opération la plus critique. Le système construit le prompt final en respectant un ordre de priorité strict : prompt système (toujours inclus intégralement), instructions projet, mémoire persistante, messages à haute importance (score > 0.8), puis les messages moyens et faibles en fonction du budget restant.

Hook 4 : `compact()` — la compression

Quand on approche les limites, compact() déclenche les stratégies de compression selon le niveau d'utilisation : stratégie légère à 60 %, agressive à 85 %, urgente à 95 %.

Hook 5 : `afterTurn()` — l'extraction de connaissances

Après chaque tour de conversation, le système extrait les faits, met à jour les indices de mémoire, et applique le decay temporel. C'est ici que l'agent « apprend » de chaque interaction.

Hook 6 et 7 : les sous-agents

prepareSubagentSpawn() sélectionne un sous-ensemble pertinent du contexte pour un agent enfant. onSubagentEnded() fusionne les résultats quand il revient. C'est ce qui permet la parallélisation des tâches sans exploser la mémoire.

Les 6 stratégies de compression

C'est là que ça devient vraiment intéressant. Le Context Engine ne se contente pas de « résumer » — il utilise 6 stratégies spécialisées, chacune inspirée de la recherche récente.

1. Importance-weighted scoring

Chaque message reçoit un score basé sur son type :

Type de messageScore d'importance
System prompt1.00
Error/exception0.95
Code generation0.70
Tool result (fichier lu)0.50
Conversation courante0.25
Acknowledgment (« ok », « compris »)0.05
💡
Les messages « ok » et « compris » font en moyenne 3-5 tokens chacun, mais sur une session de 200 tours, ça fait 600-1000 tokens de bruit pur. Le scoring d'importance les élimine en premier lors de la compression — récupération gratuite de budget.

2. Observation masking (inspiré JetBrains)

L'idée : masquer les outputs d'outils qui ne sont plus pertinents. Si tu as lu un fichier il y a 50 tours et que tu ne l'as plus référencé depuis, son contenu est remplacé par un placeholder : [output masqué — 2 340 tokens — restaurable]. Résultat mesuré par JetBrains : -7 % de coût en tokens, +2,6 % de résolution de tâches. Moins de bruit = meilleure qualité.

3. Restorable compression (inspiré Manus AI)

C'est la stratégie la plus élégante. Au lieu de supprimer un message, on le remplace par un résumé court + un identifiant. Si l'agent a besoin du contenu original plus tard, il peut appeler restore_context(id) pour le récupérer. Compression réversible.

typescript
// Avant : 2 340 tokens
"Le fichier auth.service.ts contient 187 lignes avec
les fonctions login(), register(), validateToken()..."

// Après : 45 tokens
"[résumé: auth.service.ts — 3 fonctions auth — id:ctx_a7f3]"

4. JIT context discovery (inspiré Gemini CLI)

Les instructions projet ne sont pas chargées en bloc au démarrage. Elles sont découvertes dynamiquement quand l'agent explore le filesystem. Si l'agent entre dans /src/auth/, le système cherche un .context.md dans ce répertoire et l'injecte. Résultat : les instructions pertinentes sont toujours présentes, les autres ne consomment jamais de tokens.

5. Partial summarization

Résumé sélectif des parties les moins critiques. Pas un résumé global de toute la conversation — un résumé ciblé des zones à faible importance, préservant intégralement les zones à haute importance.

6. Proactive compaction

Avant même de compresser, le système flush les faits et patterns extraits vers la mémoire persistante (SQLite). Comme ça, même si le message source est compressé, l'information survit dans la base de données et peut être réinjectée dans les prochaines sessions.

⚠️
Sans proactive compaction, la compression est destructive : on perd de l'information définitivement. Avec, c'est un transfert : l'information migre de la fenêtre de contexte (volatile) vers la mémoire persistante (durable). C'est la différence entre oublier et archiver.

Les 9 types de mémoire

Le Context Engine catégorise les souvenirs en 9 types, chacun avec son propre cycle de vie :

TypeExempleDecay
fact« Le projet utilise PostgreSQL 15 »Lent
preference« L'utilisateur préfère les arrow functions »Très lent
pattern« Les fichiers de test sont en *.spec.ts »Lent
decision« On a choisi JWT au lieu de sessions »Aucun
context« On travaille sur le module auth »Rapide
summary« Résumé de la session de refactoring »Moyen
instruction« Toujours utiliser ESLint avant de commiter »Aucun
error« Le bug #42 était un off-by-one dans la pagination »Moyen
definition« UserDTO = { id, email, name, role } »Lent

Le decay temporel est crucial : les faits contextuels (« on travaille sur auth ») perdent leur pertinence rapidement, tandis que les décisions architecturales ne décayent jamais. Un système de mémoire sans decay finit par noyer les informations récentes sous les anciennes.

Pour aller plus loin

Le Context Engine de Code Buddy est détaillé dans le chapitre 12 de « La Mémoire des Machines » — avec le code TypeScript complet de chaque hook, les benchmarks de compression, et les leçons apprises en production.

La Mémoire des Machines
La Mémoire des Machines

Du KV-Cache au Context Engineering.

Découvrir →

Si tu veux comprendre le pattern qui complète le Context Engine — le Ralph Loop, qui élimine la dégradation en relançant l'agent avec un contexte frais à chaque tâche — j'ai un livre dédié.

La Boucle Ralph
La Boucle Ralph

Guide Pratique du Coding Autonome par IA.

Découvrir →
No cover
Code Buddy Narratif

Agent IA de production -- edition narrative

Découvrir →
🔒

Soutenez mon travail sur Patreon

Accès anticipé aux articles, contenu exclusif, et la satisfaction de soutenir un auteur indépendant.

Rejoindre — à partir de 3€/mois

Commentaires

Chargement des commentaires...

Laisser un commentaire