Zaawansowane RAG: Wyjaśnienie LongRAG, Self-RAG i GraphRAG

LongRAG, Self-RAG, GraphRAG – techniki następnego pokolenia

Page content

Generowanie Wspomagane Odtwarzaniem (RAG) ewoluowało znacznie poza proste wyszukiwanie wektorowe oparte na podobieństwie. LongRAG, Self-RAG oraz GraphRAG reprezentują wiodącą krawędź tych możliwości.

Nowoczesne systemy RAG muszą radzić sobie z ogromnymi dokumentami, rozumieć skomplikowane relacje między bytami i wiele więcej.

a-pirate-captain Ta przyjemna grafika została wygenerowana przez model AI Flux 1 dev.

Ewolucja poza podstawowe RAG

Tradycyjne systemy RAG podążają prostym schematem: podział dokumentów na fragmenty, zamiana ich na wektory, odzyskiwanie podobnych fragmentów poprzez podobieństwo kosinusowe oraz podawanie ich do modelu językowego (LLM). Choć podejście to jest skuteczne w wielu zastosowaniach, napotyka trudności w trzech krytycznych scenariuszach:

Rozróżnienie między wyszukiwaniem, głębokim wyszukiwaniem (deepsearch) a głębokim badaniem (deep research) pomaga wyjaśnić, dlaczego zaawansowane warianty RAG są niezbędne do złożonych zadań odzyskiwania informacji. Aby zgłębić te koncepcje, zobacz Wyszukiwanie vs Deepsearch vs Deep Research.

  1. Zależności długodystansowe: Ważny kontekst może rozciągać się na tysiące tokenów na wielu fragmentach
  2. Zaufanie do odzyskiwania: System nie ma sposobu na ocenie, czy odzyskane treści są rzeczywiście istotne
  3. Złożoność relacji: Podobieństwo wektorowe nie jest w stanie uchwycić skomplikowanych powiązań między bytami

Zaawansowane warianty RAG radzą sobie z tymi ograniczeniami dzięki specjalistycznym architekturom dostosowanym do konkretnych wyzwań.

LongRAG: Podboj rozszerzonego kontekstu

Przegląd architektury

LongRAG fundamentalnie przemyśla strategię fragmentowania, wykorzystując modele językowe z rozszerzonym oknem kontekstu (32K, 100K lub nawet 1M tokenów). Zamiast dzielić dokumenty na małe fragmenty o długości 512 tokenów, LongRAG stosuje podejście hierarchiczne:

Wektoryzacja na poziomie dokumentu: Cały dokument (lub bardzo duże sekcje) jest przetwarzany jako pojedyncza jednostka. Wektor na poziomie dokumentu uchwytuje ogólne znaczenie semantyczne, zachowując pełny tekst do dalszego przetwarzania.

Minimalna fragmentacja: Gdy podział jest konieczny, LongRAG używa znacznie większych fragmentów (4K-8K tokenów) z dużym zachodzeniem (20-30%). Zachowuje to ciągłość narracji i zmniejsza rozdrobnienie kontekstu.

Składanie kontekstu: W momencie odzyskiwania, LongRAG zwraca kompletne dokumenty lub duże, spójne sekcje zamiast rozproszonych fragmentów. Model językowy otrzymuje ciągły kontekst, który zachowuje relacje strukturalne i semantyczne.

Strategia implementacji

Oto koncepcyjna implementacja używająca Pythona i nowoczesnych modeli wektorowych:

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]:
        """Tworzenie dużych fragmentów z zachodzeniem"""
        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):
        """Indeksowanie dokumentu z hierarchiczną wektoryzacją"""
        # Wektoryzacja całego dokumentu
        doc_embedding = self.model.embed(doc)
        
        # Tworzenie dużych fragmentów z zachodzeniem
        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]:
        """Odzyskiwanie istotnych treści długiego formatu"""
        query_embedding = self.model.embed(query)
        
        # Najpierw punktowanie na poziomie dokumentu
        doc_scores = [
            np.dot(query_embedding, doc['doc_embedding'])
            for doc in self.doc_embeddings
        ]
        
        # Uzyskanie najlepszych dokumentów
        top_doc_indices = np.argsort(doc_scores)[-top_k:][::-1]
        
        results = []
        for idx in top_doc_indices:
            doc_data = self.doc_embeddings[idx]
            
            # Dla każdego dokumentu znajdź najlepsze fragmenty
            chunk_scores = [
                np.dot(query_embedding, emb)
                for emb in doc_data['chunk_embeddings']
            ]
            best_chunk_idx = np.argmax(chunk_scores)
            
            # Zwróć rozszerzony kontekst wokół najlepszego fragmentu
            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]:
        """Uzyskanie rozszerzonego kontekstu wokół istotnego fragmentu"""
        start = max(0, center_idx - 1)
        end = min(len(chunks), center_idx + 2)
        return chunks[start:end]

