Just-in-Time Context — טעינת מידע רק ברגע שבו הוא נדרש
מאת צוות מדיה דיל · 12.08.2026 · Context Engineering · 5 דק׳
למה טעינה מוקדמת של כל המידע האפשרי פוגעת בביצועים ובעלות, ואיך בונים סוכן ששולף מידע רק ברגע שהוא באמת דרוש להחלטה.
סוכן תמיכה פנימי שנבנה עבור צוות משפטי קיבל בהתחלה גישה "בטוחה": בכל תחילת שיחה, להטעין למודל את כל מדיניות החברה, את כל תבניות החוזים, ואת ההיסטוריה המלאה של פניות דומות — "כדי שיהיה לו הכל". התוצאה הייתה סוכן שעונה לאט, יקר להפעלה, ולעיתים קרובות מתבלבל בין מדיניות שרלוונטית לפנייה הספציפית לבין מדיניות ממחלקה אחרת שנטענה "ליתר ביטחון". הפתרון לא היה להוסיף עוד סינון מראש, אלא לשנות גישה לגמרי: Just-in-Time Context — לתת לסוכן לשלוף רק את מה שהוא צריך, ברגע שהוא מבין שהוא צריך אותו, במקום לדחוף הכל מראש "ליתר ביטחון".
eager loading מול lazy retrieval
הגישה המסורתית ל-RAG היא eager: לפני שהמודל בכלל ראה את השאלה, כבר מריצים חיפוש, שולפים k מסמכים, ותופרים אותם לתוך ה-prompt. זה עובד סביר כשברור מראש מה סוג המידע שיידרש, אבל נשבר במשימות מורכבות שבהן מה שצריך לחפש תלוי בתשובת ביניים. Just-in-Time מהפך את הסדר: נותנים למודל כלי חיפוש (search, read_file, query_db) ומאפשרים לו להחליט בעצמו, תוך כדי הריצה, מה לשלוף ומתי. זה בדיוק הדפוס שמאחורי סוכני קידוד מודרניים שבמקום לקבל את כל בסיס הקוד בהקשר, משתמשים בכלים כמו grep ו-glob כדי לאתר את הקובץ הרלוונטי בזמן אמת ולקרוא רק אותו.
היתרון הכפול הוא גם בעלות וגם באיכות: פחות טוקנים נשלחים בממוצע, וגם — בהתאם למה שנדון במאמר על Context Rot — פחות "רעש" מצטבר בהקשר שמדלל את תשומת הלב של המודל לחלקים הרלוונטיים באמת.
מתי JIT לא עדיף
הבעיה המרכזית ב-JIT היא latency: כל שליפה בזמן ריצה היא round-trip נוסף — קריאת כלי, המתנה לתוצאה, וקריאה חוזרת למודל. במשימות שבהן ברור מראש בוודאות גבוהה מה יידרש (למשל system prompt קבוע, או תבנית תגובה סטנדרטית), טעינה מוקדמת עדיין עדיפה כי היא חוסכת סבב שלם. הכלל המעשי: מידע יציב וצפוי נטען מראש; מידע שתלוי בתוכן השיחה או משתנה לפי הקשר משימתי נשלף לפי דרישה. שילוב נכון בין השניים דורש הבנה טובה של תבניות השימוש בפועל, לא רק החלטה עקרונית אחת שחלה על הכל.
ההשפעה על Prompt Caching
נקודה שקל לפספס: JIT retrieval יכול לפגוע ביעילות ה-caching אם לא בונים אותו נכון. מנגנוני prompt caching מבוססים על כך שהחלק הראשוני של ההקשר נשאר זהה בין קריאות עוקבות — כל שינוי בתחילת ה-prompt מבטל את ה-cache עבור כל מה שאחריו. אם תוצאות שליפה שמתקבלות דינמית מוכנסות באמצע ההקשר הקבוע (למשל בין system prompt לכלים), כל תוצאה חדשה שוברת caching על השכבות שאחריה. הפתרון הארכיטקטוני הוא לשמור על סדר קבוע: system prompt וכלים בתחילת ההקשר (יציבים, cache-friendly), ותוצאות JIT מתווספות רק בסוף, אחרי כל מה שיציב.
const layout = [
systemPrompt, // יציב - cache hit
toolDefinitions, // יציב - cache hit
...jitRetrievals, // דינמי - נוסף בסוף
currentTurn
];
עיצוב כלי השליפה עצמם
הצלחת JIT תלויה במידה רבה באיכות הכלים שהמודל מקבל לשליפה, לא רק בעצם קיומם. כלי חיפוש עמום מדי (חיפוש טקסט חופשי בלבד) יגרום למודל לבצע ניסיונות שליפה מרובים וחוזרים על עצמם, מה שמבטל חלק מהיתרון. שילוב של חיפוש היברידי — שילוב חיפוש סמנטי ולקסיקלי — עם פרמטרים ברורים (סינון לפי סוג מסמך, טווח תאריכים, ID ספציפי) מאפשר למודל לצמצם את החיפוש בבת אחת במקום לגשש. חשוב גם להחזיר תוצאות בפורמט מובנה וקצר — לא לזרוק מסמך שלם כשהמודל ביקש פסקה אחת, כי זה חוזר לאותה בעיה של הצפת הקשר שניסינו למנוע מלכתחילה.
מדידת ROI בפועל
לפני שמשקיעים במעבר מ-eager ל-JIT, שווה למדוד את שיעור ה"בזבוז" בגישה הקיימת: כמה אחוז מהמידע שנטען מראש בפועל לא נזכר או לא בא לידי ביטוי בתשובה הסופית. אם המספר הזה נמוך (למשל 10%-15%), התועלת מ-JIT מוגבלת. אם הוא גבוה (50% ומעלה, מה שקורה לעיתים קרובות במערכות RAG "בטוחות מדי" שמושכות יותר מדי מראש), המעבר ל-JIT הוא בדרך כלל אחד השינויים הבודדים שמשפרים בו-זמנית עלות, latency ואיכות — קומבינציה נדירה שכדאי לזהות ולנצל.
דפוס ביניים: הצצה מקדימה קלה
בין eager מלא ל-JIT מלא קיים דפוס שימושי שכדאי להכיר: הצצה מקדימה קלה (light preview) שנטענת מראש רק כדי לעזור למודל להחליט אם בכלל שווה לשלוף עוד. במקום להטעין מסמך שלם או תוצאת חיפוש מלאה, טוענים מראש רק כותרות, תקצירים בני שורה אחת, או שמות קבצים — מספיק כדי שהמודל יוכל להחליט בעצמו אילו פריטים שווה להעמיק בהם דרך כלי שליפה מלא, ואילו אפשר להתעלם מהם. הגישה הזו מפחיתה משמעותית את מספר סבבי ה-round trip בהשוואה ל-JIT טהור, כי המודל לא צריך "לנחש בעיוורון" מה לחפש — יש לו רשימת מועמדים זולה מראש. זהו בעצם דפוס דו-שלבי: שלב זול וזריז שממפה את מרחב האפשרויות, ואחריו שלב יקר ומדויק שמעמיק רק במה שבאמת נבחר. במערכות עם כמות גדולה של מקורות פוטנציאליים (עשרות קבצים, מאות רשומות), הדפוס הזה נותן איזון טוב יותר מכל אחת מהגישות הטהורות בפני עצמה.
טיפול בכשלי שליפה חלקיים
נקודה שקל להזניח בתכנון: מה קורה כשקריאת JIT נכשלת באמצע — timeout ברשת, שירות חיצוני לא זמין, מסמך שנמחק בין רגע ההצצה לרגע השליפה המלאה. במערכת eager, כישלון כזה קורה לפני שהמודל בכלל מתחיל לעבוד, ואפשר לטפל בו בצורה מרוכזת בשכבה אחת. במערכת JIT, הכישלון קורה באמצע רצף חשיבה של המודל, ולכן חייב להיות מטופל בצורה שהמודל יכול להבין ולהגיב אליה — לא רק שגיאת מערכת גולמית, אלא הודעה מנוסחת שמסבירה שהמקור לא היה זמין, כדי שהמודל יוכל להחליט אם לנסות מקור חלופי, לדווח למשתמש על מגבלה, או להמשיך בלי הפרט החסר אם הוא לא קריטי. עיצוב כלי JIT בלי מסלול כישלון מפורש כזה גורם לעיתים קרובות למודל "להמציא" תשובה במקום להודות שהשליפה נכשלה — כי הוא לא קיבל אות ברור מספיק שמשהו השתבש, רק תוצאה ריקה או מעורפלת שהוא ניסה למלא בעצמו.
תגיות: Just-in-Time Context · RAG · Lazy Retrieval · Prompt Caching · Agent Tools