Продвинутый RAG: объяснение LongRAG, Self-RAG и GraphRAG

LongRAG, Self-RAG, GraphRAG — передовые техники

Содержимое страницы

Генерация с усилением поиска (RAG) давно вышла за рамки простого поиска векторного сходства. LongRAG, Self-RAG и GraphRAG представляют передовой край этих возможностей.

Современные системы RAG должны обрабатывать огромные документы, понимать сложные связи между сущностями и многое другое.

a-pirate-captain Это приятное изображение сгенерировано моделью ИИ Flux 1 dev.

Эволюция за пределами базового RAG

Традиционные системы RAG следуют простому шаблону: разбивают документы на блоки, превращают их в векторы, извлекают похожие блоки через косинуснуюSimilarity и подают их в LLM. Хотя этот подход эффективен во многих сценариях, он испытывает трудности с тремя критическими ситуациями:

Понимание различий между поиском, глубоким поиском (deepsearch) и глубоким исследованием (deep research) помогает прояснить, почему для сложных задач извлечения информации необходимы продвинутые варианты RAG. Для более глубокого погружения в эти концепции см. Поиск против Deepsearch против Deep Research.

  1. Дальние зависимости: Важный контекст может охватывать тысячи токенов в нескольких блоках
  2. Уверенность извлечения: Система не имеет способа оценить, действительно ли извлеченное содержимое релевантно
  3. Сложность связей: Векторное сходство не может отразить сложные соединения между сущностями

Продвинутые варианты RAG решают эти ограничения с помощью специализированных архитектур, адаптированных к конкретным вызовам.

LongRAG: Победа над расширенным контекстом

Обзор архитектуры

LongRAG фундаментально переосмысливает стратегию разбиения на блоки (чанкинга), используя LLM с расширенными окнами контекста (32K, 100K или даже 1M токенов). Вместо разбивки документов на небольшие блоки по 512 токенов, LongRAG использует иерархический подход:

Встраивание на уровне документа: Весь документ (или очень крупные разделы) обрабатывается как единое целое. Встраивание на уровне документа захватывает общий семантический смысл, сохраняя при этом полный текст для последующей обработки.

Минимальная фрагментация: Когда разбиение на блоки необходимо, LongRAG использует гораздо более крупные блоки (4K-8K токенов) с значительным перекрытием (20-30%). Это сохраняет нарративный поток и уменьшает фрагментацию контекста.

Сборка контекста: При извлечении LongRAG возвращает целые документы или крупные связные разделы, а не разбросанные фрагменты. LLM получает непрерывный контекст, сохраняющий структурные и семантические связи.

Стратегия реализации

Вот концептуальная реализация с использованием Python и современных моделей встраивания:

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]:
        """Create overlapping large chunks"""
        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):
        """Index document with hierarchical embedding"""
        # Embed entire document
        doc_embedding = self.model.embed(doc)
        
        # Create large chunks with overlap
        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]:
        """Retrieve relevant long-form content"""
        query_embedding = self.model.embed(query)
        
        # Score at document level first
        doc_scores = [
            np.dot(query_embedding, doc['doc_embedding'])
            for doc in self.doc_embeddings
        ]
        
        # Get top documents
        top_doc_indices = np.argsort(doc_scores)[-top_k:][::-1]
        
        results = []
        for idx in top_doc_indices:
            doc_data = self.doc_embeddings[idx]
            
            # For each document, find best chunks
            chunk_scores = [
                np.dot(query_embedding, emb)
                for emb in doc_data['chunk_embeddings']
            ]
            best_chunk_idx = np.argmax(chunk_scores)
            
            # Return extended context around best chunk
            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]:
        """Get extended context around relevant chunk"""
        start = max(0, center_idx - 1)
        end = min(len(chunks), center_idx + 2)
        return chunks[start:end]

Сценарии использования и производительность

LongRAG превосходит в сценариях, где важен контекст:

  • Анализ юридических документов: Договоры и юридические записки часто имеют зависимости, охватывающие десятки страниц
  • Извлечение научных статей: Понимание методологии требует связных разделов, а не изолированных абзацев
  • Репозитории кода: Функции и классы должны пониматься в контексте их модулей

Характеристики производительности:

  • Латентность: Выше из-за обработки крупных блоков (в 2-5 раза медленнее стандартного RAG)
  • Точность: Улучшение на 15-25% на бенчмарках длинного формата QA
  • Память: Требует в 3-4 раза больше памяти для окон контекста