Przypadki użycia i wydajność

LongRAG wykazuje się w scenariuszach, gdzie kontekst ma znaczenie:

  • Analiza dokumentów prawnych: Umowy i pisma procesowe często mają zależności rozciągające się na dziesiątki stron
  • Odzyskiwanie prac badawczych: Zrozumienie metodologii wymaga spójnych sekcji, a nie izolowanych akapitów
  • Repozytoria kodu: Funkcje i klasy muszą być rozumiane w kontekście ich modułu

Cechy wydajnościowe:

  • Opóźnienia (Latency): Wyższe ze względu na przetwarzanie dużych fragmentów (2-5x wolniej niż w standardowym RAG)
  • Dokładność: Poprawa o 15-25% w testach pytań i odpowiedzi długiego formatu
  • Pamięć: Wymaga 3-4x więcej pamięci dla okien kontekstowych

Self-RAG: Refleksywne odzyskiwanie

Zasady działania

Self-RAG wprowadza do systemów RAG warstwę metapoznawczą. Zamiast ślepo odzyskiwać i generować, system aktywnie refleksjonuje nad własnymi procesami za pomocą specjalnych tokenów refleksyjnych:

Token Retrieve: Decyduje, czy odzyskiwanie jest konieczne dla danego zapytania Token Relevance: Oceni, czy odzyskane dokumenty są rzeczywiście istotne Token Support: Sprawdza, czy wygenerowana odpowiedź jest poparta odzyskanymi treściami Token Critique: Oceni ogólną jakość wygenerowanej odpowiedzi

Komponenty architektury

Architektura Self-RAG składa się z trzech splecionych faz:

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):
        """Generowanie odpowiedzi z samorefleksją"""
        
        # Faza 1: Decyzja, czy odzyskiwanie jest potrzebne
        retrieve_decision = self.critic.should_retrieve(query)
        
        if not retrieve_decision:
            # Bezpośrednie generowanie bez odzyskiwania
            return self.generator.generate(query)
        
        # Faza 2: Odzyskiwanie i ocena istotności
        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:  # Progi
                relevant_docs.append(doc)
        
        if not relevant_docs:
            # Fallback do generowania bez odzyskiwania
            return self.generator.generate(query)
        
        # Faza 3: Generowanie i weryfikacja poparcia
        best_answer = None
        best_score = -1
        
        for _ in range(max_iterations):
            # Generowanie kandydackiej odpowiedzi
            answer = self.generator.generate(
                query, context=relevant_docs
            )
            
            # Ocena poparcia i jakości
            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
            
            # Wczesne zatrzymanie, jeśli osiągnięto wysoką jakość
            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
            }
        }

Trenowanie mechanizmów refleksyjnych

Self-RAG wymaga trenowania komponentu krytyka, aby dokonywał wiarygodnych ocen. Zazwyczaj obejmuje to:

  1. Trenowanie nadzorowane na zestawach danych z adnotacjami dotyczącymi ocen istotności
  2. Uczenie z wzmocnieniem z nagrodami za dokładne przewidywania
  3. Uczenie kontrastowe do rozróżniania twierdzeń popartych i niepopartych

Tokeny refleksyjne mogą być zaimplementowane jako:

  • Specjalne tokeny w słowniku (jak [RETRIEVE], [RELEVANT])
  • Oddzielne głowice klasyfikatora w modelu
  • Zewnętrzne modele krytyków (podejście ensemble)

Uwagi dotyczące produkcji

Podczas wdrażania Self-RAG w systemach produkcyjnych:

Kompromisy opóźnień: Każdy krok refleksji dodaje 20-40% nadmiaru wnioskowania. Zbalansuj staranność z wymaganiami czasu odpowiedzi.

Progi zaufania: Dostosuj progi refleksji do swojego przypadku użycia. Aplikacje prawne lub medyczne wymagają wyższego zaufania niż ogólne boty czatowe.

