lean-ctx va au-delà de la correspondance de motifs. Six algorithmes issus de la théorie de l'information, de la théorie des graphes et de la mécanique statistique travaillent ensemble pour décider quoi garder, quoi supprimer et où le placer - le tout automatiquement, localement, sans aucune configuration.
Ces algorithmes alimentent la couche d'intelligence autonome. Ils s'activent lors de chaque appel à ctx_read, ctx_preload et ctx_overview - vous ne les invoquez jamais directement.
Comment les couches interagissent
| Algorithme | Décide | Basé sur |
|---|---|---|
| Spectral Relevance | Quels fichiers sont importants | Graphe de dépendances + PageRank |
| Boltzmann Allocation | Combien de tokens par fichier | Spécificité de la tâche + score de pertinence |
| Predictive Surprise | Quelles lignes conserver | Entropie croisée des tokens BPE |
| MMR Deduplication | Quelles lignes sont redondantes | Similarité de Jaccard par bigrammes |
| Semantic Chunking | Comment ordonner la sortie | Frontières AST + flux d'attention |
| BPE Optimization | Comment encoder le texte final | Règles de compression au niveau des tokens |
Score de surprise prédictive
Les filtres de compression traditionnels utilisent l'entropie de Shannon sur les caractères bruts, ce qui traite aaaa et import comme également prévisibles. La surprise prédictive mesure plutôt l'entropie croisée par rapport à la fréquence des tokens BPE - à quel point chaque ligne est surprenante pour le tokenizer du LLM.
Comment ça fonctionne
- Chaque ligne est tokenisée à l'aide de
o200k_base(tokenizer GPT-4o / Claude). - Pour chaque token, un a priori zipfien estime la fréquence attendue en fonction du rang.
- L'entropie croisée est calculée : les lignes avec des tokens courants (code standard) obtiennent un score bas ; les lignes avec des tokens rares (logique complexe) obtiennent un score élevé.
- Les lignes en dessous du seuil de surprise sont candidates à la suppression lors de la compression agressive.
Exemple
// Low surprise (boilerplate) - candidate for removal:
return Ok(()); // surprise: 0.12
use std::collections::HashMap; // surprise: 0.18
// High surprise (unique logic) - always preserved:
let decay = (-alpha * dist as f64).exp(); // surprise: 0.89
scores[j] += heat[i] * decay / degree; // surprise: 0.94 Pourquoi c'est important
La surprise prédictive supprime 15 à 30 % de code standard de plus que l'entropie au niveau des caractères, tout en préservant la logique complexe. Elle modélise directement ce que le LLM considère comme « informatif » car elle utilise le même vocabulaire BPE.
Propagation de pertinence spectrale
Lorsque vous demandez à lean-ctx de précharger le contexte pour une tâche, il doit décider quels fichiers sont importants. La simple correspondance par mots-clés ne trouve que les fichiers qui mentionnent vos termes de recherche. La pertinence spectrale trouve les fichiers qui sont structurellement connectés aux fichiers pertinents - même s'ils ne partagent aucun mot-clé.
Comment ça fonctionne
Deux algorithmes de graphe s'exécutent sur le graphe de dépendances du projet :
- Diffusion de chaleur - Les fichiers sources correspondant à la description de la tâche reçoivent une « chaleur » initiale. La chaleur se propage le long des arêtes d'import avec une décroissance exponentielle, simulant le flux d'information à travers la base de code.
- Centralité PageRank - Les fichiers importés par de nombreux autres fichiers reçoivent des scores de centralité plus élevés. Cela identifie les hubs structurels (par exemple, un
db.tsimporté par 20 modules).
Le score de pertinence final combine les deux : 0.7 × chaleur + 0.3 × pagerank. Les fichiers en dessous d'un seuil sont exclus du préchargement.
Exemple
Task: "fix authentication bug"
Direct matches: auth.ts, login.ts
Heat diffusion adds: middleware.ts (imports auth.ts)
session.ts (imported by auth.ts)
PageRank promotes: db.ts (imported by 18 files - structural hub)
Result: 5 files preloaded instead of 2, covering the full blast radius. Zéro configuration
Le graphe de dépendances se construit automatiquement à la première utilisation via load_or_build(). Aucun ctx_graph build nécessaire - cela fonctionne tout seul.
Allocation de contexte de Boltzmann
Une fois que la pertinence spectrale a sélectionné les fichiers pertinents, chaque fichier a besoin d'un budget de tokens. Les approches naïves attribuent des budgets égaux ou trient par pertinence. L'allocation de Boltzmann utilise la mécanique statistique pour distribuer les tokens de manière optimale.
Comment ça fonctionne
- Chaque fichier possède un score de pertinence Ei issu de la pertinence spectrale.
- Un paramètre de température β est dérivé de la tâche : les tâches spécifiques ("corriger le bug d'authentification dans login.ts") produisent une température basse (allocation concentrée sur les fichiers prioritaires) ; les tâches larges ("refactoriser la base de code") produisent une température élevée (distribution uniforme).
- Les budgets de tokens suivent la distribution de Boltzmann :
budgeti = total × (eβ·Ei / Σ eβ·Ej) - Des budgets minimum et maximum sont appliqués (128–4096 tokens par fichier), et le mode de compression (
full,map,signatures) est choisi en fonction du budget alloué.
Exemple
Task: "fix the JWT validation in auth middleware"
Task specificity: 0.85 (specific) → β = 4.2
File | Relevance | Budget | Mode
auth.ts | 0.92 | 3,200 | full
middleware.ts | 0.78 | 1,800 | full
session.ts | 0.45 | 420 | map
db.ts | 0.31 | 180 | signatures
routes.ts | 0.22 | 128 | signatures
─────
Total: 5,728 tokens (within 8,000 budget) Reciprocal Rank Fusion (RRF) Cache Eviction
lean-ctx uses Reciprocal Rank Fusion for cache eviction decisions, replacing the earlier Boltzmann-inspired weighted scoring. RRF handles incomparable signals (time in seconds, frequency as counts, size in tokens) without arbitrary weight tuning.
| Aspect | Legacy (Boltzmann) | Current (RRF) |
|---|---|---|
| Signal handling | Mixed units in one formula (0.4×recency + 0.3×frequency + 0.3×size) | Each signal ranked independently, then fused |
| Weight tuning | Requires manual weight calibration (arbitrary 0.4/0.3/0.3) | No weights - only K=60 (standard IR parameter) |
| Edge cases | Large files dominate due to log-scaling of size | Fair treatment - each signal contributes equally via rank |
Formula: RRF(d) = Σ 1/(K + ranki(d)) - entries with the lowest fused score are evicted first. This produces monotonically correct ordering regardless of signal magnitude differences.
Découpage sémantique avec ponts d'attention
Les LLM souffrent du problème « Perdu au milieu » : l'information en début et en fin de contexte reçoit plus d'attention que le contenu au milieu. Le découpage sémantique restructure la sortie pour minimiser la perte d'information.
Comment ça fonctionne
- Détection de blocs - Les lignes sources sont regroupées en blocs sémantiques (fonctions, types, imports, logique libre) en se basant sur les heuristiques de frontières AST.
- Ordonnancement par pertinence - Les blocs correspondant à la tâche en cours sont promus en haut (position de haute attention). Les blocs restants sont ordonnés par priorité de type.
- Ponts d'attention - Entre les blocs, lean-ctx insère des marqueurs de pont minimaux (
---) pour que le LLM reconnaisse les frontières structurelles. - Ancres de fin - Les 2 à 3 dernières lignes du bloc le plus prioritaire sont répétées à la toute fin de la sortie, exploitant le biais de récence pour les informations critiques.
Exemple
// Without chunking (flat output):
import { db } from '../pages/docs/db';
import { hash } from '../pages/docs/crypto';
const MAX_RETRIES = 3;
export function createUser(...) { ... }
export function validateToken(...) { ... } ← lost in the middle
export function deleteUser(...) { ... }
// With semantic chunking (task: "fix token validation"):
export function validateToken(...) { ... } ← promoted to top
---
export function createUser(...) { ... }
export function deleteUser(...) { ... }
---
import { db } from '../pages/docs/db';
const MAX_RETRIES = 3;
---
// anchor: validateToken signature ← tail anchor Déduplication MMR
Lorsque plusieurs fichiers sont chargés dans le contexte, ils contiennent souvent des imports dupliqués, du code standard partagé ou des motifs de code très similaires. La pertinence marginale maximale (MMR) supprime cette redondance tout en préservant l'information unique.
Comment ça fonctionne
- Pour chaque ligne, calcule la similarité de Jaccard par bigrammes par rapport à toutes les lignes précédemment sélectionnées (l'« ensemble de couverture »).
- Le score MMR équilibre la pertinence et la redondance :
MMR(l) = λ × relevance(l) - (1 - λ) × max_similarity(l, selected) - Les lignes avec
MMR < 0sont supprimées - elles ajoutent plus de redondance que d'information. Le paramètre λ est fixé par défaut à 0.7 (favorisant la pertinence par rapport à la diversité).
Impact
Lors d'un préchargement multi-fichiers typique, le MMR supprime 10 à 25 % du contenu redondant - principalement les imports partagés et les motifs utilitaires répétés.
Optimisation de tokens alignée BPE
Après la sélection et l'ordonnancement de tout le contenu, une passe finale optimise le texte brut pour le tokenizer BPE du LLM. De petits changements de formatage peuvent réduire significativement le nombre de tokens sans altérer la sémantique.
Règles d'optimisation
| Avant | Après | Économie de tokens |
|---|---|---|
function | fn | 1 token par occurrence |
-> | -> | 2 → 1 token |
=> | => | 2 → 1 token |
{ } | {} | 2 → 1 token |
(4 espaces) | (2 espaces) | ~50 % d'économie sur l'indentation |
'static durée de vie 'static | élidé lorsque c'est sûr | 2 tokens par occurrence |
Comment ça fonctionne
Chaque règle est un simple remplacement de chaîne appliqué ligne par ligne après toutes les autres étapes de compression. Les règles sont dérivées de l'analyse des frontières de tokens BPE - elles ciblent les motifs où le tokenizer produit inutilement trop de tokens pour un texte sémantiquement équivalent.
Impact
L'optimisation BPE permet généralement d'économiser 3 à 8 % de tokens supplémentaires sur un contenu déjà compressé. Les économies se cumulent entre les fichiers et sont les plus significatives pour les langages verbeux (TypeScript, Java, C#).
Vérifier l'impact
Exécutez lean-ctx benchmark run dans votre projet pour mesurer l'effet combiné des six algorithmes. Le rapport de benchmark affiche les économies de tokens par fichier, les scores de préservation (AST, identifiants, lignes) et les ratios de compression globaux.
$ lean-ctx benchmark run
──────────────────────────────────────────
BENCHMARK - /Users/you/project
──────────────────────────────────────────
Files: 143
Total: 285,401 → 42,810 tokens (85% reduction)
Avg/file: 1,997 → 300 tokens
Preservation:
AST: 98.2%
Identifiers: 97.4%
Lines: 96.1%
Mode breakdown:
full: 68% of files
map: 22% of files
signatures: 8% of files
aggressive: 2% of files Reconnaissance structurée d'intention
lean-ctx classe chaque interaction en un StructuredIntent - une représentation à slots contenant le type de tâche, la confiance, les fichiers cibles, la portée, l'indice de langue, l'urgence et le verbe d'action. Cela pilote toutes les décisions en aval : quel mode de compression utiliser, comment router le contexte et quoi prioriser.
9 types de tâches sont reconnus : Explore, Generate, FixBug, Refactor, Test, Review, Config, Deploy et Document. Chaque type déclenche des stratégies de compression et un routage de contexte différents.
IntentScope va de SingleFile à ProjectWide en passant par MultiFile et CrossModule - déterminant l'étendue de la collecte de contexte.
Comment ça fonctionne
La compression s'adapte par intention : les tâches FixBug priorisent les lignes d'erreur et les fichiers de test via le filtre Information Bottleneck, les tâches Explore utilisent un nettoyage léger pour préserver la structure, et les tâches Generate se concentrent sur les signatures et les types.
Le sélecteur de mode automatique de ctx_read utilise le type de tâche actif pour affiner sa décision - choisissant le mode task pour les corrections de bugs sur les gros fichiers, le mode map pour l'exploration et le mode signatures pour les tâches de documentation.
Exemple
Query: "fix the NaN bug in entropy.rs"
StructuredIntent:
task_type: FixBug (confidence: 0.95)
targets: ["entropy.rs"]
scope: SingleFile
language: Rust
urgency: 0.8
action_verb: "fix"
→ Compression: Information Bottleneck filter (error lines boosted)
→ Mode: task (error-focused extraction)
→ Suggestions: tests/entropy_test.rs (deficit detection) Architecture du pipeline de contexte
Le pipeline de contexte traite l'information à travers six couches distinctes : Input → Intent → Relevance → Compression → Translation → Delivery. Chaque couche a des contrats définis (types d'entrée/sortie) et émet des métriques.
Comment ça fonctionne
Input → Intent → Relevance → Compression → Terse Engine → Delivery
│ │ │ │ │ │
│ │ │ │ │ └─ Final output to LLM
│ │ │ │ └─ 4-layer terse pipeline (see below)
│ │ │ └─ AST-aware compression per intent
│ │ └─ Graph heat + relevance scoring
│ └─ StructuredIntent classification
└─ Raw file content / shell output Les métriques par couche suivent les tokens d'entrée, les tokens de sortie, le taux de compression et le temps de traitement. Agrégées sur une session, elles révèlent où les plus grandes économies se produisent et quelles couches sont des goulots d'étranglement.
4-Layer Terse Engine
The terse engine applies four composable compression layers, controlled by
compression_level
(Off / Lite / Standard / Max). Each layer is independently verified by Lean4 proofs
(TerseQuality, TerseEngine — part of 82 total theorems).
| Layer | Name | What it does |
|---|---|---|
| 1 | Dictionary | Common token substitutions and abbreviations (function → fn, return → ret) |
| 2 | Residual | Whitespace normalization, blank-line collapse, boilerplate removal |
| 3 | Scoring | Information-theoretic ranking — keeps high-surprise blocks, prunes low-entropy filler |
| 4 | Pipeline | CEP v1 protocol: delta-only output, structured notation (+/-/~), token budgets |
Registre de contexte et gestion de la pression
Le ContextLedger suit chaque fichier envoyé à l'IA : chemin, mode de compression, tokens originaux, tokens envoyés et horodatage. Il calcule l'utilisation de la fenêtre de contexte et la pression en temps réel.
Comment ça fonctionne
Trois niveaux de pression : None (moins de 70% d'utilisation), Compress (70–90%) et Evict (plus de 95%). À chaque niveau, le système prend des actions différentes - rétrogradation des modes de compression pour les fichiers moins pertinents ou suggestion d'évictions.
Exemple
Context Window: 128,000 tokens
Loaded: 89,600 tokens (70% utilization)
Pressure: None → safe
After loading 3 more files:
Loaded: 115,200 tokens (90% utilization)
Pressure: Compress → downgrade non-target files
Re-Injection Plan:
utils.rs: full → signatures (save 2,400 tokens)
helpers.rs: full → map (save 1,800 tokens)
config.rs: full → signatures (save 1,200 tokens)
Protected: auth.rs, login.ts (target files) La détection de déficit de contexte identifie les informations manquantes : si une correction de bug cible auth.rs mais qu'aucun fichier de test n'est chargé, le système suggère tests/auth_test.rs. Pour les tâches de configuration, il recommande Cargo.toml, .env ou Dockerfile.
La réinjection intelligente génère un plan pour libérer du budget de contexte en rétrogradant les fichiers non ciblés (par ex. passage du mode full au mode signatures) tout en protégeant les fichiers critiques pour l'intention courante.
Intelligence multi-agent
Lorsque plusieurs agents IA collaborent (par ex. un codeur et un réviseur), lean-ctx fournit des transferts structurés, une profondeur de contexte basée sur le rôle et un partage de connaissances inter-agents.
Comment ça fonctionne
HandoffPackage regroupe le registre de session actuel, l'intention structurée et l'instantané du contexte en une unité transférable - afin que l'agent récepteur démarre avec une conscience situationnelle complète au lieu d'une page blanche.
Sept rôles d'agents sont reconnus : Coder, Reviewer, Planner, Explorer, Debugger, Tester et Orchestrator. Chacun reçoit une ContextDepthConfig adaptée - un Codeur obtient plus de lectures complètes, un Réviseur plus de signatures, un Explorateur un contexte graphique plus large.
Exemple
Agent "coder-1" (role: Coder):
max_files_full: 8
preferred_mode: full
context_budget: 80%
Agent "reviewer-1" (role: Reviewer):
max_files_full: 3
preferred_mode: signatures
context_budget: 60%
Shared Knowledge:
K:discovery:auth_bug = "null check missing in line 42"
K:decision:fix_approach = "add Option<T> wrapper"
→ reviewer-1 inherits these facts without re-reading files Le partage de connaissances inter-agents permet aux agents d'échanger des faits structurés (par ex. "discovery:auth_bug=vérification null manquante ligne 42") via un bloc-notes partagé. Les nouveaux agents héritent des connaissances pertinentes sans les redécouvrir.
Community Detection (Louvain)
The core::community module clusters files by their dependency graph using the
Louvain algorithm. This groups tightly-coupled files into communities, enabling
more intelligent context selection — files in the same community as your target are prioritized
for preloading and receive higher relevance scores during task-driven reads.
Code Smell Detection
The ctx_smells tool detects long functions, deep nesting, and high cyclomatic complexity
using the core::smells module. Detected smells are scored with graph-enriched weighting —
files with high PageRank or many dependents receive amplified smell scores, surfacing maintenance
hotspots that have the widest blast radius across the codebase.