Self-RAG: Рефлексивное извлечение

Основные принципы

Self-RAG вводит метакогнитивный слой в системы RAG. Вместо слепого извлечения и генерации, система активно рефлексирует над собственными процессами через специальные токены рефлексии. Эта же само-рефлексивная, итеративно-извлекающая идея воспроизводится на уровне приложения в системах Self-hosted Deep Research — см. Системы Self-Hosted Deep Research: Сравнение 12 инструментов для того, как инструменты вроде Local Deep Research и lukeswade/deep-research оценивают собственные пробелы в доказательствах и решают, что искать дальше:

Токен извлечения: Определяет, необходимо ли извлечение для данного запроса Токен релевантности: Оценивает, действительно ли извлеченные документы релевантны Токен поддержки: Проверяет, поддерживается ли сгенерированный ответ извлеченным содержимым Токен критики: Оценивает общее качество сгенерированного ответа

Компоненты архитектуры

Архитектура Self-RAG состоит из трех чередующихся фаз:

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):
        """Generate answer with self-reflection"""
        
        # Phase 1: Decide if retrieval needed
        retrieve_decision = self.critic.should_retrieve(query)
        
        if not retrieve_decision:
            # Direct generation without retrieval
            return self.generator.generate(query)
        
        # Phase 2: Retrieve and evaluate relevance
        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:  # Threshold
                relevant_docs.append(doc)
        
        if not relevant_docs:
            # Fallback to generation without retrieval
            return self.generator.generate(query)
        
        # Phase 3: Generate and verify support
        best_answer = None
        best_score = -1
        
        for _ in range(max_iterations):
            # Generate candidate answer
            answer = self.generator.generate(
                query, context=relevant_docs
            )
            
            # Evaluate support and quality
            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
            
            # Early stopping if high quality achieved
            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
            }
        }

Обучение механизмов рефлексии

Self-RAG требует обучения компонента критика для принятия надежных оценок. Обычно это включает:

  1. Мониторинг тонкой настройки на наборах данных, размеченных с оценками релевантности
  2. Обучение с подкреплением с наградами за точные прогнозы
  3. Контрастное обучение для различения поддерживаемых и не поддерживаемых утверждений

Токены рефлексии могут быть реализованы как:

  • Специальные токены в словаре (например, [RETRIEVE], [RELEVANT])
  • Отдельные классификаторные головы на модели
  • Внешние модели критика ( ансамблевый подход)

Соображения для продакшена

При развертывании Self-RAG в производственных системах:

Компромиссы латентности: Каждый шаг рефлексии добавляет 20-40% накладных расходов на инференс. Балансируйте тщательность с требованиями к времени отклика.

Пороги уверенности: Настраивайте пороги рефлексии в зависимости от вашего сценария использования. Юридические или медицинские приложения требуют более высокой уверенности, чем общие чат-боты.

Мониторинг: Отслеживайте решения о рефлексии, чтобы выявлять закономерности. Если извлечение редко требуется, вы можете выиграть от более простой архитектуры.

GraphRAG: Извлечение, усиленное графом знаний

Концептуальная основа

GraphRAG трансформирует задачу извлечения из векторного сходства в обход графа. Вместо поиска семантически похожих текстовых блоков, GraphRAG идентифицирует релевантные подграфы связанных сущностей и отношений.

Извлечение сущностей: Идентифицировать именованные сущности, концепции и их типы Картирование отношений: Извлекать отношения между сущностями (временные, каузальные, иерархические) Построение графа: Построить граф знаний со сущностями как узлами и отношениями как рёбрами Извлечение подграфа: По запросу находить релевантные связанные подграфы

Конвейер построения графа

Построение графа знаний из неструктурированного текста включает несколько этапов:

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]):
        """Build knowledge graph from documents"""
        for doc in documents:
            # Extract entities
            entities = self.entity_extractor.extract(doc)
            
            # Add entities as nodes
            for entity in entities:
                self.graph.add_node(
                    entity['text'],
                    entity_type=entity['type'],
                    context=entity['surrounding_text']
                )
            
            # Extract relationships
            relations = self.relation_extractor.extract(
                doc, entities
            )
            
            # Add relationships as edges
            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):
        """Add derived relationships and metadata"""
        # Compute node importance (PageRank, etc.)
        self.graph.compute_centrality()
        
        # Identify communities/clusters
        self.graph.detect_communities()
        
        # Add temporal ordering if timestamps available
        self.graph.add_temporal_edges()