Monitorowanie: Śledź decyzje refleksyjne, aby zidentyfikować wzorce. Jeśli odzyskiwanie jest rzadko potrzebne, możesz skorzystać z prostszej architektury.

GraphRAG: Odzyskiwanie wzbogacone grafami wiedzy

Podstawy koncepcyjne

GraphRAG przekształca problem odzyskiwania z podobieństwa wektorowego na traversowanie grafu. Zamiast znajdować semantycznie podobne fragmenty tekstu, GraphRAG identyfikuje istotne podgrafy połączonych bytów i relacji.

Ekstrakcja bytów: Zidentyfikuj nazwane byty, koncepcje i ich typy Mapowanie relacji: Wyodrębnij relacje między bytami (temporalne, przyczynowe, hierarchiczne) Konstrukcja grafu: Zbuduj graf wiedzy z bytami jako węzłami, a relacjami jako krawędziami Odzyskiwanie podgrafu: Dla danego zapytania znajdź istotne połączone podgrafy

Rurociąg konstrukcji grafu

Budowanie grafu wiedzy z nieuporządkowanego tekstu obejmuje kilka etapów:

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]):
        """Budowanie grafu wiedzy z dokumentów"""
        for doc in documents:
            # Ekstrakcja bytów
            entities = self.entity_extractor.extract(doc)
            
            # Dodawanie bytów jako węzłów
            for entity in entities:
                self.graph.add_node(
                    entity['text'],
                    entity_type=entity['type'],
                    context=entity['surrounding_text']
                )
            
            # Ekstrakcja relacji
            relations = self.relation_extractor.extract(
                doc, entities
            )
            
            # Dodawanie relacji jako krawędzi
            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):
        """Dodawanie wyprowadzonych relacji i metadanych"""
        # Obliczanie ważności węzłów (PageRank itp.)
        self.graph.compute_centrality()
        
        # Identyfikacja społeczności/klastów
        self.graph.detect_communities()
        
        # Dodawanie kolejności czasowej, jeśli dostępne są znaczniki czasu
        self.graph.add_temporal_edges()

Przetwarzanie zapytań z grafami

Zapytania GraphRAG obejmują wieloetapowe rozumowanie po grafie wiedzy:

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):
        """Odzyskiwanie istotnego podgrafu dla zapytania"""
        
        # Identyfikacja bytów nasion w zapytaniu
        query_entities = self.entity_extractor.extract(query)
        
        # Znajdowanie pasujących węzłów w grafie
        seed_nodes = []
        for entity in query_entities:
            matches = self.graph.find_similar_nodes(
                entity['text'],
                similarity_threshold=0.85
            )
            seed_nodes.extend(matches)
        
        # Rozszerzanie podgrafu poprzez traversowanie
        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
            )
        
        # Rankowanie węzłów według istotności
        ranked_nodes = self._rank_subgraph_nodes(
            subgraph, query
        )
        
        # Ekstrakcja i formatowanie kontekstu
        context = self._format_graph_context(
            ranked_nodes[:max_nodes],
            subgraph
        )
        
        return context
    
    def _expand_from_node(self, node, subgraph, visited,
                         current_hop, max_hops):
        """Rekursywne rozszerzanie podgrafu"""
        if current_hop >= max_hops or node in visited:
            return
        
        visited.add(node)
        subgraph.add_node(node)
        
        # Uzyskanie sąsiadów
        neighbors = self.graph.get_neighbors(node)
        
        for neighbor, edge_data in neighbors:
            # Dodanie krawędzi do podgrafu
            subgraph.add_edge(node, neighbor, edge_data)
            
            # Rekursywne rozszerzenie
            self._expand_from_node(
                neighbor,
                subgraph,
                visited,
                current_hop + 1,
                max_hops
            )
    
    def _format_graph_context(self, nodes, subgraph):
        """Konwersja podgrafu do kontekstu tekstowego"""
        context_parts = []
        
        for node in nodes:
            # Dodanie kontekstu węzła
            context_parts.append(f"Entity: {node.text}")
            context_parts.append(f"Type: {node.entity_type}")
            
            # Dodanie informacji o relacjach
            edges = subgraph.get_edges(node)
            for edge in edges:
                context_parts.append(
                    f"- {edge.relation_type} -> {edge.target.text}"
                )
        
        return "\n".join(context_parts)

Implementacja GraphRAG Microsoftu

