רוב כשלונות הסוכנים כיום הם לא כשלונות של המודל - הם כשלונות של context.

- צוות Manus

התובנה המרכזית

Context הוא כמו זיכרון עבודה - יש לו גבולות

בדיוק כמו שאנחנו לא יכולים להחזיק 100 דברים בראש בו-זמנית, גם LLMs מתקשים עם context עמוס. כל token שמוסיפים מנצל “תקציב תשומת לב”.

המטרה: למצוא את קבוצת ה-tokens הקטנה ביותר עם האות הגבוה ביותר, שממקסמת את הסיכוי לתוצאה הרצויה.

”מינימלי” לא אומר קצר. זה אומר: רק מה שנחוץ, אבל כל מה שנחוץ.

איך Attention עובד

הבנת attention מסבירה למה הנדסת context חשובה כל כך.

מה זה Attention?

Transformers (הארכיטקטורה מאחורי Claude, GPT, וכו’) משתמשים במנגנון שנקרא attention. כל token ב-output “מסתכל” על כל ה-tokens ב-input ומחליט כמה משקל לתת לכל אחד.

עקומת ה-U של Attention

Attention לא אחיד לאורך ה-context. יש pattern מוכר:

עוצמת Attention לאורך ה-context:

HIGH ████████░░░░░░░░░░░░████████ HIGH
   ^ התחלה              סוף ^

LOW  ░░░░░░░░████████████░░░░░░░░
            ^ אמצע ^

התחלה (system prompt) - attention גבוה

אמצע (היסטוריה ישנה) - attention נמוך (“אבוד באמצע”)

סוף (הודעות אחרונות) - attention הכי גבוה

מה זה אומר לך

1. System prompt נקרא - הוא בהתחלה, מקבל attention

2. מידע באמצע “נבלע” - history ארוך = מידע חשוב הולך לאיבוד

3. הודעות אחרונות דומיננטיות - לכן Goal Repetition עובד!

4. יותר tokens = פחות attention לכל אחד - זה “תקציב ה-attention”

Goal Repetition עובד כי את דוחפת את המטרה לסוף ה-context, שם ה-attention הכי חזק.

ארבע הבעיות

בעיה 01

ריקבון Context

דיוק המודל יורד ככל שה-context גדל, גם בתוך הגבולות הנתמכים.

בעיה 02

סחף מטרה

אחרי הרבה קריאות ל-tools, המודל מאבד את המטרה המקורית.

בעיה 03

בלבול Context

יותר מדי tools יוצרים נקודות החלטה עמומות; המודל מתקשה לבחור.

בעיה 04

אבוד באמצע

מידע שקבור באמצע ה-context מקבל התעלמות או נשכח.

חמשת הפתרונות

1

הפרדה בין אחסון להצגה

מה ששומרים לצמיתות שונה ממה שהמודל רואה בכל קריאה.

2

Context בדיוק-בזמן

לטעון מידע כשצריך, לא מראש. לשמור הפניות קלות, לשלוף לפי דרישה.

3

דחיסה

לסכם במקום למחוק. לשמר החלטות ושגיאות, לוותר על פלטים מפורטים.

4

חזרה על המטרה

לחזור על המטרות בסוף ה-context כדי לשמור אותן בטווח תשומת הלב של המודל.

5

חשיפה היררכית של כלים

לארגן כלים לרמות. כלי ליבה תמיד זמינים; כלים מיוחדים נטענים לפי הקשר.

הדפוסים

איך ליישם כל פתרון, עם דוגמאות קוד:

דפוס 1 הפרדת אחסון מהצגה

מה ששומרים לצמיתות שונה ממה שהמודל רואה בכל קריאה. ההפרדה מאפשרת לפתח את האחסון וה-prompts בנפרד.

דוגמה

כלי הזיכרון שומרים קבצים ב-storage/. המודל לא טוען את כל הקבצים - הוא קורא ל-memory_view כשצריך מידע ספציפי.

// Storage (durable) - everything saved
const storage = {
  fullHistory: [...],      // all messages ever
  allToolResults: [...],   // every tool output
  userPreferences: {...}
}

// Presentation (per-call) - curated view
const context = {
  recentHistory: summarize(storage.fullHistory),
  relevantResults: filterByTask(storage.allToolResults),
  activeGoal: storage.currentTask
}

דפוס 2 Context בדיוק-בזמן

