Vuncloud Blog
← Retour au journal de développement

Pourquoi Cursor en rate-t-il la moitié quand vous modifiez plusieurs fichiers ?

Notes de terrain · 2026.05.27 ·~16 min de lecture

Développeur et robot collaborant au code, symbole d'un Agent IA s'appuyant sur un graphe de connaissances pour comprendre un grand dépôt

Si vous utilisez Cursor ou Claude Code pour des modifications multi-fichiers — changer une interface, renommer une fonction, extraire un module, souvent une dizaine ou une centaine de fichiers — vous avez probablement déjà vu ceci : appelants oubliés, mauvais fichier modifié, module partagé cassé. Le modèle « comprend le fragment », pas le système. En 2026, les Agents lancent tests et PR automatiquement, mais plus l'équipe et le dépôt vieillissent, ce schéma d'échec persiste. La cause n'est souvent pas l'intelligence du modèle, mais l'absence d'un graphe de connaissances code (Code Knowledge Graph) interrogeable, incrémental et partageable. Cet article explique ce qu'est cette carte, pourquoi RAG vectoriel et contexte ultra-long ne suffisent pas, et comment les équipes peuvent externaliser une « mémoire structurelle » du dépôt pour leurs Agents.

Symboles
Granularité des nœuds : fonctions, types, modules, services
Arêtes
Appels, héritage, imports, implémentations, couverture tests
Hybride
Graphe + sémantique vectorielle + mémoire humaine en couches

L'angle mort de l'Agent : la fenêtre de contexte n'est pas une carte

Le pipeline typique d'un Agent de programmation IA : question utilisateur → recherche de fichiers pertinents → injection dans le contexte → génération de diff. Les moyens — @ fichier, ripgrep, similarité d'embeddings, index codebase intégré — répondent bien à « quel passage ressemble à la réponse », mais échouent systématiquement sur « qui sera impacté si je change ici », notamment parce que :

  • Les blocs texte n'ont pas de topologie : le découpage en chunks casse les chaînes d'appels ; deux fonctions au commentaire similaire peuvent être rappelées ensemble alors que le vrai lien d'appel vit dans un autre chunk.
  • grep ne voit que des chaînes, pas des types : surcharge, génériques, macros, code généré, extensions Swift — le « même nom » n'est pas le « même symbole ».
  • Le budget de contexte est un jeu à somme nulle : même avec 200 fichiers injectés, le modèle ignore quels 5 nœuds sont des passages obligatoires sur le chemin critique.
  • La session est sans état : les frontières de module définies lors du dernier refactor doivent être redevinées à chaque conversation.

Un ingénieur senior ne « mémorise pas tout le dépôt » : il porte une carte mentale en couches — frontières de modules, sens des dépendances, qui appelle qui, où sont les tests. Le graphe de connaissances code externalise cette carte, lisible par machine et versionnable.

Qu'est-ce qu'un graphe de connaissances code

Au sens strict, c'est un graphe de propriétés (Property Graph) ou un graphe hétérogène orienté génie logiciel : les nœuds représentent des entités de code, les arêtes des relations vérifiables. Contrairement à un graphe de connaissances généraliste, la plupart des arêtes se déduisent par analyse statique ou logs de build — pas par hallucination LLM.

Type de nœud (exemples) Type d'arête (exemples) Requête Agent typique
File, Module, Package imports, owns Dans quels répertoires vit cette feature ?
Function, Method, Type calls, overrides, implements Modifier authenticate() impacte quelles entrées ?
API, RPC, champ GraphQL exposes, consumes Le contrat mobile et backend est-il aligné ?
Test, job CI covers, blocks_merge Quel jeu minimal de tests lancer ?
Service, binaire (monorepo) deploys_to, depends_on Ordre de release et rayon de rollback ?

La valeur n'est pas le nombre de nœuds, mais la reproductibilité du raisonnement multi-sauts : « du clic utilisateur au SQL en base » peut être un chemin fixe, pas une supposition refaite à chaque fois.

Face au RAG vectoriel : similarité sémantique ≠ lien structurel

La recherche vectorielle traite le code comme du texte naturel — idéal pour « trouver une logique de paiement ressemblante ». Ces tâches sont naturellement des traversées de graphe :

  • Avant de retirer un feature flag, énumérer tous les vrais points de référence à if (featureX), macros et code généré inclus.
  • Passer une interface de sync à async : lister la pile d'appels full-repo et les doubles de test.
  • Découper une God class : identifier les sous-graphes cohésifs et leur fan-out externe.

En production, on adopte souvent la recherche hybride (Hybrid Retrieval) : après classification d'intention, les questions structurelles passent par le graphe, les exploratoires par les embeddings ; on trie en priorisant les nœuds sur le chemin graphe, puis on tronque le contexte. Sans arêtes, seulement des embeddings, le taux de merge des PR de l'Agent plafonne sur les gros dépôts multi-fichiers et dépendances croisées.

