Construire un graphe de connaissances unique à travers 46 dépôts
Je suis Ryan, CTO chez airCloset.
J'ai passé trois mois à construire code-graph. Il s'agit d'un graphe de connaissances unique qui unifie 46 dépôts répartis sur plusieurs services.
Beaucoup de gens pensent qu'il suffit de donner tout son code à une IA et de lui poser des questions. Cela échoue pour deux raisons :
- Fenêtres de contexte : vous ne pouvez pas faire tenir des années de code provenant de 46 dépôts dans un seul prompt.
- Hallucination : l'IA commet des erreurs lorsqu'elle tente d'inférer des relations. Elle manque des connexions.
Pour résoudre ce problème, j'ai utilisé l'analyse statique pour construire une source de vérité.
Le défi : franchir les frontières
Une base de code importante est désordonnée. Une API peut être appelée par cinq dépôts différents. Une table de base de données peut être utilisée par trois services différents.
Si vous ne regardez qu'un seul dépôt, vous manquez la vue d'ensemble. C'est dangereux. Si vous modifiez du code sans voir le véritable rayon d'impact (blast radius), vous cassez le système.
Mon approche utilise tree-sitter pour analyser le code en arbres de syntaxe. Mais tree-sitter seul ne peut pas voir au-delà des frontières des dépôts.
J'ai construit des nœuds de frontière (boundary nodes) pour résoudre cela.
Comment ça marche :
- Nous extrayons les relations au sein d'un dépôt en utilisant tree-sitter.
- Nous utilisons l'API TypeScript Compiler pour résoudre les types et les variables.
- Nous utilisons Gemini pour gérer les cas dynamiques que les outils ignorent.
Au lieu de demander à l'IA de deviner, nous lui donnons des faits. Nous lui disons : « Cette API est également appelée depuis le dépôt X ». Cela empêche les hallucinations.
La partie difficile : le zoo des frameworks
La véritable bataille a été d'extraire ces frontières. Chaque framework définit les frontières différemment.
Une équipe utilise des décorateurs NestJS. Une autre utilise des routes Express. Une autre utilise du jQuery brut. Chacun crée une structure différente dans le code.
Pour que cela fonctionne, nous avons dû construire des parseurs personnalisés pour :
- NestJS et TypeORM
- Express et Fastify
- AngularJS et Redux
- Divers schémas d'alias de chemin (path-alias)
Nous devions viser une précision de 99 %. Si notre taux de connexion n'est que de 90 %, l'IA manque 10 % des connexions. Dans un système de production, c'est dans ces 10 % que se cachent les bugs.
Nous effectuons désormais une vérification quotidienne. Si notre taux de connexion chute de plus de 5 %, nous recevons une alerte. Cela permet de détecter quand de nouveaux modèles de code cassent nos parseurs.
Limitations actuelles
Le graphe n'est pas parfait.
- La recherche est difficile. Il faut souvent connaître le nom d'une fonction pour commencer sa recherche.
- Explosion de nœuds. Suivre un chemin peut entraîner des milliers de petites fonctions utilitaires inutiles.
- Maintenance. Chaque fois qu'un nouveau framework entre dans notre stack, nous devons écrire un nouveau parseur.
Ceci est la partie 1. Dans la partie 2, je discuterai de la couche service-product-graph (SPG) que j'ai construite pour combler ces lacunes.
Communauté d'apprentissage optionnelle : https://t.me/GyaanSetuAi