Обработка запросов с графами

Запросы GraphRAG включают многошаговое рассуждение (multi-hop reasoning) через граф знаний:

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):
        """Retrieve relevant subgraph for query"""
        
        # Identify seed entities in query
        query_entities = self.entity_extractor.extract(query)
        
        # Find matching nodes in graph
        seed_nodes = []
        for entity in query_entities:
            matches = self.graph.find_similar_nodes(
                entity['text'],
                similarity_threshold=0.85
            )
            seed_nodes.extend(matches)
        
        # Expand subgraph via traversal
        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
            )
        
        # Rank nodes by relevance
        ranked_nodes = self._rank_subgraph_nodes(
            subgraph, query
        )
        
        # Extract and format context
        context = self._format_graph_context(
            ranked_nodes[:max_nodes],
            subgraph
        )
        
        return context
    
    def _expand_from_node(self, node, subgraph, visited,
                         current_hop, max_hops):
        """Recursively expand subgraph"""
        if current_hop >= max_hops or node in visited:
            return
        
        visited.add(node)
        subgraph.add_node(node)
        
        # Get neighbors
        neighbors = self.graph.get_neighbors(node)
        
        for neighbor, edge_data in neighbors:
            # Add edge to subgraph
            subgraph.add_edge(node, neighbor, edge_data)
            
            # Recursively expand
            self._expand_from_node(
                neighbor,
                subgraph,
                visited,
                current_hop + 1,
                max_hops
            )
    
    def _format_graph_context(self, nodes, subgraph):
        """Convert subgraph to textual context"""
        context_parts = []
        
        for node in nodes:
            # Add node context
            context_parts.append(f"Entity: {node.text}")
            context_parts.append(f"Type: {node.entity_type}")
            
            # Add relationship information
            edges = subgraph.get_edges(node)
            for edge in edges:
                context_parts.append(
                    f"- {edge.relation_type} -> {edge.target.text}"
                )
        
        return "\n".join(context_parts)

Реализация GraphRAG от Microsoft

GraphRAG от Microsoft использует уникальный подход, генерируя сводки сообществ:

  1. Построение начального графа из документов с использованием LLM-извлечения сущностей/отношений
  2. Обнаружение сообществ с использованием алгоритма Leiden или аналогичного
  3. Генерация сводок для каждого сообщества с использованием LLM
  4. Иерархическая структура: Построение нескольких уровней абстракций сообществ
  5. Время запроса: Извлечение релевантных сообществ и обход до конкретных сущностей

Этот подход особенно эффективен для:

  • Разведывательных запросов (“Каковы основные темы в этом корпусе?”)
  • Многошагового рассуждения (“Как A связано с C через B?”)
  • Временного анализа (“Как эволюционировали отношения этой сущности?”)

Сравнительный анализ

Когда использовать каждый вариант

Используйте LongRAG, когда:

  • Документы имеют сильную внутреннюю связность
  • Окон контекста вашей LLM поддерживают большой вход (32K+)
  • Ответы на запросы требуют понимания дальних зависимостей
  • Вы работаете со структурированными документами (отчеты, статьи, книги)

Используйте Self-RAG, когда:

  • Точность и надежность критичны
  • Вам нужны объяснимые решения об извлечении
  • Ложные положительные результаты от нерелевантного извлечения стоят дорого
  • Сложность запросов сильно варьируется (некоторым требуется извлечение, другим нет)

Используйте GraphRAG, когда:

  • Ваша область имеет богатые отношения между сущностями
  • Запросы включают многошаговое рассуждение
  • Временные или иерархические отношения важны
  • Вам нужно понимать связи между сущностями

Сравнение метрик производительности

Метрика Стандартный RAG LongRAG Self-RAG GraphRAG
Время индексирования 1x 0.8x 1.1x 3-5x
Латентность запроса 1x 2-3x 1.4x 1.5-2x
Использование памяти 1x 3-4x 1.2x 2-3x
Точность (QA) базовая +15-25% +20-30% +25-40%*
Интерпретируемость Низкая Средняя Высокая Высокая

*Улучшения GraphRAG сильно зависят от предметной области

Гибридные подходы

Самые мощные производственные системы часто комбинируют несколько техник:

LongRAG + GraphRAG: Используйте структуру графа для идентификации релевантных кластеров документов, затем извлекайте полные документы, а не фрагменты