Éditeurs multi-écrans et tableaux de bord, symbole de la construction d'un index graphe de connaissances code sur un Cloud Mac distant pour Agent IA

Face au LSP / index IDE : session vs organisation

Le Language Server alimente navigation, références, renommage — chevauchant fortement les nœuds du graphe. La différence est le cycle de vie et le consommateur :

  • Le LSP est lié au workspace ouvert ; en CI ou sur un runner distant, l'Agent n'a souvent pas la même instance.
  • Renommer une API est interactif ; l'Agent a besoin de get_callers(symbol_id) batch et scriptable.
  • Le graphe peut porter des métadonnées métier : owner de service, date de dépréciation, tags compliance — le LSP ne modélise pas ces arêtes.
  • Comparer deux branches (main vs feature) devient un diff de sous-graphes, pas deux sessions de clic manuel.

La voie pragmatique : LSP / frontend compilateur comme source de vérité, graphe comme couche persistante et protocole Agent, sans réinventer l'analyse.

Architecture recommandée : trois couches, le graphe au centre

Découper la « compréhension dépôt » de l'Agent en trois couches limite la confusion :

Couche structurelle (graphe de connaissances code)

Répond à : de quoi est fait le code et comment il se connecte. Alimentée par analyse statique, graphe de build (Bazel/Gradle/Xcode project graph), OpenAPI/Proto. Mise à jour : merge, full scan planifié, ou watch fichiers. Stockage : base graphe ou SQLite avec index d'adjacence ; exposition via outils MCP.

Couche sémantique (index vectoriel)

Répond à : quelle implémentation « ressemble » au comportement décrit. Embeddings sur corps de fonctions, commentaires, ADR, issues. Partagez le même symbol_id avec le graphe pour éviter « chunk trouvé, symbole introuvable ».

Couche épisodique (mémoire de tâches et de design)

Répond à : pourquoi avons-nous changé ainsi la dernière fois. Résumés de PR, runbooks, ou nœuds Topic d'un Memory OS type OpenHuman. Elle ne remplace pas le graphe : elle pondère les arêtes (« déjà discuté », « obsolète »).

Principe de design : chaque arête doit être auditable
Chaque arête remonte au parseur, au chemin source et au commit. Quand l'Agent produit un diff, joignez un résumé de la chaîne d'appels invoquée — la même culture d'ingénierie que dans une pipeline CI/CD Mac cloud traçable.

Cinq tâches Agent que le graphe améliore directement

  1. Refactor multi-fichiers : renommage, extraction d'interface, migration de package — modifications par arêtes d'appel, moins de fichiers oubliés.
  2. Localisation de défauts : depuis le frame de pile, remonter le calls vers la couche intermédiaire partagée, au lieu de chercher la chaîne d'erreur partout.
  3. Onboarding : « l'entrée du module paiement » = sous-graphe de la route UI au service, plus rapide qu'un README seul.
  4. Sélection de tests : selon les arêtes covers des nœuds modifiés, lancer le minimum — orchestrable avec une pipeline TestFlight sur la même machine.
  5. Scan sécurité et compliance : requêtes reachable_from sur APIs sensibles, plus fiables que des regex seules.

Comment construire : incrémental, tolérant aux échecs, sensible au langage

