דילוג לתוכן הראשי

קלוד קוד: איך בודקים אם הסקיל שכתבתם באמת שינה משהו

מאת ירון דויטשר עודכן לאחרונה:

כתבתם סקיל, הרצתם אותו, והתשובה יצאה טובה. מה זה מוכיח?

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

זה בדיוק מה שעושה ‎claude plugin eval‎, פקודה שנוספה בגרסה 2.1.269 מ-11 בספטמבר לפי יומן השינויים. התיעוד שלה דורש את הגרסה הזאת ומעלה, והיא עובדת על תוספים ועל תיקיות סקילים כאחד.

המספר היחיד שחשוב הוא ההפרש

ברירת המחדל היא שכל מקרה בדיקה רץ שלוש פעמים עם התוסף ושלוש פעמים בלעדיו. שש ריצות למקרה אחד, ושני ציונים בסוף.

ההיגיון פשוט, והתיעוד אומר אותו במפורש: אם מקרה מקבל ציון מלא גם עם התוסף וגם בלעדיו, לא התוסף הוא זה שגרם לו לעבור. ההפרש בין שני הציונים, ‎Δ‎, הוא כל מה שהתוסף תרם.

CASE        WITH  W/OUT  Δ
first-case  1.00  0.33   +0.67

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

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

איך נראה מקרה בדיקה

אין צורך לכתוב את החבילה ביד. ‎claude plugin eval init‎ פותח סשן, קורא את התוסף, שואל אתכם איך נראית תוצאה טובה, מציע ניסוחים שאמורים להפעיל את הסקיל וניסוחים שלא אמורים, ומנסה אותם פעם אחת לפני שהוא כותב את הקבצים.

מה שנכתב הוא קבצים רגילים שאפשר לפתוח ולערוך:

evals/first-case/
├── prompt.md            # מה שקלוד מקבל, ומגבלות הריצה
└── graders/
    └── criteria.md      # בודק אחד: איך מנקדים את התוצאה

ב-‎prompt.md‎ יושבת הבקשה כפי שמשתמש היה מקליד אותה, ולא כפי שמתכנת היה מנסח אותה. זו הנקודה: הבדיקה אמורה לבדוק אם קלוד בוחר בסקיל כשאיש אינו מצביע עליו.

---
max_turns: 10
allowed_tools: [Read, Glob, Grep, Skill]
---

כתבו לי הודעת קומיט לשינוי הזה: שיניתי שם של פונקציה ועדכנתי את שלושת מקומות
הקריאה שלה.

וכל קובץ תחת ‎graders/‎ הוא בדיקה אחת על מה שיצא. הבודק שכדאי להתחיל ממנו אינו שופט את איכות התשובה אלא את מקורה:

---
type: tool_used
tool: Skill
input_match: '"skill"\s*:\s*"(?:[\w-]+:)?your-skill-name"'
---

ארבעה בודקים חינם, ושניים שעולים כסף

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

שווה לדייק מה ״חינם״ אומר כאן: הריצה עצמה תמיד עולה, כי הסוכן באמת מבצע את המשימה. ארבעת הבודקים הזולים אינם מוסיפים לחשבון מעבר לריצה, ושני היקרים כן.

השופט הוא מודל קטן ומהיר כברירת מחדל, ואפשר להחליף אותו במודל חזק יותר כשהקריטריון דורש שיפוט אמיתי ולא התאמת תבנית.

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

מה שלא נטען בזמן הבדיקה

זה החלק שמפתיע את רוב מי שמריץ את הפקודה בפעם הראשונה, והוא גם זה שהופך את המספר לאמין.

כל ריצה מקבלת תיקיית בית זמנית, תיקיית עבודה ריקה והגדרות נפרדות, והסוכן הנבדק רץ שם עם התוסף שלכם בלבד. לפי התיעוד, מה שאינו נטען כולל את ההגדרות האישיות שלכם, את ה-hooks, את קובצי CLAUDE.md, את שרתי MCP, את שאר התוספים המותקנים, את הזיכרון ואת שאר הסקילים. גם רוב משתני הסביבה אינם מגיעים לריצה.

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

ועוד פרט קטן שמונע רמאות: הסוכן אינו יכול לקרוא את תיקיית הבדיקות. הוא אינו רואה את הבודקים שיפעלו עליו ואינו רואה את שאר המקרים.

התקלה הראשונה שכולם פוגשים

התיעוד מנחש מה תראו ראשון, ובצדק: הפרש קרוב לאפס, ולידו בודק ״הסקיל הופעל״ שנכשל.

המשמעות אינה שהסקיל כתוב רע. המשמעות היא שקלוד לא בחר בו כשהבקשה נוסחה בשפה של בן אדם, ולכן התשובה נכתבה בלעדיו. התיקון אינו בגוף הסקיל אלא בשורת ה-‎description‎ שלו, וזו בדיוק השורה שקלוד רואה תמיד וששאר הסקיל מוסתר מאחוריה (הרחבה במדריך הסקילים).

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

מה לעשות היום

  • להריץ על סקיל אחד קיים, לא על חדש. הערך הראשון אינו בכתיבת בדיקות אלא בגילוי שסקיל שאתם סומכים עליו חודשיים אינו משנה דבר
  • לנסח את הבקשה כמו משתמש. אם הפרומפט אומר ״תשתמש בסקיל X״, מדדתם שקלוד יודע לציית, לא שהסקיל שווה משהו
  • לתת לכל מקרה שני בודקים: אחד על התוצאה ואחד על הדרך. יחד הם אומרים גם אם התשובה נכונה וגם אם הסקיל הוא זה שייצר אותה
  • לזכור שזה עולה כסף אמיתי. כל ריצה היא קריאת מודל על החשבון שלכם, ומקרה אחד הוא שש ריצות. בזמן שעובדים על ניסוח הבודקים אפשר לוותר על הריצה חסרת-התוסף ולחתוך את העלות בחצי, ואפשר לקבוע תקרת עלות לריצה
  • לשים לב לאן הולך הדוח. בחשבון עם מנוי claude.ai הדוח נפרס אוטומטית כארטיפקט פרטי ומודפס קישור אליו. מי שמעדיף שהוא יישאר על הדיסק צריך לבקש זאת במפורש בדגל
# ריצה מלאה על כל המקרים, מתיקיית התוסף
claude plugin eval .

# מקרה אחד, ריצה אחת, בלי ההשוואה חסרת-התוסף
claude plugin eval . --case first-case --runs 1 --ablation none

שורה תחתונה

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

ההפרש מול ריצה בלי התוסף הוא ההפרדה הזאת, והוא לרוב קטן ממה שנדמה. זה אינו חדשות רעות: סקיל שההפרש שלו אפס הוא סקיל שאפשר למחוק, ומחיקה כזאת מחזירה קונטקסט בכל תור.

מי שכבר יודע אילו סקילים שלו מעולם לא הופעלו: הדוח שמראה מי אשם. ומה שקלוד באמת רואה כשהוא בוחר סקיל: המדריך המלא לסקילים.

הניוזלטר: מה חדש בקלוד, בעברית ובחינם

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

מעדיפים ללמוד את זה בקורס או בסדנה?

רוצים שאנחנו נבנה לכם עוזר AI או אוטומציה בקלוד?