Self-RAG + GraphRAG: Применяйте механизмы рефлексии к решениям обхода графа (какие пути следовать, когда останавливать расширение)

Трехэтапный конвейер: Используйте GraphRAG для начального извлечения на основе сущностей → Self-RAG для фильтрации релевантности → LongRAG для сборки контекста

Соображения по реализации

Модели встраивания

Разные варианты RAG имеют разные требования к встраиванию:

LongRAG: Нужны встраивания, которые хорошо работают и на уровне документа, и на уровне блоков. Рассмотрите модели, обученные с контрастным обучением на длинных последовательностях.

Self-RAG: Выигрывает от встраиваний, которые захватывают семантические нюансы для детальной оценки релевантности.

GraphRAG: Требует осведомленных о сущностях встраиваний. Модели, прошедшие тонкую настройку на задачах связывания сущностей, работают лучше.

Выбор модели встраивания значительно влияет на производительность. При работе с локальными моделями инструменты вроде Ollama предоставляют простой способ экспериментировать с различными моделями встраивания перед принятием решения о производственном развертывании.

Стратегии разбиения на блоки, рассмотренные вновь

Традиционное разбиение на блоки фиксированного размера недостаточно для продвинутого RAG:

Семантическое разбиение: Разбивать по естественным границам (абзацы, разделы, сдвиги тем) Рекурсивное разбиение: Создавать иерархические блоки с отношениями родитель-потомок Скользящее окно: Использовать перекрывающиеся блоки для сохранения контекста на границах Осведомленное о структуре: Уважать структуру документа (заголовки markdown, XML-теги, блоки кода)

Для реализаций на основе Python библиотеки вроде LangChain и LlamaIndex предоставляют встроенную поддержку этих стратегий разбиения на блоки.

Интеграция повторного ранжирования

Повторное ранжирование значительно улучшает качество извлечения во всех вариантах RAG. После начального извлечения специализированная модель повторного ранжирования пересчитывает баллы результатов на основе признаков взаимодействия запрос-документ. Это обеспечивает значительный прирост точности (10-20%) с минимальным влиянием на латентность при продуманной интеграции.

Масштабирование до продакшена

Конвейер индексирования:

  • Используйте распределенную обработку (Ray, Dask) для больших корпусов документов
  • Реализуйте инкрементальное индексирование для обновлений в реальном времени
  • Храните встраивания в оптимизированных векторных базах данных (Pinecone, Weaviate, Qdrant)

Оптимизация запросов:

  • Кэшируйте частые запросы и их результаты
  • Реализуйте маршрутизацию запросов (разные варианты RAG для разных типов запросов)
  • Используйте приближенный поиск ближайших соседей для сублинейного масштабирования

Мониторинг:

  • Отслеживайте баллы релевантности извлечения
  • Мониторьте решения о рефлексии в Self-RAG
  • Измеряйте пути и глубину обхода графа
  • Логгируйте баллы уверенности и обратную связь от пользователей

Приложения в реальном мире

Поиск по технической документации

Крупный облачный провайдер реализовал GraphRAG для своей документации:

  • Сущности: точки входа API, параметры, коды ошибок, имена сервисов
  • Отношения: Зависимости, совместимость версий, пути миграции
  • Результат: Снижение числа обращений в поддержку на 35%, ускорение времени разрешения на 45%

Юридическое обнаружение (Discovery)

Юридическая технологическая компания объединила Self-RAG с LongRAG:

  • Self-RAG фильтрует нерелевантные документы на ранней стадии
  • LongRAG сохраняет контекст в оставленных документах
  • Юристы проверяют на 60% меньше ложных положительных результатов
  • Сохранение критического контекста улучшилось с 71% до 94%

Обзор исследовательской литературы

Академический поисковый движок, использующий гибридный подход:

  • GraphRAG идентифицирует сети цитирования и исследовательские сообщества
  • LongRAG извлекает полные разделы, сохраняя контекст методологии
  • Улучшение обнаружения релевантных статей на 40%
  • Сокращение времени обзора литературы с недель до дней

Продвинутые темы

Мультимодальный RAG

Расширение этих вариантов для обработки изображений, таблиц и кода:

  • Визуальная привязка: Связывать текстовые сущности с изображениями в документах
  • Понимание таблиц: Разбирать структурированные данные в графический формат
  • Анализ кода: Строить графы зависимостей из кодовых баз

