Hybrid Retrieval 2.0 — שילוב SQL, גרף ידע, חיפוש מילולי וסמנטי

מאת צוות מדיה דיל · 12.08.2026 · AI Retrieval · 5 דק׳

Hybrid Search קלאסי משלב חיפוש מילולי וסמנטי בלבד. הדור הבא משלב גם שאילתות SQL מבניות וטראברסל בגרף ידע — כאן נכנס לפרטי הארכיטקטורה, הניתוב וה-Fusion.

מערכת שירות לקוחות בחברת סחר אלקטרוני קיבלה שאלה שנשמעת פשוטה: "אילו לקוחות VIP פתחו קריאת שירות בנושא משלוחים ב-30 הימים האחרונים, ומה הם אמרו בשיחות התמיכה?". שאלה כזו לא ניתנת למענה על ידי מקור מידע יחיד. "לקוחות VIP" ו"30 הימים האחרונים" הם סינון מבני מובהק — עבודה בשבילה SQL נבנה. "מה הם אמרו" דורש חיפוש סמנטי בתמלולי שיחות. ו"קשר בין לקוח לקריאת שירות למוצר שהוזמן" הוא בעצם שאילתת גרף. Hybrid Search הקלאסי, שמשלב רק חיפוש מילולי וסמנטי, פשוט לא בנוי לסוג הבעיה הזה. זה המקום שבו נדרשת שכבת retrieval שיודעת לתזמר ארבעה סוגי מקורות שונים במקביל.

למה שני מקורות כבר לא מספיקים

המודל שהתבסס בשנים האחרונות — שילוב BM25 עם חיפוש וקטורי דרך Reciprocal Rank Fusion — פותר בעיה ספציפית: איזון בין התאמה מדויקת לבין דמיון סמנטי, כפי שמפורט במדריך Hybrid Search. אבל הוא מניח שכל המידע הרלוונטי יושב במסמכי טקסט חופשי. בפועל, מערכות ארגוניות אמיתיות מחזיקות מידע קריטי בשלוש צורות נוספות: נתונים מבניים בטבלאות relational (הזמנות, סטטוסי לקוח, מלאי) שדורשים SQL ולא retrieval טקסטואלי; קשרים בין ישויות (לקוח→הזמנה→מוצר→ספק) שמיוצגים טוב בהרבה כגרף מאשר כטקסט שטוח; וטקסט חופשי לא מובנה (תמלולים, מיילים, תיעוד) שם חיפוש מילולי וסמנטי עדיין המלך. מערכת שמתעלמת משלושת המקורות הראשונים ומנסה "לדחוף הכל ל-Vector DB" מאבדת דיוק ומבנה שכבר קיימים בנתונים.

שכבת ניתוב: מי מחליט מה לשאול איפה

הרכיב המרכזי בארכיטקטורת Hybrid Retrieval 2.0 הוא Query Router — שכבה שמנתחת את השאילתה הנכנסת ומחליטה אילו מקורות לתזמן, בסדר טור או מקביל. הניתוב יכול להתבסס על סיווג מבוסס-LLM ("איזה חלקים בשאלה הזו דורשים סינון מבני, ואילו דורשים חיפוש חופשי?") או על חוקים דטרמיניסטיים (שאילתה שמכילה תאריכים ומספרים מנותבת גם ל-SQL). במקרה שתיארנו למעלה, הניתוב הנכון הוא: (1) שאילתת SQL שמסננת לקוחות VIP עם קריאת שירות ב-30 הימים האחרונים ומחזירה רשימת מזהי קריאות; (2) חיפוש היברידי מילולי-סמנטי בתוך תמלולי אותן קריאות ספציפיות בלבד, לא בכל מאגר התמלולים; ו-(3) אופציונלית, טראברסל בגרף כדי להעשיר כל תוצאה בהקשר — איזה מוצר הוזמן, מה הסטטוס הנוכחי במחסן.

נקודה קריטית: השילוב הזה לא סימטרי. SQL בדרך כלל צריך לרוץ ראשון כדי לצמצם את מרחב החיפוש (scoping) — אין טעם להריץ חיפוש סמנטי יקר על כל מאגר התמלולים כשרק 40 קריאות שירות רלוונטיות מתוך 50,000. סדר הפעולות הזה הוא ההבדל בין שאילתה שרצה בעשרות מילישניות לשאילתה שרצה בשניות ארוכות ועולה הרבה יותר קריאות API.

Fusion בין מקורות הטרוגניים

