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

808 lines
42 KiB
Markdown
Raw Normal View History

---
layout: default
title: "מפרט טכני לשיפור ביצועי GraphRAG"
parent: "Hebrew (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.
## סקירה כללית
<<<<<<< HEAD
מפרט זה מתאר שיפורי ביצועים מקיפים עבור אלגוריתם GraphRAG (Graph Retrieval-Augmented Generation) ב-TrustGraph. יישום הנוכחי סובל מבעיות ביצועים משמעותיות המגבילות את יכולת ההרחבה וזמני התגובה. מפרט זה מתייחס לארבעה תחומים עיקריים של אופטימיזציה:
1. **אופטימיזציה של מעבר גרפים**: ביטול שאילתות מסד נתונים רקורסיביות לא יעילות ויישום חקר גרפים באצווה.
2. **אופטימיזציה של פתרון תגיות**: החלפת אחזור תגיות רציף בפעולות מקבילות/באצווה.
3. **שיפור אסטרטגיית אחסון במטמון**: יישום אחסון במטמון חכם עם פינוי LRU וטעינה מראש.
4. **אופטימיזציה של שאילתות**: הוספת שמירת תוצאות במטמון ואחסון במטמון של הטמעות לשיפור זמני התגובה.
## מטרות
**הפחתת נפח שאילתות מסד הנתונים**: השגת הפחתה של 50-80% בסך כל שאילתות מסד הנתונים באמצעות אצווה ואחסון במטמון.
**שיפור זמני תגובה**: יעד לבניית תת-גרפים מהירה פי 3-5 ופתרון תגיות מהיר פי 2-3.
**שיפור יכולת הרחבה**: תמיכה בגרפי ידע גדולים יותר עם ניהול זיכרון טוב יותר.
**שמירה על דיוק**: שמירה על פונקציונליות ואיכות תוצאות GraphRAG הקיימות.
**אפשרות לעיבוד מקבילי**: שיפור יכולות עיבוד מקבילי עבור בקשות מרובות בו-זמנית.
**הפחתת טביעת רגל של זיכרון**: יישום מבני נתונים וניהול זיכרון יעילים.
**הוספת יכולת ניטור**: הכללת מדדי ביצועים ויכולות ניטור.
**הבטחת אמינות**: הוספת טיפול בשגיאות ומנגנוני תזמון מתאימים.
=======
מפרט זה מתאר שיפורים מקיפים בביצועים עבור אלגוריתם GraphRAG (Graph Retrieval-Augmented Generation) ב-TrustGraph. יישום הנוכחי סובל מבעיות ביצועים משמעותיות המגבילות את יכולת ההרחבה וזמני התגובה. מפרט זה מתייחס לארבעה תחומים עיקריים של אופטימיזציה:
1. **אופטימיזציה של מעבר גרפים**: ביטול שאילתות מסד נתונים רקורסיביות לא יעילות ויישום חקר גרפים בקבוצות
2. **אופטימיזציה של פתרון תגיות**: החלפת שליפת תגיות רציפה בפעולות מקבילות/בקבוצות
3. **שיפור אסטרטגיית אחסון במטמון**: יישום אחסון במטמון חכם עם פינוי LRU וטעינה מראש
4. **אופטימיזציה של שאילתות**: הוספת שמירת תוצאות במטמון ואחסון במטמון של הטמעות לשיפור זמני התגובה
## מטרות
**הפחתת נפח שאילתות מסד הנתונים**: השגת הפחתה של 50-80% בסך כל שאילתות מסד הנתונים באמצעות קיבוץ ואחסון במטמון
**שיפור זמני תגובה**: יעד לבניית תת-גרפים מהירה פי 3-5 ופתרון תגיות מהיר פי 2-3
**שיפור יכולת הרחבה**: תמיכה בגרפי ידע גדולים יותר עם ניהול זיכרון טוב יותר
**שמירה על דיוק**: שמירה על פונקציונליות ואיכות תוצאות GraphRAG הקיימות
**אפשרות לעיבוד מקבילי**: שיפור יכולות עיבוד מקבילי עבור בקשות מרובות בו-זמנית
**הפחתת טביעת רגל של זיכרון**: יישום מבני נתונים וניהול זיכרון יעילים
**הוספת יכולת ניטור**: הכללת מדדי ביצועים ויכולות ניטור
**הבטחת אמינות**: הוספת טיפול מתאים בשגיאות ומנגנוני תזמון
>>>>>>> 82edf2d (New md files from RunPod)
## רקע
יישום GraphRAG הנוכחי ב-`trustgraph-flow/trustgraph/retrieval/graph_rag/graph_rag.py` מציג מספר בעיות ביצועים קריטיות המשפיעות באופן משמעותי על יכולת ההרחבה של המערכת:
### בעיות ביצועים נוכחיות
**1. מעבר גרפים לא יעיל (פונקציה `follow_edges`, שורות 79-127)**
<<<<<<< HEAD
מבצע 3 שאילתות נפרדות למסד הנתונים עבור כל ישות בכל רמת עומק.
תבנית שאילתה: שאילתות מבוססות נושא, מבוססות פרידיקט ומבוססות אובייקט עבור כל ישות.
ללא אצווה: כל שאילתה מעבדת רק ישות אחת בכל פעם.
ללא זיהוי מעגלים: ניתן לחזור על צמתים זהים מספר פעמים.
יישום רקורסיבי ללא שמירה במטמון מוביל למורכבות אקספוננציאלית.
מורכבות זמן: O(entities × max_path_length × triple_limit³)
**2. פתרון תגיות רציף (פונקציה `get_labelgraph`, שורות 144-171)**
מעבד כל רכיב משולש (נושא, פרידיקט, אובייקט) ברצף.
כל קריאה ל-`maybe_label` עלולה לגרום לשאילתה למסד הנתונים.
ללא ביצוע מקבילי או אצווה של שאילתות תגיות.
גורם עד ל-3 × קריאות אישיות למסד הנתונים עבור גודל תת-גרף.
**3. אסטרטגיית אחסון במטמון בסיסית (פונקציה `maybe_label`, שורות 62-77)**
מטמון מילון פשוט ללא מגבלות גודל או TTL.
מדיניות פינוי מטמון חסרת גבולות מובילה לצמיחה בלתי מוגבלת של זיכרון.
החסרה במטמון גורמת לשאילתות נפרדות למסד הנתונים.
ללא טעינה מראש או אחסון במטמון חכם.
**4. תבניות שאילתות לא אופטימליות**
שאילתות דמיון וקטורי לישויות אינן מאוחסנות במטמון בין בקשות דומות.
ללא שמירת תוצאות במטמון לתבניות שאילתות חוזרות.
חסרים אופטימיזציות שאילתות לתבניות גישה נפוצות.
**5. בעיות קריטיות של חיי אובייקט (`rag.py:96-102`)**
**אובייקט GraphRag נוצר מחדש עבור כל בקשה**: מופע חדש נוצר עבור כל שאילתה, תוך אובדן כל יתרונות המטמון.
**אובייקט שאילתה בעל אורך חיים קצר ביותר**: נוצר ונהרס בתוך ביצוע שאילתה יחיד (שורות 201-207).
**מטמון תגיות מאופס עבור כל בקשה**: חימום מטמון וידע שנצבר אובדים בין בקשות.
**תקורה של יצירת לקוח מחדש**: לקוחות מסד נתונים פוטנציאליים מוקמים מחדש עבור כל בקשה.
**ללא אופטימיזציה חוצה בקשות**: לא ניתן להפיק תועלת מתבניות שאילתות או שיתוף תוצאות.
=======
מבצע 3 שאילתות נפרדות למסד הנתונים עבור כל ישות בכל רמת עומק
תבנית שאילתה: שאילתות מבוססות נושא, שאילתות מבוססות פרידיקט ושאילתות מבוססות אובייקט עבור כל ישות
ללא קיבוץ: כל שאילתה מעבדת רק ישות אחת בכל פעם
ללא זיהוי מעגלים: ניתן לחזור על צמתים זהים מספר פעמים
יישום רקורסיבי ללא שמירה במטמון מוביל למורכבות אקספוננציאלית
מורכבות זמן: O(entities × max_path_length × triple_limit³)
**2. פתרון תגיות רציף (פונקציה `get_labelgraph`, שורות 144-171)**
מעבד כל רכיב משולש (נושא, פרידיקט, אובייקט) ברצף
כל קריאה ל-`maybe_label` עלולה לגרום לשאילתה למסד הנתונים
ללא ביצוע מקבילי או קיבוץ של שאילתות תגיות
גורם עד ל-3 × קריאות אישיות למסד הנתונים עבור גודל תת-גרף
**3. אסטרטגיית אחסון במטמון בסיסית (פונקציה `maybe_label`, שורות 62-77)**
מטמון מילון פשוט ללא מגבלות גודל או TTL
מדיניות פינוי מטמון חסרת גבולות מובילה לצמיחה בלתי מוגבלת של זיכרון
החסרה במטמון גורמת לשאילתות נפרדות למסד הנתונים
ללא טעינה מראש או אחסון במטמון חכם
**4. תבניות שאילתות לא אופטימליות**
שאילתות דמיון וקטורי לישויות אינן מאוחסנות במטמון בין בקשות דומות
ללא שמירת תוצאות במטמון לתבניות שאילתות חוזרות
חסרים אופטימיזציות שאילתות לתבניות גישה נפוצות
**5. בעיות קריטיות של חיי אובייקט (`rag.py:96-102`)**
**אובייקט GraphRag נוצר מחדש עבור כל בקשה**: מופע חדש נוצר עבור כל שאילתה, ומאבד את כל יתרונות האחסון במטמון
**אובייקט שאילתה בעל אורך חיים קצר ביותר**: נוצר ונהרס בתוך ביצוע שאילתה יחידה (שורות 201-207)
**מטמון תגיות מאופס עבור כל בקשה**: חימום מטמון וידע שנצבר הולכים לאיבוד בין בקשות
**תקורה של יצירת לקוח**: לקוחות מסד נתונים פוטנציאליים נוצרים מחדש עבור כל בקשה
**ללא אופטימיזציה חוצה בקשות**: לא ניתן להפיק תועלת מתבניות שאילתות או שיתוף תוצאות
>>>>>>> 82edf2d (New md files from RunPod)
### ניתוח השפעת ביצועים
תרחיש גרוע ביותר נוכחי עבור שאילתה טיפוסית:
<<<<<<< HEAD
**אחזור ישות**: שאילתת דמיון וקטורית אחת.
**מעבר גרפים**: entities × max_path_length × 3 × שאילתות triple_limit.
**פתרון תגיות**: 3 × שאילתות תגיות אישיות עבור גודל תת-גרף.
פלט חוזה (יש לעקוב אחר הפורמט המדויק).
עבור פרמטרים ברירת מחדל (50 ישויות, אורך נתיב 2, מגבלת 30 משולשים, גודל תת-גרף 150):
=======
**שליפת ישות**: שאילתה אחת לדמיון וקטורי
**מעבר גרפים**: entities × max_path_length × 3 × שאילתות triple_limit
**פתרון תגיות**: 3 × שאילתות אישיות לגודל תת-גרף
פלט חוזה (יש לעקוב אחר הפורמט המדויק).
עבור פרמטרים ברירת מחדל (50 ישויות, אורך נתיב 2, מגבלת טריפל של 30, גודל תת-גרף של 150):
>>>>>>> 82edf2d (New md files from RunPod)
**מספר שאילתות מינימלי**: 1 + (50 × 2 × 3 × 30) + (150 × 3) = **9,451 שאילתות למסד נתונים**
**זמן תגובה**: 15-30 שניות עבור גרפים בגודל בינוני
**שימוש בזיכרון**: צמיחה בלתי מוגבלת של מטמון לאורך זמן
**יעילות מטמון**: 0% - המטמון מאופס בכל בקשה
**תקורה של יצירת אובייקטים**: אובייקטי GraphRag + שאילתה נוצרים/נמחקים עבור כל בקשה
מפרט זה מתייחס לפערים אלה על ידי יישום שאילתות באצווה, מטמון חכם ועיבוד מקבילי. על ידי אופטימיזציה של דפוסי שאילתות וגישה לנתונים, TrustGraph יכולה:
לתמוך בגרפי ידע בקנה מידה ארגוני עם מיליוני ישויות
לספק זמני תגובה של פחות משנייה עבור שאילתות טיפוסיות
לטפל במאות בקשות GraphRAG מקבילות
להתרחב ביעילות עם גודל ומורכבות הגרף
## עיצוב טכני
### ארכיטקטורה
אופטימיזציית הביצועים של GraphRAG דורשת את הרכיבים הטכניים הבאים:
#### 1. **שינוי ארכיטקטורה של משך חיי אובייקטים**
**הפוך את GraphRag לבעל חיים ארוך**: העבר את המופע של GraphRag לרמה של המעבד לצורך שמירה בין בקשות
**שמור על מטמון**: שמור על מטמון תוויות, מטמון הטבעות ומטמון תוצאות שאילתה בין בקשות
<<<<<<< HEAD
**אופטימיזציה של אובייקט שאילתה**: שנה את מבנה אובייקט השאילתה כהקשר ביצוע קל משקל, ולא כמכל נתונים
=======
**אופטימיזציה של אובייקט שאילתה**: שנה את מבנה אובייקט השאילתה כך שיהיה הקשר ביצוע קל משקל, ולא מיכל נתונים
>>>>>>> 82edf2d (New md files from RunPod)
**שמירה על חיבורים**: שמור על חיבורי לקוח למסד הנתונים בין בקשות
מודול: `trustgraph-flow/trustgraph/retrieval/graph_rag/rag.py` (עודכן)
#### 2. **מנוע מעבר גרפים מותאם**
החלף את `follow_edges` רקורסיבי בחיפוש רוחב-ראשוני איטרטיבי
<<<<<<< HEAD
הטמעת עיבוד אצווה של ישויות בכל רמת מעבר
הוסף זיהוי מעגלים באמצעות מעקב אחר צמתים מבקרים
כלול סיום מוקדם כאשר מגיעים למגבלות
=======
הטמע עיבוד אצווה של ישויות בכל רמת מעבר
הוסף זיהוי מעגלים באמצעות מעקב אחר צמתים שנצפו
כלול סיום מוקדם כאשר מגיעים לגבולות
>>>>>>> 82edf2d (New md files from RunPod)
מודול: `trustgraph-flow/trustgraph/retrieval/graph_rag/optimized_traversal.py`
#### 3. **מערכת פתרון תוויות מקבילה**
שאילתות תוויות באצווה עבור מספר ישויות בו-זמנית
<<<<<<< HEAD
הטמעת דפוסי async/await לגישה מקבילה למסד הנתונים
=======
הטמע דפוסי async/await לגישה מקבילה למסד הנתונים
>>>>>>> 82edf2d (New md files from RunPod)
הוסף אחזור מוקדם לדפוסי תוויות נפוצים
כלול אסטרטגיות חימום מטמון תוויות
מודול: `trustgraph-flow/trustgraph/retrieval/graph_rag/label_resolver.py`
#### 4. **שכבת מטמון תוויות שמרנית**
מטמון LRU עם TTL קצר עבור תוויות בלבד (5 דקות) כדי לאזן בין ביצועים ועקביות
ניטור מדדי מטמון ויחס פגיעות
**ללא מטמון הטבעות**: כבר שמורים עבור כל שאילתה, אין יתרון בין שאילתות
**ללא מטמון תוצאות שאילתה**: עקב חששות לגבי עקביות שינוי גרף
מודול: `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]
```
גישה זו מאפשרת:
<<<<<<< HEAD
זיהוי יעיל של מעגלים באמצעות מעקב אחר ישויות שביקרו
הכנת שאילתות באצווה בכל רמת מעבר
ניהול מצב חסכוני בזיכרון
סיום מוקדם כאשר מגיעים למגבלות גודל
=======
זיהוי יעיל של מעגלים באמצעות מעקב אחר ישויות שכבר נבדקו.
הכנת שאילתות בקבוצות בכל רמת מעבר.
ניהול מצב חסכוני בזיכרון.
סיום מוקדם כאשר מגבלות גודל הושגו.
>>>>>>> 82edf2d (New md files from RunPod)
#### מבנה מטמון משופר
```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 חדשים:
**ממשק GraphTraversal API**
```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]
```
**ממשק ניהול מטמון (Cache Management 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** - שופרה לעיבוד באצווה:
החלף עיבוד ישויות בודדות בפעולות באצווה
הוסף מנהלי הקשר אסינכרוניים לניקוי משאבים
הוסף פונקציות החזרה (callbacks) להתקדמות עבור פעולות ארוכות
### פרטי יישום
#### שלב 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
```
<<<<<<< HEAD
**זמן תגובה מקסימלי ומנגנון ניתוב מחדש:**
=======
**מגבלת זמן שאילתה ומנגנון ניתוב:**
>>>>>>> 82edf2d (New md files from RunPod)
```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")
```
## שיקולים בנוגע לעקביות מטמון
<<<<<<< HEAD
**פשרות בנוגע לרעננות נתונים:**
**מטמון תוויות (TTL של 5 דקות)**: סיכון להצגת תוויות של ישויות שנמחקו/ששמותיהן שונו.
**ללא שמירת מטמון של הטמעות (embeddings)**: לא נדרש - הטמעות כבר שמורות מטמון עבור כל שאילתה.
**ללא שמירת מטמון של תוצאות**: מונע קבלת תוצאות תת-גרף לא עדכניות מישויות/קשרים שנמחקו.
=======
**פשרות בין רעננות נתונים:**
**מטמון תוויות (TTL של 5 דקות)**: סיכון בהצגת תוויות של ישויות שנמחקו/ששמותיהן שונו.
**ללא שמירת מטמון של הטמעות (embeddings)**: לא נדרש - הטמעות כבר שמורות מטמון עבור כל שאילתה.
**ללא שמירת מטמון של תוצאות**: מונע תוצאות תת-גרף שגויות מישויות/קשרים שנמחקו.
>>>>>>> 82edf2d (New md files from RunPod)
**אסטרטגיות הפחתה:**
**ערכי TTL שמרניים**: איזון בין שיפורי ביצועים (10-20%) לבין רעננות נתונים.
**מנגנוני ביטול מטמון**: שילוב אופציונלי עם אירועי שינוי בגרף.
<<<<<<< HEAD
**לוחות מחוונים לניטור**: מעקב אחר אחוזי פגיעה במטמון (cache hit rates) לעומת מקרים של נתונים לא עדכניים.
**מדיניות מטמון הניתנות לתצורה**: אפשרות לכוונון פר-פריסה בהתאם לתדירות השינויים.
**תצורת מטמון מומלצת בהתאם לקצב שינויים בגרף:**
**קצב שינויים גבוה (>100 שינויים/שעה)**: TTL=60 שניות, גדלי מטמון קטנים יותר.
**קצב שינויים בינוני (10-100 שינויים/שעה)**: TTL=300 שניות (ברירת מחדל).
**קצב שינויים נמוך (<10 שינויים/שעה)**: TTL=600 שניות, גדלי מטמון גדולים יותר.
## שיקולים בנוגע לאבטחה
**מניעת הזרקת שאילתות:**
אימות כל מזהי ישויות ופרמטרים של שאילתות.
שימוש בשאילתות מפורמטות עבור כל אינטראקציות עם מסד הנתונים.
יישום מגבלות על מורכבות השאילתות כדי למנוע התקפות מניעת שירות (DoS).
**הגנה על משאבים:**
אכיפת מגבלות על גודל תת-גרף מקסימלי.
יישום זמני קצבה לשאילתות כדי למנוע מיצוי משאבים.
הוספת ניטור מגבלות לשימוש בזיכרון.
=======
**לוחות מחוונים לניטור**: מעקב אחר שיעורי פגיעות במטמון לעומת מקרים של נתונים לא מעודכנים.
**מדיניות מטמון הניתנות לתצורה**: אפשרות לכוונון עדין בהתאם לתדירות השינויים בכל פריסה.
**תצורת מטמון מומלצת בהתאם לקצב שינויים בגרף:**
**שינויים רבים (>100 שינויים/שעה)**: TTL=60 שניות, גדלי מטמון קטנים יותר.
**שינויים בינוניים (10-100 שינויים/שעה)**: TTL=300 שניות (ברירת מחדל).
**שינויים מעטים (<10 שינויים/שעה)**: TTL=600 שניות, גדלי מטמון גדולים יותר.
## שיקולים בנושא אבטחה
**מניעת הזרקת שאילתות:**
אימות כל מזהי ישויות ופרמטרים של שאילתות.
שימוש בשאילתות מפורטות עבור כל אינטראקציות עם מסד הנתונים.
יישום מגבלות מורכבות שאילתות למניעת התקפות מניעת שירות (DoS).
**הגנה על משאבים:**
אכיפת מגבלות גודל תת-גרף מקסימלי.
יישום זמני קצבי שאילתות למניעת מיצוי משאבים.
הוספת ניטור מגבלות שימוש בזיכרון.
>>>>>>> 82edf2d (New md files from RunPod)
**בקרת גישה:**
שמירה על בידוד משתמשים ואוספים קיימים.
הוספת רישום ביקורת עבור פעולות המשפיעות על הביצועים.
יישום הגבלת קצב עבור פעולות יקרות.
<<<<<<< HEAD
## שיקולים בנוגע לביצועים
=======
## שיקולים בנושא ביצועים
>>>>>>> 82edf2d (New md files from RunPod)
### שיפורי ביצועים צפויים
**הפחתת מספר שאילתות:**
נוכחי: ~9,000+ שאילתות עבור בקשה טיפוסית.
אופטימלי: ~50-100 שאילתות מקובצות (הפחתה של 98%).
**שיפורי זמן תגובה:**
מעבר בגרף: 15-20 שניות → 3-5 שניות (מהיר פי 4-5).
פתרון תוויות: 8-12 שניות → 2-4 שניות (מהיר פי 3).
שאילתה כוללת: 25-35 שניות → 6-10 שניות (שיפור של פי 3-4).
**יעילות זיכרון:**
גדלי מטמון מוגבלים מונעים דליפות זיכרון.
מבני נתונים יעילים מפחיתים את טביעת הרגל של הזיכרון בערך ב-40%.
איסוף אשפה טוב יותר באמצעות ניקוי משאבים נכון.
**ציפיות ריאליות בנוגע לביצועים:**
<<<<<<< HEAD
**מטמון תוויות**: הפחתה של 10-20% במספר השאילתות עבור גרפים עם קשרים נפוצים.
**אופטימיזציה של קיבוץ**: הפחתה של 50-80% במספר השאילתות (אופטימיזציה עיקרית).
=======
**מטמון תוויות**: הפחתת שאילתות ב-10-20% עבור גרפים עם קשרים נפוצים.
**אופטימיזציה של קיבוץ**: הפחתת שאילתות ב-50-80% (אופטימיזציה עיקרית).
>>>>>>> 82edf2d (New md files from RunPod)
**אופטימיזציה של חיי אובייקט**: ביטול תקורה של יצירה מחדש בכל בקשה.
**שיפור כולל**: שיפור של פי 3-4 בזמן התגובה בעיקר בזכות קיבוץ.
**שיפורי יכולת הרחבה:**
תמיכה בגרפי ידע גדולים פי 3-5 (מוגבל על ידי צרכי עקביות מטמון).
קיבולת גבוהה יותר פי 3-5 של בקשות מקבילות.
ניצול טוב יותר של משאבים באמצעות שימוש חוזר בחיבורים.
### ניטור ביצועים
**מדדים בזמן אמת:**
זמני ביצוע שאילתות לפי סוג פעולה.
<<<<<<< HEAD
אחוזי פגיעה במטמון ויעילות.
שימוש בבריכת חיבורים למסד הנתונים.
=======
שיעורי פגיעה ויעילות של מטמון.
שימוש בבריכת חיבורי מסד נתונים.
>>>>>>> 82edf2d (New md files from RunPod)
שימוש בזיכרון והשפעת איסוף אשפה.
**בדיקות ביצועים:**
בדיקות רגרסיה אוטומטיות לביצועים
בדיקות עומסים עם נפחי נתונים ריאליים
השוואות ביצועים מול המימוש הנוכחי
## אסטרטגיית בדיקות
### בדיקות יחידה
<<<<<<< HEAD
בדיקת רכיבים בודדים עבור מעבר, אחסון במטמון ופתרון תגיות
הדמיית אינטראקציות עם מסד נתונים לצורך בדיקות ביצועים
בדיקת פינוי מטמון ותפוגה של זמן תפוגה (TTL)
=======
בדיקת רכיבים בודדים עבור מעבר, אחסון במטמון ופתרון תוויות
הדמיית אינטראקציות עם מסד נתונים לצורך בדיקות ביצועים
בדיקת פינוי מטמון ותפוגת זמן (TTL)
>>>>>>> 82edf2d (New md files from RunPod)
בדיקת טיפול בשגיאות ותסריטי תזמון
### בדיקות אינטגרציה
בדיקות מקצה לקצה של שאילתות GraphRAG עם אופטימיזציות
בדיקת אינטראקציות עם מסד נתונים עם נתונים אמיתיים
טיפול בבקשות מקבילות וניהול משאבים
<<<<<<< HEAD
זיהוי דליפות זיכרון ואימות ניקוי משאבים
=======
זיהוי דליפות זיכרון ובדיקת ניקוי משאבים
>>>>>>> 82edf2d (New md files from RunPod)
### בדיקות ביצועים
בדיקות ביצועים מול המימוש הנוכחי
בדיקות עומסים עם גדלים ומורכבויות גרף משתנים
בדיקות לחץ עבור מגבלות זיכרון וחיבורים
בדיקות רגרסיה לשיפורי ביצועים
### בדיקות תאימות
אימות תאימות של ממשקי API קיימים של GraphRAG
בדיקה עם מנועי גרפים שונים
אימות דיוק התוצאות בהשוואה למימוש הנוכחי
## תוכנית יישום
### גישת יישום ישירה
<<<<<<< HEAD
מכיוון שמותר לשנות ממשקי API, ליישם אופטימיזציות ישירות ללא מורכבות של העברה:
1. **החלפת `follow_edges`:** כתיבה מחדש עם מעבר אצווה איטרטיבי
2. **אופטימיזציה של `get_labelgraph`:** יישום פתרון תגיות מקבילי
3. **הוספת GraphRag ארוך טווח:** שינוי של מעבד כדי לשמור על מופע קבוע
4. **יישום אחסון במטמון של תגיות:** הוספת מטמון LRU עם TTL למחלקת GraphRag
### היקף השינויים
**מחלקה של שאילתות:** החלפת כ-50 שורות ב-`follow_edges`, הוספת כ-30 שורות לטיפול באצווה
**מחלקה של GraphRag:** הוספת שכבת אחסון במטמון (כ-40 שורות)
**מחלקה של מעבד:** שינוי לשימוש במופע קבוע של GraphRag (כ-20 שורות)
=======
מכיוון שמותר לשנות ממשקי API, ליישם אופטימיזציות ישירות ללא מורכבות של מעבר:
1. **החלפת `follow_edges`:** כתיבה מחדש עם מעבר אצווה איטרטיבי
2. **אופטימיזציה של `get_labelgraph`:** יישום פתרון תוויות מקבילי
3. **הוספת GraphRag ארוך טווח:** שינוי של Processor לשמירה על מופע קבוע
4. **יישום אחסון תוויות במטמון:** הוספת מטמון LRU עם TTL למחלקת GraphRag
### היקף השינויים
**מחלקת שאילתה:** החלפת כ-50 שורות ב-`follow_edges`, הוספת כ-30 שורות לטיפול באצווה
**מחלקת GraphRag:** הוספת שכבת אחסון במטמון (כ-40 שורות)
**מחלקת Processor:** שינוי לשימוש במופע קבוע של GraphRag (כ-20 שורות)
>>>>>>> 82edf2d (New md files from RunPod)
**סה"כ:** כ-140 שורות של שינויים ממוקדים, בעיקר בתוך מחלקות קיימות
## ציר זמן
**שבוע 1: יישום ליבה**
החלפת `follow_edges` עם מעבר אצווה איטרטיבי
<<<<<<< HEAD
יישום פתרון תגיות מקבילי ב-`get_labelgraph`
הוספת מופע GraphRag ארוך טווח למעבד
יישום שכבת אחסון במטמון של תגיות
=======
יישום פתרון תוויות מקבילי ב-`get_labelgraph`
הוספת מופע GraphRag ארוך טווח ל-Processor
יישום שכבת אחסון במטמון
>>>>>>> 82edf2d (New md files from RunPod)
**שבוע 2: בדיקות ושילוב**
בדיקות יחידה ללוגיקה חדשה של מעבר ואחסון במטמון
בדיקות ביצועים מול המימוש הנוכחי
בדיקות אינטגרציה עם נתוני גרף אמיתיים
סקירת קוד ואופטימיזציה
**שבוע 3: פריסה**
פריסת המימוש המותאם
ניטור שיפורי ביצועים
כוונון עדין של זמן תפוגה של מטמון וגדלי אצווה בהתבסס על שימוש אמיתי
## שאלות פתוחות
**בריכת חיבורים למסד נתונים:** האם עלינו ליישם בריכת חיבורים מותאמת אישית או להסתמך על בריכת חיבורים קיימת של לקוח מסד נתונים?
<<<<<<< HEAD
**שימור מטמון:** האם מטמון התגיות וההטבעות צריך להתמיד בין הפעלות מחדש של השירות?
**אחסון במטמון מבוזר:** עבור פריסות מרובות מופעים, האם עלינו ליישם אחסון במטמון מבוזר עם Redis/Memcached?
**פורמט תוצאות שאילתה:** האם עלינו לייעל את הייצוג הפנימי של משולש לטובת יעילות זיכרון טובה יותר?
**שילוב ניטור:** אילו מדדים יש לחשוף למערכות ניטור קיימות (Prometheus, וכו')?
=======
**שימור מטמון:** האם מטמון תוויות ו-embedding צריך להתמיד בין הפעלות מחדש של השירות?
**אחסון מבוזר:** עבור פריסות מרובות מופעים, האם עלינו ליישם אחסון מבוזר עם Redis/Memcached?
**פורמט תוצאות שאילתה:** האם עלינו לייעל את הייצוג הפנימי של משולש לטובת יעילות זיכרון טובה יותר?
**שילוב ניטור:** אילו מדדים צריכים להיות חשופים למערכות ניטור קיימות (Prometheus, וכו')?
>>>>>>> 82edf2d (New md files from RunPod)
## הפניות
[מימוש מקורי של GraphRAG](trustgraph-flow/trustgraph/retrieval/graph_rag/graph_rag.py)
[עקרונות ארכיטקטורה של TrustGraph](architecture-principles.md)
[מפרט ניהול אוספים](collection-management.md)