Pipeline minimal viable (aligné sur le schéma HowTo en tête d'article) :

  • Parse : tree-sitter (multilingue), SourceKit (Swift), rust-analyzer (Rust), etc., pour exporter la table de symboles AST.
  • Arêtes : résolution d'appels en approximation conservative (mieux sous-rapporter que sur-rapporter) ; héritage et implémentation doivent être exacts.
  • Incrémental : hash par fichier ; invalidation locale des voisins à deux sauts en amont et aval.
  • Version : graphe porteur de commit_sha ; paramètre obligatoire dans les outils Agent pour éviter le mélange inter-branches.
  • Surface outils : 6 à 10 API haut niveau (get_callers, get_module_graph…) — pas de Cypher ad hoc laissé au modèle.
Exemple de retour d'outil Agent (extrait JSON, dépôt fictif)
{
  "symbol": "PaymentService.charge",
  "callers": [
    {"id": "CheckoutViewModel.submit", "file": "ios/Checkout/VM.swift", "line": 88},
    {"id": "SubscriptionRenewalJob.run", "file": "jobs/renewal.ts", "line": 41}
  ],
  "graph_version": "a3f9c2e"
}

Spécificités des gros dépôts Apple / iOS

Swift, Objective-C, SPM et projets Xcode rendent le « RAG texte pur » particulièrement fragile : extensions, compilation conditionnelle, ponts @objc produisent des arêtes invisibles statiquement, visibles à l'exécution. La construction du graphe doit :

  • Parser dans un environnement macOS aligné sur Xcode (Mac local ou Mac mini M4 Cloud Mac), pas une CI Linux qui échoue silencieusement.
  • Modéliser les dépendances .xcodeproj / cibles SPM en arêtes au niveau Module, puis descendre au symbole.
  • Pour les dépôts mixtes Flutter iOS, relier Dart ↔ Platform Channel (annotation manuelle + scan du code généré).

L'indexation est gourmande en CPU et disque ; un Cloud Mac dédié peut la faire tourner 24/7 en incrémental, tandis que Cursor local consomme l'API graphe distante via SSH/MCP — le portable reste un client léger. Comme dans Mac VPS vs Cloud Mac, isolez calcul et disque : le service graphe ne doit pas se battre pour l'I/O avec un VPS surbooké.

Articulation avec OpenClaw et agentmemory

OpenClaw et agents multicanaux excellent à orchestrer tâches planifiées, webhooks et outils externes ; le graphe de connaissances code est le backend structuré de la brique « lire le dépôt ». Les produits de mémoire personnelle (Memory Tree OpenHuman, etc.) gardent fil de décision et conversations — un résumé en langage naturel ne remplace pas un graphe d'appels.

Intégration recommandée : enregistrer des outils code_graph_* dans OpenClaw / Cursor MCP ; le Memory OS ne stocke que des métadonnées du type « cette refactor a notifié l'équipe X », et journalise la version du graphe dans l'audit.

Pièges et anti-patterns courants

  • Deviner les appels avec un LLM : non testable en régression, le graphe pourrit après merge.
  • Graphe désynchronisé du source : pire que pas de graphe — l'Agent modifie le mauvais fichier en toute confiance.
  • Nœuds fichier seulement : équivalent à @folder, insuffisant pour rename/refactor.
  • Dump du graphe entier dans le prompt : préférez appels d'outils + élagage multi-sauts.
  • Ignorer code généré et lockfiles : Protobuf, GraphQL codegen, macros Swift — intégrez-les aux hooks de build.

FAQ

Faut-il choisir entre graphe et RAG vectoriel ? Non. Le graphe gère la structure, le vecteur la sémantique ; reliez-les par un même symbol_id.

Le LSP suffit-il ? Pour une personne et une session, pas pour un Agent d'organisation ; alimentez le graphe avec la sortie LSP.

Petit projet : en vaut-il la peine ? Quand l'Agent oublie régulièrement des appelants ; le coût peut être amorti via un service d'index managé.

Fréquence de mise à jour ? Incrément à chaque merge sur main ; validez graph_version avant une longue tâche.

Index produit intégré : faut-il construire le vôtre ? Oui si vous avez besoin de CI, d'audit compliance et d'une source de faits unique entre outils.

Intérêt d'un Cloud Mac ? Base graphe persistante, parsing Swift/ObjC, cohabitation Xcode, consommation SSH depuis l'IDE local.

Sécurité ? Structure de modules et noms de symboles — mêmes droits que le source ; n'écrivez pas le graphe dans des logs LLM publics.

Et le Memory OS ? Graphe = faits structurels ; mémoire = décisions et préférences ; combinez à la couche interface.

Conclusion

Le plafond des Agents de programmation IA dépend de plus en plus de la compréhension structurelle du dépôt, pas des astuces de prompt. Un graphe de connaissances code externalise chaînes d'appels, frontières de modules et cartographie tests en données interrogeables, versionnées et auditables — complémentaires à la recherche vectorielle et à un Memory OS personnel. En 2026, les équipes qui comptent seulement sur « plus de contexte + recherche de fichiers » paieront encore le coût des oublis sur les monorepos et projets Apple. Indexer dans le bon environnement (parsing macOS, disque persistant) est l'investissement minimal pour passer de « l'Agent sait écrire du code » à « l'Agent sait modifier le système ».

Faire tourner l'index graphe et l'Agent sur Mac mini M4 Cloud Mac

Louez un Mac mini M4 Cloud Mac dédié Vuncloud pour construire un index graphe de connaissances code 24/7 sur de gros dépôts iOS/Swift ; Cursor local consomme via SSH, avec place pour des expériences MLX et un workflow IA Apple Silicon sur la même machine.

Raccourcis : Voir les offres Cloud Mac, Guide de configuration Mac distant, Retour au blog.

Développeurs IA

Une mémoire de dépôt structurée commence par l'index Cloud Mac

Parsing Swift/ObjC · base graphe persistante · SSH + toolchain Agent

Voir les offres Cloud Mac
Offre limitée Voir M4