כשמקורות תוצאות שונים כל כך במהותם — שורות טבלה מ-SQL, צמתים וקשתות מגרף, ומסמכי טקסט מדורגים — האתגר הוא לאחד אותם לתשובה קוהרנטית אחת. אי אפשר פשוט להשוות ציון ts_rank מ-Postgres עם ציון cosine similarity מחיפוש וקטורי; הסקאלות שונות לגמרי ולא ניתנות להשוואה ישירה. הפתרון המקובל הוא Reciprocal Rank Fusion (RRF) — במקום להשוות ציונים גולמיים, מסתכלים על הדירוג היחסי של כל תוצאה בתוך המקור שלה, ומחשבים ציון משוקלל: score = Σ 1 / (k + rank_i) על פני כל המקורות שבהם התוצאה הופיעה. שיטה כזו לא רגישה להבדלי סקאלה, וקל לכייל אותה עם משקלים שונים לכל מקור בהתאם לביטחון בו.

תוצאות מגרף ידע דורשות טיפול מיוחד ב-Fusion כי הן לרוב לא "מסמכים" אלא עובדות בודדות (triples) שצריך לנסח מחדש לטקסט קריא לפני שממזגים אותן עם תוצאות טקסטואליות אחרות. גישות GraphRAG עוסקות בדיוק בבעיה הזו — כיצד הופכים תת-גרף רלוונטי לקונטקסט טקסטואלי שמודל שפה יכול לצרוך יחד עם מסמכים רגילים, כמפורט במדריך GraphRAG ובמדריך ארכיטקטורת גרפי ידע.

מימוש מעשי: PostgreSQL כפלטפורמה מאוחדת

יתרון מעשי גדול שכדאי לשקול: PostgreSQL מודרני עם pgvector, tsvector, ותמיכה ב-recursive CTEs (שמאפשרת טראברסל גרף בסיסי) יכול לשרת שלושה מתוך ארבעת המקורות מתוך אותו מסד נתונים — בלי לתחזק שלוש מערכות נפרדות, בלי סנכרון בין מקורות, ובלי בעיות עקביות (consistency) שנוצרות כשנתונים מפוזרים בין שירותים. גרף ידע מורכב עם טראברסלים עמוקים עדיין יצדיק לרוב מסד ייעודי כמו Neo4j, אבל עבור רוב מקרי השימוש הארגוניים, איחוד סביב Postgres מפחית משמעותית את מורכבות התפעול. פירטנו את הגישה הזו במדריך pgvector.

מלכודות נפוצות במעבר לארכיטקטורה מרובת-מקורות

הטעות השכיחה ביותר היא לבנות את שכבת ה-Fusion כ"תוספת" בסוף הפיתוח, אחרי שכל מקור כבר בנוי ועובד בנפרד — מה שמוביל לממשקים לא-אחידים בין המקורות וקושי אמיתי לחבר אותם. עדיף להגדיר מראש חוזה אחיד (interface) שכל מקור מיישם: פונקציה שמקבלת שאילתה ומחזירה רשימת תוצאות בפורמט אחיד עם ציון, מקור, ומזהה — כך שהוספת מקור רביעי או חמישי בעתיד לא דורשת שינוי בשכבת ה-Fusion עצמה. טעות שנייה נפוצה היא הזנחת latency budget: כשמריצים ארבעה מקורות במקביל, זמן התגובה הכולל נקבע לפי המקור הכי איטי, לא לפי הממוצע — ולכן שאילתת SQL כבדה שלא מנוצלת (unindexed) יכולה להאט את כל התשובה גם אם שלושת המקורות האחרים חוזרים תוך מילישניות.

טעות שלישית, עדינה יותר, היא לתת לכל המקורות משקל שווה ב-Fusion בלי קשר לביטחון בהם. תוצאה שמגיעה משאילתת SQL מדויקת (סינון VIP לפי שדה בוליאני) אמינה יותר במהותה מתוצאה שמגיעה מדמיון סמנטי גבולי, ולכן שווה לתת למקורות מבניים משקל התחלתי גבוה יותר בנוסחת ה-RRF, ולכייל את המשקלים האלה אמפירית לפי ביצועים על סט הערכה אמיתי — לא להשאיר את כולם שווים כברירת מחדל.

טעות רביעית ואחרונה היא שכחת caching בשכבה הזו. מכיוון ששאילתה יחידה מפעילה עד ארבעה מקורות שונים במקביל, כל אחד מהם צריך שכבת cache עצמאית משלו — cache על תוצאות SQL, cache נפרד על תוצאות טראברסל גרף, וכן הלאה — כי דפוסי החזרתיות שונים מהותית בין המקורות. שאילתת SQL חוזרת פעמים רבות בדיוק באותה צורה (סינון VIP קבוע), בעוד שאילתה סמנטית כמעט אף פעם לא זהה מילה במילה, ולכן לכל מקור נדרשת אסטרטגיית caching נפרדת המותאמת לדפוס החזרתיות שלו, ולא מנגנון אחיד גורף שמניח שכל המקורות מתנהגים אותו הדבר.

תגיות: Hybrid Retrieval · Query Router · Reciprocal Rank Fusion · Knowledge Graph · SQL · GraphRAG

← חזרה לבלוג · צור קשר