GraphRAG erklärt: RAG mit Wissensgraphen verbessern
Einführung in RAG und seine Herausforderungen
Retrieval Augmented Generation (RAG) ist eine Technik, die externe Datenquellen anbindet, um die Ausgabe von Large Language Models (LLMs) zu verbessern. Diese Technik ist ideal dafür geeignet, LLMs den Zugriff auf private oder domänenspezifische Daten zu ermöglichen und Probleme mit Halluzinationen zu adressieren. Daher wird RAG häufig eingesetzt, um viele GenAI-Anwendungen zu betreiben, wie etwa KI-Chatbots und Empfehlungssysteme.
Ein grundlegendes RAG integriert in der Regel eine Vektordatenbank und ein LLM, wobei die Vektordatenbank kontextbezogene Informationen für Nutzeranfragen speichert und abruft und das LLM auf Grundlage des abgerufenen Kontexts Antworten generiert. Obwohl dieser Ansatz in vielen Fällen gut funktioniert, hat er Schwierigkeiten mit komplexen Aufgaben wie Multi-Hop-Reasoning oder der Beantwortung von Fragen, die das Verknüpfen unterschiedlicher Informationsstücke erfordern.
Betrachten wir zum Beispiel diese Frage: “Welcher Name wurde dem Sohn des Mannes gegeben, der den Usurpator Allectus besiegte?”
Ein grundlegendes RAG würde im Allgemeinen diese Schritte befolgen, um diese Frage zu beantworten:
Den Mann identifizieren: Bestimmen, wer Allectus besiegte.
Den Sohn des Mannes recherchieren: Informationen über die Familie dieser Person nachschlagen, insbesondere über seinen Sohn.
Den Namen finden: Den Namen des Sohnes identifizieren.
Die Herausforderung entsteht normalerweise im ersten Schritt, weil ein grundlegendes RAG Text auf Basis von semantischer Ähnlichkeit abruft und komplexe Anfragen nicht direkt beantwortet, bei denen bestimmte Details möglicherweise nicht ausdrücklich im Datensatz erwähnt werden. Diese Einschränkung erschwert es, die exakt benötigten Informationen zu finden, und erfordert häufig teure und unpraktische Lösungen wie das manuelle Erstellen von Q&A-Paaren für häufige Anfragen.
Um solchen Herausforderungen zu begegnen, stellte Microsoft Research GraphRAG vor, eine brandneue Methode, die RAG-Retrieval und -Generierung mit Wissensgraphen erweitert. In den folgenden Abschnitten erklären wir, wie GraphRAG im Hintergrund funktioniert und wie man es mit der Milvus -Vektordatenbank ausführt.
Was ist GraphRAG und wie funktioniert es?
Im Gegensatz zu einem grundlegenden RAG, das eine Vektordatenbank verwendet, um semantisch ähnlichen Text abzurufen, erweitert GraphRAG RAG durch die Einbindung von Wissensgraphen (KGs). Wissensgraphen sind Datenstrukturen, die verwandte oder nicht verwandte Daten auf Grundlage ihrer Beziehungen speichern und verknüpfen.
Eine GraphRAG-Pipeline besteht in der Regel aus zwei grundlegenden Prozessen: Indexierung und Abfrage.
Die GraphRAG-Pipeline
Die GraphRAG-Pipeline (Bildquelle: GraphRAG Paper)
Indexierung
Der Indexierungsprozess umfasst vier zentrale Schritte:
Segmentierung in Texteinheiten: Der gesamte Eingabekorpus wird in mehrere Texteinheiten (Textabschnitte) unterteilt. Diese Abschnitte sind die kleinsten analysierbaren Einheiten und können Absätze, Sätze oder andere logische Einheiten sein. Durch die Segmentierung langer Dokumente in kleinere Abschnitte können wir detailliertere Informationen über diese Eingabedaten extrahieren und bewahren.
Extraktion von Entitäten, Beziehungen und Behauptungen: GraphRAG verwendet LLMs, um alle Entitäten (Namen von Personen, Orten, Organisationen usw.), Beziehungen zwischen ihnen und zentrale im Text ausgedrückte Behauptungen aus jeder Texteinheit zu identifizieren und zu extrahieren. Wir werden diese extrahierten Informationen verwenden, um einen initialen Wissensgraphen zu erstellen.
Hierarchisches Clustering: GraphRAG verwendet die Leiden-Technik, um hierarchisches Clustering auf den anfänglichen Wissensgraphen durchzuführen. Leiden ist ein Community-Detection-Algorithmus, der Community-Strukturen innerhalb des Graphen effektiv entdecken kann. Entitäten in jedem Cluster werden verschiedenen Communities zugewiesen, um eine eingehendere Analyse zu ermöglichen.
Hinweis: Eine Community ist eine Gruppe von Knoten innerhalb des Graphen, die untereinander dicht verbunden sind, aber nur spärlich mit anderen dichten Gruppen im Netzwerk verbunden sind.
- Generierung von Community-Zusammenfassungen: GraphRAG generiert Zusammenfassungen für jede Community und ihre Mitglieder mithilfe eines Bottom-up-Ansatzes. Diese Zusammenfassungen umfassen die wichtigsten Entitäten innerhalb der Community, ihre Beziehungen und zentrale Behauptungen. Dieser Schritt gibt einen Überblick über den gesamten Datensatz und liefert nützliche Kontextinformationen für nachfolgende Abfragen.
Abbildung 1- Ein von einem LLM generierter Wissensgraph, der mit GPT-4 Turbo erstellt wurde.
Abbildung 1: Ein von einem LLM generierter Wissensgraph, der mit GPT-4 Turbo erstellt wurde.
(Bildquelle: Microsoft Research)
Abfragen
GraphRAG verfügt über zwei verschiedene Abfrage-Workflows, die auf unterschiedliche Abfragen zugeschnitten sind.
Global Search zum Schlussfolgern über ganzheitliche Fragen im Zusammenhang mit dem gesamten Datenkorpus unter Nutzung der Community-Zusammenfassungen.
Local Search zum Schlussfolgern über bestimmte Entitäten, indem auf deren Nachbarn und zugehörige Konzepte ausgeweitet wird.
Dieser globale Such-Workflow umfasst die folgenden Phasen.
Abbildung 2- Datenfluss der globalen Suche
Abbildung 2: Datenfluss der globalen Suche (Bildquelle: Microsoft Research)
Benutzerabfrage und Gesprächsverlauf: Das System verwendet die Benutzerabfrage und den Gesprächsverlauf als anfängliche Eingabe.
Community-Berichts-Batches: Das System verwendet von dem LLM aus einer bestimmten Ebene der Community-Hierarchie generierte Knoten-Community-Berichte als Kontextdaten. Diese Community-Berichte werden gemischt und in mehrere Batches aufgeteilt (Gemischter Community-Berichts-Batch 1, Batch 2... Batch N).
RIR (Bewertete Zwischenantworten): Jeder Batch von Community-Berichten wird weiter in Textabschnitte vordefinierter Größe unterteilt. Jeder Textabschnitt wird verwendet, um eine Zwischenantwort zu generieren. Die Antwort enthält eine Liste von Informationsstücken, die Punkte genannt werden. Jeder Punkt hat eine numerische Bewertung, die seine Wichtigkeit angibt. Diese generierten Zwischenantworten sind die Bewerteten Zwischenantworten (Bewertete Zwischenantwort 1, Antwort 2... Antwort N).
Ranking und Filterung: Das System ordnet und filtert diese Zwischenantworten und wählt die wichtigsten Punkte aus. Die ausgewählten wichtigen Punkte bilden die Aggregierten Zwischenantworten.
Endgültige Antwort: Die aggregierten Zwischenantworten werden als Kontext verwendet, um die endgültige Antwort zu generieren.
Wenn Benutzer Fragen zu bestimmten Entitäten stellen (wie Namen von Personen, Orten, Organisationen usw.), empfehlen wir Ihnen, den lokalen Such-Workflow zu verwenden. Dieser Prozess umfasst die folgenden Schritte:
Abbildung 3- Datenfluss der lokalen Suche
Abbildung 3: Datenfluss der lokalen Suche (Bildquelle: Microsoft Research)
Benutzerabfrage: Zunächst erhält das System eine Benutzerabfrage, die eine einfache Frage oder eine komplexere Abfrage sein kann.
Suche nach ähnlichen Entitäten: Das System identifiziert eine Gruppe von Entitäten aus dem Wissensgraphen, die semantisch mit der Benutzereingabe verwandt sind. Diese Entitäten dienen als Einstiegspunkte in den Wissensgraphen. Dieser Schritt verwendet eine Vektordatenbank wie Milvus, um Textähnlichkeitssuchen durchzuführen.
Zuordnung von Entitäten zu Texteinheiten: Die extrahierten Texteinheiten werden den entsprechenden Entitäten zugeordnet, wobei die ursprünglichen Textinformationen entfernt werden.
Extraktion von Entitätsbeziehungen: Dieser Schritt extrahiert spezifische Informationen über die Entitäten und ihre entsprechenden Beziehungen.
Zuordnung von Entitäten zu Kovariaten: Dieser Schritt ordnet Entitäten ihren Kovariaten zu, die statistische Daten oder andere relevante Attribute umfassen können.
Zuordnung von Entitäten zu Community-Berichten: Community-Berichte werden in die Suchergebnisse integriert und beziehen einige globale Informationen ein.
Nutzung des Gesprächsverlaufs: Falls bereitgestellt, nutzt das System den Gesprächsverlauf, um die Absicht und den Kontext des Benutzers besser zu verstehen.
Antwortgenerierung: Schließlich erstellt das System auf Grundlage der in den vorherigen Schritten generierten gefilterten und sortierten Daten eine Antwort auf die Benutzeranfrage und gibt sie aus.
Baseline RAG vs. GraphRAG in der Ausgabequalität
Um die Wirksamkeit von GraphRAG zu demonstrieren, vergleichen seine Entwickler die Ausgabequalität eines Baseline RAG und von GraphRAG in ihrem Ankündigungsblog. Ich zitiere hier ein einfaches Beispiel zur Veranschaulichung.
Verwendeter Datensatz
Die GraphRAG-Entwickler verwendeten den Datensatz Violent Incident Information from News Articles (VIINA) für ihre Experimente.
Hinweis: Dieser Datensatz enthält sensible Themen. Er wurde ausschließlich aufgrund seiner Komplexität und des Vorhandenseins unterschiedlicher Meinungen und partieller Informationen ausgewählt. Es handelt sich um einen unübersichtlichen realen Testfall, der aktuell genug war, um nicht in das Training des Basismodells des LLM aufgenommen worden zu sein.
Überblick über das Experiment
Sowohl dem Baseline RAG als auch GraphRAG wurde dieselbe Frage gestellt, die das Aggregieren von Informationen über den gesamten Datensatz hinweg erfordert, um eine Antwort zu formulieren.
F: Was sind die 5 wichtigsten Themen im Datensatz?
Die Antworten sind im Bild unten dargestellt. Die Ergebnisse des Baseline RAG waren für die Kriegsthemen irrelevant, da die Vektorsuche nicht verwandten Text abrief, was zu einer ungenauen Einschätzung führte. Im Gegensatz dazu lieferte GraphRAG eine klare und relevante Antwort, indem es die Hauptthemen und unterstützende Details identifizierte. Die Ergebnisse stimmten mit dem Datensatz überein, mit Verweisen auf Quellmaterial.
Abbildung 4- BaselineRAG vs. GraphRAG bei der Beantwortung komplexer Zusammenfassungsfragen
Abbildung 4: BaselineRAG vs. GraphRAG bei der Beantwortung komplexer Zusammenfassungsfragen
Weitere Experimente in der Arbeit „From Local to Global: A Graph RAG Approach to Query-Focused Summarization.“ zeigen, dass GraphRAG das Multi-Hop-Reasoning und die komplexe Informationszusammenfassung erheblich verbessert. Die Forschung deutet darauf hin, dass GraphRAG Baseline RAG sowohl in Bezug auf Vollständigkeit als auch auf Vielfalt übertrifft:
Vollständigkeit: Das Ausmaß, in dem die Antwort alle Aspekte der Frage abdeckt.
Vielfalt: Die Bandbreite und Reichhaltigkeit der Perspektiven und Erkenntnisse, die die Antwort bietet.
Wir empfehlen Ihnen, die ursprüngliche GraphRAG-Arbeit zu lesen, um weitere Details zu diesen Experimenten zu erhalten.
So implementieren Sie GraphRAG mit der Milvus-Vektordatenbank
GraphRAG erweitert RAG-Anwendungen um Wissensgraphen und stützt sich außerdem auf eine Vektordatenbank, um relevante Entitäten abzurufen. Dieser Abschnitt zeigt, wie man GraphRAG implementiert, einen GraphRAG-Index erstellt und ihn mithilfe der Milvus-Vektordatenbank abfragt.
Voraussetzungen
Bevor Sie den Code in diesem Blog ausführen, stellen Sie sicher, dass Sie die folgenden Abhängigkeiten installiert haben:
pip install --upgrade pymilvus
pip install git+https://github.com/zc277584121/graphrag.git
Hinweis: Wir haben GraphRAG aus einem geforkten Repository installiert, da die Milvus-Speicherfunktion zum Zeitpunkt der Erstellung noch auf einen offiziellen Merge wartet.
Beginnen wir mit dem Indexierungs-Workflow.
Datenvorbereitung
Laden Sie eine kleine Textdatei mit etwa tausend Zeilen von Project Gutenberg herunter und verwenden Sie sie für die GraphRAG-Indexierung.
Dieser Datensatz handelt von der Geschichte Leonardo Da Vincis. Wir verwenden GraphRAG, um einen Graphindex aller Beziehungen im Zusammenhang mit Da Vinci zu erstellen, und die Milvus-Vektordatenbank, um nach relevantem Wissen zur Beantwortung von Fragen zu suchen.
import nest_asyncio
nest_asyncio.apply()
import os
import urllib.request
index_root = os.path.join(os.getcwd(), 'graphrag_index')
os.makedirs(os.path.join(index_root, 'input'), exist_ok=True)
url = "https://www.gutenberg.org/cache/epub/7785/pg7785.txt"
file_path = os.path.join(index_root, 'input', 'davinci.txt')
urllib.request.urlretrieve(url, file_path)
with open(file_path, 'r+', encoding='utf-8') as file:
# We use the first 934 lines of the text file, because the later lines are not relevant for this example.
# If you want to save api key cost, you can truncate the text file to a smaller size.
lines = file.readlines()
file.seek(0)
file.writelines(lines[:934]) # Decrease this number if you want to save api key cost.
file.truncate()
Arbeitsbereich initialisieren
Verwenden wir nun GraphRAG, um die Textdatei zu indexieren. Um Ihren Arbeitsbereich zu initialisieren, führen wir zunächst den Befehl graphrag.index --init aus.
python -m graphrag.index --init --root ./graphrag_index
Konfigurieren der Datei env und der Einstellungen
Sie finden die Datei .env im Stammverzeichnis des Index. Um sie zu verwenden, fügen Sie Ihren OpenAI-API-Schlüssel zur Datei .env hinzu.
Wichtige Hinweise: __
Wir werden für dieses Beispiel OpenAI-Modelle verwenden; stellen Sie sicher, dass Sie einen API-Schlüssel bereithalten.
Die GraphRAG-Indexierung ist kostspielig, da sie den gesamten Textkorpus mit LLMs verarbeitet. Das Ausführen dieser Demo kann ein paar Dollar kosten. Um Geld zu sparen, sollten Sie erwägen, die Textdatei auf eine kleinere Größe zu kürzen.
Ausführen der Indexierungspipeline
Der Indexierungsprozess wird einige Zeit dauern. Nach Abschluss finden Sie einen neuen Ordner unter ./graphrag_index/output/<timestamp>/artifacts, der eine Reihe von Parquet-Dateien enthält.
python -m graphrag.index --root ./graphrag_index
Abfragen mit der Milvus-Vektordatenbank
Während der Abfragephase verwenden wir Milvus, um Entitätsbeschreibungs-Embeddings für die GraphRAG-lokale Suche zu speichern. Diese Methode kombiniert strukturierte Daten aus dem Wissensgraphen mit unstrukturierten Daten aus Eingabedokumenten und erweitert den LLM-Kontext um relevante Entitätsinformationen für präzisere Antworten.
import os
import pandas as pd
import tiktoken
from graphrag.query.context_builder.entity_extraction import EntityVectorStoreKey
from graphrag.query.indexer_adapters import (
# read_indexer_covariates,
read_indexer_entities,
read_indexer_relationships,
read_indexer_reports,
read_indexer_text_units,
)
from graphrag.query.input.loaders.dfs import (
store_entity_semantic_embeddings,
)
from graphrag.query.llm.oai.chat_openai import ChatOpenAI
from graphrag.query.llm.oai.embedding import OpenAIEmbedding
from graphrag.query.llm.oai.typing import OpenaiApiType
from graphrag.query.question_gen.local_gen import LocalQuestionGen
from graphrag.query.structured_search.local_search.mixed_context import (
LocalSearchMixedContext,
)
from graphrag.query.structured_search.local_search.search import LocalSearch
from graphrag.vector_stores import MilvusVectorStore
output_dir = os.path.join(index_root, "output")
subdirs = [os.path.join(output_dir, d) for d in os.listdir(output_dir)]
latest_subdir = max(subdirs, key=os.path.getmtime) # Get latest output directory
INPUT_DIR = os.path.join(latest_subdir, "artifacts")
COMMUNITY_REPORT_TABLE = "create_final_community_reports"
ENTITY_TABLE = "create_final_nodes"
ENTITY_EMBEDDING_TABLE = "create_final_entities"
RELATIONSHIP_TABLE = "create_final_relationships"
COVARIATE_TABLE = "create_final_covariates"
TEXT_UNIT_TABLE = "create_final_text_units"
COMMUNITY_LEVEL = 2
Daten aus dem Indexierungsprozess laden
Während des Indexierungsprozesses werden einige Parquet-Dateien generiert. Wir laden sie in den Arbeitsspeicher und speichern die Entitätsbeschreibungsinformationen in der Milvus-Vektordatenbank.
Entitäten lesen:
# read nodes table to get community and degree data
entity_df = pd.read_parquet(f"{INPUT_DIR}/{ENTITY_TABLE}.parquet")
entity_embedding_df = pd.read_parquet(f"{INPUT_DIR}/{ENTITY_EMBEDDING_TABLE}.parquet")
entities = read_indexer_entities(entity_df, entity_embedding_df, COMMUNITY_LEVEL)
description_embedding_store = MilvusVectorStore(
collection_name="entity_description_embeddings",
)
# description_embedding_store.connect(uri="http://localhost:19530") # For Milvus docker service
description_embedding_store.connect(uri="./milvus.db") # For Milvus Lite
entity_description_embeddings = store_entity_semantic_embeddings(
entities=entities, vectorstore=description_embedding_store
)
print(f"Entity count: {len(entity_df)}")
entity_df.head()
Entitätsanzahl: 651
Abbildung 5: ein Screenshot von Entitäten
Abbildung 5: ein Screenshot von Entitäten
Beziehungen lesen
relationship_df = pd.read_parquet(f"{INPUT_DIR}/{RELATIONSHIP_TABLE}.parquet")
relationships = read_indexer_relationships(relationship_df)
print(f"Relationship count: {len(relationship_df)}")
relationship_df.head()
Beziehungsanzahl: 290
Abbildung 6- ein Screenshot von Beziehungen
Abbildung 6: ein Screenshot von Beziehungen
Community-Berichte lesen
report_df = pd.read_parquet(f"{INPUT_DIR}/{COMMUNITY_REPORT_TABLE}.parquet")
reports = read_indexer_reports(report_df, entity_df, COMMUNITY_LEVEL)
print(f"Report records: {len(report_df)}")
report_df.head()
Berichtsdatensätze: 45
Abbildung 7- ein Screenshot von Berichtsdatensätzen
Abbildung 7: ein Screenshot von Berichtsdatensätzen
Texteinheiten lesen
text_unit_df = pd.read_parquet(f"{INPUT_DIR}/{TEXT_UNIT_TABLE}.parquet")
text_units = read_indexer_text_units(text_unit_df)
print(f"Text unit records: {len(text_unit_df)}")
text_unit_df.head()
Texteinheit-Datensätze: 51
Abbildung 8- ein Screenshot von Texteinheit-Datensätzen
Abbildung 8: ein Screenshot von Texteinheit-Datensätzen
Eine lokale Suchmaschine erstellen
Wir haben die notwendigen Daten für die lokale Suchmaschine vorbereitet. Jetzt können wir mit ihnen, einem LLM und einem Einbettungsmodell eine LocalSearch-Instanz erstellen.
Wir haben die notwendigen Daten für die lokale Suchmaschine vorbereitet. Jetzt können wir mit ihnen, einem LLM und einem Einbettungsmodell eine LocalSearch-Instanz erstellen.
api_key = os.environ["OPENAI_API_KEY"] # Your OpenAI API key
llm_model = "gpt-4o" # Or gpt-4-turbo-preview
embedding_model = "text-embedding-3-small"
llm = ChatOpenAI(
api_key=api_key,
model=llm_model,
api_type=OpenaiApiType.OpenAI,
max_retries=20,
)
token_encoder = tiktoken.get_encoding("cl100k_base")
text_embedder = OpenAIEmbedding(
api_key=api_key,
api_base=None,
api_type=OpenaiApiType.OpenAI,
model=embedding_model,
deployment_name=embedding_model,
max_retries=20,
)
context_builder = LocalSearchMixedContext(
community_reports=reports,
text_units=text_units,
entities=entities,
relationships=relationships,
covariates=None, #covariates,#todo
entity_text_embeddings=description_embedding_store,
embedding_vectorstore_key=EntityVectorStoreKey.ID, # if the vectorstore uses entity title as ids, set this to EntityVectorStoreKey.TITLE
text_embedder=text_embedder,
token_encoder=token_encoder,
)
local_context_params = {
"text_unit_prop": 0.5,
"community_prop": 0.1,
"conversation_history_max_turns": 5,
"conversation_history_user_turns_only": True,
"top_k_mapped_entities": 10,
"top_k_relationships": 10,
"include_entity_rank": True,
"include_relationship_weight": True,
"include_community_rank": False,
"return_candidate_context": False,
"embedding_vectorstore_key": EntityVectorStoreKey.ID, # set this to EntityVectorStoreKey.TITLE if the vectorstore uses entity title as ids
"max_tokens": 12_000, # change this based on the token limit you have on your model (if you are using a model with 8k limit, a good setting could be 5000)
}
llm_params = {
"max_tokens": 2_000, # change this based on the token limit you have on your model (if you are using a model with 8k limit, a good setting could be 1000=1500)
"temperature": 0.0,
}
search_engine = LocalSearch(
llm=llm,
context_builder=context_builder,
token_encoder=token_encoder,
llm_params=llm_params,
context_builder_params=local_context_params,
response_type="multiple paragraphs", # free form text describing the response type and format, can be anything, e.g. prioritized list, single paragraph, multiple paragraphs, multiple-page report
)
Eine Abfrage stellen.
result = await search_engine.asearch("Tell me about Leonardo Da Vinci")
print(result.response)
# Leonardo da Vinci
Leonardo da Vinci, 1452 in der Stadt Vinci nahe Florenz geboren, wird weithin als eines der vielseitigsten Genies der italienischen Renaissance gefeiert. Sein vollständiger Name lautete Leonardo di Ser Piero d'Antonio di Ser Piero di Ser Guido da Vinci, und er war der leibliche und erstgeborene Sohn von Ser Piero, einem Landnotar [Data: Entities (0)]. Leonardos Beiträge erstreckten sich über verschiedene Bereiche, darunter Kunst, Wissenschaft, Ingenieurwesen und Philosophie, und brachten ihm den Titel des universellsten Genies der christlichen Zeit ein [Data: Entities (8)].
## Frühes Leben und Ausbildung
Leonardos frühes Talent wurde von seinem Vater erkannt, der einige seiner Zeichnungen zu Andrea del Verrocchio, einem renommierten Künstler und Bildhauer, brachte. Beeindruckt von Leonardos Begabung nahm Verrocchio ihn um 1469-1470 in seine Werkstatt auf. Hier traf Leonardo andere bedeutende Künstler, darunter Botticelli und Lorenzo di Credi [Data: Sources (6, 7)]. Bis 1472 wurde Leonardo in die Gilde der florentinischen Maler aufgenommen, was den Beginn seiner beruflichen Laufbahn markierte [Data: Sources (7)].
## Künstlerische Meisterwerke
Leonardo ist vielleicht am bekanntesten für seine ikonischen Gemälde wie die "Mona Lisa" und "The Last Supper." Die "Mona Lisa," berühmt für ihren subtilen Ausdruck und den detaillierten Hintergrund, ist im Louvre untergebracht und bleibt eines der berühmtesten Kunstwerke der Welt [Data: Relationships (0, 45)]. "The Last Supper," ein Fresko, das den Moment darstellt, in dem Jesus ankündigte, dass einer seiner Jünger ihn verraten würde, befindet sich im Refektorium von Santa Maria delle Grazie in Mailand [Data: Sources (2)]. Weitere bedeutende Werke sind "The Virgin of the Rocks" und die "Treatise on Painting," die er um 1489-1490 begann [Data: Relationships (7, 12)].
## Wissenschaftliche und technische Beiträge
Leonardos Genie erstreckte sich über die Kunst hinaus auf verschiedene wissenschaftliche und technische Unternehmungen. Er machte bedeutende Beobachtungen in Anatomie, Optik und Hydraulik, und seine Notizbücher sind gefüllt mit Skizzen und Ideen, die viele moderne Erfindungen vorwegnahmen. So nahm er beispielsweise Kopernikus' Theorie der Bewegung der Erde und Lamarcks Klassifikation der Tiere vorweg [Data: Relationships (38, 39)]. Seine Arbeit über die Gesetze von Licht und Schatten sowie seine Meisterschaft im Chiaroscuro hatten einen tiefgreifenden Einfluss sowohl auf die Kunst als auch auf die Wissenschaft [Data: Sources (45)].
## Mäzenatentum und berufliche Beziehungen
Leonardos Laufbahn wurde maßgeblich von seinen Mäzenen beeinflusst. Ludovico Sforza, der Herzog von Mailand, beschäftigte Leonardo als Hofmaler und allgemeinen Kunsthandwerker, gab verschiedene Werke in Auftrag und schenkte ihm 1499 sogar einen Weinberg [Data: Relationships (9, 19, 84)]. In seinen späteren Jahren zog Leonardo nach Frankreich unter der Schirmherrschaft von König Franz I., der ihm ein fürstliches Einkommen gewährte und ihn hoch schätzte [Data: Relationships (114, 37)]. Leonardo verbrachte seine letzten Jahre im Herrenhaus von Cloux nahe Amboise, wo er häufig vom König besucht und von seinem engen Freund und Assistenten Francesco Melzi unterstützt wurde [Data: Relationships (28, 122)].
## Vermächtnis und Einfluss
Leonardo da Vincis Einfluss reichte weit über seine Lebenszeit hinaus. Er gründete eine Malschule in Mailand, und seine Techniken und Lehren wurden von seinen Schülern und Anhängern wie Giovanni Ambrogio da Predis und Francesco Melzi weitergetragen [Data: Relationships (6, 15, 28)]. Seine Werke werden weiterhin gefeiert und studiert und festigen sein Vermächtnis als einer der größten Meister der Renaissance. Leonardos Fähigkeit, Kunst und Wissenschaft zu verbinden, hat in beiden Bereichen unauslöschliche Spuren hinterlassen und unzählige Generationen von Künstlern und Wissenschaftlern inspiriert [Data: Entities (148, 86); Relationships (27, 12)].
Zusammenfassend machen Leonardo da Vincis beispiellose Beiträge zu Kunst, Wissenschaft und Ingenieurwesen, verbunden mit seinem innovativen Denken und seinem tiefgreifenden Einfluss auf seine Zeitgenossen und zukünftige Generationen, ihn zu einer herausragenden Gestalt in der Geschichte menschlicher Leistungen. Sein Vermächtnis inspiriert weiterhin Bewunderung und Forschung und unterstreicht die zeitlose Relevanz seines Genies.
Die Ergebnisse von GraphRAG sind spezifisch, wobei zitierte Datenquellen klar gekennzeichnet sind.
Fragengenerierung
GraphRAG kann auch Fragen auf Grundlage historischer Abfragen generieren, was nützlich ist, um empfohlene Fragen in einem Chatbot-Dialog zu erstellen. Diese Methode kombiniert strukturierte Daten aus dem Wissensgraphen mit unstrukturierten Daten aus Eingabedokumenten, um Kandidatenfragen zu erzeugen, die sich auf bestimmte Entitäten beziehen.
question_generator = LocalQuestionGen(
llm=llm,
context_builder=context_builder,
token_encoder=token_encoder,
llm_params=llm_params,
context_builder_params=local_context_params,
)
question_history = [
"Tell me about Leonardo Da Vinci",
"Leonardo's early works",
]
Generieren Sie Fragen basierend auf dem Verlauf.
candidate_questions = await question_generator.agenerate(
question_history=question_history, context_data=None, question_count=5
)
candidate_questions.response
["- What were some of Leonardo da Vinci's early works and where are they housed?",
"- How did Leonardo da Vinci's relationship with Andrea del Verrocchio influence his early works?",
'- What notable projects did Leonardo da Vinci undertake during his time in Milan?',
"- How did Leonardo da Vinci's engineering skills contribute to his projects?",
"- What was the significance of Leonardo da Vinci's relationship with Francis I of France?"]
Sie können den Index-Root entfernen, wenn Sie den Index löschen möchten, um Speicherplatz zu sparen.
# import shutil
#
# shutil.rmtree(index_root)
Zusammenfassung
In diesem Blog haben wir GraphRAG untersucht, eine innovative Methode, die RAG-Technologie durch die Integration von Wissensgraphen verbessert. GraphRAG ist ideal für die Bewältigung komplexer Aufgaben wie Multi-Hop-Reasoning und die Beantwortung umfassender Fragen, die das Verknüpfen unterschiedlicher Informationsstücke erfordern.
In Kombination mit der Milvus-Vektordatenbank kann GraphRAG komplexe semantische Beziehungen innerhalb großer Datensätze navigieren und genauere sowie aufschlussreichere Ergebnisse liefern. Diese leistungsstarke Kombination macht GraphRAG zu einem unschätzbaren Vorteil für verschiedene praktische GenAI-Anwendungen und bietet eine robuste Lösung für das Verstehen und Verarbeiten komplexer Informationen.
Weitere Ressourcen
Das GraphRAG-Paper: From Local to Global: A Graph RAG Approach to Query-Focused Summarization
GraphRAG GitHub: https://github.com/microsoft/graphrag
Weitere Techniken zur RAG-Verbesserung:
Weiterlesen

Zilliz Cloud Update: Smarter Autoscaling for Cost Savings, Stronger Compliance with Audit Logs, and More
What's new in Zilliz Cloud? Smarter autoscaling with scale-down, audit logs GA, enhanced SSO, and Milvus 2.6 in Private Preview.

Legal Document Analysis: Harnessing Zilliz Cloud's Semantic Search and RAG for Legal Insights
Enhance legal document analysis with Zilliz Cloud’s Semantic Search and RAG. Improve accuracy, efficiency, and scalability for contracts, case law, and compliance.

Introducing DeepSearcher: A Local Open Source Deep Research
In contrast to OpenAI’s Deep Research, this example ran locally, using only open-source models and tools like Milvus and LangChain.



