Context engineering היא הפרקטיקה של להחליט על כל מה שמודל שפה רואה כשהוא עונה: לא רק השאלה שאתם מקלידים, אלא גם ההוראות שמסביבה, המסמכים ותוצאות הכלים שמוכנסים אליה, הזיכרון השמור על המשתמש והשיחה עד עכשיו. כל זה חולק חלון הקשר אחד, והמודל עונה מתוך הטקסט הזה ותו לא. המונח התפשט ב-2025, כשיותר מוצרי AI הפכו לסוכנים שמרכיבים את רוב ההקשר שלהם אוטומטית.
Prompt engineering עוסקת בעיקר באיך לנסח בקשה. Context engineering עוסקת במה צריך להיות מול המודל בכל קריאה, ובאיזה סדר.
מפרומפט להקשר
באפליקציית צ'אט אתם כותבים את רוב ההקשר בעצמכם: האפליקציה מוסיפה פרומפט מערכת ואת ההיסטוריה, ואתם מוסיפים את השאר. באפליקציה שבנויה על מודל המאזן מתהפך. משתמש מקליד משפט אחד, והקוד שמסביב למודל מוסיף הוראות, פרופיל משתמש, שלושה מאמרי עזרה שנמצאו בחיפוש, את רשימת הכלים הזמינים ואת הפלט של הקריאה האחרונה לכלי. המשפט של המשתמש יכול להיות חלק קטן ממה שהמודל קורא.
כשמערכת כזו עונה רע, התיקון נמצא רק לעיתים רחוקות בניסוח. הסיבה הרגילה היא שלמודל היה החומר הלא נכון: עובדה חסרה, תוצאת כלי מיושנת, מסמך לא רלוונטי שנראה רלוונטי לחיפוש.
מה נכנס לחלון ההקשר
קריאה טיפוסית באפליקציית AI מכילה חלק מהדברים האלה או את כולם, בערך בסדר הזה:
- הוראות מערכת: התפקיד, הכללים ופורמט הפלט, בדרך כלל קבועים לכל האפליקציה. ראו פרומפטים של מערכת.
- הגדרות כלים: שמות, תיאורים ופרמטרים של הכלים שהמודל רשאי לקרוא להם.
- דוגמאות: כמה קלטים ופלטים לדוגמה שמראים את ההתנהגות הצפויה.
- זיכרון: עובדות שנשמרו מסשנים קודמים, כמו התוכנית של המשתמש, השפה או ההעדפות שלו.
- מסמכים שנשלפו: קטעים שנמצאו בחיפוש במאגר ידע עבור השאלה הזו (retrieval-augmented generation, או RAG).
- היסטוריית השיחה: תורות קודמים, מילה במילה או בסיכום.
- תוצאות כלים: פלט של חיפושים, הרצות קוד או קריאות API שבוצעו במהלך המשימה, כמו בלולאת ReAct.
- ההודעה הנוכחית: מה שהמשתמש שאל עכשיו.
הבלוק הבא הוא הקשר מורכב אחד של עוזר תמיכה. כבו את החלקים אחד אחרי השני. בלי חלק ההקשר המודל לא יכול לדעת מה התוכנית של הלקוחה; בלי חלק הקלט אין לו עובדות על המוצר, והמגבלות שלו אומרות לו לומר זאת במקום לנחש.
היי דנה, מצב אופליין הוא חלק מתוכנית Pro, והחשבון שלך נמצא כרגע בתוכנית Free, ולכן הוא לא זמין לך כרגע. עם Pro, פתקים שתיצרי במהלך הטיסה יסתנכרנו אוטומטית כשהטלפון יתחבר מחדש. מגבלה אחת שכדאי לדעת: קבצים מצורפים שגדולים מ-20 MB אינם זמינים במצב אופליין.
שימו לב שהתשובה הנכונה תלויה בחיבור בין שני מקורות: הזיכרון (תוכנית Free) ומסמך (מצב אופליין רק ב-Pro). אף אחד מהם לבדו לא מספיק, וזה מצב טיפוסי. חלק גדול מ-context engineering הוא לוודא שהחלקים שזקוקים זה לזה מגיעים יחד.
ארבע דרכים שבהן הקשר משתבש
- מידע חסר. המודל ממלא פערים בניחושים סבירים, ומכאן מגיעות הרבה הזיות. הוסיפו את העובדה, או אמרו למודל מה לעשות כשעובדה חסרה.
- יותר מדי חומר. כל פסקה לא רלוונטית עולה טוקנים ומתחרה על תשומת הלב. Liu et al. 2023, "Lost in the Middle: How Language Models Use Long Contexts", מצאו שהמודלים שבדקו השתמשו במידע שבתחילת קלט ארוך או בסופו בצורה אמינה יותר מאשר במידע שבאמצע. מודלים חדשים יותר מתמודדים טוב יותר עם קלטים ארוכים, אבל לשלוח את הקטעים הספורים שעונים על השאלה עדיין זול יותר, וקל יותר למודל להשתמש בזה, מאשר להדביק את כל המדריך.
- מידע מיושן. תוצאת כלי מלפני עשרה צעדים יכולה לתאר קובץ או יתרה שהשתנו מאז. אם המודל רואה את שתי הגרסאות, הוא עלול להשתמש בישנה.
- סתירות. שני מסמכים לא מסכימים, או שהזיכרון אומר דבר אחד והמשתמש דבר אחר. אמרו למודל איזה מקור גובר, למשל "ההודעה האחרונה של המשתמש גוברת על הזיכרון השמור".
סידור ההקשר
הסדר משפיע גם על התוצאות וגם על העלות.
- חלקים יציבים קודם. הוראות מערכת, הגדרות כלים וחומר עזר קבוע משתנים לעיתים רחוקות בין קריאות. כמה ספקי API מציעים prompt caching, שמשתמש מחדש בעיבוד של התחלה זהה של הקלט, כך שקידומת שלא משתנה הופכת קריאות חוזרות לזולות ומהירות יותר.
- חומר ארוך לפני השאלה. כשיש מסמך ארוך או אוסף גדול של קטעים, שימו את החומר קודם ואת השאלה וההוראות הסופיות אחריו. מדריך הפרומפטים של Anthropic, למשל, ממליץ על הסדר הזה לקלטים ארוכים, עם השאלה ממש לפני שהמודל מתחיל לכתוב.
- תייגו כל חלק. עטפו כל מקור בתגיות כמו
<document>,<memory>או<tool_result>, עם שם המקור. תגיות מאפשרות למודל להבחין בין נתונים להוראות, ומאפשרות לכם לבקש ממנו לציין מאיפה הגיעה תשובה. מפרידים ותגיות XML מסביר את הפורמטים.
קיצוץ הקשר ארוך
כל תור בצ'אט שולח מחדש את כל ההיסטוריה, ולכן סשנים ארוכים גדלים עד שמשהו חייב לצאת. תלוי באפליקציה, היא עשויה לסכם הודעות ישנות או להשמיט אותן, או לבקש מכם לפתוח צ'אט חדש. תקבלו תוצאות טובות יותר אם תקצצו בכוונה.
- שמרו את התורות האחרונים מילה במילה, והחליפו את הישנים יותר בסיכום.
- אחרי שהשתמשתם בתוצאה של כלי, החליפו אותה בהערה של שורה אחת על מה שהיא הראתה.
- שמרו מזהים מדויקים בכל סיכום: שמות קבצים, שמות פונקציות, מזהים, הודעות שגיאה ומספרים. סיכום שאומר "קובץ ההגדרות" במקום שבו ההיסטוריה אמרה
settings.prod.yamlמאבד את הפרט היחיד שהיה חשוב. - באפליקציית צ'אט, כשהשיחה מתפזרת, פתחו צ'אט חדש עם הערת העברה. הפרומפט הבא כותב אחת.
מטרה: להחליף את הבדיקות שנכתבו ידנית בטופס ההרשמה בסכמת אימות משותפת אחת שמשמשת גם את הדפדפן וגם את השרת.
החלטות
- קובץ סכמה אחד,
signupSchema.ts, שמיובא על ידיSignupForm.tsxו-api/signup.ts, כדי ששתי מערכות הכללים לא יוכלו להתרחק זו מזו. - הודעות השגיאה נשארות מילה במילה, כי מרכז העזרה מצטט אותן.
מצב נוכחי
- האימות בדפדפן משתמש בסכמה, ו-
SignupForm.test.tsxעובר. - השרת עדיין קורא ל-
validateSignup()הישנה ב-api/signup.ts.
פרטים מדויקים: סיסמאות צריכות לפחות 8 תווים ומספר אחד. טקסט שגיאת האימייל: "נא להזין כתובת אימייל תקינה."
הצעד הבא: להחליף את validateSignup() בסכמה ולהריץ את בדיקות ה-API.
שאלה פתוחה: האם אימייל שכבר רשום צריך להחזיר 409 או 400?
זיכרון בין סשנים
זיכרון הוא הקשר שנשאר אחרי שהשיחה נגמרת: עובדות שנכתבות לאחסון בסוף סשן אחד ונטענות לתוך הסשן הבא. אפליקציות צ'אט מציעות גרסאות של זה, כמו זיכרונות שמורים או הוראות פרויקט שמתווספות לכל צ'אט בפרויקט. באפליקציה שלכם, זיכרון הוא טבלה או קובץ הערות שהקוד שלכם קורא ומכניס. שני כללים שומרים עליו שימושי: שמרו עובדות שנשארות נכונות (תוכנית, שפה, סטאק מועדף), לא תמלילים; וטענו רק את מה שרלוונטי למשימה הנוכחית, כי הזיכרון מתחרה על אותו מקום כמו כל השאר.
הרכבת הקשר בקוד
באפליקציה, context engineering היא קוד רגיל. הסקיצה הזו עם ה-SDK של Anthropic ל-Python שמה את הכללים הקבועים ואת הזיכרון בפרומפט המערכת, שומרת רק היסטוריה אחרונה, וממקמת מסמכים מתויגים לפני השאלה.
import anthropic
client = anthropic.Anthropic()
MODEL = "your-model-id" # e.g. from your provider's model list
def build_context(question, docs, history, memory, max_messages=6):
documents = "\n".join(
f'<document source="{d["source"]}">\n{d["text"]}\n</document>' for d in docs
)
system = (
"You are the support assistant for Acme Notes. Answer only from the documents. "
"If they do not cover the question, say so.\n"
f"<memory>\n{memory}\n</memory>"
)
# history holds complete user/assistant pairs, so an even slice starts with a user turn
recent = history[-max_messages:]
user = f"<documents>\n{documents}\n</documents>\n\n{question}"
return system, recent + [{"role": "user", "content": user}]
# question, docs, history and memory come from your application
system, messages = build_context(question, docs, history, memory)
response = client.messages.create(model=MODEL, max_tokens=1024, system=system, messages=messages)
print(response.content[0].text)
כל החלטה בפונקציה הזו (אילו מסמכים, כמה הודעות, איפה הזיכרון נכנס) היא בחירה של context engineering, וכדאי לבדוק כל אחת מהן על שאלות אמיתיות, בדיוק כמו שהייתם בודקים שינוי בניסוח.
שאלות נפוצות
מה זה context engineering?
Context engineering היא העבודה של בחירה, סידור וקיצוץ של כל מה שמודל שפה מקבל בקריאה: הוראות המערכת, דוגמאות, מסמכים שנשלפו, הגדרות של כלים ותוצאותיהם, זיכרון שמור, היסטוריית השיחה וההודעה של המשתמש. המודל עונה רק מתוך הטקסט הזה, ולכן מה שיש בו, ומה שנשאר מחוצה לו, קובע את איכות התשובה.
מה ההבדל בין context engineering ל-prompt engineering?
Prompt engineering עוסקת בעיקר בניסוח ההוראות. Context engineering מכסה את כל הקלט, שחלק גדול ממנו מורכב על ידי קוד ולא מוקלד על ידי אדם: אילו מסמכים לשלוף, אילו תוצאות של כלים לשמור, כמה היסטוריה לכלול ובאיזה סדר. בצ'אט אתם כותבים את רוב ההקשר בעצמכם; באפליקציה או בסוכן, את רובו בוחרת המערכת שמסביב למודל.
האם יותר הקשר זה תמיד יותר טוב?
לא. חומר לא רלוונטי או מיושן מתחרה בחלקים החשובים, עולה טוקנים ויכול לסתור את המצב הנוכחי. מחקרים על קלטים ארוכים מצאו שמודלים עלולים לפספס מידע שנמצא באמצע הקשר ארוך. כללו את מה שהמשימה צריכה, תייגו אותו, והסירו את מה שכבר לא נחוץ.
למה שיחה ארוכה הולכת ומשתבשת עם הזמן?
כל השיחה נשלחת מחדש בכל תור, כך שטעויות ישנות, רעיונות שננטשו וקוד שהוחלף נשארים בהקשר וממשיכים להשפיע על התשובות. כשהשיחה גדלה מעבר לחלון ההקשר, האפליקציה צריכה להשמיט הודעות ישנות או לסכם אותן. פתיחת צ'אט חדש עם סיכום קצר של ההחלטות והמצב הנוכחי עובדת לעיתים קרובות טוב יותר מהמשך השיחה.
מה זה RAG ב-context engineering?
RAG (retrieval-augmented generation) פירושו חיפוש במסמכים שלכם אחר קטעים שרלוונטיים לשאלה והכנסתם להקשר לפני שהמודל עונה. זה אחד הכלים המרכזיים של context engineering: המודל מקבל עובדות עדכניות ומדויקות שלא יכול היה לדעת מהאימון, ואפשר להורות לו לענות רק מתוך הקטעים האלה.