GraphRAG Microsoftu podejmuje unikalne podejście, generując podsumowania społeczności:

  1. Budowanie początkowego grafu z dokumentów przy użyciu ekstrakcji bytów i relacji opartej na LLM
  2. Wykrywanie społeczności przy użyciu algorytmu Leiden lub podobnych
  3. Generowanie podsumowań dla każdej społeczności przy użyciu LLM
  4. Struktura hierarchiczna: Budowanie wielu poziomów abstrakcji społeczności
  5. Czas zapytania: Odzyskiwanie istotnych społeczności i traversowanie do konkretnych bytów

Podejście to jest szczególnie skuteczne dla:

  • Zapytań eksploracyjnych (“Jakie są główne tematy w tym korpusie?”)
  • Rozumowania wieloetapowego (“Jak A jest połączone z C przez B?”)
  • Analizy temporalnej (“Jak relacje tego bytu ewoluowały?”)

Analiza porównawcza

Kiedy używać każdego wariantu

Użyj LongRAG, gdy:

  • Dokumenty mają silną spójność wewnętrzną
  • Okna kontekstu Twojego LLM obsługują duże wejścia (32K+)
  • Odpowiedzi na zapytania wymagają zrozumienia zależności długodystansowych
  • Praca z uporządkowanymi dokumentami (raporty, prace, książki)

Użyj Self-RAG, gdy:

  • Dokładność i godność zaufania są krytyczne
  • Potrzebujesz wyjaśnialnych decyzji odzyskiwania
  • Fałszywe pozytywy z nieistotnego odzyskiwania są kosztowne
  • Złożoność zapytań zmienia się szeroko (niektóre wymagają odzyskiwania, inne nie)

Użyj GraphRAG, gdy:

  • Twój domen ma bogate relacje między bytami
  • Zapytania wymagają rozumowania wieloetapowego
  • Relacje temporalne lub hierarchiczne mają znaczenie
  • Potrzebujesz zrozumienia powiązań między bytami

Porównanie wskaźników wydajności

Wskaźnik Standardowe RAG LongRAG Self-RAG GraphRAG
Czas indeksowania 1x 0.8x 1.1x 3-5x
Opóźnienie zapytania 1x 2-3x 1.4x 1.5-2x
Zużycie pamięci 1x 3-4x 1.2x 2-3x
Dokładność (QA) bazowe +15-25% +20-30% +25-40%*
Interpretowalność Niska Średnia Wysoka Wysoka

*Poprawy w GraphRAG są silnie zależne od domeny

Podejścia hybrydowe

Najpotężniejsze systemy produkcyjne często łączą wiele technik:

LongRAG + GraphRAG: Użyj struktury grafu do identyfikacji istotnych klastrów dokumentów, a następnie odzyskaj pełne dokumenty zamiast fragmentów

Self-RAG + GraphRAG: Zastosuj mechanizmy refleksyjne do decyzji traversowania grafu (które ścieżki podążać, kiedy przestać rozszerzać)

Trzyetapowa rurociąg: Użyj GraphRAG do początkowego odzyskiwania opartego na bytach → Self-RAG do filtrowania istotności → LongRAG do składania kontekstu

Uwagi dotyczące implementacji

Modele wektorowe

Różne warianty RAG mają różne wymagania dotyczące wektorów:

LongRAG: Wymaga wektorów, które dobrze działają zarówno na poziomie dokumentu, jak i fragmentu. Rozważ modele trenowane z uczeniem kontrastowym na długich sekwencjach.

Self-RAG: Korzysta z wektorów, które uchwytują niuanse semantyczne dla precyzyjnej oceny istotności.

GraphRAG: Wymaga wektorów świadomych bytów. Modele dostrojone do zadań łączenia bytów osiągają lepsze wyniki.

Wybór modelu wektorowego znacząco wpływa na wydajność. Przy pracy z modelami lokalnymi narzędzia takie jak Ollama zapewniają prosty sposób na eksperymentowanie z różnymi modelami wektorowymi przed zobowiązaniem się do wdrożenia produkcyjnego.

Strategie fragmentowania ponownie

Tradycyjne fragmentowanie o stałym rozmiarze jest niewystarczające dla zaawansowanego RAG:

Fragmentowanie semantyczne: Rozbijanie w naturalnych granicach (akapity, sekcje, zmiany tematyczne) Fragmentowanie rekurencyjne: Tworzenie hierarchicznych fragmentów z relacjami rodzic-dziecko Okno przesuwne: Używanie fragmentów z zachodzeniem do zachowania kontekstu na granicach Świadome struktury: Szanowanie struktury dokumentu (nagłówki markdown, tagi XML, bloki kodu)

Dla implementacji opartych na Pythonie, biblioteki takie jak LangChain i LlamaIndex zapewniają wbudowane wsparcie dla tych strategii fragmentowania.

Integracja Rerankingu

Reranking dramatycznie poprawia jakość odzyskiwania we wszystkich wariantach RAG. Po wstępnym odzyskaniu, specjalistyczny model rerankingu ponownie punktuje wyniki na podstawie cech interakcji zapytanie-dokument. Daje to znaczący wzrost dokładności (10-20%) z minimalnym wpływem na opóźnienia, jeśli jest zintegrowany przemyślanie.

Skalowanie do produkcji

Rurociąg indeksowania:

  • Użyj przetwarzania rozproszonego (Ray, Dask) dla dużych zbiorów dokumentów
  • Zaimplementuj indeksowanie inkrementalne dla aktualizacji w czasie rzeczywistym
  • Przechowuj wektory w zoptymalizowanych bazach wektorowych (Pinecone, Weaviate, Qdrant)

Optymalizacja zapytań:

  • Plikuj często występujące zapytania i ich wyniki
  • Zaimplementuj routing zapytań (różne warianty RAG dla różnych typów zapytań)
  • Użyj przybliżonego wyszukiwania najbliższych sąsiadów dla skalowania podliniowego

Monitorowanie:

  • Śledź punkty istotności odzyskiwania
  • Monitoruj decyzje refleksyjne w Self-RAG
  • Mierz ścieżki i głębokość traversowania grafu
  • Zapisuj punkty zaufania i opinie użytkowników

Zastosowania w świecie rzeczywistym

Wyszukiwanie w dokumentacji technicznej

Duży dostawca usług chmurowych wdrożył GraphRAG dla swojej dokumentacji:

  • Byty: punkty końcowe API, parametry, kody błędów, nazwy usług
  • Relacje: zależności, kompatybilność wersji, ścieżki migracji
  • Wynik: 35% redukcja biletów wsparcia, 45% szybszy czas rozwiązania

Discovery prawny

Firma technologiczna prawna połączyła Self-RAG z LongRAG:

  • Self-RAG filtruje nieistotne dokumenty na wczesnym etapie
  • LongRAG zachowuje kontekst w zachowanych dokumentach
  • Prawnicy przeglądają o 60% mniej fałszywych pozytywów
  • Zachowanie krytycznego kontekstu poprawiło się z 71% do 94%

Przegląd literatury badawczej

Silnik wyszukiwania akademicki używający podejścia hybrydowego:

  • GraphRAG identyfikuje sieci cytowań i społeczności badawcze
  • LongRAG odzyskuje pełne sekcje zachowujące kontekst metodologii
  • 40% poprawa w odnajdywaniu istotnych prac
  • Skrócenie czasu przeglądu literatury z tygodni do dni

Zaawansowane tematy

Multi-modalne RAG

Rozszerzanie tych wariantów na obszar obrazów, tabel i kodu:

  • Wizualne zakotwiczenie: Łączenie bytów tekstowych z obrazami w dokumentach
  • Rozumienie tabel: Parsowanie danych strukturalnych do formatu grafu
  • Analiza kodu: Budowanie grafów zależności z kodu

Adaptacyjne RAG

Dynamiczna selekcja strategii RAG w oparciu o cechy zapytania:

  • Klasyfikator złożoności zapytania
  • Detektor typu dokumentu
  • Optymalizator kosztu-korzyści dla wyboru strategii

RAG chroniące prywatność

Wdrażanie tych wariantów z ograniczeniami prywatności:

  • Odzyskiwanie federowane w silosach danych
  • Prywatność różniczkowa w wektorach
  • Szyszukanie podobieństwa zaszyfrowane

Rozpoczęcie pracy

Szybki start z Pythonem

Dla tych, którzy chcą zaimplementować te techniki, rozpoczęcie od solidnych podstaw Pythona jest niezbędne. Bogaty ekosystem Pythona dla uczenia maszynowego czyni go naturalnym wyborem do rozwoju RAG.

Oto prosty punkt wyjścia do eksperymentów:

