Faire coder un LLM pour lire 10 millions de tokens - Le fonctionnement de RLM
Une fenêtre de contexte plus grande ne rend pas l'IA plus intelligente. RLM change la donne en laissant les LLM écrire du code pour lire sélectivement des documents massifs.
On nous promet des fenêtres de contexte toujours plus grandes. 128K, 1M, bientôt 10M tokens. L’idée implicite : si le modèle peut tout ingérer, il comprendra mieux. C’est faux. Et RLM (Recursive Language Model) part de ce constat pour proposer une approche radicalement différente.
La pourriture du contexte : pourquoi plus de tokens ne signifie pas plus d’intelligence
Un LLM calcule des distributions de probabilité sur chaque token. Plus la séquence d’entrée s’allonge, plus le bruit s’accumule. Les modèles à 128K ou 1M de tokens affichent leur meilleure précision aux alentours de 10K tokens. Au-delà de 100K, la qualité chute brutalement - c’est ce qu’on appelle la pourriture du contexte (context rot).
Concrètement, gaver un modèle avec un corpus entier de documentation revient à lui demander de trouver une aiguille dans une botte de foin tout en augmentant la taille de la botte à chaque requête. Le modèle ne lit pas mieux : il noie l’information pertinente dans un océan de tokens inutiles. Les benchmarks le confirment systématiquement : la performance de rappel (needle-in-a-haystack) s’effondre bien avant d’atteindre la limite théorique de la fenêtre de contexte.
La solution n’est donc pas d’agrandir la fenêtre. C’est de lire plus intelligemment.
L’idée centrale de RLM : le LLM écrit du code pour lire
RLM renverse le paradigme. Au lieu de tout charger dans le contexte, on stocke les 10 millions de tokens dans des variables Python. Le LLM n’ingère jamais l’intégralité du corpus. Il écrit du code pour accéder sélectivement aux parties dont il a besoin.
L’analogie est parlante : le LLM devient le processeur (CPU), et le texte fait office de disque dur. Le modèle ne charge jamais tout en mémoire vive. Il effectue des lectures ciblées, traite environ 50K tokens pertinents à la fois, puis passe à la suite. Sur un corpus de 10 millions de tokens ou plus, seule la fraction nécessaire transite par la fenêtre de contexte à chaque instant.
C’est un changement de philosophie fondamental. On passe d’un modèle passif qui reçoit tout à un agent actif qui décide quoi lire.
Les trois composants de l’architecture
RLM repose sur trois briques interconnectées :
1. RLM Orchestrator (le contrôleur) C’est le chef d’orchestre. Il gère le flux d’exécution, maintient l’historique des actions et décide quand le processus est terminé. Il envoie les instructions au LLM et récupère le code généré pour l’exécuter dans l’environnement sandboxé.
2. LMHandler (serveur socket pour le relais API) Un serveur socket qui fait le pont entre l’orchestrateur et l’API du modèle de langage. Il gère les appels, le formatage des prompts et la communication asynchrone. Cette couche d’abstraction permet de brancher n’importe quel fournisseur de LLM sans modifier le reste de l’architecture.
3. Environment / REPL (sandbox Python)
Un environnement Python isolé qui contient deux éléments essentiels : la variable context (qui stocke l’intégralité du corpus en mémoire Python, pas dans le contexte du LLM) et la fonction llm_query() qui permet au code généré de rappeler récursivement le modèle. C’est cette récursivité qui donne son nom à RLM : le modèle peut, depuis le code qu’il a lui-même écrit, poser de nouvelles questions au LLM sur des sous-ensembles de données.
Le flux d’exécution en quatre phases
À chaque itération, le LLM produit du code Python qui est exécuté dans le sandbox. Le processus suit quatre phases distinctes :
Explorer - Le modèle commence par examiner la structure des données. Il écrit du code pour inspecter les clés, compter les documents, échantillonner quelques extraits. Il cartographie le terrain avant de plonger.
Decomposer - Face à une question complexe, le modèle découpe le corpus en segments et génère des sous-questions ciblées. Chaque sous-question est traitée via un appel récursif à llm_query(), ce qui permet de traiter chaque chunk indépendamment sans saturer le contexte.
Agreger - Les réponses partielles des sous-questions sont rassemblées et synthétisées. Le modèle écrit du code pour combiner, dédupliquer et structurer les résultats intermédiaires en une réponse cohérente.
Terminer - Quand le modèle juge avoir suffisamment d’information, il émet un signal FINAL(answer) qui arrête la boucle et retourne la réponse finale à l’utilisateur.
Ce cycle peut s’exécuter plusieurs fois. Le modèle décide lui-même combien d’itérations sont nécessaires - c’est du raisonnement agentique pur.
Le lien avec Ralph Wiggum et Claude Code
Si vous connaissez Ralph Wiggum, le plugin Claude Code qui utilise un mécanisme de Stop Hook pour itérer sur des tâches complexes, vous trouverez des similitudes frappantes avec RLM. Les deux systèmes partagent une philosophie itérative : au lieu d’essayer de tout résoudre en un seul passage, ils bouclent jusqu’à obtenir un résultat satisfaisant.
La différence de focale est néanmoins importante. Ralph Wiggum cible l’orchestration de tâches de développement dans un IDE - gestion de fichiers, exécution de commandes, vérifications de code. RLM, lui, s’attaque spécifiquement au problème de la lecture de corpus massifs. L’un pilote un environnement de développement, l’autre pilote la compréhension de documents. Mais le mécanisme sous-jacent - un agent qui boucle, évalue et décide de la prochaine action - est fondamentalement le même.
Conseils pratiques pour implémenter RLM
Si vous envisagez d’adopter cette approche, quelques leçons tirées de l’expérience :
-
Traitement par lots (batch processing) : Ne découpez pas vos documents token par token. Regroupez-les par thème, par fichier ou par section logique. Le modèle travaille mieux sur des unités sémantiques cohérentes que sur des fragments arbitraires.
-
Pre-filtrage par regex : Avant de soumettre un chunk au LLM, appliquez des filtres regex pour éliminer les sections manifestement hors sujet. Chaque token économisé dans le contexte améliore la qualité de la réponse.
-
Limite de profondeur de récursion : Sans garde-fou, un appel récursif à
llm_query()peut engendrer d’autres appels, qui en engendrent d’autres. Fixez une profondeur maximale (3 à 5 niveaux suffisent pour la plupart des cas) pour éviter l’explosion des coûts et de la latence. -
Historique glissant (rolling window) : Conservez un résumé des actions précédentes plutôt que l’intégralité de l’historique. Le modèle a besoin de savoir ce qu’il a déjà exploré, pas de relire chaque ligne de code qu’il a généré.
Conclusion : des patterns d’accès plus intelligents valent mieux que des fenêtres plus grandes
La course à la fenêtre de contexte la plus large est un piège. Elle repousse la limite sans résoudre le problème fondamental : un LLM qui reçoit trop d’information perd en précision.
RLM propose une alternative élégante - transformer le LLM en agent qui écrit du code pour lire sélectivement. Au lieu de tout voir mal, il choisit quoi regarder et le voit bien. C’est exactement la direction vers laquelle converge tout l’écosystème : le raisonnement agentique, où le modèle ne se contente pas de répondre mais décide activement comment chercher la réponse.
La prochaine fois que vous serez tenté de tout balancer dans le contexte, demandez-vous plutôt : est-ce que mon modèle a vraiment besoin de tout lire, ou juste de savoir où chercher ?
Rejoindre la newsletter
Recevez des mises à jour sur mes derniers projets, articles et expériences en IA et développement web.