אל תטען הכל מראש “למקרה שיצטרך”. שמור מזהים קלים ושלוף תוכן כשבאמת צריך.

רע: טעינה מראש
system_prompt = f"""
Here is the entire codebase:
{read_all_files()}
"""
# 100K tokens wasted
טוב: טעינה לפי דרישה
system_prompt = """
Use Glob to find files.
Use Read to view them.
"""
# Files loaded only when needed
דוגמה: Claude Code

CLAUDE.md נטען בהתחלה (~500 tokens). אבל ה-codebase? נטען דרך Glob ו-Read רק כשהמשימה דורשת קבצים ספציפיים.

דפוס 3 אסטרטגיות דחיסה

כשה-context גדל מדי, צמצם אותו אסטרטגית תוך שמירה על מידע חיוני.

  • ניקוי תוצאות Tools: החלף פלטים מפורטים בסיכומים. “הקובץ נקרא ונותח” במקום 5000 tokens של קוד.
  • סיכום היסטוריה: דחס turns ישנים. שמור את 3 האחרונים גולמיים כדי לשמר “קצב”.
  • בידוד Sub-agents: העבר למשנה עם context נקי, קבל סיכום של 1-2K tokens.
// Instead of just deleting:
messages.shift()

// Summarize before removing:
const oldMessages = messages.splice(0, 10)
const summary = await summarize(oldMessages)
messages.unshift({ role: 'system', content: summary })

דפוס 4 חזרה על המטרה

אחרי 50 קריאות tools, המודל שוכח את המטרה המקורית. הילחם בזה על ידי חזרה מתמדת על המטרות בסוף ה-context.

איך Manus עושים את זה

כותבים מחדש את רשימת המשימות בסוף כל turn. זה דוחף את התוכנית הכללית ל”טווח תשומת הלב האחרון”, ומונע בעיות של “אבוד באמצע”.

// At session start:
memory_view("current_goals.md")

// After completing each task:
memory_str_replace(
  "current_goals.md",
  oldGoals,
  updatedGoals  // with completed items marked
)

דפוס 5 חשיפה היררכית של כלים

100+ כלים = בלבול context. המודל לא יכול להחליט במה להשתמש. הפתרון: לארגן כלים לרמות ולטעון אותם לפי הקשר.

// Tier 1: Core (always available) ~10 tools
const coreTools = [
  "Read", "Write", "Bash", "Grep", "WebSearch",
  "memory_view", "memory_create", "Task", "Skill"
]

// Tier 2: Domain-specific (load when detected)
const googleTools = [  // Load when "email", "calendar" detected
  "list_gmail", "send_gmail", "list_calendar", ...
]

// Dynamic loading:
if (userMessage.includes("gmail") || userMessage.includes("email")) {
  activeTools = [...coreTools, ...googleTools]
}

זה מצמצם את מרחב ההחלטה של הכלים מ-30 ל~10-15, מה שהופך את המודל להחלטי יותר.

דפוס 6 עקרונות עיצוב כלים

כלים מעוצבים היטב מפחיתים עומס context ומורכבות החלטות.

  • עצמאי: בלי תלויות נסתרות ב-state. כל כלי עובד בנפרד.
  • החזרות יעילות ב-tokens: מחזיר את המינימום הנדרש. לא כל הקובץ, רק החלק הרלוונטי.
  • תיאורים ברורים: אם אדם לא יכול להחליט באיזה כלי להשתמש, גם המודל לא.
  • ללא חפיפה: לכל כלי מטרה ייחודית. אין שני כלים שעושים אותו דבר.
דוגמה טובה

archive_gmail לעומת trash_gmail - שני כלים נפרדים עם מטרות ברורות ולא חופפות.

דוגמה רעה (היפותטית)

delete_email, remove_email, trash_email - שלושה כלים שעושים אותו דבר. המודל יתבלבל.

טעויות נפוצות

זיהום Context

טעינת הכל “למקרה שיצטרך” - מציף את המודל במידע לא רלוונטי.

הרעבת Context

קיצוץ אגרסיבי מדי - למודל חסר מידע לקבל החלטות טובות.

סחף מטרה

אי-חזרה על המטרות - המודל נודד מהמשימה המקורית אחרי הרבה turns.

פיצוץ כלים

הוספת כלי לכל פונקציה - יוצר שיתוק החלטות ובלבול context.


מקורות: