GraphRAG-:® Warum Vektorsuche auf der Corpus-Ebene nach unten bricht
Ihr RAG-System ist großartig bei Fragen, die Sie benötigen, um ein paar relevante Brocken abzurufen und eine Antwort zu synthetisieren.
- SensemakingWas sind die wichtigsten Themen in diesem corpus.
- VerbundenWie bezieht sich X auf Y in verschiedenen Dokumenten?
Jene, die von jedem einzelnen Stück beantwortet werden Berichterstattung - Clustering-Verknüpfung.
Warum die Vektorsuche hier fehlschlägt
- Es ordnet Stücke unabhängig durch Ähnlichkeit mit der Abfrage
- Ähnlichkeit optimiert Relevanz Globale Abdeckung
- Embeddings fangen ein, was ähnlich klingt ,", , nicht , " , was mit dem verbindet, was ," ,
Sie können brute--, dies mit Aufforderungen und Post--, Verarbeitung, aber Sie am Ende Wiederaufbau einer Graphen-MSC3, Formlösung, .
Die wichtigsten Erkenntnisse GraphRAG ändert die Retrieval-Einheit... Für Korpusfragen, die Sie wünschen.'. vernetzte Konzept-Communities Und ihre Zusammenfassungen, also sieht das Modell Struktur, nicht Fragmente, nicht .
GraphRAG kommt von Microsoft Research.' Papier und ist als Open---Source-ImplementierungEs hält Vektor-Suche nach spezifischen Fragen, aber fügt ein Wissen Diagramm und Gemeinschaft Zusammenfassungen für corpus.-...
GraphRAG-Seriennavigation
- Teil - Grundlagen der GraphRAG Dieser Artikel
- Teil: Mindestausführbare GraphRAG-Anrufe
Wann wird GraphRAG NICHT verwendet?
Vor dem Tauchen in ,,' lassen ,''s klar sein, wenn dies ist Overkill , :'
- Kleine Dokumentsätze Verwenden Sie einfach Vektorsuche
- **Nur Fragen zu I"**Hilfe von GraphRAG
- Einheitlicher Inhalt Keine Entity-Vielfalt, keine Graphenstruktur zu nutzen
- KostenvoranschlägeIndexierung erfordert viele LLM-Aufrufe
Wenn Ihre Benutzer nur spezifische Fragen stellen semantische SucheGlänzt GraphRAG, wenn Benutzer die Großes Bild, und dass ein kleineres Publikum als Verkäufer vorschlagen
Einleitung
Serie Navigation .: Dies ist Teil der RAG-Serie.
- Teil: Ursprung und Grundlagen Geschichte, Motivation und Kernkonzepte
- Teil Architektur und Innenarchitektur Technischer Tieftauchgang
- RAG in der Praxis Bau von realen Systemen
- Teil Umsetzung des Qdrant-Systems Benutzerfreundliche semantische Suche
- Teil - Semantische Suche in Aktion Hybride Suche nach , und UI
- Teil-Hybridsuche Integration der Produktion
- Teil 6:-GraphRAG Diesen Artikel lesen Sie unter ) Wissensgraphen für das Verständnis von Corpus-.
Während dieser Serie haben wir uns immer ausgeklügeltere RAG-Systeme aufgebaut.Wir begannen mit der grundlegenden Vektorsuche. ähnliche StückeNicht vernetzte KonzepteFür corpus---Level Fragen, die viele Dokumente überspannen, müssen Sie Struktur
Der empfohlene Pfad Wenn Sie bereits Qdrant-- based lokale Suche arbeiten, so wie wir den Prototyp von ), mit dem Python Sidecar machen, um Wert zu bestätigen, halten Sie Vektoren für die lokale Suche und fügen Sie einen leichten Graphen für globale / DRIFT Abfragen hinzu.
Das Problem mit Pure Vector RAG
Lassen Sie mich Ihnen zeigen, was ich mit einem konkreten Beispiel meine.
Was Vector RAG gut macht
Frage Wie verwende ich HTMX mit Alpine-.?
Vector RAG-Prozess - :
- Die Frage einbetten
[0.234, -0.891, 0.567, ...] - Ähnliche Brocken in Qdrant finden
- Zurück nach oben--K Spiele über HTMX und Alpine-.-Js
- LLM synthetisiert Antwort aus diesen Brocken
Dies funktioniert, weil die Frage und der relevante Inhalt semantisch ähnlichDie Einbettungen erfassen diese Ähnlichkeit.
// This is what our current SemanticSearchService does
var embedding = await _embeddingService.GetEmbeddingAsync(query);
var results = await _qdrantService.SearchAsync(
collectionName: "blog_posts",
queryVector: embedding,
limit: 10
);
// Returns chunks about HTMX, Alpine.js, frontend patterns
Wo Vector RAG kämpft
Frage Was sind die wichtigsten Technologien, über die ich schreibe und wie sie miteinander in Beziehung stehen?
Welcher Vektor RAG zurückgibt?
Result 1: "HTMX makes it easy to add AJAX to your pages..."
Result 2: "Docker Compose orchestrates multiple containers..."
Result 3: "PostgreSQL's full-text search is surprisingly capable..."
Result 4: "Alpine.js provides reactive state management..."
Es erwähnt Docker, ,, PostgreSQL,,, HTMX-,, ONNX-MSC3, aber nicht Gruppe sie oder erklären Sie, wie sie verbinden, ., erhalten Sie Fragmente nicht Einsicht
Diese Frage erfordert Aggregation und Beziehungsverständnis über den gesamten Korpus, ., Sie müssen :,
- Alle genannten Technologien identifizieren
- Verstehen, die zusammen verwendet werden
- Sie in kohärente Themen einteilen
Vektor-Ähnlichkeit allein doesn's''t geben Ihnen diese ..' Wenn Sie versuchen, dies mit Aufforderungen zu patchen ?,' Sie am Ende neu erfinden einen Graphen
GraphRAG eingeben
GraphRAG ist Microsoft Research-' s Lösung für dieses Problem GraphRAG-Papier identifiziert die beiden Abfragetypen, die Basis-RAG schlecht behandeltSinnesbildung und BindemittelSie bauten ein System, um sie zu adressieren
Statt nur embedding chunks-, Builds a Wissensgraphik die Entitäten und ihre Beziehungen erfassen, clustert sie dann in Gemeinschaften mit Zusammenfassungen zusammen.
Wie GraphRAG funktioniert
Pipeline auf einen Blick
- Indexierung Zusammenstellungen von Daten aus der Zeit vor dem 1. Januar 2015
- Abfragen Lokale Zusammenfassungen von =, Graphen-Nachbarschaften von |, Global Zusammenfassungen der Gemeinschaft von MKK4, DRIFT, =, Pfade von MSC6, Zusammenfassungen
GraphRAG fügt der RAG-Pipeline mehrere Komponenten hinzu, die in drei Kategorien gruppiert sind:
- Gewinnung ,(-Stellen Beziehungen
- Schaubilderaufbau Wissens Graphenspeicher (MSK)
- Zusammenfassung Ermittlung der Gemeinde-Erkennung (MSK)
flowchart TB
subgraph "Traditional RAG (What We Have)"
A[Documents] --> B[Chunks]
B --> C[Embeddings]
C --> D[Vector Store]
end
subgraph "GraphRAG Additions"
B --> E[Entity Extraction]
E --> F[Relationship Extraction]
F --> G[Knowledge Graph]
G --> H[Community Detection]
H --> I[Community Summaries]
end
subgraph "Query Time"
J[User Query] --> K{Query Type?}
K -->|Specific| L[Local Search]
K -->|Global| M[Global Search]
K -->|Hybrid| N[DRIFT Search]
D --> L
G --> L
I --> M
G --> N
I --> N
end
style E stroke:#f9f,stroke-width:2px
style H stroke:#bbf,stroke-width:2px
style I stroke:#9f9,stroke-width:2px
Schritt: Entitätsextraktion
Ein LLM liest jeden Stück und extrahiert Einrichtungen Die Dinge, über die diskutiert wird
Chunk: "Docker Compose makes it easy to define multi-container applications.
I use it with PostgreSQL for my blog's database layer."
Extracted Entities:
- Docker Compose (technology)
- PostgreSQL (database)
- blog (project)
- database layer (concept)
Schritt: Verhältnis-Extraktion
Das gleiche LLM identifiziert, wie Entities miteinander in Beziehung stehen.
Relationships:
- Docker Compose --[used_with]--> PostgreSQL
- blog --[has_component]--> database layer
- PostgreSQL --[implements]--> database layer
Schritt 3:-Wissensgraphenbau
Alle Entitäten und Beziehungen bilden einen Graphen.
graph LR
subgraph "Frontend Cluster"
HTMX[HTMX]
Alpine[Alpine.js]
Tailwind[Tailwind CSS]
end
subgraph "Infrastructure Cluster"
Docker[Docker]
Compose[Docker Compose]
Postgres[PostgreSQL]
Qdrant[Qdrant]
end
subgraph "AI/ML Cluster"
ONNX[ONNX Runtime]
Embeddings[Embeddings]
RAG[RAG]
end
HTMX -->|used_with| Alpine
HTMX -->|styled_by| Tailwind
Alpine -->|styled_by| Tailwind
Docker -->|orchestrated_by| Compose
Compose -->|runs| Postgres
Compose -->|runs| Qdrant
ONNX -->|generates| Embeddings
Embeddings -->|stored_in| Qdrant
RAG -->|uses| Embeddings
RAG -->|uses| Qdrant
style HTMX stroke:#f9f
style Docker stroke:#bbf
style RAG stroke:#9f9
Schritt: Gemeinschaftsdetektion von (Leiden Algorithmus)
Das Leiden-Algorithmus Cluster dicht verbunden Knoten in Communities. Das ist wichtig, weil es Ihnen stabil Cluster zum Zusammenfassen und Abrufen der Communities werden zu Ihren Retrieval-Einheiten für globale Abfragen.
- Gemeinschaft"Vorderer Stack"Vordere Stack (HTMX,Alpine.Js,Rückwind)
- Gemeinschaft"Container-Infrastruktur: ", (, Docker, ,, Compose,, PostgreSQL, MSC6, Qdrant, MCSK7,
- Gemeinschaft"RAG Pipeline"B(ONNX2,Embeddings,Qdrant,RAG-)E
Beachten Sie, wie Qdrant in zwei Communities erscheint.
Schritt - Zusammenfassungen der Gemeinschaft
Ein LLM generiert für jede Gemeinschaft auf jeder Hierarchieebene Zusammenfassungen
Community 1 Summary (Frontend Stack):
"The frontend approach combines HTMX for server-driven interactivity
with Alpine.js for client-side state management, styled using Tailwind CSS.
This stack prioritizes HTML-first development with minimal JavaScript,
focusing on progressive enhancement over SPA complexity."
Community 2 Summary (Container Infrastructure):
"The blog runs on Docker Compose, orchestrating PostgreSQL for persistent
storage, Qdrant for vector search, and the ASP.NET Core application.
This containerized architecture enables consistent local development
and production deployment."
Abfrage-Modi
GraphRAG stellt drei Abfragemodi zur Verfügung, die jeweils für verschiedene Fragetypen optimiert sind.
Globale Suche
Am besten für ,:' Was sind die Hauptthemen? - ?"? - Zusammenfassung der wichtigsten Themen.
Verwendet gemeinschaftliche Zusammenfassungen nicht einzelne Stücke, um sinnvolle Fragen zu beantworten.
Query: "What technologies does this blog cover most?"
Process:
1. Retrieve all community summaries
2. Map: Ask LLM to extract technology themes from each summary
3. Reduce: Combine partial answers into final response
Response:
"The writing centres on three technology clusters:
1. **Frontend Development** - HTMX, Alpine.js, Tailwind CSS for minimal-JS web UIs
2. **AI/ML Infrastructure** - RAG pipelines, ONNX embeddings, vector search with Qdrant
3. **DevOps/Containerization** - Docker, PostgreSQL, ASP.NET Core deployment"
Lokale Suche
Am besten für ,:' Wie konfiguriere ich X-?"? - Was ist Y-MSC3?
Kombiniert Entity---fokussierte Graphentraversal mit traditioneller Vektorsuche:-
Query: "How do I use Qdrant with ONNX embeddings?"
Process:
1. Identify entities in query: Qdrant, ONNX, embeddings
2. Retrieve graph neighborhood around those entities
3. Also retrieve vector-similar chunks
4. Combine into rich context for LLM
Response includes:
- Direct relationships (ONNX generates embeddings stored in Qdrant)
- Related entities (all-MiniLM-L6-v2 model, cosine similarity)
- Specific code examples from vector-retrieved chunks
ENTWURFSUCHUNG
Am besten für ,:' Wie bezieht sich X auf Y.?"?
DRIFT-Suche mit flexiblem Traversal - Dynamische Vernunft und Schlussfolgerung Wie in den GraphRAG docs beschriebenDie Struktur hilft dem LLM, Verbindungen zu sehen, die es mit flachen Brocken vermissen würde.
Query: "How do the frontend and backend technologies connect?"
Process:
1. Start with entities: HTMX, ASP.NET Core
2. Traverse graph to find connection paths
3. Include community summaries for context
4. Generate answer showing the full picture
Response:
"HTMX makes requests to ASP.NET Core endpoints, which query PostgreSQL
and Qdrant. The connection flows through the API layer, where endpoints
return HTML fragments that HTMX swaps into the DOM. Alpine.js handles
client-side state for interactive components like search typeahead."
Vergleich von GraphRAG mit unserem aktuellen System
Let.' s Karte GraphRAG Konzepte zu dem, was wir bereits in Mostlylucid.SemanticSearch:
| Komponenten des aktuellen Systems des | , GraphRAG Äquivalente des MSC3, |
|---|---|
| Einbettungen , | , ONNX , (, all ,-, MiniLM, -, MKS4, V2), MSSK6, M( oder OpenAI, MSC8 und |
| Vektorspeicher Qdrant Qdant QDrant /® LanceDB | |
| Entitätenextraktion Keine LLM, -, strombetriebene Extraktion | |
| Wissensdiagramm Keine Graphendatenbank in - Memory | |
| Gemeinschaftserkennung Keinen Leitalgorithmus | |
| Abfrage-:-Spezifische | SemanticSearchService.SearchAsync() Lokale Suche |
| Abfrage-:- Global Nicht unterstützt Globale Suche |
Unsere aktuelle Implementierung übernimmt Lokale Suche Nun, ., GraphRAG würde hinzufügen Globale Suche und ENTWURFSUCHUNG Fähigkeiten
// What we have today (Local Search equivalent)
public async Task<List<SearchResult>> SearchAsync(string query, int limit = 10)
{
var embedding = await _embeddingService.GetEmbeddingAsync(query);
return await _qdrantService.SearchAsync("blog_posts", embedding, limit);
}
// What GraphRAG would add
public async Task<string> GlobalSearchAsync(string query)
{
// 1. Retrieve community summaries (not chunks)
var summaries = await _graphService.GetCommunitySummariesAsync();
// 2. Map: Extract relevant themes from each summary
var partialAnswers = await Task.WhenAll(
summaries.Select(s => _llm.ExtractThemesAsync(query, s))
);
// 3. Reduce: Combine into final answer
return await _llm.SynthesizeAsync(query, partialAnswers);
}
Umsetzungsansätze
Es gibt drei Möglichkeiten, GraphRAG einem bestehenden System hinzuzufügen.
Option "Python-Sidecar" für die Exploration empfohlen
Führen Sie Microsoft®'®s GraphRAG als separaten Dienst aus
# docker-compose.graphrag.yml
services:
graphrag:
build:
context: ./graphrag
volumes:
- ./data/input:/app/input
- ./data/output:/app/output
environment:
- OPENAI_API_KEY=${OPENAI_API_KEY}
graphrag-api:
build:
context: ./graphrag-api
ports:
- "8001:8000"
depends_on:
- graphrag
// GraphRagClient.cs - Call from ASP.NET Core
public class GraphRagClient
{
private readonly HttpClient _http;
public GraphRagClient(HttpClient http)
{
_http = http;
_http.BaseAddress = new Uri("http://graphrag-api:8000");
}
public async Task<string> GlobalSearchAsync(string query)
{
var response = await _http.PostAsJsonAsync("/query/global", new { query });
var result = await response.Content.ReadFromJsonAsync<GraphRagResponse>();
return result.Answer;
}
public async Task<string> LocalSearchAsync(string query)
{
var response = await _http.PostAsJsonAsync("/query/local", new { query });
var result = await response.Content.ReadFromJsonAsync<GraphRagResponse>();
return result.Answer;
}
}
Vorbemerkungen Verwenden Sie Microsoft .' s battle . - Bewährte Implementierung , , Schnell zum Prototyp Verwechslungen Python-Abhängigkeit,-LLM-Kosten für die Indexierung cross---Prozesskommunikation
Option 2: Native (" Produktionspfad )
Bauen Sie die Schlüsselkomponenten in der BERT-- based Extraktion und Ollama Muster aus DocSummarizer Arbeite ähnlich hier.
Entitätenextraktion
Bitten Sie einen LLM zu identifizieren Dinge (-Stellen in jedem Stück strukturierte Entitäten statt freiem --Format Themen
public async Task<List<Entity>> ExtractEntitiesAsync(string chunk)
{
var prompt = $"""
Extract entities from this text. Return JSON array.
Types: technology, concept, project, person, organization
Text: {chunk}
Format: [{{"name": "Docker", "type": "technology"}}]
""";
var response = await _ollama.GenerateAsync(prompt);
return JsonSerializer.Deserialize<List<Entity>>(response);
}
Produktionsanforderung LLM JSON-Ausgabe wird Dies ist nicht optionale Verhärtung... Du brauchst eine von...
- Schema---beschränkte Generation ](-Ollama-'
format: jsonFunktion OpenAI-' mit Aufruf von ) - Retry-- mit --Reparaturschleifen (-detektieren Sie missgebildete JSON-,- fragen LLM, um es zu beheben
- Rückfallextraktion Muster für gemeinsame Entitätstypen (MSK)
LLMs sind probabilistisch, ;-Ihre Extraktion Pipeline darf nicht sein
Beziehungsextraktion
Sobald Sie Entities haben, fragen Sie die LLM, wie sie verbinden.
public async Task<List<Relationship>> ExtractRelationshipsAsync(
string chunk, List<Entity> entities)
{
var names = string.Join(", ", entities.Select(e => e.Name));
var prompt = $"""
Given entities: {names}
Extract relationships. Return JSON array.
Text: {chunk}
Format: [{{"source": "Docker", "target": "PostgreSQL", "rel": "runs"}}]
""";
return JsonSerializer.Deserialize<List<Relationship>>(
await _ollama.GenerateAsync(prompt));
}
Graphenspeicherung mit Entity-Normalisierung
Der größte praktische Schmerz ist Unternehmen, die eine Aliasierung vornehmenDie einfache Normalisierung hilft :.
public class KnowledgeGraph
{
private readonly Dictionary<string, Entity> _entities = new();
private readonly List<Relationship> _relationships = new();
public void AddEntity(Entity entity)
{
var key = Normalise(entity.Name); // "ASP.NET Core" → "aspnetcore"
_entities[key] = entity;
}
private string Normalise(string name) =>
name.ToLowerInvariant().Replace(".", "").Replace("-", "").Trim();
}
Für den ernsthaften Gebrauch betrachten embedding-- based entity deduplication-: , wenn zwei Entitätsnamen ähnliche Einbettungen haben
Produktionsschmerzpunkte Die Werte hängen von der Graphenqualität ab.
- Synonyme TabellenAufrechterhaltung kanonischen Namens und bekannter Aliasnamen
- BeziehungsschemasteuerungConstrain erlaubte Prädikate, halluzinierte Beziehungstypen zu verhindern
- Vertrauensscoring BeschneidungNicht alle extrahierten Beziehungen sind gleichermaßen zuverlässig
- Inkrementelle Re---IndexierungWenn Dokumente aktualisiert werden, müssen Sie den Graphen patchen.
Schaubild Traversal
Die Suche nach verwandten Entities ist eine Breite
public List<Entity> GetNeighbors(string entityName, int depth = 1)
{
var result = new HashSet<Entity>();
var queue = new Queue<(string Name, int Depth)>();
queue.Enqueue((Normalise(entityName), 0));
while (queue.Count > 0)
{
var (name, d) = queue.Dequeue();
if (d >= depth) continue;
// Find all entities connected to this one
var neighbours = _relationships
.Where(r => Normalise(r.Source) == name || Normalise(r.Target) == name)
.SelectMany(r => new[] { r.Source, r.Target });
foreach (var neighbour in neighbours)
if (_entities.TryGetValue(Normalise(neighbour), out var entity))
if (result.Add(entity))
queue.Enqueue((Normalise(neighbour), d + 1));
}
return result.ToList();
}
Gemeinschaftserkennung
Dies ist ein verbundener used---Komponenten-Baseline-Ausgangswert nicht Volle Leiden®.-Leiden optimiert für Modularität · (-Dense interne Verbindungen • ,- spärliche externe Verbindungen •).-Für eine korrekte Implementierung verwenden Sie bitte eine Graphbibliothek oder portieren Sie den Algorithmus • .-
public List<Community> DetectCommunities(KnowledgeGraph graph)
{
// Connected components: group everything reachable together
var visited = new HashSet<string>();
var communities = new List<Community>();
foreach (var entity in graph.GetAllEntities())
{
if (visited.Contains(entity.Name)) continue;
// BFS to find all connected entities
var community = new Community();
var queue = new Queue<string>();
queue.Enqueue(entity.Name);
while (queue.Count > 0)
{
var name = queue.Dequeue();
if (!visited.Add(name)) continue;
community.Entities.Add(graph.GetEntity(name));
foreach (var neighbor in graph.GetNeighbors(name, depth: 1))
queue.Enqueue(neighbor.Name);
}
communities.Add(community);
}
return communities;
}
Zusammenfassung der Gemeinschaft
Jede Gemeinschaft erhält eine Zusammenfassung, die ihr Thema beschreibt.
public async Task<string> SummarizeCommunityAsync(Community community)
{
var entities = string.Join("\n",
community.Entities.Select(e => $"- {e.Name}: {e.Description}"));
var prompt = $"""
Summarize what unites these concepts (2-3 sentences):
{entities}
""";
return await _ollama.GenerateAsync(prompt);
}
Option "Hybrid" (pragmatischer Mittelboden)
Dies ist der empfohlene Ansatz, wenn Sie bereits arbeitende Vektor-Suche haben, halten Sie Qdrant für die lokale Suche, fügen Sie eine leichte Graphenschicht für globale Anfragen, / und DRIFT hinzu.
Abfrageklassifikation
Zuerst erkennen Sie, welche Art von Frage dies ist.
// WARNING: Toy heuristic for illustration only.
// In production, use a classifier prompt or few-shot rules and log misroutes.
private QueryMode ClassifyQuery(string query)
{
var q = query.ToLowerInvariant();
if (q.Contains("main theme") || q.Contains("summarize") || q.Contains("what topics"))
return QueryMode.Global;
if (q.Contains("relate") || q.Contains("connect") || q.Contains("compare"))
return QueryMode.Drift;
return QueryMode.Local;
}
Lokale Suche
Vorhandene Vektorsuche verwenden – Optional mit Graphenkontext angereichert – :
private async Task<string> LocalSearchAsync(string query)
{
// Existing semantic search (what we have today)
var chunks = await _semanticSearch.SearchAsync(query, limit: 10);
// NEW: Enrich with related entities from graph
var entities = await _graphService.ExtractEntitiesFromQueryAsync(query);
var related = await _graphService.GetEntityContextAsync(entities);
return await _llm.GenerateAsync(query, FormatContext(chunks, related));
}
Globale Suche
Karte ,- , reduce über Gemeinde Zusammenfassungen , ( , keine Vektorsuche erforderlich
private async Task<string> GlobalSearchAsync(string query)
{
var summaries = await _graphService.GetAllCommunitySummariesAsync();
// Map: Extract relevant info from each community
var partials = await Task.WhenAll(
summaries.Select(s => _llm.ExtractRelevantInfoAsync(query, s)));
// Reduce: Combine into final answer
return await _llm.SynthesizeAsync(query, partials.Where(p => !string.IsNullOrEmpty(p)));
}
DRIFT-Suche
Kombinieren Sie lokale Ergebnisse mit dem Community-Kontext für X bezieht sich auf Fragen von Y.:
private async Task<string> DriftSearchAsync(string query)
{
var localResults = await LocalSearchAsync(query);
var entities = await _graphService.ExtractEntitiesFromQueryAsync(query);
var communities = await _graphService.GetCommunitiesForEntitiesAsync(entities);
var themes = string.Join("\n", communities.Select(c => c.Summary));
return await _llm.GenerateAsync(
$"Question: {query}\n\nDetails:\n{localResults}\n\nBroader themes:\n{themes}",
systemPrompt: "Synthesize the details with the thematic context.");
}
Kosten und Leistung
GraphRAG hat im Vergleich zu reinem Vektor deutliche Tradeoffs
Indexierungskosten
Entitäts-/-Bezugskosten unterscheiden sich signifikant durch Modell-MSC1-Promptdesign und Stückgröße.- als grobe Reihenfolge- von --Magnitude, annehmen ein oder zwei LLM-Anrufe pro Stück plus eine kleinere Anzahl von Aufrufen für gemeinschaftliche Zusammenfassungen
Vector RAG GraphRAG GraphRAG |-----------|------------|----------| | Einbetten ,| , , 1 , rufen Sie an ,/ , kunk , | , die gleiche , | , | Entität/-Relationship Extraction Keine Anrufe von LLM-Anrufen von /, | Zusammenfassung der Gemeinschaft Keine Anrufe aus LLM
Für einen Korpus von Blog-Posts mit einem Stück 5, jeder Stück MSC2, insgesamt ),, nur Indexierung ist im Wesentlichen nur Einbettungskosten ., GraphRAG fügt Tausende LLM-Aufrufe zur Extraktion und Zusammenfassung hinzu., die exakten Kosten hängen stark von Ihrer Modellwahl und der prompten Effizienz ab.;, wobei lokale Modelle verwendet werden, (,Ollama mit Lama-3.2 oder ähnlichem ), eliminiert API-Kosten vollständig ,, was der empfohlene Ansatz für Experimente . ist.
Abfragekosten
| Suchen Typ des Vektors RAG | ® GraphRAG lokal , | , GraphRAG global , | , |
|---|---|---|---|
| Vektorsuche Ausrufe aus der 1Ausrufe von | Ausrufen aus dem 1Ausruf-Ausruf | ||
| Graphenquerschnitt | -Abfragen 0-Abfrage | -Abruf | |
| LLM Anrufe Weitere Informationen: http:europa.eu.int/en/comm/index_de.htm |
Globale Suche ist teurer pro Abfrage., , aber es beantwortet Fragen, dass die lokale Suche einfach kann. ' ,t ,. , Sie können auch globale Antworten zwischenspeichern und aktualisieren sie nur, wenn das Corpus ändert.
GraphRAG-Ausfallmodi
GraphRAG ist die Magie von '.
- ExtraktionsfehlerLLMs vermissen Entitäten oder halluzinierte Beziehungen
- Aliasierung des Unternehmens"ASP®.Aspnet-Core-"Vs "ASP«.Aspnetz"Vs"aspnetcore-" werden zu getrennten Knoten
- AbbildungsdriftBeim Aktualisieren von docs kann der Graph veralten
- Gemeinschaftliche Zusammenfassungen werden vertagtZusammenfassungen don-'.t auto--.aktualisieren, wenn Entitäten sich ändern
Entity-Normalisierung ist der größte praktische Schmerz, den Sie brauchen
- Kanonische Bezeichnungen Aliasnamen
- Fall---Falten und Interpunktion Normalisierung
- Optionale Einbettung der auf --Basis basierenden Entitätsdeduplikation
Integration in unsere Blog-Suche
Hier ist ', wie GraphRAG den Blog verbessern könnte. ' Vorhandene semantische Suche.
Aktueller Fluss
User types in search → SemanticSearchService → Qdrant → Results
Verbesserter Fluss
Der Klassifikator leitet Abfragen zu unterschiedlichen Suchstrategien ein. globale Abfrage fliesst --Beachten Sie, dass es nie berührt den Vektor speichern :
sequenceDiagram
participant U as User
participant API as Search API
participant C as Query Classifier
participant G as Global Search
participant KG as Knowledge Graph
U->>API: "What topics does this blog cover?"
API->>C: Classify query
C-->>API: QueryMode.Global
API->>G: GlobalSearch(query)
G->>KG: GetCommunitySummaries()
KG-->>G: [Frontend, Infrastructure, AI/ML]
G->>G: MapReduce over summaries
G-->>API: Synthesized answer
API-->>U: "The blog covers three main areas..."
Vergleichen Sie dies mit einem Lokale AbfrageDie Vektorsuche mit dem Graphenkontext für reichere Antworten kombiniert
sequenceDiagram
participant U as User
participant API as Search API
participant C as Query Classifier
participant L as Local Search
participant Q as Qdrant
participant KG as Knowledge Graph
U->>API: "How do I use HTMX?"
API->>C: Classify query
C-->>API: QueryMode.Local
API->>L: LocalSearch(query)
L->>Q: Vector search
Q-->>L: Relevant chunks
L->>KG: GetEntityContext("HTMX")
KG-->>L: Related: Alpine.js, Tailwind, ASP.NET
L-->>API: Answer with rich context
API-->>U: "HTMX is used with Alpine.js for..."
Der Schlüsselunterschied: globale Abfragen Aggregate von Community Zusammenfassungen (Corporate Themen auf Ebene ),, während lokale Abfragen spezifische Brocken abrufen, die mit Entity-Beziehungen angereichert sind
Eine einfachere Alternative GraphRAG ist immer noch sehr viel ein Forschungs-Tool Entitätsextraktion., graph construction. und Community Detection hinzufügen erhebliche Komplexität und LLM Kosten. BERT-Einbettungen - Schlüsselwort-Matching Das ist, was funktioniert besser Quelle: Bild der Cody verwendet für Code-Intelligence und was DocSummarizer Verwendungen für die Zusammenfassung von Dokumenten ,. , das Muster , : , hybride Retrieval-Handles Relevanz , die LLM Griffe MontageNicht EntscheidungsfindungSie erhalten die Vorteile mit der Komplexität.
Umsetzungsskizze
Die API ist einfach ,: , klassifizieren Sie die Abfrage ., , Route zu den entsprechenden Handler .
[HttpGet("api/search")]
public async Task<IActionResult> Search([FromQuery] string q, [FromQuery] string mode = "auto")
{
if (mode == "auto")
mode = ClassifyQuery(q);
// global/local return synthesised answers; default returns raw search results
return mode switch
{
"global" => Ok(await _graphRag.GlobalSearchAsync(q)), // synthesised answer
"local" => Ok(await SearchWithGraphContext(q)), // answer with citations
_ => Ok(await _semanticSearch.SearchAsync(q)) // raw ranked results
};
}
Vektorsuche und Graphensuchung ergänzen einander.Verwenden Sie Vektoren für ", wie tun IM", Fragen.,, Diagramme für ", was sind die Themen?", Fragen...
Schlußfolgerung
GraphRAG erweitert die RAG von ähnlichen Brocken auf ", um die Wissensstruktur zu verstehen..", es ist kein Ersatz für die Vektorsuche.;, es ermöglicht eine Erweiterung, die neue Abfragetypen ermöglicht
Was GraphRAG hinzufügt
- Entität und Beziehungsextraktion
- Aufbau von Wissensgrafiken
- Gemeinschaftsdetektion und hierarchische Zusammenfassungen
- Globale Suche nach sinnvollen Fragen
- DRIFT Suche nach verbindenden Überlegungen
Wann es zu verwenden ist
- Sie haben eine umfangreiche Dokumentensammlung
- Benutzer fragen, was die Themen sind, " tippen Fragen
- Ihr Inhalt hat klare Wesenheiten und Beziehungen
- Sie wollen Verbindungen automatisch aufdecken
Umsetzungspfad
- Zuerst ,, , fragen , : , müssen Sie wirklich diese brauchen , um ? , BERT , + , Hybrid Retrieval behandelt die meisten Use Cases
- Wenn ja, ,-Prototyp mit Python Sidecar zur Validierung des Wertes
- Bauen Sie Natives, wenn Kosten /Latenz-Materie
- Verwenden Sie lokale LLMs, um Indexierungskosten zu kontrollieren
Aufkommen
GraphRAG Beamter
- GraphRAG-Dokumentation Offizielle docs von Microsoft
- GraphRAG GitHub Quelle und Beispiele
- GraphRAG Papier Das ursprüngliche Forschungspapier
- Leiden Algorithmus Papier Gemeinschafts-Detektionsalgorithmus
RAG-Serien-:
- RAG-Ursprünge und Grundlagen
- RAG-Architektur und Innenarchitektur
- RAG in der Praxis
- Semantische Suche mit ONNX und Qdrant
- Teil-Hybridsuche
Einfachere Alternative
- DocSummarizer Teil Hybrid-Retrieval ohne Graphenüberkopf
- Sourcegraph Cody Architektur Produktionshybridsuche