trustgraph/docs/tech-specs/graphrag-performance-optimization.ru.md

746 lines
48 KiB
Markdown
Raw Normal View History

---
layout: default
title: "Техническая спецификация оптимизации производительности GraphRAG"
parent: "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`
### Модели данных
#### Оптимизированное состояние обхода графа
Движок обхода поддерживает состояние для предотвращения избыточных операций:
```python
@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]
```
Этот подход позволяет:
Эффективное обнаружение циклов за счет отслеживания посещенных сущностей.
Подготовку запросов пакетами на каждом уровне обхода.
Экономичное использование памяти для управления состоянием.
Раннее завершение, когда достигнуты ограничения по размеру.
#### Улучшенная структура кэша
```python
@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
```
#### Структуры пакетных запросов
```python
@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**
```python
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 для разрешения меток пакетов**
```python
async def resolve_labels_batch(
entities: List[str],
cache_manager: CacheManager
) -> Dict[str, str]
```
**API управления кэшем**
```python
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: Критическая архитектурная реорганизация жизненного цикла
**Текущая проблемная реализация:**
```python
# 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
```
**Оптимизированная архитектура с длительным сроком службы:**
```python
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: Оптимизация обхода графа
**Проблемы текущей реализации:**
```python
# 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)
```
**Оптимизированная реализация:**
```python
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: Параллельное разрешение меток
**Текущая последовательная реализация:**
```python
# 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
```
**Оптимизированная параллельная реализация:**
```python
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:**
```python
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: Оптимизация запросов и мониторинг
**Сбор показателей производительности:**
```python
@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
```
**Тайм-аут запроса и предохранитель:**
```python
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
=======
4. **Реализуйте кэширование меток**: Добавьте кэш 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](trustgraph-flow/trustgraph/retrieval/graph_rag/graph_rag.py)
=======
[Исходная реализация GraphRAG](trustgraph-flow/trustgraph/retrieval/graph_rag/graph_rag.py)
>>>>>>> 82edf2d (New md files from RunPod)
[Принципы архитектуры TrustGraph](architecture-principles.md)
[Спецификация управления коллекциями](collection-management.md)