# Instalacja zależności
# pip install sentence-transformers faiss-cpu langchain

from sentence_transformers import SentenceTransformer
import faiss
import numpy as np

# Podstawowe ustawienie do eksperymentowania z długimi fragmentami
model = SentenceTransformer('all-MiniLM-L6-v2')

documents = [
    # Tutaj Twoje dokumenty długiego formatu
]

# Tworzenie wektorów
embeddings = model.encode(documents)

# Budowanie indeksu FAISS
dimension = embeddings.shape[1]
index = faiss.IndexFlatL2(dimension)
index.add(embeddings.astype('float32'))

# Zapytanie
query = "Twoje pytanie tutaj"
query_embedding = model.encode([query])
distances, indices = index.search(
    query_embedding.astype('float32'), k=3
)

Wybór frameworka

LangChain: Najlepszy do szybkiego prototypowania, rozległe integracje LlamaIndex: Zoptymalizowany do indeksowania i odzyskiwania dokumentów Haystack: Gotowy do produkcji, silne abstrakcje rurociągów Niestandardowy: Gdy potrzebujesz pełnej kontroli i optymalizacji

Framework oceny

Zaimplementuj rygorystyczną ocenę przed wdrożeniem produkcyjnym:

Wskaźniki odzyskiwania:

  • Precyzja@K, Przywracanie@K, MRR (Średnia Reciprokna Ranga)
  • NDCG (Znormalizowana Zliczona Zyskowność)

Wskaźniki generowania:

  • ROUGE, BLEU dla podobieństwa tekstu
  • BERTScore dla podobieństwa semantycznego
  • Ocena ludzka dla jakości

Wskaźniki end-to-end:

  • Współczynnik sukcesu zadania
  • Punkty satysfakcji użytkowników
  • Percentyle opóźnień (p50, p95, p99)

Podsumowanie

Landscape systemów RAG znacznie się rozwinął poza podstawowe wyszukiwanie wektorowe. LongRAG, Self-RAG i GraphRAG każdy rozwiązuje specyficzne ograniczenia tradycyjnych podejść:

LongRAG rozwiązuje problem fragmentacji kontekstu, przyjmując rozszerzone okna kontekstowe i minimalne fragmentowanie. Jest to wybór numer jeden, gdy spójność dokumentu ma znaczenie i masz zasoby obliczeniowe do obsługi dużych kontekstów.

Self-RAG dodaje krytyczną samoświadomość do systemów odzyskiwania. Reflekując nad własnymi decyzjami, zmniejsza fałszywe pozytywy i poprawia godność zaufania – niezbędne dla aplikacji wysokiego ryzyka, gdzie dokładność jest ważniejsza niż szybkość.

GraphRAG odblokowuje moc strukturalnej reprezentacji wiedzy. Gdy Twój domen obejmuje złożone relacje między bytami, odzyskiwanie oparte na grafach może ujawnić powiązania, które podobieństwo wektorowe całkowicie przegania.

Przyszłość RAG prawdopodobnie będzie obejmować podejścia hybrydowe, które łączą mocne strony tych wariantów. System produkcyjny może używać GraphRAG do identyfikacji istotnych klastrów bytów, Self-RAG do filtrowania i walidacji odzyskiwań oraz LongRAG do składania spójnego kontekstu dla LLM.

W miarę jak modele językowe się ulepszają, a okna kontekstowe się rozszerzają, zobaczymy jeszcze bardziej wyrafinowane warianty RAG. Kluczem jest zrozumienie specyficznych wymagań Twojego przypadku użycia – struktura dokumentów, wzorce zapytań, wymagania dokładności i ograniczenia obliczeniowe – oraz wybranie odpowiedniej techniki lub ich kombinacji.

Ekosystem narzędzi ewoluuje szybko, z frameworkami takimi jak LangChain, LlamaIndex i Haystack zapewniającymi coraz bardziej wyrafinowane wsparcie dla tych zaawansowanych wzorców. Połączone z potężnymi lokalnymi runtime’ami LLM i modelami wektorowymi, nigdy nie było łatwiej eksperymentować z i wdrażać systemy RAG klasy produkcyjnej.

Zacznij od podstaw, mierz wydajność rygorystycznie i ewoluuj swoją architekturę zgodnie z wymaganiami. Zaawansowane warianty RAG omówione tutaj stanowią mapę drogową dla tej ewolucji.

Przydatne linki

Linki zewnętrzne