Présentation sur HN : FastGraphRAG – une technique RAG améliorée qui exploite le PageRank traditionnel
(github.com/circlemind-ai)- Fast GraphRAG est un framework GraphRAG simplifié pour des workflows de recherche pilotés par agents interprétables et de haute précision, qui met l’accent sur l’ajout d’un RAG avancé à un pipeline de recherche sans construire directement des workflows d’agents complexes
- Il rend les graphes de connaissances explorables par des humains, permet de les interroger, de les visualiser et de les mettre à jour, et génère et affine automatiquement les graphes selon les exigences du domaine et de l’ontologie
- Pour répondre aux requêtes, il utilise une exploration de graphe fondée sur le personalized PageRank afin de trouver les informations pertinentes, et le README renvoie au papier HippoRAG pour une vue d’ensemble de cette approche
- Dans l’exemple de coût basé sur The Wizard of Oz,
fast-graphragest indiqué à 0,08 $, contre 0,48 $ pourgraphrag, et il est affirmé que cette réduction des coûts par 6 s’améliore encore à mesure que la taille des données et le nombre d’insertions augmentent - Il fonctionne avec Python 3.10.1 ou supérieur, prend en charge l’installation depuis les sources et via PyPI, puis permet d’insérer des documents et d’effectuer des requêtes après configuration de la clé API OpenAI, tout en conservant automatiquement les connaissances dans le même répertoire de travail
Le framework de recherche proposé par Fast GraphRAG
- Fast GraphRAG est un framework GraphRAG visant une connaissance interprétable et débogable
- Le graphe présente les connaissances sous une forme que l’humain peut explorer, et prend en charge les opérations suivantes
- requête
- visualisation
- mise à jour
- Il cherche à offrir des fonctionnalités RAG avancées tout en réduisant la charge liée à la construction et à la conception directes de workflows d’agents
Principales fonctionnalités
- Conçu pour pouvoir être exécuté rapidement et à faible coût à grande échelle, avec une orientation vers la réduction des besoins en ressources lourdes et des coûts
- Prend en charge les données dynamiques, et génère puis affine automatiquement les graphes en fonction des exigences du domaine et de l’ontologie
- Prend en charge les mises à jour incrémentales lorsque les données changent, ce qui permet des mises à jour en temps réel
- Fournit une exploration intelligente qui améliore la précision et la fiabilité en exploitant une exploration de graphe fondée sur PageRank
- L’ensemble adopte une approche asynchrone et vise des workflows robustes et prévisibles grâce à une prise en charge complète du typage
Exemple de coût
- Dans l’exemple utilisant The Wizard of Oz, le coût de
fast-graphragest indiqué à 0,08 $, contre 0,48 $ pourgraphrag - Le README présente cela comme une réduction des coûts par 6 et indique que l’effet d’économie s’améliore encore lorsque la taille des données et le nombre d’insertions augmentent
Installation et déroulement d’exécution
- La méthode d’installation recommandée se divise entre l’installation depuis les sources pour les performances et l’installation via PyPI pour la stabilité
- Installation depuis les sources : cloner le dépôt puis exécuter
poetry install - Installation via PyPI :
pip install fast-graphrag
- Installation depuis les sources : cloner le dépôt puis exécuter
- L’exemple de démarrage rapide commence par définir la variable d’environnement
OPENAI_API_KEY - Après avoir téléchargé le texte de A Christmas Carol, on initialise
GraphRAGdans le code Python - L’exemple d’initialisation comprend les valeurs suivantes
working_dir="./book_example"- un
domainqui analyse les personnages de l’histoire, leurs interactions, les lieux et les relations - une liste d’exemples de requêtes
- les types d’entités
["Character", "Animal", "Place", "Object", "Activity", "Event"]
- Le document est inséré avec
grag.insert(f.read()), puis le résultat d’une requête est affiché avecgrag.query("Who is Scrooge?").response - Si l’on réinitialise dans le même répertoire de travail, les connaissances sont automatiquement conservées
- Pour contrôler le nombre de tâches LLM traitées en parallèle, notamment avec des modèles locaux, il est possible de définir en option une variable d’environnement comme
CONCURRENT_TASK_LIMIT=8
Exemples et options de configuration
- Le dossier
examplesfournit des tutoriels sur les cas d’usage courants de la bibliothèque custom_llm.pyest un exemple simple montrant comment configurer différemment un modèle de langage compatible avec l’API OpenAI et les embedderscheckpointing.ipynbtraite de l’usage des checkpoints afin d’éviter des corruptions de données irréversiblesquery_parameters.ipynbcouvre divers paramètres de requête et montre comment inclure des références aux informations utilisées dans les réponses avecwith_references=True
Philosophie de conception et méthode d’exploration
- L’objectif est d’augmenter le nombre d’applications GenAI réussies, et pour cela l’équipe explique construire des outils de mémoire et de données permettant aux applications LLM d’exploiter des pipelines de recherche spécialisés sans avoir à configurer et maintenir des workflows d’agents complexes
- Fast GraphRAG explore le graphe avec l’algorithme de personalized PageRank afin de trouver les informations les plus pertinentes pour répondre à la requête en cours
- Pour un aperçu des raisons du fonctionnement de cette approche, le papier HippoRAG est donné en référence
Open source et service managé
- Le dépôt est proposé sous licence MIT ; davantage de détails sont disponibles dans LICENSE.txt
- Un service managé est proposé comme moyen de démarrer rapidement et de manière fiable
- Ce service managé inclut 100 requêtes gratuites chaque premier mois, puis une facturation à l’usage
- Pour en savoir plus sur le service managé, il est possible de réserver une démo ou de consulter la documentation
- Les informations de contribution se trouvent dans CONTRIBUTING.md, et les questions peuvent être posées sur Discord
1 commentaires
Commentaires sur Hacker News
En plus de PageRank, il existe plusieurs mesures de centralité intéressantes qui peuvent influencer le RAG sur des données structurées
Parmi elles, la Triangle Centrality calcule la centralité en comptant les triangles autour d’un nœud, sur l’idée que les triangles renforcent fortement la fermeture des relations, tandis que les connexions ouvertes retirent du poids au centre et diluent ainsi la centralité
https://arxiv.org/abs/2105.00110
L’article affirme qu’elle est plus efficace que d’autres centralités comme PageRank, mais dans une étude utilisant GraphBLAS, sur plusieurs graphes creux allant jusqu’à 1,8 milliard d’arêtes, la TC était plus lente que notre implémentation creuse de PageRank
Cela dit, plus le graphe grossit, plus la TC semble bien passer à l’échelle, et elle pourrait être plus efficace à l’échelle du billion d’arêtes
https://fossies.org/linux/SuiteSparse/GraphBLAS/Doc/The_Grap...
De toute façon, le goulot d’étranglement sera la partie que le LLM doit parser pour générer la réponse
PageRank n’est qu’une première étape, mais j’aimerais bien tester aussi des alternatives plus précises
Ici, on utilise un PageRank personnalisé, avec un poids initial attribué à un ensemble précis de nœuds ; je me demande si la Triangle Centrality prend aussi cela en charge
On regarde également les poids d’arêtes, donc j’aimerais savoir si c’est possible aussi
https://link.springer.com/content/pdf/10.1007/978-3-030-6097...
J’ai pas mal travaillé dans ce domaine, et j’en ai tiré quelques enseignements
En combinant ces trois éléments, on a construit une étape similaire de décomposition/extraction des connaissances, à laquelle on a ajouté un méta-prompteur pour générer pratiquement automatiquement les types de domaine/d’entité
Les LLM ont, de manière générale, du mal à trouver le bon niveau de granularité pour des connaissances décomposées
Une astuce consiste à demander au LLM de produire une mind map mermaid.js afin de découper l’entrée en arbre hiérarchique, puis de dire à la fin à quel niveau se trouve la bonne racine pour un nœud de connaissance
On génère ensuite les questions auxquelles les connaissances de ce nœud permettent de répondre, puis on indexe ce texte de questions et on en fait aussi des embeddings
Faire correspondre directement la requête utilisateur à ces questions avec du BM25 pur donne déjà de bons résultats, et l’approche hybride est encore meilleure, sans que l’écart soit énorme
Si on n’utilise pas de LLM au moment de la requête, on peut aussi descendre hiérarchiquement depuis la racine vers des nœuds plus profonds en utilisant la similarité d’embedding comme fonction de coût de parcours
Au final, on a décidé de passer au graphe comme généralisation de l’arbre
L’idée clé, selon moi, est d’utiliser la similarité d’embedding pour “parcourir” le graphe, et on l’intègre activement dans FastGraphRAG aussi, en pondérant les arêtes selon la requête
C’est intéressant de voir plusieurs solutions converger vers une architecture semblable
L’idée de générer une réponse hypothétique à partir de la requête puis de faire la recherche d’embeddings avec cette réponse est intéressante, et j’aimerais l’ajouter à ma liste d’expériences
Je me demande maintenant si cela marcherait encore mieux en générant la réponse hypothétique avec un LLM finement ajusté sur le corpus
J’aimerais aussi savoir si, au moment de générer la réponse hypothétique, vous promptiez des réponses adaptées à la “taille de chunk”
Utiliser PageRank pour améliorer la centralité semble une bonne idée, mais cela ne résout toujours pas le défaut probablement insoluble du RAG, à savoir pourquoi le RAG a fondamentalement du mal à fonctionner
Si toutes les bases RAG affichent des performances inférieures aux attentes, c’est parce que le RAG ne parvient pas fondamentalement à retrouver les relations entre les mots nécessaires pour trouver l’information que cherche l’utilisateur
Cela peut sembler étrange, car on pourrait penser que le mécanisme d’“attention” est justement censé bien faire ce genre de choses, mais en pratique ce n’est pas suffisant
Par exemple, imaginons qu’un texte dise qu’une personne nommée ‘Sharon’ a assisté à plusieurs conférences de physicochimie, mais sans préciser sa profession
Si l’on cherche “Quelle est la profession de Sharon ?”, la plupart des approches RAG auront probablement du mal à relier ‘profession’, la participation à des conférences et le type de conférence pour en déduire ‘chimiste’
Ce type d’erreur se retrouve dans de nombreuses catégories d’information lorsqu’on récupère de l’information avec du RAG
Au final, des solutions comme celle-ci donnent l’impression de réinventer, avec davantage d’étapes, d’autres méthodes de requête comme SQL ou PageRank, et à ce stade la vectorisation n’a plus beaucoup de sens
Le composant RAG n’a qu’à retrouver, dans un grand jeu de données, l’article concernant Sharon et à transmettre l’ensemble au LLM comme contexte
Si vous regardez l’article HippoRAG cité dans le billet d’origine, l’exemple de motivation est presque identique, et l’évaluation vise globalement ce type de questions-réponses multi-sauts
Il suffit de récupérer l’entité Sharon, puis de recevoir comme contexte supplémentaire les nœuds et arêtes proches de Sharon
Ensuite, c’est le rôle du LLM, et si la profession ne figure pas dans le contexte fourni, il doit indiquer que “dans le contexte fourni, il est impossible de trouver la profession de Sharon”
J’ai trouvé ça intéressant, donc je me suis inscrit et j’ai téléversé quelques documents PDF sur le tableau de bord
Mon cas d’usage consiste à analyser des documents de conformité liés à la fabrication dans une startup IA, mais pour que cela nous soit utile, il faut comprendre jusqu’à quelle échelle cela fonctionne et quel est le modèle de coût
Nous avons environ 300 000 PDF par client, et nous nous attendons à ce qu’environ 10 % du corpus documentaire change chaque mois
Tout système de GraphRAG doit pouvoir traiter des documents à grande échelle, et même si S3 peut servir de mécanisme d’ingestion, nous avons besoin de connaître le coût et le temps de traitement avant que le système soit de nouveau disponible au point suivant
J’aimerais en discuter plus en détail, donc n’hésitez pas à me contacter à antonio [at] circlemind.co
Intéressant, mais je me demande quelle taille doit avoir un corpus de textes spécialisé par domaine pour produire un graphe de connaissances utile
Aider applique depuis longtemps PageRank au graphe d’appels des dépôts de code
Tout code non trivial contient beaucoup de structure de graphe pour alimenter PageRank, et cela fonctionne très bien pour trouver le contexte le plus pertinent dans un projet par rapport à la tâche en cours
https://aider.chat/docs/repomap.html#optimizing-the-map
J’aimerais beaucoup avoir des retours quand davantage de personnes commenceront à l’utiliser
Je me demande si vous prévoyez de permettre de forcer la génération d’une repo map et de l’inspecter
Super
Je me demande comment le graphe est stocké et interrogé
Je connais bien les bases de données orientées graphe, mais ça ne semble pas être une dépendance
Je me demande aussi si vous avez essayé le modèle sciphi triplex pour l’extraction
Quand j’ai fait de l’extraction auparavant, les résultats n’étaient pas cohérents si j’extrayais plusieurs fois de suite le même chunk
La base de code est conçue pour pouvoir intégrer facilement n’importe quelle base de données graphe avec un léger wrapper, et nous prévoyons de prendre en charge prochainement des solutions comme neo4j
Nous n’avons pas encore essayé triplex, car gpt4o-mini est pour l’instant suffisamment rapide et précis
Nous utilisons aussi gpt4o-mini non seulement pour l’extraction des entités et des relations, mais aussi pour la génération de descriptions et la résolution des conflits
Avec du fine-tuning, les résultats seraient certainement encore meilleurs
L’interrogation du graphe consiste à trouver un ensemble initial de nœuds pertinents pour une requête donnée, puis à exécuter un PageRank personnalisé à partir de ces nœuds pour trouver d’autres passages pertinents
Pour l’instant, nous choisissons les nœuds initiaux par recherche sémantique à la fois sur la requête complète et sur les entités extraites de la requête, mais nous avons aussi prévu quelques ajouts intéressants à cette approche
Bonne idée
Personnellement, je pense que pour le RAG, la voie à suivre est la recherche d’information traditionnelle
La recherche vectorielle est bien, mais elle est lente et coûteuse, et les gens ont tendance à l’utiliser comme de la poudre magique
Elle fonctionne bien sur les données non structurées, mais n’est pas forcément aussi adaptée aux données structurées
À moins d’un réglage très poussé, la recherche vectorielle n’est pas non plus tellement meilleure qu’une requête traditionnelle bien optimisée
J’ai déjà vu en pratique des gens transformer des données structurées en données non structurées pour ensuite faire de la recherche vectorielle ou du prompt engineering, et globalement cela donne l’impression de prendre le problème à l’envers
Ça peut fonctionner dans une certaine mesure, mais il y a probablement des façons plus intelligentes d’obtenir le même résultat
L’essence même de Graph RAG est d’exploiter la structure des données
Que ce soit avec des jointures SQL ou des requêtes de base de données graphe n’a pas vraiment d’importance
Il y aurait aussi de la valeur à apprendre au LLM comment interroger ces systèmes, ou à l’interfacer avec des API de recherche/requête existantes
Un mauvais classement peut être compensé par une fenêtre de contexte plus grande, et en récupérant plus de centaines de résultats avec plusieurs requêtes
Ce type de passage à l’échelle sera bien plus rapide et moins coûteux que la recherche vectorielle
Ça a l’air bien, mais j’ai déjà été échaudé par d’autres couches d’abstraction comme LangChain, donc je crains une simplification excessive
Je me demande comment vous comptez éviter de répéter les mêmes erreurs
Je me demande s’il existe des scores de métriques d’évaluation pour la recherche et la génération
Par exemple sur des jeux de données comme KILT ou NQ
Les jeux de données de benchmark ne font pas tout, mais montrer des scores corrects ainsi que des temps d’inférence aiderait beaucoup à convaincre les auteurs de frameworks ou à orienter le choix des ingénieurs
En tant qu’ingénieur freelance en traitement automatique du langage, j’ai déjà construit beaucoup de pipelines RAG, et je compte essayer celui-ci moi-même
Je construis actuellement un chatbot de questions-réponses et j’ai du mal à gérer le scénario suivant
Quand l’utilisateur demande « qu’est-ce que tu voulais dire dans la phrase précédente que tu viens de dire ? », je me demande comment ce framework peut récupérer le bon petit sous-ensemble de connaissances brutes et l’intégrer au LLM pour produire une réponse pertinente
Il m’a été difficile de résoudre ce problème sans dépendre de frameworks externes
https://www.reddit.com/r/LocalLLaMA/comments/1gtzdid/d_optim...
J’aimerais savoir comment ce framework résout ce problème et comment il peut simplifier le processus
Sans cela, il échouait souvent quand l’utilisateur posait des questions comme « peux-tu détailler le point 2 ? » ou « donne un exemple détaillé de ce qui précède »
L’implémentation actuelle maintient trois index, fournit la requête et les messages précédents, puis demande au LLM de les décomposer en
requête complète, question optimisée pour BM25, mots-clés, question optimisée pour la recherche sémantique
Ensuite, on exécute le RAG et un reranking, puis on transmet les N meilleurs passages avec la requête complète à un second appel au LLM
Il faut se concentrer sur l’étape d’orchestration
Vous pouvez regarder du côté des agents ReAct, et le construire avec LangGraph ou Bedrock Agents