mirror of
https://github.com/trustgraph-ai/trustgraph.git
synced 2026-04-25 16:36:21 +02:00
808 lines
42 KiB
Markdown
808 lines
42 KiB
Markdown
|
|
---
|
|||
|
|
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)
|