trustgraph/docs/tech-specs/graphrag-performance-optimization.he.md
Alex Jenkins 8954fa3ad7 Feat: TrustGraph i18n & Documentation Translation Updates (#781)
Native CLI i18n: The TrustGraph CLI has built-in translation support
that dynamically loads language strings. You can test and use
different languages by simply passing the --lang flag (e.g., --lang
es for Spanish, --lang ru for Russian) or by configuring your
environment's LANG variable.

Automated Docs Translations: This PR introduces autonomously
translated Markdown documentation into several target languages,
including Spanish, Swahili, Portuguese, Turkish, Hindi, Hebrew,
Arabic, Simplified Chinese, and Russian.
2026-04-14 12:08:32 +01:00

42 KiB
Raw Blame History

layout title parent
default מפרט טכני לשיפור ביצועי GraphRAG 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

מודלים של נתונים

מצב מעבר גרפים מותאם

מנוע המעבר שומר על מצב כדי להימנע מפעולות מיותרות:

@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)

מבנה מטמון משופר

@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 חדשים:

ממשק GraphTraversal API

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]

ממשק ניהול מטמון (Cache Management 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 - שופרה לעיבוד באצווה: החלף עיבוד ישויות בודדות בפעולות באצווה הוסף מנהלי הקשר אסינכרוניים לניקוי משאבים הוסף פונקציות החזרה (callbacks) להתקדמות עבור פעולות ארוכות

פרטי יישום

שלב 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

<<<<<<< HEAD זמן תגובה מקסימלי ומנגנון ניתוב מחדש:

מגבלת זמן שאילתה ומנגנון ניתוב:

82edf2d (New md files from RunPod)

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 מפרט ניהול אוספים