Auto-amélioration récursive des langages : affiner l'intelligence du code sur environ 280 langages
> Nous prenons en charge l'intelligence du code pour environ 280 langages. Aucun humain ne peut auditer cela à la main. Nous avons donc construit une boucle d'auto-amélioration récursive des langages — contrôle ponctuel, LLM en tant que juge, correction d'un seul élément, revalidation — et nous la faisons tourner avec une flotte d'agents isolés jusqu'à ce que l'extraction soit vraiment correcte, pas seulement au vert.
Les chiffres de cet article reflètent le système au moment de la publication (mai 2026). Consultez notre page équipe pour les chiffres actuels.
Maguyva extrait symboles, références et graphe de dépendances à partir du code source dans environ 280 langages. Chaque langage repose sur un handler tree-sitter sur mesure — requêtes, heuristiques, cas limites — et chaque handler peut se tromper subtilement, à sa manière propre. Un appel de méthode émis comme une lecture. Une fonction attribuée à la mauvaise portée englobante. Une relation qui, tout simplement, n’existe pas.
On ne peut pas auditer cela à la main. Aucune équipe ne peut lire la sortie d’extraction sur 280 grammaires et repérer les mauvaises arêtes. La question intéressante n’est donc pas « notre extraction est-elle correcte » — c’est « comment découvrir qu’elle est fausse, à cette échelle, sans un humain dans chaque boucle ». Notre réponse est l’auto-amélioration récursive des langages : une boucle de qualité pilotée par des agents de langage, un LLM agissant comme juge, et une règle que nous réapprenons sans cesse : le vert n’est pas synonyme de correct.
Le vert n’est pas correct
Chaque langage dispose d’une suite de fixtures, et une porte de mise en production le note sur cinq dimensions — précision, intégrité structurelle, exhaustivité, qualité et performance. Un langage passe au VERT seulement quand, sur ses fixtures, la précision ≥ 0,95, le rappel ≥ 0,99 et le F1 ≥ 0,97, avec au moins 20 arêtes attendues pour la confiance statistique. En dessous, c’est JAUNE ou ROUGE, et cela ne part pas en production.
Cette porte est nécessaire, mais pas suffisante. Les fixtures valident par rapport à des fixtures que nous avons écrites. Elles encodent les cas auxquels nous avons déjà pensé. Un handler peut être irréprochable sur ses fixtures et malgré tout massacrer un schéma qui n’apparaît que dans du code réel — un idiome de macro, une méthode à borne générique, une fonctionnalité de langage pour laquelle personne n’a écrit de fixture. VERT signifie que les fixtures passent. Cela ne signifie pas qu’un dépôt réel s’extrait proprement. La boucle doit donc laisser les fixtures de côté et regarder dans la nature.
La boucle interne : contrôle ponctuel, jugement, correction, preuve
La boucle centrale fait tourner un langage à la fois :
┌──────────────────────────────────────────────────────────┐
│ │
▼ │
1. corpus run ── clone real-world repos, extract relationships │
│ │
▼ │
2. spot-check 100 edges (seed 42, then seed 123 to cross-check) │
│ │
▼ │
3. LLM judge classifies every sampled edge: │
CORRECT · FALSE_POSITIVE · TYPE_ERROR · │
SCOPE_ERROR · METADATA_ERROR │
│ │
▼ │
4. fix ONE thing — handler .py, .scm query, or config │
│ │
▼ │
5. re-validate — F1 + re-classify + manifest diff (no regressions)│
│ │
better? ──no──► revert, try a different fix ────────────────────┤
│ yes │
▼ │
6. promote the fix into fixtures (a permanent regression guard) ──┘
Quelques éléments font que cela fonctionne plutôt que cela ne se débatte.
Le juge, c’est l’agent, pas un appel d’API. Quand nous disons « LLM en tant que juge », nous voulons dire que l’agent de langage lit lui-même chaque arête échantillonnée face à la source réelle, et la classe selon une grille fixe à cinq catégories : cette arête est-elle correcte, un faux positif, la bonne relation avec le mauvais type, rattachée à la mauvaise portée, ou porteuse de métadonnées erronées ? Cette grille, c’est tout l’enjeu — un « taux d’erreur de 23 % » ne veut rien dire tant qu’on ne sait pas s’il s’agit de vrais défauts ou d’un mauvais comptage du juge.
Corriger une chose, puis le prouver. Chaque itération modifie exactement un actif éditable, puis relance le harnais fixe et ne conserve le changement que si le F1 s’améliore et que la reclassification paraît meilleure. Sinon, elle est annulée. Pas de lot de modifications spéculatives, pas de « ça devrait aller mieux ». Un changement gagne sa place ou il disparaît. Et quand une correction tient, elle est promue dans la suite de fixtures — pour que le bug qu’elle a corrigé ne puisse jamais revenir en silence. C’est cette étape de promotion qui rend la boucle récursive plutôt que simplement répétitive : chaque passage durcit l’oracle sur lequel le passage suivant se valide.
La leçon que nous réapprenons sans cesse : les métriques surestiment
Voici le piège, et nous y sommes tombés tête baissée. Les métriques secondaires de corpus — à quelle fréquence une cible extraite n’a aucun symbole résolvable, combien de symboles paraissent « orphelins », et ainsi de suite — surestiment massivement les problèmes. Ce sont surtout des artefacts de paradigme, pas des bugs.
L’exemple le plus net : llvm a un jour affiché un taux de « source sans symbole » de 73 % et a été catalogué comme catastrophique. Nous avons creusé. La précision réelle était de 98,5 %. Les « symboles manquants » étaient presque tous des références externes légitimes — des appels vers la bibliothèque standard, vers des frameworks, vers du code qui vit hors du dépôt. La métrique mesurait une propriété du langage, pas un défaut du handler. Des langages comme Zig, COBOL et Odin affichent des taux « orphelins » de 65 à 70 % et sont pourtant entièrement corrects ; COBOL n’avait aucune vraie erreur.
Si nous avions laissé ces chiffres piloter le travail, nous aurions passé des semaines à « corriger » des handlers déjà justes, en ignorant les langages porteurs de vrais bugs discrets. La conclusion est brutale : les métriques agrégées sont, au mieux, un signal de tri grossier. Le vrai signal de qualité est le contrôle ponctuel avec classification des arêtes — regarder les arêtes réelles dans des dépôts réels et les juger une par une. Les données plutôt que l’intuition, mais seulement une fois qu’on sait quelles données disent la vérité.
La boucle externe : une flotte, pas un marathon
Un langage à la fois prendrait une éternité sur 280 d’entre eux, donc la boucle interne est enveloppée dans une boucle externe qui en fait tourner beaucoup en parallèle.
pick a wave of near-GREEN / high-error languages
│
▼
fan out 10–15 agents, each ISOLATED in its own git worktree,
each grinding ONE language, committing to its own branch
│
▼
orchestrator integrates serially: file-scoped apply, then
`manifest diff` — any cross-language regression blocks the batch
│
▼
gated push (reviewed and confirmed) ──► rotate to the next wave
Chaque agent travaille dans un worktree jetable, pour qu’ils ne puissent pas se marcher dessus. L’orchestrateur intègre leurs corrections une par une, chacune derrière un contrôle de régression sur l’ensemble du manifeste : un changement qui aide son propre langage mais casse discrètement trois autres ne passe pas. L’intégration est verrouillée et confirmée avant que quoi que ce soit ne soit poussé — la porte de régression décide de ce qui est sûr, un humain décide toujours de ce qui part en production. Puis le pool bascule vers le lot de langages suivant, et tout recommence.
Ce qui reste imparfait
Le juge peut se tromper, et l’erreur a une direction : un agent qui tourne avec trop peu de contexte surestime les problèmes. Sur un lot, huit langages ont été signalés avec un taux d’erreur de 5 à 20 % ; à l’examen, un seul était un vrai bug propre au langage — le reste venait d’erreurs du juge par méconnaissance de la sémantique propre au langage (une seule ligne source émettant légitimement plusieurs arêtes, des liaisons de paramètres modélisées comme des affectations, des langages à référence par identifiant). C’est pourquoi nous échantillonnons avec deux graines et procédons à des vérifications croisées, et pourquoi un désaccord entre le juge et les fixtures est traité comme le signal le plus intéressant, pas comme un verdict définitif — parfois, c’est la fixture qui a tort.
Nous sommes aussi honnêtes sur l’objectif. Le but est zéro erreur réelle, point final — mais « zéro » est une direction vers laquelle nous nous acharnons, langage par langage, pas une case que l’on coche. Il y a toujours un autre dépôt avec un autre idiome.
Gagné, pas affirmé
Tout ce que Maguyva fait pour un agent — trouver un symbole, tracer une dépendance, répondre à une question avec du code cité — repose sur la justesse de l’extraction sous-jacente. Sur 280 langages, cette justesse ne peut pas être affirmée ; elle doit être gagnée en continu face au code réel. La boucle est notre façon de la gagner : un cycle autonome de contrôle ponctuel et de correction qui se méfie de ses propres métriques, prouve chaque changement, et transforme chaque correction en garde-fou contre la prochaine régression. Ce n’est pas glamour. C’est le travail qui nous permet de dire « nous prenons en charge votre langage » et de le penser vraiment. Le vert est facile. Le correct se gagne.
Lectures associées
Encore plus du journal de bord Maguyva
Pourquoi nous avons fait évoluer la recherche de code vers voyage-4-large_
Nous avons migré nos embeddings de code vers voyage-4-large — actuellement en tête du classement public RTEB pour la récupération de code. La version honnête : le compromis que nous faisons, ce que nous indexons réellement, et pourquoi nous payons pour des embeddings premium.
Recherche par fusion multimodale : choisir le bon moteur de récupération pour chaque requête_
Une requête comme « où est défini parseConfig » appelle une recherche différente de « comment fonctionne l'authentification ». Maguyva classe l'intention, pondère en conséquence quatre modalités de récupération, puis fusionne les résultats avec une Reciprocal Rank Fusion pondérée.
Observabilité des agents : hooks, Alloy et Grafana_
Nous avons relié Claude Code et Codex à une seule pile Grafana avec OpenTelemetry et Alloy, puis utilisé traces et logs pour repérer et corriger les problèmes de comportement des agents à la source.