בפוסט הזה נדבר על ״הטסטים״ של מערכות LLM, הרי הם ה Evaluations.
בשנת 2026, אף אחד לא מדמיין לשלוח לפרודקשיין מערכת שלא נבדקה בבדיקות אוטומטיות: בדיקות יחידה, בדיקות רכיבים ובדיקות אינטגרציה – שכבות שונות של בדיקות המוודאות שהמערכת עושה מה שאנו מצפים שהיא תעשה.
באופן דומה, לא סביר לשלוח מערכת, או מנגנון מבוסס LLM לפרודקשיין בלי Evaluations.
מדוע Evaluations ולא טסטים? מה נשתנה?
מערכות LLM (או LLM Apps) דורשות כמובן גם testing – כמו כל מערכת קוד. החלק שפונה ל LLM הוא החלק שלא ניתן לבדוק בעזרת מתודולוגית הבדיקה הרגילה:
- אי-דטרמניזם: אותו הקלט יכול להחזיר פלט שונה בכל פעם. במתודולוגיות בדיקות רגילות אנו יודעים לכל היותר להתמודד עם סבילות (tolerance), נניח לבדוק שהערך יהיה בין 5.5 ל 7.5.
- אין תמיד הגדרה חד־משמעית ל“נכון”: נניח בתשובה של סוכן-שירות-לקוחות ללקוח אין תשובה ״נכונה״. יש תשובות טובות יותר, וטובות פחות – במגוון פרמטרים.
- גם כשנדמה שהבעיה “סגורה” עם פלט בינארי (true/false) – עדיין חסרה ההגדרה החשובה באמת: מה מחיר הטעות, ואיזה סוג טעות גרוע יותר. האם עדיף לומר מדי פעם true כשהתשובה false או להיפך? מה ה tradeoff בין האופציות?
- ככל שמרחב הפלט שלנו מורכב יותר – כך בעיית הגדרת ה success היא מורכבת יותר.
- מרחב קלט/פלט עצום: לעתים מגוון האפשרויות הוא לא עשרות או מאות אופציות משמעותיות, אלא מרחב שלצורך העניין הוא אין-סופי. במקרים כאלו אי אפשר לעשות "test coverage״.
- שבירות: לא פעם שינוי קטן בקלט או בפרומפט יכול מאוד לשנות את התוצאה. זו סיבה חשובה נוספת לבדוק – אבל היא לא מקילה על הבדיקות. זה אומר שאם בדקתי קלט מאוד דומה עשרות פעמים והתוצאה היא טובה – זה לא מבטיח ששינוי קטן בקלט לא ישנה משמעותית את התוצאה.
- שחזור (Reproducibility) הוא קשה – נניח זיהיתי תסריט שבו המערכת נתנה תוצאה לא טובה. אני מתקן את ה prompt/RAG/מה שזה ורוצה להריץ מחדש.
- א. אני חייב לוודא שכל ה prompts, הגדרות tools או skills, גרסאת המודל (מתעדכנים כל כמה חודשים), ה context הכל זהה – אחרת אני לא בודק אותו הדבר.
- ב. אקראיות המודל עדיין משחקת תפקיד.
- למשל: פרקטיקה מקובלת היא לקבוע את ה temperature ל 0 בזמן eval (אפילו אם המודל ירוץ בסוף בטמפ׳ גבוהה יותר) – וכך לצמצם את האקראיות.
אפשר להעלות עוד בעיות, אבל זה הבסיס.
חשוב לבדוק. חשוב מאוד לבדוק, אבל המתודולוגיה הקיימת ל testing פשוט מאוד רחוקה מדי מכדי לתת מענה.
מה עושים? יש כבר מתודוליה מבוססת וידועה. מדענים/חוקרים עם הדילמות האלו כבר עשורים. בעצם אנו זקוקים לשילוב בין Empirical Evaluation ל Statistical Evaluation או בקיצור Evaluations. זו הבשורה הטובה.
הבשורה הפחות נוחה, היא שאין ״EUnit״ (על משקל JUnit) או JasmineEval מוכן, לא כי קשה לבנות framework כזה אלא מכיוון שצריך להתאים את שיטת הבדיקה הספציפית למערכת הספציפית. אין one-size-fits-all.
עבור כל מערכת LLM תצטרכו לתפור Evaluation המתאים למידותיה. זה לא מסובך כמו שזה עשוי להישמע בתחילה – אבל זה בהחלט מציב אתכם בעולם של ניהול סיכונים תמידי שאולי פחות הייתם רגילים לו בתור מהנדסים.

