Compétence GraphRAG
Génération augmentée de récupération sur un graphe de connaissances au lieu de fragments plats. Les entités et les relations sont extraites de vos documents, stockées dans une base de données graphe, et le LLM raisonne sur la structure du graphe au moment de la requête.
Pourquoi un graphe plutôt que des vecteurs
La recherche vectorielle trouve des fragments similaires. Elle ne peut pas suivre les connexions :
- "Quels fournisseurs ont été affectés par la panne de l'usine X ?" nécessite
Panne → affecte → Usine → fournie_par → Fournisseur— deux sauts qu'aucun fragment unique ne contient. - "Résume tout ce que nous savons sur le projet Y" nécessite la communauté d'entités autour de Y, pas les dix paragraphes les plus similaires.
Si vos questions sont des recherches de faits uniques, restez avec le RAG vectoriel — c'est plus simple. Utilisez GraphRAG lorsque les questions impliquent des relations.
Stack
- Kuzu — base de données graphe embarquée (
pip install kuzu), pas de serveur à lancer, langage de requête Cypher. Commencez ici. - Neo4j — lorsque vous dépassez l'embarqué : multi-utilisateurs, graphes plus grands, visualisation Bloom. Mêmes compétences Cypher transférables.
- Extraction LLM — tout modèle puissant avec sortie structurée pour l'extraction d'entités/relations.
Pipeline
1. Définir le schéma d'abord
Ne laissez pas l'extracteur inventer librement les types — vous obtiendrez 40 orthographes de la même relation. Déclarez les types de nœuds et d'arêtes dès le départ :
CREATE NODE TABLE Personne(nom STRING, PRIMARY KEY(nom));
CREATE NODE TABLE Projet(nom STRING, statut STRING, PRIMARY KEY(nom));
CREATE NODE TABLE Document(titre STRING, date DATE, PRIMARY KEY(titre));
CREATE REL TABLE TRAVAILLE_SUR(DE Personne VERS Projet, role STRING);
CREATE REL TABLE MENTIONNE(DE Document VERS Personne);
CREATE REL TABLE MENTIONNE_PROJET(DE Document VERS Projet);
Gardez le schéma petit (5-10 types de nœuds). Vous pouvez l'étendre ; vous ne pouvez pas revenir en arrière d'un graphe brouillon à moindre coût.
2. Extraire les entités et les relations
Découpez les documents (500-1000 tokens, avec chevauchement), puis invitez l'extracteur :
Extrayez les entités et les relations du texte ci-dessous.
Types de nœuds autorisés : Personne, Projet, Document
Types d'arêtes autorisés : TRAVAILLE_SUR (Personne→Projet), MENTIONNE (Document→Personne),
MENTIONNE_PROJET (Document→Projet)
Règles :
- Normalisez les noms ("J. Dupont" et "Jean Dupont" sont la même Personne)
- Extrayez uniquement les relations énoncées ou clairement implicites dans le texte
- Renvoyez JSON : {"nodes": [...], "edges": [...]}
Texte :
<extrait>
Vérifiez manuellement 10 à 20 extraits. La qualité de l'extraction est le plafond pour tout ce qui suit — un graphe bruité donne des réponses bruitées.
3. Charger dans Kuzu
import kuzu
db = kuzu.Database("./connaissances.kz")
conn = kuzu.Connection(db)
# créer le schéma, puis MERGE/CREATE paramétré par nœud/arête extrait
Dédupliquez au chargement (MERGE sur la clé primaire) — la même entité apparaît
dans de nombreux extraits.
4. Modèles de requêtes
Recherche locale — tout ce qui est connecté à une entité :
MATCH (p:Personne {nom: $nom})-[r]-(voisin)
RETURN type(r), voisin;
Raisonnement multi-sauts — suivez les relations à travers le graphe :
// Qui travaille sur des projets mentionnés dans des documents sur la panne ?
MATCH (d:Document)-[:MENTIONNE_PROJET]->(proj:Projet)<-[:TRAVAILLE_SUR]-(p:Personne)
WHERE d.titre CONTAINS 'panne'
RETURN DISTINCT p.nom, proj.nom;
Synthèse globale — détection de communautés, puis résumé de chaque communauté :
// Trouver les clusters densément connectés (exécuter une fois, stocker l'ID de communauté sur les nœuds)
CALL show_tables(); // puis utilisez la détection de communautés de votre graphe
Résumez chaque communauté avec le LLM : "ces entités se regroupent autour du sujet X." C'est la "requête globale" de GraphRAG — des questions comme "quels sont les thèmes principaux dans ces documents ?"
5. Répondre avec le LLM
Le modèle de requête qui fonctionne :
- L'agent traduit la question en 1 à 3 requêtes Cypher
- Les résultats reviennent sous forme de lignes structurées
- Le LLM synthétise la réponse à partir des lignes, en citant les preuves nœuds/arêtes
- Si une requête ne renvoie rien, l'agent reformule — il n'hallucine jamais le contenu du graphe
Connaissance temporelle (mémoire d'agent)
Pour la mémoire d'agent entre sessions, ajoutez le temps aux arêtes : horodatages VALID_FROM /
VALID_TO, les faits supplantés sont marqués plutôt que supprimés. C'est le
modèle de graphe de connaissances temporel (voir Graphiti/Zep) : "l'utilisateur préférait
X, maintenant préfère Y" reste interrogeable au lieu d'être écrasé.
Anti-patrons
- Extraire sans schéma. L'extraction libre produit un graphe que personne ne peut interroger.
- GraphRAG pour tout. Recherche de fait unique sur des documents propres ? La recherche vectorielle est moins chère et meilleure. Utilisez le graphe là où les relations comptent.
- Faire aveuglément confiance à l'extraction. Chaque pipeline a besoin d'une boucle de vérification manuelle ; les erreurs d'extraction s'accumulent silencieusement.
- Gros extraits. L'extraction d'entités se dégrade au-delà de ~1000 tokens — le modèle commence à perdre des relations. Extraits plus petits, plus nombreux.
- Pas de déduplication au chargement. "Jean Dupont", "J. Dupont", "Dupont" comme trois nœuds casse silencieusement les requêtes multi-sauts.