Avancerad RAG: LongRAG, Self-RAG och GraphRAG förklarat
LongRAG, Self-RAG, GraphRAG - Nästa generations tekniker
Retrieval-Augmented Generation (RAG) har utvecklats långt bortom enkel vektorsimilitetssökning. LongRAG, Self-RAG och GraphRAG representerar den senaste utvecklingen inom dessa möjligheter.
Moderna RAG-system måste hantera enorma dokument, förstå komplexa entitetsrelationer och mycket mer.
Det här trevliga bilden är genererad av AI-modellen Flux 1 dev.
Utvecklingen bortom grundläggande RAG
Traditionella RAG-system följer ett enkelt mönster: dela upp dokument i bitar, kodning av dem till vektorer, hämta liknande bitar via kosinuslikhet och mata dem till en LLM. Även om det är effektivt för många användningsområden, har denna metod svårt med tre kritiska scenarier:
- Långväga beroenden: Viktig kontext kan sträcka sig över tusentals token över flera bitar
- Hämtningssäkerhet: Systemet har inget sätt att bedöma om hämtat innehåll verkligen är relevant
- Komplexitetsrelationer: Vektorsimilitet kan inte fånga invecklade samband mellan entiteter
Avancerade RAG-varianter hanterar dessa begränsningar med specialiserade arkitekturer anpassade för specifika utmaningar.
LongRAG: Erövringen av utökad kontext
Arkitekturoversikt
LongRAG omdefinierar grundläggande strategin för uppdelning genom att utnyttja LLMs med utökade kontextfönster (32K, 100K eller till och med 1M token). Istället för att dela upp dokument i små 512-token-bitar använder LongRAG ett hierarkiskt tillvägagångssätt:
Dokumentnivåskodning: Hela dokumentet (eller mycket stora avsnitt) bearbetas som en enda enhet. En dokumentnivåskodning fångar den övergripande semantiska betydelsen, samtidigt som hela texten bevaras för efterföljande bearbetning.
Minimal fragmentering: När uppdelning är nödvändig använder LongRAG mycket större bitar (4K-8K token) med betydande överlappning (20-30%). Detta bevarar berättelsens flöde och minskar kontextfragmentering.
Kontextsammanställning: Vid hämtningstid returnerar LongRAG hela dokument eller stora sammanhängande avsnitt istället för spridda fragment. LLM:n får kontinuerlig kontext som bevarar strukturella och semantiska samband.
Implementeringsstrategi
Här är en konceptuell implementering med Python och moderna kodningsmodeller:
from typing import List, Dict
import numpy as np
class LongRAGRetriever:
def __init__(self, model, chunk_size=8000, overlap=1600):
self.model = model
self.chunk_size = chunk_size
self.overlap = overlap
self.doc_embeddings = []
self.documents = []
def create_long_chunks(self, text: str) -> List[str]:
"""Skapa överlappande stora bitar"""
chunks = []
start = 0
while start < len(text):
end = start + self.chunk_size
chunk = text[start:end]
chunks.append(chunk)
start += (self.chunk_size - self.overlap)
return chunks
def index_document(self, doc: str, metadata: Dict):
"""Indexera dokument med hierarkisk kodning"""
# Kodning av hela dokumentet
doc_embedding = self.model.embed(doc)
# Skapa stora bitar med överlappning
chunks = self.create_long_chunks(doc)
chunk_embeddings = [self.model.embed(c) for c in chunks]
self.doc_embeddings.append({
'doc_id': len(self.documents),
'doc_embedding': doc_embedding,
'chunk_embeddings': chunk_embeddings,
'chunks': chunks,
'full_text': doc,
'metadata': metadata
})
self.documents.append(doc)
def retrieve(self, query: str, top_k: int = 3) -> List[Dict]:
"""Hämta relevant långformigt innehåll"""
query_embedding = self.model.embed(query)
# Poängsättning på dokumentnivå först
doc_scores = [
np.dot(query_embedding, doc['doc_embedding'])
for doc in self.doc_embeddings
]
# Hämta toppdokument
top_doc_indices = np.argsort(doc_scores)[-top_k:][::-1]
results = []
for idx in top_doc_indices:
doc_data = self.doc_embeddings[idx]
# För varje dokument, hitta bästa bitar
chunk_scores = [
np.dot(query_embedding, emb)
for emb in doc_data['chunk_embeddings']
]
best_chunk_idx = np.argmax(chunk_scores)
# Returnera utökad kontext runt bästa bit
context_chunks = self._get_extended_context(
doc_data['chunks'],
best_chunk_idx
)
results.append({
'text': ''.join(context_chunks),
'score': doc_scores[idx],
'metadata': doc_data['metadata']
})
return results
def _get_extended_context(self, chunks: List[str],
center_idx: int) -> List[str]:
"""Hämta utökad kontext runt relevant bit"""
start = max(0, center_idx - 1)
end = min(len(chunks), center_idx + 2)
return chunks[start:end]
Användningsområden och prestanda
LongRAG utmärker sig i scenarier där kontext är viktig:
- Analys av juridiska dokument: Kontrakt och juridiska handlingar har ofta beroenden som sträcker sig över flera sidor
- Hämtning av forskningsartiklar: Förståelse av metodik kräver sammanhängande avsnitt, inte isolerade stycken
- Kodrepositorier: Funktioner och klasser måste förstås inom sin modulkontxt
Prestandegenskaper:
- Latens: Högre på grund av bearbetning av stora bitar (2-5 gånger långsammare än standard RAG)
- Noggrannhet: 15-25% förbättring på långformiga fråga-svar-bänkar
- Minne: Kräver 3-4 gånger mer minne för kontextfönster
Self-RAG: Reflekterande hämtning
Grundläggande principer
Self-RAG introducerar en metakognitiv nivå till RAG-system. Istället för att blindt hämtning och generering, reflekterar systemet aktivt över sina egna processer genom specialreflektionstoken:
Hämtningstoken: Bestämmer om hämtning är nödvändig för en given fråga Relevanstoken: Bedömer om hämtade dokument är relevanta Stödtoken: Kontrollerar om det genererade svaret stöds av det hämtade innehållet Kritiktoken: Bedömer den övergripande kvaliteten på det genererade svaret
Arkitekturkomponenter
Self-RAG-arkitekturen består av tre sammanvävda faser:
class SelfRAGSystem:
def __init__(self, retriever, generator, critic):
self.retriever = retriever
self.generator = generator
self.critic = critic
def generate_with_reflection(self, query: str,
max_iterations: int = 3):
"""Generera svar med självreflektion"""
# Fas 1: Besluta om hämtning behövs
retrieve_decision = self.critic.should_retrieve(query)
if not retrieve_decision:
# Direkt generering utan hämtning
return self.generator.generate(query)
# Fas 2: Hämta och bedöma relevans
retrieved_docs = self.retriever.retrieve(query)
relevant_docs = []
for doc in retrieved_docs:
relevance_score = self.critic.assess_relevance(
query, doc
)
if relevance_score > 0.7: # Tröskelvärde
relevant_docs.append(doc)
if not relevant_docs:
# Fallback till generering utan hämtning
return self.generator.generate(query)
# Fas 3: Generera och verifiera stöd
best_answer = None
best_score = -1
for _ in range(max_iterations):
# Generera kandidatsvar
answer = self.generator.generate(
query, context=relevant_docs
)
# Bedöma stöd och kvalitet
support_score = self.critic.check_support(
answer, relevant_docs
)
quality_score = self.critic.assess_quality(answer)
total_score = 0.6 * support_score + 0.4 * quality_score
if total_score > best_score:
best_score = total_score
best_answer = answer
# Tidig avslutning om hög kvalitet uppnås
if total_score > 0.9:
break
return {
'answer': best_answer,
'confidence': best_score,
'sources': relevant_docs,
'reflections': {
'retrieved': retrieve_decision,
'relevance': len(relevant_docs),
'support': support_score
}
}
Träning av reflektionmekanismer
Self-RAG kräver träning av kritikerkomponenten för att göra tillförlitliga bedömningar. Detta innebär vanligtvis:
- Superviserad finjustering på dataset med relevansbedömningar
- Förstärkningsinlärning med belöningar för korrekta förutsägelser
- Kontrastinlärning för att skilja mellan stödda och icke-stödda påståenden
Reflektionstoken kan implementeras som:
- Specialtoken i vokabulären (som
[RETRIEVE],[RELEVANT]) - Separata klassificeringshuvuden på modellen
- Externa kritikermodeller (ensemble-tillvägagångssätt)
Produktionsöverväganden
När Self-RAG implementeras i produktionssystem:
Latensavvägningar: Varje reflektionsteg lägger till 20-40% inferensöverhead. Balansera noggrannhet med svarstidskrav.
Konfidensgränser: Justera reflektionströsklar baserat på ditt användningsområde. Juridiska eller medicinska applikationer kräver högre konfidens än allmänna chattbotar.
Övervakning: Följ reflektionsbeslut för att identifiera mönster. Om hämtning sällan behövs kan du dra nytta av en enklare arkitektur.
GraphRAG: Knowledge Graph-Enhanced Retrieval
Konceptuell grund
GraphRAG omvandlar hämtningsproblemet från vektorsimilitet till graftraversering. Istället för att hitta semantiskt liknande textsegment identifierar GraphRAG relevanta delgrafer av sammanhängande entiteter och relationer.
Entitetsextraktion: Identifiera namngivna entiteter, begrepp och deras typer Relationskartläggning: Extrahera relationer mellan entiteter (temporala, kausala, hierarkiska) Grafkonstruktion: Bygg en kunskapsgraf med entiteter som noder och relationer som kanter Delgrafhämtning: Ge en fråga, hitta relevanta sammanhängande delgrafer
Grafkonstruktionspipeline
Att bygga en kunskapsgraf från ostrukturerad text innebär flera steg:
class GraphRAGBuilder:
def __init__(self, entity_extractor, relation_extractor):
self.entity_extractor = entity_extractor
self.relation_extractor = relation_extractor
self.graph = NetworkGraph()
def build_graph(self, documents: List[str]):
"""Bygg kunskapsgraf från dokument"""
for doc in documents:
# Extrahera entiteter
entities = self.entity_extractor.extract(doc)
# Lägg till entiteter som noder
for entity in entities:
self.graph.add_node(
entity['text'],
entity_type=entity['type'],
context=entity['surrounding_text']
)
# Extrahera relationer
relations = self.relation_extractor.extract(
doc, entities
)
# Lägg till relationer som kanter
for rel in relations:
self.graph.add_edge(
rel['source'],
rel['target'],
relation_type=rel['type'],
confidence=rel['score'],
evidence=rel['text_span']
)
def enrich_graph(self):
"""Lägg till härledda relationer och metadata"""
# Beräkna nodviktighet (PageRank, etc.)
self.graph.compute_centrality()
# Identifiera samhällen/kluster
self.graph.detect_communities()
# Lägg till tidsordning om tidsstämplar finns
self.graph.add_temporal_edges()
Frågebehandling med grafer
GraphRAG-frågor innebär multi-hop-resonemang över kunskapsgrafen:
class GraphRAGRetriever:
def __init__(self, graph, embedder):
self.graph = graph
self.embedder = embedder
def retrieve_subgraph(self, query: str,
max_hops: int = 2,
max_nodes: int = 50):
"""Hämta relevant delgraf för fråga"""
# Identifiera fröentiteter i frågan
query_entities = self.entity_extractor.extract(query)
# Hitta matchande noder i grafen
seed_nodes = []
for entity in query_entities:
matches = self.graph.find_similar_nodes(
entity['text'],
similarity_threshold=0.85
)
seed_nodes.extend(matches)
# Expandera delgraf via traversering
subgraph = self.graph.create_subgraph()
visited = set()
for seed in seed_nodes:
self._expand_from_node(
seed,
subgraph,
visited,
current_hop=0,
max_hops=max_hops
)
# Rangordna noder efter relevans
ranked_nodes = self._rank_subgraph_nodes(
subgraph, query
)
# Extrahera och formatera kontext
context = self._format_graph_context(
ranked_nodes[:max_nodes],
subgraph
)
return context
def _expand_from_node(self, node, subgraph, visited,
current_hop, max_hops):
"""Expandera delgraf rekursivt"""
if current_hop >= max_hops or node in visited:
return
visited.add(node)
subgraph.add_node(node)
# Hämta grannar
neighbors = self.graph.get_neighbors(node)
for neighbor, edge_data in neighbors:
# Lägg till kant till delgrafen
subgraph.add_edge(node, neighbor, edge_data)
# Expandera rekursivt
self._expand_from_node(
neighbor,
subgraph,
visited,
current_hop + 1,
max_hops
)
def _format_graph_context(self, nodes, subgraph):
"""Konvertera delgraf till textuell kontext"""
context_parts = []
for node in nodes:
# Lägg till nodkontext
context_parts.append(f"Entitet: {node.text}")
context_parts.append(f"Typ: {node.entity_type}")
# Lägg till relationsinformation
edges = subgraph.get_edges(node)
for edge in edges:
context_parts.append(
f"- {edge.relation_type} -> {edge.target.text}"
)
return "\n".join(context_parts)
Microsofts GraphRAG-implementering
Microsofts GraphRAG tar ett unikt tillvägagångssätt genom att generera samhällssammanfattningar:
- Bygg initial graf från dokument med LLM-baserad entitets-/relationsextraktion
- Detektera samhällen med Leiden-algoritm eller liknande
- Generera sammanfattningar för varje samhälle med LLMs
- Hierarkisk struktur: Bygg flera nivåer av samhällsabstraktioner
- Frågetid: Hämta relevanta samhällen och traversera till specifika entiteter
Detta tillvägagångssätt är särskilt effektivt för:
- Exploratoriska frågor (“Vilka är de huvudsakliga temana i detta korpus?”)
- Multi-hop-resonemang (“Hur är A kopplat till C genom B?”)
- Temporala analyser (“Hur har denna entitets relationer utvecklats?”)
Jämförande analys
När man ska använda varje variant
Använd LongRAG när:
- Dokument har stark intern sammanhållning
- Kontextfönster för din LLM stöder stora indata (32K+)
- Svar på frågor kräver förståelse av långväga beroenden
- Du arbetar med strukturerade dokument (rapporter, artiklar, böcker)
Använd Self-RAG när:
- Noggrannhet och tillförlitlighet är kritiska
- Du behöver förklarliga hämtningsbeslut
- Falska positiva resultat från irrelevant hämtning är kostsamma
- Frågekomplexiteten varierar mycket (vissa behöver hämtning, andra inte)
Använd GraphRAG när:
- Ditt område har rika entitetsrelationer
- Frågor involverar multi-hop-resonemang
- Temporala eller hierarkiska relationer är viktiga
- Du behöver förstå kopplingar mellan entiteter
Prestandametriskt jämförelse
| Metrik | Standard RAG | LongRAG | Self-RAG | GraphRAG |
|---|---|---|---|---|
| Indexeringstid | 1x | 0.8x | 1.1x | 3-5x |
| Frågelatens | 1x | 2-3x | 1.4x | 1.5-2x |
| Minneanvändning | 1x | 3-4x | 1.2x | 2-3x |
| Noggrannhet (QA) | baslinje | +15-25% | +20-30% | +25-40%* |
| Tolkbarhet | Låg | Medel | Hög | Hög |
*GraphRAG-förbättringar är starkt domänberoende
Hybridtillvägagångssätt
De mest kraftfulla produktionssystemen kombinerar ofta flera tekniker:
LongRAG + GraphRAG: Använd grafrstruktur för att identifiera relevanta dokumentkluster, sedan hämta hela dokument istället för fragment
Self-RAG + GraphRAG: Tillämpa reflektionmekanismer på graftraverseringsbeslut (vilka vägar att följa, när man ska stoppa expansion)
Tretrappspipeline: Använd GraphRAG för initial entitetsbaserad hämtning → Self-RAG för relevansfiltrering → LongRAG för kontextsammanställning
Implementeringsöverväganden
Embeddingsmodeller
Olika RAG-varianter har olika embeddingskrav:
LongRAG: Behöver embeddings som fungerar bra både på dokumentnivå och chunknivå. Överväg modeller tränade med kontrastivt lärande på långa sekvenser.
Self-RAG: Dra nytta av embeddings som fångar semantiska nyanser för finmaskig relevansbedömning.
GraphRAG: Kräver entitetsmedvetna embeddings. Modeller finjusterade på entitetslänkning uppvisar bättre prestanda.
Valet av embeddingsmodell påverkar prestanda betydligt. När man arbetar med lokala modeller ger verktyg som Ollama ett enkelt sätt att experimentera med olika embeddingsmodeller innan man går över till produktionsdistribution.
Chunkningsstrategier omprövade
Traditionell fast storleksbaserad chunkning räcker inte för avancerad RAG:
Semantisk chunkning: Bryt vid naturliga gränser (stycken, avsnitt, ämnesförskjutningar) Rekursiv chunkning: Skapa hierarkiska chunkar med förälder-barn-relationer Glidande fönster: Använd överlappande chunkar för att bevara kontext vid gränser Strukturmedveten: Respektera dokumentstruktur (markdown-rubriker, XML-taggar, kodblock)
För Python-baserade implementeringar erbjuder bibliotek som LangChain och LlamaIndex inbyggt stöd för dessa chunkningsstrategier.
Reranking-integration
Reranking förbättrar hämtningskvaliteten avsevärt för alla RAG-varianter. Efter initial hämtning ombedömer en specialiserad rerankingmodell resultaten baserat på interaktionsfunktioner mellan fråga och dokument. Detta ger en betydande noggrannhetsförbättring (10-20%) med minimal påverkan på latens när det integreras på ett genomtänkt sätt.
Skalning till produktion
Indexeringspipeline:
- Använd distribuerad bearbetning (Ray, Dask) för stora dokumentkorpus
- Implementera inkrementell indexering för realtidsuppdateringar
- Lagra embeddings i optimerade vektordatabaser (Pinecone, Weaviate, Qdrant)
Frågeoptimering:
- Cacha frekventa frågor och deras resultat
- Implementera frågerutning (olika RAG-varianter för olika frågetyper)
- Använd approximativ närmaste granne-sökning för sublinjär skalning
Övervakning:
- Följ hämtningsrelevanspoäng
- Övervaka reflektionsbeslut i Self-RAG
- Mät graftraverseringsvägar och djup
- Logga konfidenspoäng och användaråterkoppling
Verkliga tillämpningar
Söktjänst för teknisk dokumentation
En stor molnleverantör implementerade GraphRAG för sin dokumentation:
- Entiteter: API-ändpunkter, parametrar, felkoder, tjänsternamn
- Relationer: Beroenden, versionskompatibilitet, migreringsvägar
- Resultat: 35% minskning av supportärenden, 45% snabbare lösningstid
Juridisk upptäckt
Ett juridiskt teknikföretag kombinerade Self-RAG med LongRAG:
- Self-RAG filtrerar bort irrelevanta dokument tidigt
- LongRAG bevarar kontext i behållna dokument
- Advokater granskar 60% färre falska positiva resultat
- Kritisk kontextbevaring förbättrades från 71% till 94%
Forskningslitteraturöversikt
Akademisk söktjänst som använder hybridtillvägagångssätt:
- GraphRAG identifierar citationsnätverk och forskarsamhällen
- LongRAG hämtar hela avsnitt som bevarar metodkontext
- 40% förbättring i upptäckt av relevanta artiklar
- Minskat tid för litteraturöversikt från veckor till dagar
Avancerade ämnen
Multi-Modal RAG
Förlängning av dessa varianter för att hantera bilder, tabeller och kod:
- Visuell grundning: Länka textentiteter till bilder i dokument
- Tabellförståelse: Parsa strukturerade data till grafformat
- Kodanalys: Bygg beroendegrafer från kodbaser
Adaptiv RAG
Dynamisk val av RAG-strategi baserat på frågeegenskaper:
- Klassificering av frågekomplexitet
- Detektor för dokumenttyp
- Kostnads-nytto-optimering för strategival
Integritetsskyddande RAG
Implementering av dessa varianter med integritetskrav:
- Federerad hämtning över datasilos
- Differentiell integritet i inbäddningar
- Krypterad likhetsökning
Att börja med
Snabbstart med Python
För dem som vill implementera dessa tekniker är det viktigt att börja med en solid Python-plattform. Pythons rika ekosystem för maskininlärning gör det till det naturliga valet för RAG-utveckling.
Här är en enkel startpunkt för experiment:
# Installera beroenden
# pip install sentence-transformers faiss-cpu langchain
from sentence_transformers import SentenceTransformer
import faiss
import numpy as np
# Grundläggande inställning för experiment med långa segment
model = SentenceTransformer('all-MiniLM-L6-v2')
documents = [
# Dina långformade dokument här
]
# Skapa inbäddningar
embeddings = model.encode(documents)
# Bygg FAISS-index
dimension = embeddings.shape[1]
index = faiss.IndexFlatL2(dimension)
index.add(embeddings.astype('float32'))
# Fråga
query = "Din fråga här"
query_embedding = model.encode([query])
distances, indices = index.search(
query_embedding.astype('float32'), k=3
)
Ramverkval
LangChain: Bäst för snabb prototypning, omfattande integrationer LlamaIndex: Optimerad för dokumentindexering och hämtning Haystack: Produktionsklar, starka pipeline-abstraktioner Anpassad: När du behöver full kontroll och optimering
Utvärderingsramverk
Implementera noggrann utvärdering innan produktionsdistribution:
Hämtningsmått:
- Precision@K, Recall@K, MRR (Mean Reciprocal Rank)
- NDCG (Normalized Discounted Cumulative Gain)
Genereringsmått:
- ROUGE, BLEU för textlikhet
- BERTScore för semantisk likhet
- Mänsklig utvärdering för kvalitetsbedömning
Slut-till-slut-mått:
- Uppgiftslyckandesats
- Användarnöjdhetspoäng
- Latenspercentiler (p50, p95, p99)
Slutsats
Landskapet för RAG-system har mognat betydligt bortom grundläggande vektorsimilaritetsökning. LongRAG, Self-RAG och GraphRAG löser var och en specifika begränsningar hos traditionella metoder:
LongRAG löser problemet med kontextfragmentering genom att omfatta utökade kontextfönster och minimal segmentering. Det är det självklara valet när dokumentkoherens är viktig och du har de beräkningsresurser som krävs för att hantera stora kontexter.
Self-RAG lägger till kritisk självmedvetenhet i hämtningssystem. Genom att reflektera över sina egna beslut minskar det falska positiva resultat och förbättrar tillförlitligheten - avgörande för högriskapplikationer där noggrannhet är viktigare än hastighet.
GraphRAG låser upp kraften i strukturerad kunskapsrepresentation. När ditt domän involverar komplexa relationer mellan entiteter kan grafbaserad hämtning framhäva samband som vektorsimilaritet helt missar.
Framtiden för RAG innebär troligen hybrida tillvägagångssätt som kombinerar styrkorna hos dessa varianter. Ett produktionssystem kan använda GraphRAG för att identifiera relevanta entitetskluster, Self-RAG för att filtrera och validera hämtningar, och LongRAG för att sammanställa sammanhängande kontext för LLM.
När LLMs fortsätter att förbättras och kontextfönster expanderar, kommer vi att se ännu mer sofistikerade RAG-varianter framträda. Nyckeln är att förstå dina specifika krav för användningsfall - dokumentstruktur, frågemönster, noggrannhetskrav och beräkningsbegränsningar - och välja den lämpliga tekniken eller kombinationen av dessa.
Verktygsmiljön mognar snabbt, med ramverk som LangChain, LlamaIndex och Haystack som erbjuder alltmer sofistikerat stöd för dessa avancerade mönster. Kombinerat med kraftfulla lokala LLM-runtime och inbäddningsmodeller har det aldrig varit enklare att experimentera med och distribuera produktionsklara RAG-system.
Börja med grunderna, mäta prestanda noggrant och utveckla din arkitektur efter behov. De avancerade RAG-varianter som täcks här ger en vägledning för denna utveckling.
Användbara länkar
- Python Cheatsheet
- Reranking med inbäddningsmodeller
- LLMs och strukturerad output: Ollama, Qwen3 & Python eller Go
- Molnbaserade LLM-leverantörer
- LLM-jämförelse: Qwen3:30b vs GPT-OSS:20b
Externa referenser
- Microsoft GraphRAG: Ett modulärt grafbaserat hämtningssystem för förstärkt generering
- Self-RAG: Lärande att hämta, generera och kritisera genom självreflektion
- LongRAG: Förbättring av hämtning med förstärkt generering med långkontextiga LLMs
- Hämtning med förstärkt generering för stora språkmodeller: En översikt
- FAISS: Ett bibliotek för effektiv likhetsökning
- LangChain Dokumentation: Avancerade RAG-tekniker
- HuggingFace: Sentence Transformers för inbäddningsmodeller
- RAG-översikt: En omfattande analys av hämtning med förstärkt generering