תהליכי האימות הם לא קלים ולא זולים, אבל בלעדיהם:
- לא נדע באמת כמה טובה/מדויקת המערכת שלנו.
- לא נדע לזהות במהירות רגרסיות בביצועים.
- יהיה מאוד קשה להשתפר, או לדעת היכן / מתי צריך להשתפר.
- לא נדע להעריך כמה מסוכנות ״תשובות לא טובות״. האם הן ״לא טובות״ או מהוות סיכון ממשי (חושפות מידע רגיש, סיכוניים משפטיים, או הטעייה קשה של המשתשמש).

אז איך מתמודדים עם כל חוסר השלמות / ודאות הזה? האם נידונו לתסכול ושחיקה?
אפשר להגיע למסקנה הזו ברגעים הראשונים, אבל התשובה היא שלא – חשוב להבין שזה עולם הבעיה, וצריך להכיל את חוסר השלמות / דיוק / ודאות שבוודאי ניתקל בו.
שכלית – אני בטוח שכולנו נצליח להפנים את הרעיונות בצורה דיי מהירה.
רגשית – זה לפעמים לוקח יותר זמן. בתור מהנדסים שרגילים לעבודה מסודרת/מדוייקת/נקייה – יהיה עלינו להסתגל לפחות שליטה על מה שקורה.
איך אני יודע שזה אפשרי? גידול ילדים. למהנדסים דקדקנים רבים יש ילדים – וגם שם, אין לנו שליטה מלאה על הדברים. אבל אנחנו מסתדרים, ואולי אפילו נחמד לנו 🙂🙂🙂.
Guardrails מול Evaluation
כדי לכסות מערכת מורכבת, ובצורה יעילה ולא יקרה מדי אנחנו משלבים את האימות שלנו בכמה רמות. כמו שבתוכנה ״רגילה״ יש בדיקות יחידה/רכיב/אינטגרציה כך בבדיקה של מערכת LLM נהוג להשתמש ברמה רמות של בדיקה.
בגדול* יש לנו שתי קטגוריות עיקריות של שיטות אימות:
- Evaluations – מריצים את המערכת על סט דוגמאות מוכנות מראש, נותנים ציונים לתוצאות, ומצפים לרף מסוים (משתנה) של תוצאות כדי להחשב הצלחה. למשל: ציון ממוצע 80 ומעלה.
- Guardrails – אלו בדיקות שמתבצעות כחלק מכל בקשה, בזמן ריצה: לבדוק ששלבים שונים בתהליך הם מספיק טובים ולא מעידים על תקלה. למשל: כשלון מסוים של Retrieval יכול להשבית את הסיכוי למודל לספק תשובה טובה, ולכן עדיף לנסות מחדש חלק או את כל התהליך.
* ניתן להגדיר עוד כמה קטגרויות, וכמה תתי-קטוגוריות – אבל בואו נתקדם שלב-שלב.
מפתה לנסות להקביל Guardrails ל בדיקות יחידה ו Evaluations ל בדיקות אינטגרציה אבל זה לא מדויק בכמה מישורים. הדמיון אולי הכי חשוב הוא שמערכות מורכבות – נרצה את שניהם. לרוב דווקא מתחילים ב Evals ומוסיפים Guardrails עם הזמן כדי לשפר את הכיסוי.
| תכונה | Evaluations | Guardrails (או SafeGuards) |
| מתי רצים | תקופתית / לפני השקת גרסה. | בכל בקשה (request) בפועל. |
| זמני ריצה | דקות עד שעות. Batch / Offline. כל הפעלה מפעילה מודל LLM (עקרונית). | עשרות מילי-שניות עד שניות בודדות (וידוא מול מקורות חיצוניים). גם אם נשתמש במודל LLM זה לרוב יהיה מודל קטן ויעיל. Online/realtime. |
| אתגרים | יקרות לפיתוח, תחזוקה, והרצה. ״היכן ניתן לעשות פחות?״ | למצוא את המינון הנכון של אפשור / חסימה. |
| מה עושים כאשר הבדיקה נכשלת? | חוקרים מהיכן נובע ה drift – ואיך לתקן אותו. חקירה = עבודה. | החלטת זמן-ריצה (fallback/חסימה/הורדת יכולת/תיעוד). ניתוח אנושי תקופתי גם כאן. |
| כלים נפוצים (לא חובה) | DeepEval, LangSmith, TruLens | GuardRails AI, NeMo Guardrails, various imperative validations |
דוגמה קצרה לתהליך Evaluation
בשלב הזה אני רוצה להדגים דוגמה פשוטה לתהליך Evaluation. דוגמה קונקרטית ולא תאוריה.
הצורך: כחלק מהגשת תביעה במערכת שלנו, לקוחות מעלים מסמכים. המסמכים נמצאים ב pool אחד (אינם מסווגים) – מה שגורם לעבודה רבה יותר על הטיפול בתביעה. אנחנו רוצים לקחת מסמכים בפורמט תמונה / PDF ולסווג אותם לאחת מ 4 קטגוריות:
- הצעת מחיר Estimate
- קבלה Receipt
- חשבונית Invoice
- תצהיר Declaration
זו בדיוק סוג המשימה שמאוד קשה לתכנת בקוד, אבל LLM מצליח לטפל באופן מרשים מאוד.
יצרנו פרומפט, שלחנו איזה 10 מסמכים לדוגמה, ונראה שהתוצאות ממש טובות! המודל כמעט תמיד הצליח חוץ משני מסמכים ש… אפשר להבין מדוע התבלבל. האם אפשר כבר לצאת לפרודקשיין?
אנשי הפרודקט יירצו כנראה לדעת כמה אנחנו מדויקים. מה הסיכוי לטעות – וכמה גדולות הטעויות? יש גם AI Compliance שרוצים את זה בכתב ועם בקרה רבעונית (בארגונים יותר גדולים). מה עושים?
המקרה שלנו מרגיש לא כל-כך מסובך:
- ״הטעות הכי גדולה הוא המרחק בין 2 קטגוריות: הנחנו מסמך אחד והתקבל אחר״.
- ״התוצר משפיע בעיקר על פרודקטיביות של הטיפול בתביעה (נזק קל) ואפשר לתקן בדיעבד (סרקתי את המסמכים וגיליתי שמה שסומן כ״חשבונית״ הוא בעצם ״קבלה״)״.
שווה לציין שמשימת Classification היא ברורה יחסית לתהליך ה Eval. לבדוק Generation (טקסט חופשי) – הרבה יותר מורכב.
שלב ראשון: בניית Golden Dataset
ברור שגם אדם שמסווג מסמך לקטגוריה עלול לטעות. אולי לא תמיד ניתן לסווג את המסמך בצורה חד-חד ערכית: נניח חשבונית שהיא גם קבלה. שאנחנו בונים Golden Dataset אנחנו רוצים:
- למפות בצורה אמינה את המרחב – להבין אלו מקרים אפשריים, וכמה הם תדירים.
- לצמצם את המרחב בצורה מספקת – להגדיר את הבעיה כבעיה פשוטה ככל שנכון עסקית, ולאו דווקא לסבך את הדברים.
לכמה דוגמאות אנחנו זקוקים?
עבור בדיקת התכנות ראשונית? לפחות 50 דוגמאות.
עבור יציאה לפרודקשיין 200-1000 דוגמאות.
מדוע אלו המספרים? אלו כללי-אצבע להתחיל איתם. כמובן שכל מקרה לגופו.
האם אפשר פשוט לשלוף מבסיס הנתונים 200 רשומות אחרונות?
אם נבחר 200 רשומות רציפות יש סיכוי טוב שהמדגם שלנו לא יהיה מייצג. נניח: בימים שונים בשבוע / חודש / שנה – יש סוג אחר של מסמכים שאנו נתקלים בהם יותר. זו נקראת הטיית זמן. מדגם רציף מגדיל את התלות בין דוגמאות ולכן מגביר את הסיכוי לקורולציה. יותר בעייתי הוא חוסר-הייצוג למקרים נדירים, כי מתוך 200 רשומות רצופות בוודאי נפספס מקרי קצה חשובים, בטח במשקל החשיבות העסקית שלהם.
האם לברור 200 רשומות מייצגות ידנית?
גם זה לא יעיל. אנחנו לא יודעים בדיוק מה מייצג, ואנחנו לא רוצים לעבוד קשה סתם לכן הדרך המומלצת היא:
- לבחור מגוון אקראי של דוגמאות, נניח 90% מה dataset הן רשומות אקראיות מהשנה האחרונה.
- לברר עם מומחי הדומיין מהם מקרי הקצה בעלי משמעות עסקית גבוהה – ולברור מגוון של מקרים כאלו (ה 10% הנותרים).
ה Golden Dataset שלנו הוא לא רק ״נתונים לצורך בדיקות״, הוא בעצם המיקוד שלפיו נאפטם את ה pipeline. הבחירה היא משמעותית.
את ה golden dataset צריך לתייג. מישהו צריך לעבור ידנית על 200 המסמכים הללו ולתייג אותם בדייקנות. דיוק התיוג חשוב לא פעם יותר מגודל ה dataset. פרקטיקה מקובלת היא לעשות שני מעברים – שני מתייגים כך שאם יש סתירה – הם יושבים ומבלנים את הפער – וכך הדיוק איכותי יותר.
כמובן שזו הרבה עבודה, ולכן יש גם טכניקות להוזלת עלויות. למשל: LLM as a judge, ניתן חלק מהתיוג או בדיקת התיוג – למודל LLM נוסף; לרוב: הכי חזק שנגיש לנו, לא זה שנשתמש בו בזמן ריצה.
יש כלים שונים שעוזרים לבצע ולבדוק את התיוק, להצליב תוצאות וכו׳. למשל SuperAnnotate for Data Trainers.
במהלך התיוג, סביר שניתקל במקרי קצה שלא לקחנו בחשבון. למשל חשבונית שהיא גם קבלה. מה נעשה? יש שתי גישות עיקריות:
- נחליט לתייג קבלה+חשבונית כחשבונית – ו״נַטֶּה״ את ה pipeline לטעות העדיפה מבחינתו (מבלי להוסיף עוד קטגוריה – שתסבך את הכל).
- נוסיף קטגוריה נוספת Unknown ונלמד את ה pipeline שלנו להודות שהוא לא בטוח. זה עדיף, הרבה פעמים, על לנחש לא נכון.
שלב שני: קביעת מדדי הצלחה
חשוב להבין מה התסריט העסקי. לא רק ״מקסימום דיוק״ אלא ״אלו טעות יותר כואבת מטעות אחרת״. למשל אמרנו קודם (חוסר-דיוק):
״הטעות הכי גדולה הוא המרחק בין 2 קטגוריות: הנחנו מסמך אחד והתקבל אחר״.
אבל אם חשוב במיוחד לעבור ידנית על תצהירים, והמערכת שלנו נוטה לפספס תצהירים ולסמן אותם כחשבוניות – אז הנזק הוא לא סימטרי. זמן רב יותר יתבזבז ואולי ייגרמו טעויות משמעותיות יותר.
כלומר: התוצאה יכולה להיות משהו כזה:
- הכי חשוב לנו לא לפספס תצהירים. עדיף לסווג מסמך שאינו תצהיר – כתצהיר, ולטעות (הבוחן יתקן את ההגדרה) מאשר לפספס את התצהירים ולסווג אותם כמסמכים שונים. זה נקרא recall(Declaration).
- חשוב גם כן להבחין נכון בין חשבוניות וקבלות. זה מבלבל גם אנשים, ואנחנו רוצים לחסוך להם את הזמן בהבחנה בינהם. צד אחד לא חשוב יותר מהשני. זה נקרא pair confusion(Invoice,Reciept).
כן. השלב הזה הוא איסוף דרישות ולא תמיד איש הפרודקט יידע לעשות זאת. תוכלו לספק יותר ערך לחברה אם תדעו לגרום לזה לקרות נכון.
שלב שלישי: יישום (איטרציה ראשונה)
אז יש לנו dataset איכותי ומדדי הצלחה. נממש את ה pipeline שלנו: Prompt, אולי קצת context building (הדוגמה הזו נראית פשוטה), בחירת מודל, temperature וכו׳ – ונריץ את 200 הדוגמאות. נחשב את הפערים בין התוצאות של ה pipeline (קרי: ה LLM) מה שנקרא גם prediction מול המתייגים האנושיים (שאנחנו מחשיבים כאמת, מה שנקרא ground truth). במקום ה ״assert״ יהיה לנו חישוב שתוצאתיו יראו משהו כזה:
- recall(Declaration) = 0.77
- pair confusion(Invoice,Reciept) = 0.68
האם זה מספיק טוב לביזנס? – זאת שאלת המפתח. בכל מקרה, מכיוון שזו איטרציה ראשונה, ואחרי שהשקענו כל-כך הרבה זמן בבניית ה golden dataset שווה לנסות עוד כמה איטרציות נוספות: שינויים ב prompt, בפרמטרים למודל, מודלים שונים, וכו׳. אולי אחרי כמה עשרות איטרציות נגיע לתוצאה כמו:
- recall(Declaration) = 0.74
- pair confusion(Invoice,Reciept) = 0.81
האם זה טוב יותר? זו כמובן שאלה עסקית לאנשי המוצר. אלו הדילמות שתתקלו בהן שוב ושוב. קשה לשפר הכל – ולא פעם צריך לקבל פשרות.
כיצד מריצים את החישובים הנ״ל? אנחנו משתמשים בכלי פנימי להרצה וחישוב (על בסיס scikit-learn – הכלי מקובל לחישובי נכונות ססטיסטית). יש גם פתרונות יותר שלמים – סוויטות שלמות של איסוף נתונים, בדיקה, וניתוח (בעיקר כלים מסחריים). פחות חשוב הכלי, יותר חשוב שהתהליך יהיה מבוקר ו reproducible.
להשוואת התוצאות (מהר מאוד יצטברו עשרות ניסויים שתרצו לברור ביניהם) הכלי המקובל הוא MLOps.
חשוב להזכיר שהרצה של LLM pipeline הוא פעולה יקרה:
- כל הרצה יכולה לקחת דקות עד שעות.
- כל הרצה יכולה לעלות בדולרים – במיוחד אם יש LLM as a judge. נניח: 4$~ להרצה.
כדי לבדוק יציבות, לפעמים אנחנו מריצים את אותו ה pipleline כמה פעמים, ננניח 3-5 פעמים ועושים ממוצע.
זה לא נשמע הרבה – אבל זה מצטבר. כנראה שלא תרצו להריץ את ה evaluation כחלק מה CI/CD pipeline שלכם, אלא רק כאשר אתם עושים שינוי רלוונטי (נניח: ב prompt) או פעם בשבוע כדי למצוא רגרסיות.
סיכום
קיבלנו הצצה על איך נראה תהליך Evaluation ובמה הוא שונה מ Automated Testing.
יש עוד הרבה מה לכסות בנושא ה Evaluations:
- אלו מטריקות קיימות, ואיך בוחרים ביניהן? single class vs. multi-class וממוצעים (micro/macro/weighted)? אופרציונליזציה (הפיכת תוצאות כלליות – למדידות).
- סטטיסטיקה ל LLM App Engineers: מובהקות, טעויות סטטיסטיות אפשריות (biases) ואיך להיזהר מהן, וכו׳.
- LLM-as-a-Judge: איך עושים ומנהלים את ה tradeoff בין הוזלת עלויות – לדיוק/ניהול סיכונים.
- Context/Retrieval Evalaution: כאשר ה RAG מורכב, יתכן ונרצה לעשות Eval גם לו.
- Post-Deployment Evaluation: איך לאסוף ולייצר פידבק מפרודקשיין שנוכל להשתמש כדי לשפר את המודל?
האמת שהתחלתי את הפוסט עם יותר deep dive – והוא נראה לי קשה מדי לעיכול, ושכתבתי אותו לחלוטין. אני מקווה שזה היה משתלם…
שיהיה בהצלחה!
