מדוע בדיקות A/B של פרומפטים מניבות מסקנות שגויות
אותו פרומפט שנשלח פעמיים מחזיר ניסוחים שונים — היצירה אינה דטרמיניסטית. הטמפרטורה והבחירה האקראית של ההמשך יוצרות פיזור על אותו קלט, ולכן המסקנה "וריאנט ב' עונה מדויק יותר" לעיתים קרובות רק אומרת שווריאנט ב' נפל על ריצה מוצלחת.
חוסר היציבות של התשובות הוא תכונה של המודל עצמו, לא פגם בהגדרה, והוא מכניס רעש לכל השוואה מהשלב הראשון.
הסיבה השנייה — נפח מדגם קטן. על שניים-שלושה עשרות דוגמאות, ההבדל בשיעור התשובות המוצלחות טובע ברעש הזה: כדי להבחין בביטחה בעלייה של כמה נקודות אחוז, יש צורך במאות בקשות בלתי תלויות, לא בעשרות.
ככל שהמדגם קטן יותר, כך גבוה הסיכוי שהמוביל ייקבע בהטלת מטבע ולא ניתן יהיה לשחזר את תוצאתו על נתונים חדשים.
השלישית — קריטריון ההערכה עצמו. אם את האיכות מסמן אדם בלי הנחיה חד-משמעית או מודל-שופט בלי כיול על דוגמאות שנויות במחלוקת, הרעש בהערכה מכסה את האפקט של עריכת ההנחיה.
שני מעריכים על אותן תשובות חלוקים באופן קבוע, ובלי מדידת שיעור אי-ההסכמות תוצאת ההשוואה אינה ניתנת להבחנה מהעדפות אישיות של מי שמסתכל על הפלט.
לבסוף, תנאי ההשוואה לעיתים רחוקות מקובעים במלואם. את הווריאנטים מריצים על מערכי קלט שונים, מחליפים את המודל או את הפרמטרים שלו באמצע הניסוי, ואת היסטוריית השיחה מוסיפים רק לענף אחד.
כל הבדל כזה הופך את הווריאנטים לבלתי ניתנים להשוואה, ומכאן מתווכחים כבר לא על ההנחיה, אלא על למי היה מערך קלט קל יותר.
התוצאה צפויה: לעבודה יוצא וריאנט אקראי, ושיפור אמיתי מוחזר לאחור כ"לא עבד". נבחן כיצד להציב בדיקות A/B של פרומפטים כך שמסקנות שגויות לא יעברו בדיקה חוזרת.
מה נותן מעגל הערכה מבוקר לאיכות התשובות
מחזור השוואה קבוע בנוי כך: לכל הנחיה יש גרסה ותגית, את הווריאנטים מריצים על אותו מערך בקשות, והערכת האיכות מורכבת מבדיקות אוטומטיות — מבנה התשובה, עמידה בעובדות, הימנעות מפרטים מומצאים — ומהשוואה עיוורת בידי בני אדם במקרים שנויים במחלוקת. תוצאת הריצה היא לא "השתפר", אלא שיעור הבדיקות שעברו לכל וריאנט ורשימת אי-ההתאמות.
שיעור התשובות הכושלות מפסיק להיות נושא לדיון ומתחיל להימדד. רגרסיה נראית בשלב ההשוואה, לפני שחרור: אם עריכת ההנחיה משפרת תרחיש אחד ושוברת שלושה אחרים, זה מתועד מיד, ולא לפי תלונות כעבור שבועות. מכאן גם הפחתת הסיכון לרגרסיה — שינוי או שעובר את סף הבדיקות, או לא נכנס לעבודה.
מהירות שחרור השינויים עולה בזכות אוטומציה של ההשוואה: ריצה אורכת דקות, וההחלטה מתקבלת לפי טבלת מדדים, בלי תיאומים ארוכים "לפי הטעם". בקרת גרסאות של ההנחיות מתבצעת יחד עם היסטוריית הריצות ב-MLflow — לכל גרסה רואים על איזה מערך בקשות היא נבדקה ואילו בדיקות עברה.
שחזוריות — האפקט המרכזי: כעבור חודש אפשר לחזור על אותה ריצה על אותו מדגם ולהבין מה בדיוק שינה את התוצאה — גרסה חדשה של ההנחיה, עדכון המודל או הרכב הבקשות. זה הופך את כיוונון הפרומפטים מהתאמה ידנית לתהליך הנדסי, שבו לכל שינוי יש עקבות ניתנות לבדיקה.
מצבי בדיקות A/B של פרומפטים: ריצה, פיצול, הרצה בצל
בחירת המצב תלויה בשני דברים: האם יש ארכיון של פניות אמיתיות להשוואה והאם אפשר להציג תשובה חדשה לחלק מהמשתמשים. מכאן ריצה לא-מקוונת על שיחות שמורות ופיצול מקוון, שבו שתי גרסאות של הפרומפט מחלקות ביניהן את התעבורה.
הרצה בצל נמצאת בין השניים — הווריאנט החדש מחושב במקביל לנוכחי, אבל התשובות לא מוצגות, ולכן ההשוואה נעשית בלי סיכון למשתמשים.
המצבים לא מחליפים זה את זה אלא משלימים זה את זה: הרצה בצל מסננת גרסאות חלשות מראש, ריצה לא-מקוונת מחשבת מדדים על ההיסטוריה, פיצול מקוון מאשר אותם על פניות חיות, והפצה מדורגת מביאה את המנצח לכלל הקהל בחלקים — מ-5% עד 100%.
| מצב | מתי מתאים | מה נדרש ובמה הוא מוגבל |
|---|---|---|
| ריצה לא-מקוונת | יש ארכיון פניות ותשובות ייחוס; נדרש סינון מהיר של גרסאות | קורפוס שיחות מתויג; אינו מציג תגובה התנהגותית |
| הרצה בצל | התרחיש קריטי, תשובה שגויה יקרה | צריכה כפולה של משאבי עיבוד; נדרשת השוואה ידנית של תשובות |
| פיצול מקוון | המדד נמדד דרך פעולות משתמשים | חלק משמעותי מהתעבורה ובקרת אחידות של הקבוצות |
| הפצה מדורגת של שינויים | הווריאנט כבר ניצח, צריך להבטיח את ההוצאה לפרודקשן | החזרה אוטומטית לאחור לפי מדדי סף |
בחירת המצב קובעת גם את היקף ההכנה: לריצה אוספים ומתייגים קורפוס שיחות, לפיצול מגדירים חלוקה לקבוצות ואיסוף מדדים. אם אין עדיין ארכיון פניות, מתחילים בהרצה בצל — היא צוברת נתונים בלי להשפיע על חוויית המשתמשים.
מהאודיט ועד למסירה: שלבי העבודה ההנדסית
סדר העבודה זהה גם לפתרון חדש וגם לכזה שכבר פועל: תחילה מתעדים כיצד התהליך בנוי כיום, אחר כך — לפי איזה מדד נשפוט את התוצאה. בלי זה ההשוואה בין הווריאנטים הופכת לוויכוח על טעם, והפרומפט הנבחר מתפרק בתעבורה חיה.
- אודיט של הריצה. מפרקים כיצד נוצרים הפרומפטים, מאין מגיעים נתוני הקלט, מה כבר נרשם בלוגים ובאיזה אופן נשמרות התשובות. התוצר — מפת התהליך ורשימת נקודות שבהן הווריאנטים מתפצלים בלי שליטה.
- קריטריוני השוואה. לפני ההרצה מקבעים את המדד הראשי ואת כלל העצירה: שיעור התשובות שעברו בדיקה לפי התיוג, שיעור הסירובים והחזרות, יציבות הניסוח על קלטים מנוסחים מחדש. שאר המדדים משמשים כמדדי בקרה.
- סכמת הבדיקה. קובעים כיצד הווריאנטים מחלקים את זרם הקלט: אותו מדגם בדיוק ל-A ול-B, סדר אקראי, בידוד — בכל ריצה משתנה בדיוק חלק אחד של הפרומפט. אז מייחסים את התוצאה לשינוי, ולא להבדל בנתוני הקלט.
- הגדרת ההרצה. רושמים בלוג את גרסת הפרומפט יחד עם התשובה ופרמטרי הקריאה, כדי שכל תוצאה תשתחזר ותוסבר, ולא תישאר הצלחה חד-פעמית.
- מדגם מושהה. מחזיקים מערך נפרד של דוגמאות שלא השתתף בבחירת הניסוחים, ובודקים את המנצח רק עליו. זה מסנן וריאנטים שניצחו בזכות התאמה למקרים מוכרים.
- מסירה לצוות. מוסרים את נוהל הריצה, תבנית הדוח, תיאור המדדים וכלל החזרה לגרסה הקודמת — את הווריאנט הבא תבדקו בעצמכם.
ארטיפקטים: מערכי בדיקות, כללי הערכה, נוהל ריצות
התוצאה של בדיקות A/B לפרומפטים נשענת לא על דוח, אלא על קבצים שהצוות שלכם פותח בלעדינו. דוח מתיישן מהר: הפרומפט נערך, המודל מתעדכן, והרכב הבדיקות מתרחק מהבקשות האמיתיות.
לעומת זאת מערך הבדיקות, כללי ההערכה והנוהל נשארים מעגל עבודה — לפיהם מהנדס חדש משחזר את השוואת הווריאנטים ומקבל מספרים ברי-השוואה.
מה נשאר בידיכם:
- מערך בדיקות — פניות אמתיות של משתמשים עם תיוג: התשובה הצפויה, ניסוחים מותרים, סוג הסירוב. נשמר לצד הפרומפט ומתעדכן בכל בירור תקלה.
- כללי הערכה — לפיהם קובעים שווריאנט טוב יותר: שיעור התשובות הנכונות, שיעור הסירובים, עמידה בתבנית, פיזור על קלטים זהים. מסוכמים לפני הריצות, כדי שהתוצאה לא תותאם למה שרצוי.
- נוהל ריצות — כמה בקשות דרושות למסקנה מובהקת, כמה חזרות לכל וריאנט, ומאיזו אי-התאמה ההבדל נחשב לרעש. מבטל את הוויכוח "לדעתי הפרומפט הזה טוב יותר".
- יומן החלטות — תאריך, גרסת פרומפט, מדדים, מי בחר את הווריאנט ולמה. כעבור חצי שנה רואים מאין הגיע הטקסט הנוכחי, ולא רק מה הוא.
- סקריפטים לריצה ולבירור — רצים בצד שלכם, בלי גישה לתשתית שלנו ובלי השוואה ידנית של תשובות.
- תיעוד פנימי — סכימת מעגל הבדיקות, סדר ניהול הגרסאות של הפרומפטים, נקודות שבהן צריך להריץ מחדש בדיקות אחרי החלפת מודל.
מקרה בוחן: צמצמנו את שיעור התשובות הכושלות ואת זמן הבדיקה
במקור זה היה קו תמיכה ראשון: כמה עשרות אלפי שיחות בחודש בנושאי הזמנות והחזרות. את הפרומפט תיקנו לפי אינטואיציה ישירות בקונפיגורציית הפרודקשן, ואת הגרסה לחזרה אחורה החזיקו בהתכתבות.
שיעור התשובות הכושלות עמד על כ-18% — העוזר נקב בביטחה במועדי אספקה שגויים והציע תנאי החזרה שלא היו קיימים.
הבדיקה נמשכה יומיים לכל וריאנט: ארבעים שיחות הורצו ידנית, אדם אחד העריך, ומקרים שנויים במחלוקת לא תויגו מחדש. לא היה עם מה להשוות את העריכה — עם הזיכרון, לא עם מספרים.
מה שינינו
אספנו מערך רגרסיה של שלוש מאות פניות אמיתיות עם תשובות ייחוס ורובריקה: נכונות העובדה, שלמות, טון, היעדר תנאים מומצאים. הריצה נעשית לא-מקוון על אותו מערך, התיוג עיוור — שני מעריכים לא רואים איזה וריאנט לפניהם, ואי-ההתאמות נבחנות בידי שלישי. גרסאות הפרומפטים ותוצאות הריצות מתועדות ב-Langfuse, ולכן ההשוואה ניתנת לשחזור גם כעבור חודש.
מה השתנה
שיעור התשובות הכושלות ירד מ-18% ל-6%, והעברות לנציג אנושי — מ-27% ל-14%. זמן בדיקת הווריאנט הצטמצם מיומיים ל-45 דקות: הריצה מתבצעת בלילה, ובבוקר מוכן דוח עם פילוח לפי רובריקות ורשימת שיחות שבהן הווריאנטים נבדלו.
התמיכה בעוזר הפכה לנוהל: בכל שבוע מוסיפים למערך שיחות שבהן הוא טעה בפרודקשן, ומריצים עליהן את הווריאנט הקודם. רגרסיה נראית לפני העלייה לאוויר, ולא אחרי תלונות.
במה שונה הערכה לא-מקוונת מפיצול מקוון במעגל שלכם
הערכה לא-מקוונת — זו הרצה של וריאנטים של הפרומפט על מערך קבוע של מקרים, שבו התשובות כבר מתויגות. ההשוואה אורכת שעות, היא ניתנת לחזרה ואינה משפיעה על משתמשים: שתי הגרסאות רצות על אותם קלטים, ואי-ההתאמות נראות שורה-שורה. המגבלה — המערך תמיד צר מהתעבורה החיה, וניסוחים נדירים לא נכנסים אליו.
פיצול מקוון עונה על שאלה אחרת: כיצד הפרומפט מתנהג בבקשות אמיתיות. חלק מהתעבורה עובר לגרסה החדשה, והמדדים מחושבים לפי קבוצות. המסקנה הוגנת יותר, אבל מהירות קבלת המסקנה תלויה בנפח: עד שהקבוצה צוברת מספיק בקשות, ההבדל טובע ברעש.
| מה משווים | הערכה לא-מקוונת | פיצול מקוון |
|---|---|---|
| בסיס | מערך מקרים מתויג | תעבורה חיה ומדדי התנהגות |
| מהירות קבלת המסקנה | שעות, אינה תלויה בנפח | ימים, תלויה בגודל הקבוצה |
| נקודות עיוורות | ניסוחים נדירים מחוץ למערך | רעש על מדגם קטן |
בפועל אין מדובר בחלופה, אלא ברצף. אופליין מסנן רגרסיות ברורות ותיקונים זולים, אונליין מאשר את האפקט על נתונים חיים, ולאחר מכן את הגרסה מפיצים על כל התעבורה.
אם כבר יש לכם ריצה משלכם, מעבירים אותה כייחוס: תיוג התשובות מתחבר למערכת ההערכה, והתוצאות נשארות בנות-השוואה בין איטרציות. בהמשך מוסיפים פיצול מקוון ומחזיקים את שני הקווים על אותו מערך מדדים — כך רואים ששינוי הפרומפט שיפר בדיוק את ההתנהגות הנבדקת, ולא במקרה חפף לעלייה עונתית.
ספקות טכניים: שחזוריות, תיוג, סחיפת נתונים
התנגדויות הנדסיות לבדיקות A/B של פרומפטים נוגעות לא למכניקה, אלא לאמון במסקנות: האם הריצה משתחזרת, האם האפקט לא טובע ברעש ההערכה, ומה יקרה למדד כעבור חודש. להלן תשובות לספקות שצפים לפני ההתחלה.
איך לשחזר ריצה שהניבה שיפור?
כל הרצה מתעדים כקונפיגורציה: טקסט הפרומפט, גרסת המודל, פרמטרי היצירה, גרעין קבוע, גרסת מערך הייחוס. הקונפיגורציה מקבלת hash ועוברת לבקרת גרסאות יחד עם הנתונים — הריצה חוזרת כעבור חודש עם אותה תוצאה. את הנתונים מנהלים בגרסאות ב-DVC.
איך להבין שההבדל בין הווריאנטים אינו רעש?
ריצה אחת על וריאנט לא מוכיחה דבר: כשהטמפרטורה אינה אפס, המודל עונה אחרת. מחשבים שונות לפי ריצות חוזרות על אותו מערך, משווים את הווריאנטים בזוגות על דוגמאות זהות ובודקים רווח סמך. אם הם חופפים — קובעים תיקו, לא "מנצח".
מה לעשות עם סחיפת נתונים?
הרכב הבקשות משתנה: ניסוחים חדשים, אורך קלט אחר, עלייה בשיעור הסירובים. מחזיקים מערך רגרסיה קפוא להשוואת גרסאות ובנפרד עוקבים אחר התפלגות הקלטים. אם שיעור הניסוחים הלא מוכרים עבר את הסף — בונים מחדש את המערך ומריצים את הבדיקה מחדש, אחרת המדד מתאר את העבר.
איך לתייג ולא לטבוע באי-ההתאמות?
כותבים הנחיה עם דוגמאות לכל מחלקה, מכיילים את המתייגים על חתך משותף ומחשבים הסכמה ביניהם. מקרים שנויים במחלוקת עוברים לבורר, ולא נמסים בממוצע. הסכמה נמוכה מעידה על בעיה בקריטריון ההערכה, לא במודל.
מה לשלוח להתחלה ואיך נחזור עם הערכה
כדי שהתחלת העבודה לא תימשך להתכתבות ארוכה, מספיק מכתב אחד עם נתוני פתיחה — את השאר נדייק בשיחה. ככל שנתוני המקור קונקרטיים יותר, כך מדויקת יותר הערכת ההיקף: רואים כמה פרומפטים יש במעגל, לפי אילו מדדים להשוות וריאנטים והאם יש על מה להישען בבחירת המנצח. להלן המינימום שמספיק לדיון במשימה.
- פרומפטים פעילים — כל הווריאנטים שנמצאים כעת בעבודה, כולל ניסוחי גיבוי למקרים מורכבים וכללי הרכבה אם הפרומפט נבנה מחלקים.
- ייצוא של בקשות ותשובות אמיתיות לתקופה — עליו בונים מערך בדיקה: הוא צריך לשקף תרחישים שכיחים, ולא רק דוגמאות מייצגות.
- תיאור ההתנהגות הרצויה — מה נחשב לתשובה טובה ומה בלתי קביל: שלמות, טון, סירוב לעסוק בנושא, טיפול בבקשות הבהרה.
- מדדים ואופן המדידה — שיעור התשובות הנכונות, שיעור העריכות הידניות, הערכות הנציגים, זמן תגובה; בנפרד — כיצד המספרים האלה נאספים כיום.
- נקודות קריאה — איזה שירות פונה למודל וכיצד התוצאה חוזרת למוצר, כדי שהבדיקה תרוץ בנתיב הפרודקשן ולא בצד.
- מגבלות — דרישות להגנת נתונים, איסור על העברת מידע אישי, עומס מותר ומגבלות על פניות.
- הרשאות — מעגל בדיקות, פרטי גישה, אחסון נפרד לתיוג, כדי שריצות לא יתערבבו בתעבורה תפעולית.
תארו את המשימה בצורה חופשית — זה מספיק כדי להתחיל. נחזור עם תוכנית עבודה: כמה פרומפטים ניקח לריצה הראשונה, כיצד נבנה את מערך הבדיקה, אילו מדדים נקבע כמכריעים, על איזו תוצאה נעצור ובאילו לוחות זמנים נעמוד.







