תחשבו על זה כמו על שולחן עבודה. מה שמונח עליו, המודל רואה. מה שנפל ממנו על הרצפה, לא. שיחה ארוכה מפילה דברים מהשולחן, מהישנים לחדשים, בלי להודיע.
טוקנים וחלון הקשר: למה המודל שוכח באמצע שיחה, ולמה זה עולה כסף
כל שיחה עם מודל נמדדת בטוקנים, ולכל מודל יש כמות מוגבלת שהוא מסוגל להחזיק מול העיניים בכל רגע. מי שמבין את שני הדברים האלה מבין למה השיחה הארוכה התחילה לזייף, ולמה החשבון בסוף החודש נראה ככה.
המדריך הזה מבוסס על התיעוד של Anthropic ו-OpenAI על טוקנים, חלונות הקשר ותמחור, ועל מה שאני רואה אצל צוותים שעובדים עם הכלים האלה כל יום. הוא מיועד למי שהמודל ׳שכח׳ לו משהו באמצע שיחה ולא הבין למה, למי שמעלה מסמכים ארוכים ומקבל תשובות חלקיות, ולמי שמשלם על API ורוצה להבין על מה בדיוק.
להתחיל לקרוא ↓למה המודל שכח מה אמרתם לפני שעה
למודל אין זיכרון. יש לו חלון: כמות מוגבלת של טקסט שהוא רואה בכל פעם שהוא עונה. כשהשיחה עוברת את הגודל הזה, הכלי מתחיל להשמיט את ההתחלה. מבחינת המודל, מה שהושמט מעולם לא נאמר.
זה קורה לכולם באותו שלב. שיחה של שעתיים על הצעת מחיר, ובהודעה האחרונה המודל מציע בדיוק את המחיר שסיכמתם בהתחלה שלא מציעים. התחושה היא שהוא מתעייף. יש לזה הסבר פשוט יותר.
התיעוד של Anthropic מגדיר את חלון ההקשר ככל הטקסט שהמודל יכול להתייחס אליו כשהוא מייצר תשובה, כולל התשובה עצמה, ומכנה אותו זיכרון עבודה. בכל הודעה חדשה, כל השיחה עד עכשיו נשלחת שוב למודל. כשהיא גדולה מהחלון, ממשקי הצ׳אט משמיטים את ההודעות הישנות ביותר קודם. וגם לפני שמגיעים לגבול, ככל שיש יותר טקסט בחלון, הדיוק יורד. בתיעוד זה נקרא context rot.
אם משהו חשוב נאמר בתחילת שיחה ארוכה, תניחו שהוא כבר לא בחלון. תחזרו עליו בהודעה חדשה, או תפתחו שיחה חדשה עם סיכום. זה לוקח דקה וחוסך תשובה שבנויה על מידע חסר.
ב-API אין השמטה אוטומטית. אתם שולחים את כל ההיסטוריה בכל בקשה, ואם הקלט לבדו עובר את החלון, ה-API של Anthropic מחזיר 400 עם ההודעה prompt is too long. ניהול החלון, קיצוץ, סיכום או דחיסה, הוא באחריות האפליקציה שלכם.
מה זה טוקן, ולמה לא סופרים מילים
טוקן הוא היחידה שהמודל קורא וכותב בה. לפעמים זו מילה שלמה, לפעמים חצי מילה, לפעמים סימן פיסוק. באנגלית, לפי OpenAI, טוקן הוא בערך ארבעה תווים, ומאה טוקנים הם בערך 75 מילים. בעברית היחס שונה. כל מגבלה וכל מחיר נמדדים בטוקנים.
המודל לא רואה אותיות ולא מילים. לפני שהטקסט מגיע אליו, הוא נחתך לרצף של טוקנים, ומה שחוזר ממנו הוא רצף טוקנים שמורכב בחזרה לטקסט. בתיעוד של OpenAI יש דוגמה: המילה tokenization נחתכת לשניים, token ו-ization, בזמן שמילה קצרה ונפוצה כמו the היא טוקן אחד. רווח לפני מילה, אות גדולה בהתחלה, כל אלה משנים את החיתוך.
למה זה מעניין מישהו שלא מתכנת? כי גודל החלון והמחיר נספרים בטוקנים. מסמך של עשרים עמודים הוא מבחינת המודל כמה אלפי טוקנים, והמספר תלוי בשפה. שני היצרנים מציינים שהיחס בין תווים לטוקנים משתנה בין שפות, ובמה שאני סופר, עברית יוצאת לרוב יקרה יותר לכל מילה מאנגלית.
| סוג הטוקן | מה נכנס לשם | למה זה חשוב לכם |
|---|---|---|
| קלט (input) | כל מה שאתם שולחים: ההודעה, ההיסטוריה, המסמכים שצירפתם | זה החלק שגדל עם כל הודעה בשיחה ארוכה |
| פלט (output) | מה שהמודל כותב בחזרה | מתומחר גבוה יותר מקלט אצל שני היצרנים |
| קלט מהמטמון (cached) | חלקים מהקלט שכבר עובדו בבקשה קודמת | מחיר נמוך יותר, רלוונטי למי שבונה על API |
| חשיבה (reasoning) | טוקנים שהמודל חושב בהם לפני התשובה ולא מוצגים | נספרים ומחויבים כפלט, גם כשהתשובה הגלויה קצרה |
חלון ההקשר: הזיכרון העובד של המודל
חלון ההקשר הוא כל מה שהמודל רואה כשהוא עונה: הוראות הקבע, כל ההודעות בשיחה, הקבצים שצירפתם, והתשובה שהוא כותב עכשיו. הכל ביחד, בטוקנים, עד תקרה שתלויה במודל. מה שבפנים משפיע על התשובה. מה שבחוץ לא קיים.
יש כאן שני דברים שמתבלבלים כל הזמן. מה שהמודל למד באימון: ידע כללי, שפה, סגנון, ואת זה אי אפשר לשנות בשיחה. וחלון ההקשר: הטקסט שמול העיניים שלו עכשיו. התיעוד של Anthropic מדגיש שהחלון שונה מהמאגר שהמודל אומן עליו, והוא זיכרון עבודה זמני. כשהשיחה נגמרת, הוא מתרוקן.
בתוך שיחה, החלון מתמלא בהדרגה: כל הודעה וכל תשובה נוספות אליו, עד שנגמר המקום. וגם לפני שנגמר המקום יש מחיר. התיעוד אומר במפורש שיותר הקשר הוא לא אוטומטית יותר טוב, וככל שכמות הטוקנים גדלה, הדיוק יורד. מה שמכניסים לחלון חשוב לא פחות מכמה מקום יש בו.
הגדלים משתנים בין מודלים ומתעדכנים כל כמה חודשים, אז אין טעם לזכור מספר. מה שכן כדאי לזכור: יש תקרה, השיחה מתקרבת אליה בלי שתרגישו, ומסמך ארוך אחד יכול למלא חלק גדול ממנה לבד.
כשמתחילים לקבל תשובות שסותרות דברים שנאמרו קודם, זה הסימן. אין צורך לחכות להודעת שגיאה. באותו רגע פותחים שיחה חדשה ומעבירים אליה רק מה שרלוונטי.
החלון כולל את ה-system prompt, הגדרות הכלים, כל ההודעות, תוצאות הכלים והפלט. ב-API של Anthropic, אם הקלט לבדו חורג, חוזר 400 invalid_request_error. אם הקלט ועוד max_tokens חורגים ביחד, במודלים החדשים הבקשה מתקבלת והייצור נעצר עם stop_reason של model_context_window_exceeded. תטפלו בשני המקרים בקוד.
למה מסמך ארוך מקבל תשובה חלקית
שני דברים קורים למסמך ארוך. או שהוא גדול מהחלון, ואז חלק ממנו פשוט לא נכנס. או שהוא נכנס, אבל הוא כל כך גדול שהמודל מפספס פרטים באמצע. בשני המקרים התשובה נראית בסדר ומפספסת בדיוק את מה שחיפשתם.
התיעוד של Anthropic נותן שלושה כללים למסמכים ארוכים, וכולם עובדים גם בצ׳אט רגיל. הראשון: המסמך למעלה, השאלה למטה. בבדיקות שלהם, שאלה שמגיעה אחרי המסמך משפרת את התשובה עד שלושים אחוז. השני: כשיש כמה מסמכים, לתחום כל אחד בתגיות עם שם ומקור. השלישי: לבקש מהמודל לצטט קודם את הקטעים הרלוונטיים, ורק אז לענות. הציטוט מכריח אותו למצוא את הטקסט לפני שהוא מסיק ממנו.
ואם המסמך גדול מדי גם ככה? ההמלצה של OpenAI פשוטה: לקצר, להסיר הקשר מיותר או כפול, או לחלק את הקלט לחלקים קטנים. סיכום פרק אחרי פרק, ואז שאלה על הסיכומים, עובד טוב יותר מלדחוף ספר שלם ולקוות.
<document> <source>[השלם את המידע כאן: שם הקובץ או המקור]</source> [השלם את המידע כאן: הדביקו את המסמך המלא] </document> אני [השלם את המידע כאן: תפקיד והקשר]. תענה על השאלה הבאה על בסיס המסמך למעלה בלבד. קודם תצטט מילה במילה את הקטעים מהמסמך שרלוונטיים לשאלה, ממוספרים. אם אין קטע רלוונטי, תכתוב ׳לא נמצא במסמך׳. אחר כך תענה, ותפנה למספרי הציטוטים. השאלה: [השלם את המידע כאן: השאלה שלכם]
איך מחשבים מחיר לטוקן, בלי מספרים שיתיישנו
ב-API משלמים על טוקנים בשני מונים נפרדים: מה שנכנס ומה שיוצא. פלט יקר יותר מקלט. וכל הודעה חדשה שולחת מחדש את כל ההיסטוריה, אז ההודעה העשירית עולה יותר מהראשונה גם אם היא זהה.
התמחור אצל שני היצרנים מוצג כמחיר למיליון טוקנים, בנפרד לקלט ולפלט. המספרים עצמם משתנים עם כל דור מודלים, ולכן אין כאן מחירים. מה שלא משתנה הוא המבנה: עלות בקשה אחת היא טוקני קלט כפול מחיר קלט, ועוד טוקני פלט כפול מחיר פלט. מודלים שחושבים לפני התשובה מוסיפים טוקני חשיבה, שמחויבים כפלט גם כשלא רואים אותם.
החלק שמפתיע אנשים הוא ההיסטוריה. בכל פנייה למודל, כל השיחה עד עכשיו נשלחת כקלט מחדש. שיחה עם עשרים הודעות משלמת על ההודעה הראשונה עשרים פעם. זו הסיבה ששני היצרנים מציעים מטמון לפרומפט: חלק שחוזר על עצמו, כמו הוראות קבע או מסמך גדול, מעובד פעם אחת ונקרא מהמטמון בשבריר מהמחיר בבקשות הבאות.
אם אתם על מנוי צ׳אט חודשי, המחיר קבוע והחישוב הזה לא מגיע לחשבונית. הוא כן מגיע לאיכות: שיחה ארוכה היא שיחה כבדה למודל, והוא מתחיל לפספס. שיחה חדשה לכל משימה פותרת את שני הדברים.
כשמישהו בונה לכם אוטומציה שקוראת למודל, תשאלו שתי שאלות: כמה טוקנים נכנסים בכל קריאה, וכמה קריאות ביום. הכפלה של השניים היא החשבון החודשי בקירוב. מסמך ארוך שמצורף לכל קריאה מחדש הוא הטעות הנפוצה ביותר שראיתי.
לפני שליחה, Anthropic מספקים endpoint לספירת טוקנים, ו-OpenAI מספקים tokenizer, ספריית tiktoken ו-API לספירת קלט. אחרי הבקשה, שדה usage מחזיר input_tokens ו-output_tokens בפועל. תרשמו אותם לכל קריאה. בלי זה תגלו את הבעיה רק בחשבונית.
שיחה חדשה לכל משימה, וסיכום כשעוברים
ההרגל שמשנה הכי הרבה: שיחה אחת למשימה אחת. כשמשימה נגמרת, מבקשים מהמודל סיכום קצר של מה שסוכם, ומדביקים אותו בתחילת השיחה הבאה. ככה החלון נשאר קטן, ממוקד, וזול.
- תפתחו שיחה חדשה לכל משימה נפרדת: הצעת מחיר, מייל ללקוח, ניתוח קובץ. ערבוב משימות מבלבל את המודל ומייקר כל הודעה
- לפני שסוגרים, תבקשו סיכום: ההחלטות, הנתונים שסוכמו, מה עוד פתוח. תשמרו אותו בפתק
- בשיחה הבאה תדביקו את הסיכום כהודעה ראשונה, לפני הבקשה החדשה
- מידע קריטי, כמו מחיר שאסור לחרוג ממנו, תחזרו עליו בהודעה שבה הוא נדרש, גם אם כבר אמרתם אותו
- מסמכים ארוכים תשימו בתחילת ההודעה, והשאלה בסוף
אני עומד לסגור את השיחה הזאת ולהמשיך את העבודה בשיחה חדשה, שבה לא יהיה לך שום זיכרון ממנה. תכתוב סיכום מעבר של עד 200 מילים שכולל: 1. מה המשימה ומי הלקוח או הקהל 2. החלטות שסגרנו, כולל מספרים ותאריכים מדויקים 3. מה נפסל ולמה, כדי שלא נחזור לשם 4. מה עוד פתוח וצריך להמשיך 5. הנחיות סגנון וטון שביקשתי לאורך הדרך תכתוב רק עובדות מהשיחה. אם משהו לא סוכם במפורש, תכתוב ׳לא סוכם׳ במקום להשלים לבד. [השלם את המידע כאן: נושא שחשוב לכם במיוחד שייכנס לסיכום, או ׳אין׳]
הקשר שנטען לבד: מה שמים בפרויקט
כשאותם מסמכים ואותן הנחיות חוזרים בכל שיחה, שמים אותם ב-Project. ב-Claude, קבצים שמעלים למאגר הידע של הפרויקט זמינים לכל שיחה בתוכו, וההנחיות של הפרויקט נטענות לבד. זה מחליף את ההדבקה הידנית. זה לא מבטל את החלון: הקבצים האלה יושבים בו.
לפי תיעוד התמיכה של Anthropic, פרויקט מאפשר להעלות מסמכים, טקסט וקוד למאגר ידע שהמודל משתמש בו כרקע לכל שיחה בפרויקט, ולהגדיר הנחיות קבועות, למשל טון או תפקיד. ב-ChatGPT יש כלים מקבילים, והעיקרון זהה: מה שקבוע, מגדירים פעם אחת.
מה שכדאי לזכור: מאגר הידע של הפרויקט נכנס לחלון כמו כל טקסט אחר. פרויקט עם עשרה מסמכים ארוכים מתחיל כל שיחה כשחלק גדול מהחלון כבר תפוס. Anthropic מציינים שבתוכניות בתשלום, כשהידע מתקרב לגבול, המערכת עוברת למצב אחזור (RAG) ושולפת רק את החלקים שנראים רלוונטיים לשאלה. זה פותר חלון מלא, וזה גם המקום שבו תשובה יכולה לפספס מסמך שלא נשלף.
מה עושים עם זה מחר בבוקר
תפתחו את השיחה הכי ארוכה שיש לכם בכלי. תבקשו ממנה סיכום מעבר לפי הפרומפט מסעיף 06, ותסגרו אותה. מחר כל משימה מתחילה בשיחה נקייה, עם הסיכום למעלה ועם המסמך לפני השאלה.
- תעברו על השיחות הפתוחות ותסגרו את אלה שמערבבות כמה נושאים, אחרי שהוצאתם מהן סיכום
- תכינו פתק עם סיכומי מעבר למשימות שחוזרות אצלכם
- מסמכים שחוזרים בכל שיחה: תעלו אותם פעם אחת ל-Project ותפסיקו להדביק
כלל אחד לשבוע הקרוב: שיחה חדשה לכל משימה. אם תפסתם את עצמכם גוללים למעלה כדי למצוא מה אמרתם, זה הסימן לפתוח חדשה.
תבנו לעצמכם שני פרומפטים קבועים: אחד לסיכום מעבר ואחד לעבודה עם מסמך ארוך. תשמרו אותם בפתק, ותשתמשו בהם בכל פעם שהשיחה מתארכת או שאתם מדביקים יותר מכמה עמודים.
תוסיפו רישום של input_tokens ו-output_tokens לכל קריאה שאתם עושים למודל, ותסתכלו על המספרים אחרי שבוע. אחר כך תבדקו מה נשלח שוב ושוב בכל קריאה: system prompt ארוך, מסמכים, היסטוריה שלמה. זה החומר למטמון או לקיצוץ, ושם רוב החיסכון.
שאלות שאני שומע על זה
כמה טוקנים יש בעמוד טקסט?
תלוי בשפה ובצפיפות. באנגלית, לפי OpenAI, מאה טוקנים הם בערך 75 מילים. בעברית היחס שונה, ולרוב פחות נוח. הדרך המדויקת היחידה היא לספור: יש כלי ספירה של OpenAI ו-endpoint לספירה של Anthropic.
אם אעבור למודל עם חלון גדול יותר, הבעיה נפתרת?
חלקית. חלון גדול דוחה את הרגע שבו ההתחלה נשמטת, אבל התיעוד של Anthropic מציין שככל שיש יותר טוקנים בחלון, הדיוק יורד. שיחה ממוקדת בחלון קטן עדיין נותנת תשובה טובה יותר משיחה עמוסה בחלון ענק.
המודל זוכר אותי בין שיחות?
החלון מתרוקן בסוף שיחה. מה שכן עובר בין שיחות הוא מה שהגדרתם במפורש: הנחיות קבועות וקבצים בפרויקט. מידע קריטי למשימה תכתבו שוב בשיחה שבה הוא נדרש.
