ארגון זיכרון לפי סוג מפחית את כמות הטוקנים שנשלפים בכ-40%.
למה מאגר זיכרון שטוח קורס
רוב המדריכים למתחילים מלמדים סוכן LLM "לזכור" על ידי הוספת כל פיסת מידע חדשה לרשימה אחת והזנת הרשימה הזו חזרה למודל בכל תור. הקוד הוא באמת באורך של שלוש שורות בלבד, והוא מייצר דמו עובד. בפועל, הרשימה גדלה ללא בקרה. שני תסמינים מופיעים:
- הסוכן מתייחס לנתונים מיושנים כאילו הם עדיין נכונים, למשל מספק זמן הגעה משוער (ETA) שפג תוקפו לפני שעות.
- חלון ההקשר (context window) מתמלא בפרטים טריוויאליים שמעולם לא משפיעים על התשובה, מה שמנפח את עלויות ה-API ומאט את זמני התגובה.
מאגר וקטורי (vector store) רגיל או מטמון (cache) פשוט מסוג key-value לא יכולים להבחין בין הגדרת תפקיד של משתמש לבין סטטוס זמני של פרויקט. כאשר הסוכן מריץ חיפוש סמנטי, אלגוריתם הדמיון עשוי להציף ETA ישן פשוט כי השאילתה מכילה את אותן מילים, למרות שהנתון כבר אינו רלוונטי.
זיכרון מובנה: ארבעה דליים, מטרה אחת
הפתרון הוא להפסיק להתייחס לזיכרון כאל מונוליט ולהתחיל לסווג כל רשומה לאחת מארבע קטגוריות:
- עובדות משתמש (User facts) – מאפיינים יציבים כגון תפקיד המשתמש, שפה מועדפת או רמת סיווג ביטחונית. אלו משתנים לעיתים רחוקות וניתן לשמור אותם במטמון לאורך כל הסשן.
- משוב (Feedback) – כללים מפורשים שהסוכן חייב לציית להם, למשל "לעולם אל תחשוף סיסמאות למסד נתונים" או "הימנע מהומור בשאילתות ציות". מכיוון שהם שולטים בהתנהגות, הם שייכים ל-system prompt ולא למאגר הניתן לחיפוש.
- מצב פרויקט (Project state) – נתונים דינמיים כמו ETAs נוכחיים, התקדמות משימות או טוקנים זמניים. לדלי זה נדרשת בדיקת תוקף; ברגע שחותמת זמן (timestamp) יוצאת מטווח מוגדר, יש למחוק את הרשומה.
- התייחסויות (References) – מצביעים לשירותים חיצוניים, מזהי מסמכים או נקודות קצה של API. הם אינם תוכן שצריך להציג, אלא נתיבים לשליפת נתונים טריים בעת הצורך.
Mem0 מאפשרת למפתחים לצרף מטא-דאטה שרירותי לכל רשומת זיכרון. באמצעות אינדוקס על שדה ה-"kind", שאילתה יכולה תחילה לסנן את הדלי הרלוונטי לפני שה-LLM מחליט כיצד להשתמש בתוצאה.
שליפה בשני שלבים עם Mem0
- שליפת זיכרונות לפי סוג (kind) – שאילתת סינון קצרה מבקשת מ-Mem0 "את כל המשוב" או "רשומות מצב-פרויקט חדשות יותר מטווח זמן קצר". סט התוצאות כבר מכווץ לקטגוריה המתאימה.
- לתת ל-LLM להחליט – קטעי הטקסט המסוננים מוכנסים לתוך ה-prompt יחד עם שאלת המשתמש הנוכחית. כעת המודל יכול להסיק מסקנות לגביהם מבלי לנבור בעובדות לא רלוונטיות.
דוגמה קונקרטית: במקום לחכות שחיפוש סמנטי יציף את הכלל "אל תלעג למסד הנתונים", המפתח מזריק את הכלל הזה ישירות ל-system prompt בתחילת הסשן ושומר אותו במטמון לכל אורך האינטראקציה. גם אם בשאילתת המשתמש אין התייחסות מפורשת למסדי נתונים, המודל כבר מכיר את המגבלה.
טריקים פרקטיים לשמירה על עלויות נמוכות
- שמירת כללי משוב במטמון (Cache) – שמירת סט הכללים פעם אחת בכל סשן ושימוש חוזר בו במקום לבצע חיפוש מחדש בכל תור. זה מפחית את צריכת הטוקנים בכל סבב.
- דילוג על חיפושי מצב-פרויקט כשאינם רלוונטיים – אם המשתמש שואל שאלה קונספטואלית טהורה ("מה ההבדל בין למידה מונחית לבין למידת חיזוק?"), אין צורך לשלוף נתוני ETA או התקדמות משימות.
על ידי יישום שתי ההרגלים הללו, ניתן להפחית את צריכת הטוקנים בכ-40% בהשוואה לגישת זיכרון שטוח נאיבית. החיסכון מתרגם ישירות לחשבונות API נמוכים יותר ולזמן תגובה מהיר יותר, במיוחד עבור סוכנים הפועלים לאורך חילופים רבים.
מי מרוויח, ומי דואג
המנצחים – צוותים שבונים בוטים לתמיכה בלקוחות, עוזרי תזרים עבודה פנימיים, או כל ממשק LLM מרובה-תורים. הם מקבלים תשובות אמינות יותר, נמנעים מטעויות מביכות שנגרמו מנתונים מיושנים, ומנצלים את התקציב שלהם בצורה יעילה יותר.
שורה תחתונה
אם אתם רוצים סוכן LLM שנשאר חד לאורך סשנים ארוכים, הפסיקו לדחוס כל עובדה לחלון הקשר יחיד. תייגו כל זיכרון כעובדת משתמש, משוב, מצב פרויקט או התייחסות, אכידו תוקף במידת הצורך, ותנו לכלי כמו Mem0 לעשות את העבודה הקשה. התוצאה היא תשובות טריות יותר, פחות טוקנים מיותרים וקיצוץ ניכר בעלויות התפעול.