trustgraph/docs/tech-specs/ru/graphrag-performance-optimization.ru.md
cybermaggedon e7efb673ef
Structure the tech specs directory (#836)
Tech spec some subdirectories for different languages
2026-04-21 16:06:41 +01:00

48 KiB
Raw Blame History

layout title parent
default Техническая спецификация оптимизации производительности GraphRAG Russian (Beta)

Техническая спецификация оптимизации производительности GraphRAG

Beta Translation: This document was translated via Machine Learning and as such may not be 100% accurate. All non-English languages are currently classified as Beta.

Обзор

Эта спецификация описывает комплексные оптимизации производительности для алгоритма GraphRAG (Graph Retrieval-Augmented Generation) в TrustGraph. Текущая реализация страдает от значительных узких мест в производительности, которые ограничивают масштабируемость и время отклика. Эта спецификация охватывает четыре основные области оптимизации:

  1. Оптимизация обхода графа: Исключение неэффективных рекурсивных запросов к базе данных и реализация пакетной обработки графа.
  2. Оптимизация разрешения меток: Замена последовательной загрузки меток параллельными/пакетными операциями.
  3. Улучшение стратегии кэширования: Реализация интеллектуального кэширования с вытеснением по принципу LRU и предварительной загрузкой.
  4. Оптимизация запросов: Добавление мемоизации результатов и кэширования вложений для повышения скорости отклика.

Цели

Сокращение объема запросов к базе данных: Достижение снижения общего количества запросов к базе данных на 50-80% за счет пакетной обработки и кэширования. Улучшение времени отклика: Целевое увеличение скорости построения подграфов в 3-5 раз и ускорение разрешения меток в 2-3 раза. Повышение масштабируемости: Поддержка более крупных графов знаний с улучшением управления памятью. Сохранение точности: Сохранение существующей функциональности GraphRAG и качества результатов. Обеспечение параллельности: Улучшение возможностей параллельной обработки для нескольких одновременных запросов. <<<<<<< HEAD Уменьшение объема памяти: Реализация эффективных структур данных и управления памятью.

Уменьшение объема используемой памяти: Реализация эффективных структур данных и управления памятью.

82edf2d (New md files from RunPod) Добавление возможностей мониторинга: Включение показателей производительности и возможностей мониторинга. Обеспечение надежности: Добавление надлежащей обработки ошибок и механизмов таймаута.

Предыстория

Текущая реализация GraphRAG в trustgraph-flow/trustgraph/retrieval/graph_rag/graph_rag.py имеет несколько критических проблем с производительностью, которые серьезно влияют на масштабируемость системы:

Текущие проблемы с производительностью

1. Неэффективный обход графа (функция follow_edges, строки 79-127) Выполняет 3 отдельных запроса к базе данных для каждой сущности на каждом уровне глубины. Шаблон запроса: запросы на основе субъекта, запросы на основе предиката и запросы на основе объекта для каждой сущности. Без пакетной обработки: Каждый запрос обрабатывает только одну сущность за раз. Без обнаружения циклов: Может повторно посещать одни и те же узлы несколько раз. Рекурсивная реализация без мемоизации приводит к экспоненциальной сложности. Временная сложность: O(entities × max_path_length × triple_limit³)

2. Последовательное разрешение меток (функция get_labelgraph, строки 144-171) Обрабатывает каждый компонент тройки (субъект, предикат, объект) последовательно. Каждый вызов maybe_label потенциально вызывает запрос к базе данных. Без параллельного выполнения или пакетной обработки запросов меток. <<<<<<< HEAD В результате получается до 3 × subgraph_size отдельных вызовов базы данных.

Приводит до 3 × subgraph_size отдельных вызовов базы данных.

82edf2d (New md files from RunPod)

3. Примитивная стратегия кэширования (функция maybe_label, строки 62-77) Простой кэш в виде словаря без ограничений размера или TTL. Отсутствие политики вытеснения кэша приводит к неограниченному росту памяти. Пропуски кэша вызывают отдельные запросы к базе данных. Без предварительной загрузки или интеллектуального подогрева кэша.

4. Субоптимальные шаблоны запросов Запросы на сравнение векторного сходства сущностей не кэшируются между похожими запросами. Без мемоизации результатов для повторяющихся шаблонов запросов. <<<<<<< HEAD Отсутствие оптимизации запросов для распространенных шаблонов доступа.

Отсутствует оптимизация запросов для распространенных шаблонов доступа.

82edf2d (New md files from RunPod)

5. Критические проблемы с жизненным циклом объектов (rag.py:96-102) Объект GraphRag создается для каждого запроса: Новый экземпляр создается для каждого запроса, что приводит к потере всех преимуществ кэша. Объект запроса имеет очень короткий срок службы: Создается и уничтожается в течение выполнения одного запроса (строки 201-207). Кэш меток сбрасывается для каждого запроса: Подогрев кэша и накопленные знания теряются между запросами. <<<<<<< HEAD Накладные расходы на повторное создание клиента: Клиенты базы данных потенциально повторно устанавливаются для каждого запроса. Без оптимизации между запросами: Невозможно извлечь выгоду из шаблонов запросов или совместного использования результатов.

Накладные расходы на повторное создание клиента: Клиенты базы данных потенциально пересоздаются для каждого запроса. Отсутствие оптимизации между запросами: Невозможно извлечь выгоду из шаблонов запросов или обмена результатами.

82edf2d (New md files from RunPod)

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

Текущий наихудший сценарий для типичного запроса: Извлечение сущности: 1 запрос на сравнение векторного сходства. Обход графа: entities × max_path_length × 3 × triple_limit запросов. Разрешение меток: subgraph_size × 3 отдельных запросов на разрешение меток.

<<<<<<< HEAD Для параметров по умолчанию (50 сущностей, длина пути 2, ограничение в 30 тройки, размер подграфа 150): Минимальное количество запросов: 1 + (50 × 2 × 3 × 30) + (150 × 3) = 9451 запрос к базе данных Время отклика: 15-30 секунд для графов среднего размера Использование памяти: Неограниваемый рост кэша со временем

Для параметров по умолчанию (50 сущностей, длина пути 2, ограничение в 30 троек, размер подграфа 150): Минимальное количество запросов: 1 + (50 × 2 × 3 × 30) + (150 × 3) = 9451 запрос к базе данных Время отклика: 15-30 секунд для графов среднего размера Использование памяти: Неограниченный рост кэша со временем

82edf2d (New md files from RunPod) Эффективность кэша: 0% - кэши сбрасываются при каждом запросе Накладные расходы на создание объектов: Объекты GraphRag + Query создаются/удаляются для каждого запроса

Эта спецификация решает эти проблемы, реализуя пакетные запросы, интеллектуальное кэширование и параллельную обработку. Оптимизируя шаблоны запросов и доступ к данным, TrustGraph может: Поддерживать графы знаний корпоративного уровня с миллионами сущностей Обеспечивать время отклика менее 1 секунды для типичных запросов Обрабатывать сотни одновременных запросов GraphRAG <<<<<<< HEAD Эффективно масштабироваться в зависимости от размера и сложности графа

Эффективно масштабироваться с увеличением размера и сложности графа

82edf2d (New md files from RunPod)

Технический дизайн

Архитектура

Оптимизация производительности GraphRAG требует следующих технических компонентов:

1. Архитектурная реорганизация жизненного цикла объектов

<<<<<<< HEAD Сделать GraphRag долгоживущим: Переместить экземпляр GraphRag на уровень Processor для сохранения между запросами Сохранять кэши: Поддерживать кэш меток, кэш вложений и кэш результатов запросов между запросами Оптимизировать объект Query: Переработать Query как легковесный контекст выполнения, а не контейнер данных Сохранять подключения к базе данных: Поддерживать подключения к базе данных между запросами

Сделать GraphRag долгоживущим: Переместить экземпляр GraphRag на уровень Processor для сохранения данных между запросами Сохранять кэши: Поддерживать кэш меток, кэш вложений и кэш результатов запросов между запросами Оптимизировать объект Query: Переработать Query как легковесный контекст выполнения, а не контейнер данных Сохранять соединения с базой данных: Поддерживать соединения с базой данных между запросами

82edf2d (New md files from RunPod)

Модуль: trustgraph-flow/trustgraph/retrieval/graph_rag/rag.py (изменен)

2. Оптимизированный движок обхода графа

<<<<<<< HEAD Заменить рекурсивную follow_edges на итеративный поиск в ширину Реализовать пакетную обработку сущностей на каждом уровне обхода Добавить обнаружение циклов с помощью отслеживания посещенных узлов

Заменить рекурсивную функцию follow_edges на итеративный поиск в ширину Реализовать пакетную обработку сущностей на каждом уровне обхода Добавить обнаружение циклов с использованием отслеживания посещенных узлов

82edf2d (New md files from RunPod) Включить раннее завершение при достижении лимитов

Модуль: trustgraph-flow/trustgraph/retrieval/graph_rag/optimized_traversal.py

3. Параллельная система разрешения меток

Пакетные запросы меток для нескольких сущностей одновременно Реализовать шаблоны async/await для параллельного доступа к базе данных Добавить интеллектуальную предварительную загрузку для распространенных шаблонов меток Включить стратегии предварительного заполнения кэша меток

Модуль: trustgraph-flow/trustgraph/retrieval/graph_rag/label_resolver.py

4. Консервативный слой кэширования меток

Кэш LRU с коротким TTL только для меток (5 минут) для баланса между производительностью и согласованностью <<<<<<< HEAD Мониторинг метрик кэша и коэффициента попадания Без кэширования вложений: Уже кэшируются для каждого запроса, нет преимуществ для межзапросных данных

Мониторинг метрик кэша и коэффициента попаданий Без кэширования вложений: Уже кэшируются для каждого запроса, нет преимуществ для межзапросных операций

82edf2d (New md files from RunPod) Без кэширования результатов запросов: Из-за проблем согласованности изменений графа

Модуль: trustgraph-flow/trustgraph/retrieval/graph_rag/cache_manager.py

5. Фреймворк оптимизации запросов

Анализ шаблонов запросов и предложения по оптимизации Пакетный координатор запросов для доступа к базе данных <<<<<<< HEAD Управление пулами соединений и временем ожидания запросов

Управление пулом соединений и временем ожидания запросов

82edf2d (New md files from RunPod) Мониторинг производительности и сбор метрик

Модуль: trustgraph-flow/trustgraph/retrieval/graph_rag/query_optimizer.py

Модели данных

Оптимизированное состояние обхода графа

Движок обхода поддерживает состояние для предотвращения избыточных операций:

@dataclass
class TraversalState:
    visited_entities: Set[str]
    current_level_entities: Set[str]
    next_level_entities: Set[str]
    subgraph: Set[Tuple[str, str, str]]
    depth: int
    query_batch: List[TripleQuery]

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

Улучшенная структура кэша

@dataclass
class CacheEntry:
    value: Any
    timestamp: float
    access_count: int
    ttl: Optional[float]

class CacheManager:
    label_cache: LRUCache[str, CacheEntry]
    embedding_cache: LRUCache[str, CacheEntry]
    query_result_cache: LRUCache[str, CacheEntry]
    cache_stats: CacheStatistics

Структуры пакетных запросов

@dataclass
class BatchTripleQuery:
    entities: List[str]
    query_type: QueryType  # SUBJECT, PREDICATE, OBJECT
    limit_per_entity: int

@dataclass
class BatchLabelQuery:
    entities: List[str]
    predicate: str = LABEL

API

Новые API:

API GraphTraversal

async def optimized_follow_edges_batch(
    entities: List[str],
    max_depth: int,
    triple_limit: int,
    max_subgraph_size: int
) -> Set[Tuple[str, str, str]]

API для разрешения меток пакетов

async def resolve_labels_batch(
    entities: List[str],
    cache_manager: CacheManager
) -> Dict[str, str]

API управления кэшем

class CacheManager:
    async def get_or_fetch_label(self, entity: str) -> str
    async def get_or_fetch_embeddings(self, query: str) -> List[float]
    async def cache_query_result(self, query_hash: str, result: Any, ttl: int)
    def get_cache_statistics(self) -> CacheStatistics

Измененные API:

GraphRag.query() - Улучшено с оптимизациями производительности: Добавлен параметр cache_manager для управления кэшем. Добавлено возвращаемое значение performance_metrics. Добавлен параметр query_timeout для повышения надежности.

Класс Query - Рефакторинг для пакетной обработки: Замена обработки отдельных сущностей на пакетные операции. Добавлены асинхронные контекстные менеджеры для очистки ресурсов. Добавлены обратные вызовы для отслеживания прогресса длительных операций.

Детали реализации

Фаза 0: Критическая архитектурная реорганизация жизненного цикла

Текущая проблемная реализация:

# INEFFICIENT: GraphRag recreated every request
class Processor(FlowProcessor):
    async def on_request(self, msg, consumer, flow):
        # PROBLEM: New GraphRag instance per request!
        self.rag = GraphRag(
            embeddings_client = flow("embeddings-request"),
            graph_embeddings_client = flow("graph-embeddings-request"),
            triples_client = flow("triples-request"),
            prompt_client = flow("prompt-request"),
            verbose=True,
        )
        # Cache starts empty every time - no benefit from previous requests
        response = await self.rag.query(...)

# VERY SHORT-LIVED: Query object created/destroyed per request
class GraphRag:
    async def query(self, query, user="trustgraph", collection="default", ...):
        q = Query(rag=self, user=user, collection=collection, ...)  # Created
        kg = await q.get_labelgraph(query)  # Used briefly
        # q automatically destroyed when function exits

Оптимизированная архитектура с длительным сроком службы:

class Processor(FlowProcessor):
    def __init__(self, **params):
        super().__init__(**params)
        self.rag_instance = None  # Will be initialized once
        self.client_connections = {}

    async def initialize_rag(self, flow):
        """Initialize GraphRag once, reuse for all requests"""
        if self.rag_instance is None:
            self.rag_instance = LongLivedGraphRag(
                embeddings_client=flow("embeddings-request"),
                graph_embeddings_client=flow("graph-embeddings-request"),
                triples_client=flow("triples-request"),
                prompt_client=flow("prompt-request"),
                verbose=True,
            )
        return self.rag_instance

    async def on_request(self, msg, consumer, flow):
        # REUSE the same GraphRag instance - caches persist!
        rag = await self.initialize_rag(flow)

        # Query object becomes lightweight execution context
        response = await rag.query_with_context(
            query=v.query,
            execution_context=QueryContext(
                user=v.user,
                collection=v.collection,
                entity_limit=entity_limit,
                # ... other params
            )
        )

class LongLivedGraphRag:
    def __init__(self, ...):
        # CONSERVATIVE caches - balance performance vs consistency
        self.label_cache = LRUCacheWithTTL(max_size=5000, ttl=300)  # 5min TTL for freshness
        # Note: No embedding cache - already cached per-query, no cross-query benefit
        # Note: No query result cache due to consistency concerns
        self.performance_metrics = PerformanceTracker()

    async def query_with_context(self, query: str, context: QueryContext):
        # Use lightweight QueryExecutor instead of heavyweight Query object
        executor = QueryExecutor(self, context)  # Minimal object
        return await executor.execute(query)

@dataclass
class QueryContext:
    """Lightweight execution context - no heavy operations"""
    user: str
    collection: str
    entity_limit: int
    triple_limit: int
    max_subgraph_size: int
    max_path_length: int

class QueryExecutor:
    """Lightweight execution context - replaces old Query class"""
    def __init__(self, rag: LongLivedGraphRag, context: QueryContext):
        self.rag = rag
        self.context = context
        # No heavy initialization - just references

    async def execute(self, query: str):
        # All heavy lifting uses persistent rag caches
        return await self.rag.execute_optimized_query(query, self.context)

Это архитектурное изменение обеспечивает: Сокращение количества запросов к базе данных на 10-20% для графов с общими связями (по сравнению с текущими 0%) Устранение накладных расходов на создание объектов для каждого запроса Постоянное использование пула соединений и повторное использование клиентов Оптимизация между запросами в пределах временных окон TTL кэша

Важное ограничение согласованности кэша: Долгосрочное кэширование создает риск устаревания данных, когда сущности/метки удаляются или изменяются в базовом графе. Кэш LRU с TTL обеспечивает баланс между повышением производительности и актуальностью данных, но не может обнаруживать изменения в графе в режиме реального времени.

Фаза 1: Оптимизация обхода графа

Проблемы текущей реализации:

# INEFFICIENT: 3 queries per entity per level
async def follow_edges(self, ent, subgraph, path_length):
    # Query 1: s=ent, p=None, o=None
    res = await self.rag.triples_client.query(s=ent, p=None, o=None, limit=self.triple_limit)
    # Query 2: s=None, p=ent, o=None
    res = await self.rag.triples_client.query(s=None, p=ent, o=None, limit=self.triple_limit)
    # Query 3: s=None, p=None, o=ent
    res = await self.rag.triples_client.query(s=None, p=None, o=ent, limit=self.triple_limit)

Оптимизированная реализация:

async def optimized_traversal(self, entities: List[str], max_depth: int) -> Set[Triple]:
    visited = set()
    current_level = set(entities)
    subgraph = set()

    for depth in range(max_depth):
        if not current_level or len(subgraph) >= self.max_subgraph_size:
            break

        # Batch all queries for current level
        batch_queries = []
        for entity in current_level:
            if entity not in visited:
                batch_queries.extend([
                    TripleQuery(s=entity, p=None, o=None),
                    TripleQuery(s=None, p=entity, o=None),
                    TripleQuery(s=None, p=None, o=entity)
                ])

        # Execute all queries concurrently
        results = await self.execute_batch_queries(batch_queries)

        # Process results and prepare next level
        next_level = set()
        for result in results:
            subgraph.update(result.triples)
            next_level.update(result.new_entities)

        visited.update(current_level)
        current_level = next_level - visited

    return subgraph

Фаза 2: Параллельное разрешение меток

Текущая последовательная реализация:

# INEFFICIENT: Sequential processing
for edge in subgraph:
    s = await self.maybe_label(edge[0])  # Individual query
    p = await self.maybe_label(edge[1])  # Individual query
    o = await self.maybe_label(edge[2])  # Individual query

Оптимизированная параллельная реализация:

async def resolve_labels_parallel(self, subgraph: List[Triple]) -> List[Triple]:
    # Collect all unique entities needing labels
    entities_to_resolve = set()
    for s, p, o in subgraph:
        entities_to_resolve.update([s, p, o])

    # Remove already cached entities
    uncached_entities = [e for e in entities_to_resolve if e not in self.label_cache]

    # Batch query for all uncached labels
    if uncached_entities:
        label_results = await self.batch_label_query(uncached_entities)
        self.label_cache.update(label_results)

    # Apply labels to subgraph
    return [
        (self.label_cache.get(s, s), self.label_cache.get(p, p), self.label_cache.get(o, o))
        for s, p, o in subgraph
    ]

Фаза 3: Продвинутая стратегия кэширования

Кэш LRU с TTL:

class LRUCacheWithTTL:
    def __init__(self, max_size: int, default_ttl: int = 3600):
        self.cache = OrderedDict()
        self.max_size = max_size
        self.default_ttl = default_ttl
        self.access_times = {}

    async def get(self, key: str) -> Optional[Any]:
        if key in self.cache:
            # Check TTL expiration
            if time.time() - self.access_times[key] > self.default_ttl:
                del self.cache[key]
                del self.access_times[key]
                return None

            # Move to end (most recently used)
            self.cache.move_to_end(key)
            return self.cache[key]
        return None

    async def put(self, key: str, value: Any):
        if key in self.cache:
            self.cache.move_to_end(key)
        else:
            if len(self.cache) >= self.max_size:
                # Remove least recently used
                oldest_key = next(iter(self.cache))
                del self.cache[oldest_key]
                del self.access_times[oldest_key]

        self.cache[key] = value
        self.access_times[key] = time.time()

Фаза 4: Оптимизация запросов и мониторинг

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

@dataclass
class PerformanceMetrics:
    total_queries: int
    cache_hits: int
    cache_misses: int
    avg_response_time: float
    subgraph_construction_time: float
    label_resolution_time: float
    total_entities_processed: int
    memory_usage_mb: float

Тайм-аут запроса и предохранитель:

async def execute_with_timeout(self, query_func, timeout: int = 30):
    try:
        return await asyncio.wait_for(query_func(), timeout=timeout)
    except asyncio.TimeoutError:
        logger.error(f"Query timeout after {timeout}s")
        raise GraphRagTimeoutError(f"Query exceeded timeout of {timeout}s")

Соображения по обеспечению согласованности кэша

Компромиссы между актуальностью данных: Кэш меток (TTL 5 минут): Риск предоставления устаревших меток сущностей (удаленных или переименованных). <<<<<<< HEAD Отсутствие кэширования вложений: Не требуется, так как вложения уже кэшируются для каждого запроса.

Отсутствие кэширования вложений: Не требуется - вложения уже кэшируются для каждого запроса.

82edf2d (New md files from RunPod) Отсутствие кэширования результатов: Предотвращает получение устаревших результатов подграфов из-за удаленных сущностей/связей.

Стратегии смягчения: Консервативные значения TTL: Баланс между приростом производительности (10-20%) и актуальностью данных. <<<<<<< HEAD Хуки для аннулирования кэша: Необязательная интеграция с событиями изменения графа. Панели мониторинга: Отслеживание показателей попадания в кэш по сравнению с инцидентами устаревания данных. Настраиваемые политики кэширования: Возможность тонкой настройки для каждого развертывания в зависимости от частоты изменений.

Рекомендуемая конфигурация кэша в зависимости от частоты изменений графа: Высокая частота изменений (>100 изменений/час): TTL=60 секунд, меньшие размеры кэша. Средняя частота изменений (10-100 изменений/час): TTL=300 секунд (по умолчанию). Низкая частота изменений (<10 изменений/час): TTL=600 секунд, большие размеры кэша.

Механизмы аннулирования кэша: Необязательная интеграция с событиями изменения графа. Информационные панели мониторинга: Отслеживание показателей попадания в кэш по сравнению с инцидентами устаревания данных. Настраиваемые политики кэширования: Возможность тонкой настройки для каждого развертывания в зависимости от частоты изменений.

Рекомендуемая конфигурация кэша в зависимости от скорости изменений графа: Высокая скорость изменений (>100 изменений/час): TTL=60 секунд, меньшие размеры кэша. Средняя скорость изменений (10-100 изменений/час): TTL=300 секунд (по умолчанию). Низкая скорость изменений (<10 изменений/час): TTL=600 секунд, большие размеры кэша.

82edf2d (New md files from RunPod)

Соображения безопасности

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

Защита ресурсов: Применение ограничений на максимальный размер подграфа. Реализация таймаутов запросов для предотвращения исчерпания ресурсов. Добавление мониторинга и ограничений использования памяти.

Контроль доступа: Поддержание существующей изоляции пользователей и коллекций. Добавление ведения журнала аудита для операций, влияющих на производительность. Реализация ограничения скорости для дорогостоящих операций.

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

<<<<<<< HEAD

Ожидаемые улучшения производительности

Сокращение количества запросов: Сейчас: ~9000+ запросов для типичного запроса. Оптимизировано: ~50-100 пакетных запросов (снижение на 98%).

Ожидаемое повышение производительности

Сокращение количества запросов: Текущее: ~9000+ запросов для типичного запроса. Оптимизированное: ~50-100 пакетных запросов (снижение на 98%).

82edf2d (New md files from RunPod)

Улучшение времени отклика: Обход графа: 15-20 секунд → 3-5 секунд (в 4-5 раза быстрее). Разрешение меток: 8-12 секунд → 2-4 секунды (в 3 раза быстрее). Общий запрос: 25-35 секунд → 6-10 секунд (улучшение в 3-4 раза).

Эффективность использования памяти: Ограниченные размеры кэша предотвращают утечки памяти. Эффективные структуры данных уменьшают объем используемой памяти примерно на 40%. <<<<<<< HEAD Улучшен сбор мусора благодаря правильной очистке ресурсов.

Улучшенная сборка мусора благодаря правильной очистке ресурсов.

82edf2d (New md files from RunPod)

Реалистичные ожидания производительности: Кэш меток: Уменьшение количества запросов на 10-20% для графов с общими связями. Оптимизация пакетной обработки: Уменьшение количества запросов на 50-80% (основная оптимизация). Оптимизация времени жизни объектов: Исключение накладных расходов на создание объектов для каждого запроса. Общее улучшение: Улучшение времени отклика в 3-4 раза, в основном за счет пакетной обработки.

Улучшения масштабируемости: Поддержка графов знаний в 3-5 раза большего размера (ограничено потребностями согласованности кэша). Увеличение количества одновременных запросов в 3-5 раза. Лучшее использование ресурсов благодаря повторному использованию соединений.

Мониторинг производительности

Метрики в реальном времени: Время выполнения запросов по типу операции. Показатели попадания в кэш и его эффективность. Использование пула соединений с базой данных. Использование памяти и влияние сборки мусора.

Бенчмаркинг производительности: Автоматизированное регрессионное тестирование производительности Тестирование нагрузки с использованием реалистичных объемов данных Сравнительные тесты с текущей реализацией

Стратегия тестирования

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

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

Интеграционное тестирование

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

Тестирование производительности

Тестирование производительности по сравнению с текущей реализацией <<<<<<< HEAD Тестирование нагрузки с различными размерами и сложностью графов

Тестирование нагрузки с графами различного размера и сложности

82edf2d (New md files from RunPod) Стресс-тестирование для проверки лимитов памяти и соединений Регрессионное тестирование для проверки улучшений производительности

Тестирование совместимости

Проверка совместимости существующего API GraphRAG Тестирование с различными бэкендами графовых баз данных Проверка точности результатов по сравнению с текущей реализацией

План реализации

Прямой подход к реализации

Поскольку API могут изменяться, реализуйте оптимизации напрямую без сложности миграции:

  1. Замените метод follow_edges: Перепишите с использованием пакетного итеративного обхода
  2. Оптимизируйте get_labelgraph: Реализуйте параллельное разрешение меток
  3. Добавьте долгоживущий GraphRag: Измените Processor для поддержания постоянной инстанции <<<<<<< HEAD
  4. Реализуйте кэширование меток: Добавьте кэш LRU с TTL в класс GraphRag =======
  5. Реализуйте кэширование меток: Добавьте кэш LRU со сроком действия TTL в класс GraphRag

82edf2d (New md files from RunPod)

Область изменений

Класс запроса: Замените ~50 строк в follow_edges, добавьте ~30 строк для обработки пакетов Класс GraphRag: Добавьте слой кэширования (~40 строк) Класс Processor: Измените для использования постоянной инстанции GraphRag (~20 строк) <<<<<<< HEAD Всего: ~140 строк целенаправленных изменений, в основном в существующих классах

Всего: ~140 строк изменений, в основном в существующих классах

82edf2d (New md files from RunPod)

Временная шкала

Неделя 1: Основная реализация Замените follow_edges пакетным итеративным обходом Реализуйте параллельное разрешение меток в get_labelgraph Добавьте долгоживущую инстанцию GraphRag в Processor Реализуйте слой кэширования меток

Неделя 2: Тестирование и интеграция Модульные тесты для новой логики обхода и кэширования Бенчмаркинг производительности по сравнению с текущей реализацией <<<<<<< HEAD Интеграционное тестирование с реальными данными графа

Интеграционное тестирование с реальными графовыми данными

82edf2d (New md files from RunPod) Проверка кода и оптимизация

Неделя 3: Развертывание Разверните оптимизированную реализацию Отслеживайте улучшения производительности <<<<<<< HEAD Тонкая настройка TTL кэша и размеров пакетов на основе реального использования

Открытые вопросы

Пул соединений с базой данных: Следует ли нам реализовать собственный пул соединений или использовать существующий пул соединений от клиента базы данных? Постоянство кэша: Должны ли кэши меток и внедрений сохраняться после перезапуска службы? Распределенное кэширование: Для развернутых в нескольких экземплярах систем следует ли нам реализовать распределенное кэширование с использованием Redis/Memcached? Формат результата запроса: Следует ли нам оптимизировать внутреннее представление тройки для повышения эффективности использования памяти?

Тонкая настройка срока действия TTL кэша и размеров пакетов на основе реального использования

Открытые вопросы

Пул соединений с базой данных: Следует ли нам реализовывать собственный пул соединений или использовать существующий пул соединений от клиента базы данных? Постоянство кэша: Должны ли кэши меток и вложений сохраняться после перезапуска сервиса? Распределенное кэширование: Для развернутых в нескольких инстанциях систем следует ли реализовывать распределенное кэширование с использованием Redis/Memcached? Формат результата запроса: Следует ли оптимизировать внутреннее представление тройки для повышения эффективности использования памяти?

82edf2d (New md files from RunPod) Интеграция мониторинга: Какие метрики следует предоставлять существующим системам мониторинга (Prometheus и т. д.)?

Ссылки

<<<<<<< HEAD Оригинальная реализация GraphRAG

Исходная реализация GraphRAG

82edf2d (New md files from RunPod) Принципы архитектуры TrustGraph Спецификация управления коллекциями