Адаптивный RAG

Динамический выбор стратегии RAG на основе характеристик запроса:

  • Классификатор сложности запроса
  • Детектор типа документа
  • Оптимизатор выгоды для выбора стратегии

RAG с сохранением конфиденциальности

Реализация этих вариантов с ограничениями конфиденциальности:

  • Федеративное извлечение между изолированными данными
  • Дифференциальная конфиденциальность в встраиваниях
  • Зашифрованный поиск сходства

Начало работы

Быстрый старт с Python

Для тех, кто хочет реализовать эти техники, начало с солидной основы на Python необходимо. Богатая экосистема Python для машинного обучения делает его естественным выбором для разработки RAG.

Вот простая отправная точка для экспериментов:

# Install dependencies
# pip install sentence-transformers faiss-cpu langchain

from sentence_transformers import SentenceTransformer
import faiss
import numpy as np

# Basic setup for experimenting with long chunks
model = SentenceTransformer('all-MiniLM-L6-v2')

documents = [
    # Your long-form documents here
]

# Create embeddings
embeddings = model.encode(documents)

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

# Query
query = "Your question here"
query_embedding = model.encode([query])
distances, indices = index.search(
    query_embedding.astype('float32'), k=3
)

Выбор фреймворка

LangChain: Лучший для быстрого прототипирования, обширные интеграции LlamaIndex: Оптимизирован для индексирования и извлечения документов Haystack: Готов к продакшену, сильные абстракции конвейеров Кастомный: Когда вам нужен полный контроль и оптимизация

Фреймворк оценки

Реализуйте строгую оценку перед производственным развертыванием:

Метрики извлечения:

  • Precision@K, Recall@K, MRR (Средний реципрокальный ранг)
  • NDCG (Нормализованный дисконтированный кумулятивный выигрыш)

Метрики генерации:

  • ROUGE, BLEU для текстового сходства
  • BERTScore для семантического сходства
  • Человеческая оценка для оценки качества

Сквозные метрики:

  • Уровень успешности задачи
  • Баллы удовлетворенности пользователей
  • Процентили латентности (p50, p95, p99)

Заключение

Ландшафт систем RAG значительно созрел за пределами базового векторного поиска сходства. LongRAG, Self-RAG и GraphRAG каждый решают конкретные ограничения традиционных подходов:

LongRAG решает проблему фрагментации контекста, принимая расширенные окна контекста и минимальный чанкинг. Это выбор для случаев, когда связность документа важна и у вас есть вычислительные ресурсы для обработки больших контекстов.

Self-RAG добавляет критически важную самоосознанность системам извлечения. Рефлексируя над собственными решениями, он уменьшает ложные положительные результаты и улучшает надежность — что обязательно для высокоответственных приложений, где точность важнее скорости.

GraphRAG открывает мощь структурированного представления знаний. Когда ваша область включает сложные отношения между сущностями, графовое извлечение может выявить связи, которые векторное сходство полностью упускает. Более глубокий вопрос о том, как структурировать знания до того, как они будут извлечены, — и почему представление так же важно, как и извлечение, — исследуется в Извлечение против Представления в Системах Знаний.

Будущее RAG, вероятно, будет включать гибридные подходы, которые объединяют преимущества этих вариантов. Производственная система может использовать GraphRAG для идентификации релевантных кластеров сущностей, Self-RAG для фильтрации и валидации извлечений и LongRAG для сборки связного контекста для LLM.

По мере того, как LLM продолжают улучшаться, а окна контекста расширяются, мы увидим появление еще более изощренных вариантов RAG. Ключом является понимание ваших конкретных требований сценария использования — структура документов, паттерны запросов, требования к точности и вычислительные ограничения — и выбор соответствующей техники или комбинации.

Экосистема инструментов быстро созревает, при этом фреймворки вроде LangChain, LlamaIndex и Haystack предоставляют все более изощренную поддержку для этих продвинутых паттернов. В сочетании с мощными локальными рантаймами LLM и моделями встраивания, никогда ранее не было так просто экспериментировать и разворачивать RAG-системы производственного уровня.

Начните с основ, строго измеряйте производительность и развивайте вашу архитектуру по мере того, как это диктуют требования. Продвинутые варианты RAG, рассмотренные здесь, предоставляют дорожную карту для этой эволюции.

Полезные ссылки

Внешние ссылки

Подписаться

Получайте новые материалы про системы, инфраструктуру и AI engineering.