Compounding של agentic workflows: כשה-skill רץ בפעם השנייה
Claude נהג היום באפליקציה שלי כמו משתמש — לחץ דרך feature, צילם אחד-עשר screenshots, כתב לי את המדריך התפעולי בעברית, PDF מוכן לאימייל עד הצהריים. החלק המעניין הוא לא הפלט. אלא שזו הייתה הריצה השנייה של ה-workflow, וריצה שנייה הייתה מבנית קלה יותר מהראשונה.
Claude נהג היום באפליקציה שלי כמו משתמש. לחץ דרך feature, צילם אחד-עשר screenshots, למד את ה-UI תוך כדי, ואז כתב לי את המדריך התפעולי בעברית — טקסט, פריסה, RTL, screenshots משובצים. PDF מוכן לאימייל עד הצהריים.
המשפט הזה הוא מה שאנשים מצטטים. הוא גם הדבר הלא נכון להתמקד בו. אחד-עשר ה-screenshots וה-PDF הם לא ה-claim ההנדסי. ה-claim ההנדסי הוא שזו הייתה הריצה השנייה של workflow, והריצה השנייה הייתה מבנית קלה יותר מהראשונה. ה-skill שרץ היום קוטלג מאתמול. הריצה של מחר תהיה קלה יותר מזו של היום.
זה מה שאני באמת רוצה לדבר עליו. Agentic efficiency אינה תכונה של המודל או של הכלים. היא תכונה של ה-artifact שאתה בונה עם ה-agent לאורך זמן. Compounding הוא המנגנון. הריצה השנייה היא איפה שאתה מגלה אם ה-compounding באמת עבד.
Agentic efficiency אינה תכונה של ה-agent. היא תכונה של ה-artifact שאתה בונה עם ה-agent לאורך זמן.
הריצה הראשונה הייתה prompt אחד
האפליקציה היא מערכת מכירות והזמנות בעברית, שעובדים לא-הנדסיים משתמשים בה. כל פעם שאני שולחת feature, שני דברים בסופו של דבר צריכים להתקיים בשבילו: מדריך שהמפעיל קורא כדי ללמוד את ה-feature, ו-automation skill כך ש-Claude יוכל להריץ את אותו flow דרך ה-API מאוחר יותר לעבודה ב-bulk. שני צרכנים, אותו source of truth — ה-UI עצמו.
הפעם הראשונה שבניתי את הזוג הזה, זה היה prompt אחד בשפה טבעית. תיארתי מה אני רוצה: לאמת את ה-code path, לנהוג באפליקציה מ-tab של דפדפן אמיתי כמו לקוח, לצלם screenshot של כל מסך, לכתוב automation skill שמכה את אותו flow דרך ה-API, ואז לכתוב מדריך בעברית למפעיל עם ה-screenshots משובצים. session אחד. מקצה לקצה.
הפלט לא היה draft. זה היה מדריך גמור, נשלח למפעיל, בשימוש. ה-API skill עובד. ה-PDF נרנדר נכון עם RTL בעברית. ההבחנה הזו חשובה למה שבא אחר כך, אז אני רוצה להדגיש: כשאני אומרת “ריצה ראשונה”, אני לא מתכוונת ל-prototype. אני מתכוונת ל-artifact אמיתי שעשה את העבודה שלו ב-production. כל כך טוב שרציתי שכל feature עתידי יקבל את אותו טיפול.
/skillify, בסוף
לכן הרצנו /skillify בסוף ה-session. Skillify היא meta-skill — אתה מצביע אותה על workflow שזה עתה סיימת, והיא צופה במה שעשית בפועל, מנתחת את החלקים הנושאים, ופולטת SKILL.md שהריצה הבאה תוכל לקרוא. הפלט הוא קובץ skill מקומי ל-project, ניתן לקריאה דרך slash-command, שמקודד את ה-workflow כהוראות ש-Claude קורא בראש כל invocation עתידית.
ה-framing חשוב. אתה לא יושב ומתכנן skill. אתה שולח artifact אמיתי ביד, ובסוף — כשהעבודה הייתה מספיק טובה שאתה רוצה שכל instance עתידי של העבודה הזו יקבל את אותו טיפול — אתה skill it. ה-skill הוא קיטלוג של ריצה מוצלחת, לא spec מלמעלה למטה.
ההבדל הוא הכל. Skill מתוכנן הוא ניחוש של מישהו על מה ה-workflow צריך להיות. Skill מקוטלג הוא מה שה-workflow היה בפועל בפעם האחת שבה הוא הפיק artifact אמיתי. הראשון הוא תיאוריה. השני נשלח.
הריצה השנייה
היום בחרתי feature אחר באפליקציה, הצבעתי את /feature-runbook עליו, ו-Claude יצא לדרך. הוא קרא את ה-route handlers ב-backend. הוא חיבר chrome-cdp ל-tab production אמיתי בדפדפן — read-only על כל mutation form, כי זה היה production, לא dev. פתח טפסים, צילם מצבי empty state, סגר בלי ללחוץ save, השתמש ב-entities קיימים ב-database עבור מצבי “after”. אחד-עשר screenshots, אפס כתיבות.
ואז הוא כתב את המדריך בעברית פסקה אחר פסקה, image refs וכל זה. בנה אותו ל-HTML. רינדר ל-PDF דרך headless Chrome. שלח לי את ה-PDFs באימייל דרך AgentMail כשהוא סיים. כל ה-loop היה slash command אחד וכמה תשובות הבהרה.
אני רוצה לפרק מה באמת עושה את העבודה ב-loop הזה, כי הפסקאות של ה-skill הן הדבר ש-compounds — ואלא אם כן אתה יכול לתת שם לחלקים הנושאים, אתה לא יכול לדעת אילו מה-workflows שלך הם skillable.
Claude כמשתמש, לא Claude כ-tester
ה-primitive הראשון הוא ה-agent מפעיל את האפליקציה כמו אדם אמיתי. לא בודק אותה. משתמש בה.
ההבחנה חדה. בדיקה טוענת ציפייה כלפי input ידוע. משתמש מגלה את ה-UI תוך כדי — מה במסך הזה, איפה הכפתור, מה התווית הזו אומרת, מה קורה אם אני לוחץ פה. Chrome-cdp נותן ל-Claude את התנוחה השנייה. הוא פותח את האפליקציה, מסתכל על מה שמרונדר בפועל, קורא את הכפתורים, מנווט, ומבין את ה-flow.
זה חשוב כי חצי מה-artifacts שאני רוצה — המדריך התפעולי, ה-API skill, סט ה-screenshots, עדכוני הידע ל-voice agent — תלויים במה שהמשתמש רואה, לא במה שה-component מרנדר. קוד של component משקר, במובן הידידותי: הוא מספר לך מה צריך להופיע, modulo i18n keys, modulo הרשאות, modulo conditional rendering, modulo שבעה דברים אחרים שמחליטים מה באמת מופיע. הדפדפן הוא ה-source of truth היחיד. Claude מסתכל עליו.
Read-only הוא החצי השני של ה-primitive הזה. נתוני production הם אמיתיים. Mutation forms נפתחים ומצולמים ב-empty state, אף פעם לא נשלחים. מצב ה-”after” מגיע מ-entities קיימים ש-database כבר מכיל. הכלל הזה מקודד כפסקה ב-skill: לעולם אל תלחץ Save על טופס prod; צלם empty state, מצא entity קיים למצב התוצאה. זו פסקה אחת. היא תקפה לכל feature עתידי.
ה-skill יודע מתי לשאול
ה-primitive השני הוא ה-agent יודע איפה ה-human-in-the-loop גר.
ל-feature של היום היו שני קהלים. צוות פנימי משתמש בו בצורה אחת. משתמשים חיצוניים משתמשים בו בצורה אחרת. הריצה הראשונה לא נתקלה בזה — ל-feature ההוא היה רק קהל אחד. הריצה השנייה פגעה בזה ביום הראשון.
מה שה-skill עשה, מוקדם בריצה, היה לעצור ולשאול. דרך ה-clarifying-question tool, הוא העלה ארבע שאלות scope: runbook אחד או שניים? עברית פנימית בגוף שלישי, או גם גרסה ללקוח בגוף שני? ללכת דרך prod או dev מקומי? לייצר את ה-API skill המזווג כן או לא? אני בחרתי: שני קהלים, walkthrough על prod, skill מזווג כן. אותה תיקיית screenshots, שני מדריכים.
זו החלטה הנדסית שהרבה מערכות agentic מפספסות. או שהן ממשיכות בכוח ומפיקות artifact אחד כששניים נצרכו, או שהן שואלות עשרים שאלות בכל ריצה והאדם בסוף עושה את העבודה בעצמו. הצעד הנכון הוא לשאול בדיוק את השאלות שהעבודה עד כה לא יכולה לענות עליהן. ה-skill קידד אילו שאלות אלו — כי הנקודה העיוורת של הריצה הראשונה הייתה שהיא מעולם לא חשבה לפצל לפי קהל. ברגע שהנקודה העיוורת הזו הייתה גלויה, הפסקה ל-skill כתבה את עצמה: אם ל-feature יותר מ-role משתמש אחד, שאל אם להפיק runbook אחד או שניים.
זו התרומה של הריצה השנייה. ריצה אחת הייתה הגילוי. ריצה שתיים stress-testing את הגילוי על feature בצורה אחרת, וה-skill מעלה רמה על מה שהריצה הראשונה החליקה עליו.
ריצה אחת היא גילוי. ריצה שתיים היא ה-stress test. ריצה שלוש היא ה-skill שמריץ אותך.
Verification בזמן הכתיבה
ה-primitive השלישי הוא verification אפוי לתוך שלב הכתיבה, לא אחריו.
ה-API skill המזווג שה-workflow מייצר הוא קובץ markdown עם דוגמאות curl לכל endpoint שה-feature נוגע בו. האינסטינקט הראשון הוא: לכתוב את דוגמאות ה-curl מתוך זיכרון של איך ה-feature מתנהג. הפסקה ב-skill אומרת לא. קרא כל route handler ב-ה-route handlers ב-source לפני שאתה כותב דוגמת curl אחת. אמת את ה-endpoint path, ה-HTTP method, צורת ה-request body, צורת ה-response. רק אז כתוב את ה-curl.
היום הכלל הזה תפס שני באגי שמות-שדות בזמן הכתיבה. שמות זעירים שנראים נכון במבט חטוף ונכשלים ב-API — סוג הבאג שעולה שעת debugging כשמישהו מריץ את ה-curl ומקבל 400. ה-skill תפס את שניהם לפני שהקובץ נשמר.
זה מה ש”agentic efficiency” באמת אומר בפועל. זה לא אומר שה-agent מהיר. זה אומר שה-agent נכון, כי verification קורה בשלב הכתיבה במקום אחרי שה-artifact נשלח ומישהו במורד הזרם משלם את המחיר.
Gotchas מקודדים
ה-primitive הרביעי — וזה שעושה את ה-compounding האמיתי — הוא שכל gotcha מריצה קודמת היא פסקה ב-SKILL.md שהריצה הבאה קוראת בראש ה-invocation.
רשימה קצרה של פסקאות ב-skill ה-runbook, רק כדי להיות קונקרטית:
- אמת כל endpoint shape כנגד ה-route handlers ב-source לפני כתיבת דוגמאות curl.
- לעולם אל תלחץ Save על mutation form ב-prod. צלם empty state, השתמש ב-entity קיים למצב התוצאה.
- מחרוזות עברית ב-eval shell args של
cdp.mjsנכשלות תחת zsh quoting. כתוב את ה-JS לקובץ ו-eval $(cat path.js). - Markdown-to-PDF: השתמש ב-Chrome headless עם
--no-pdf-header-footer. עברית RTL צריכהdir="rtl"על ה-body, לא רק per-element. - מגבלת body-size של AgentMail היא 9MB. אם יש לך יותר מ-PDF אחד, שלח אותם כאימיילים נפרדים.
כל אחת מהפסקאות האלה היא קיר שנתקלתי בו בריצה קודמת. עכשיו הם קירות שהריצה הבאה לא נתקלת בהם.
זה מנגנון ה-compounding. הריצה הראשונה משלמת את מס הגילוי. הריצה השנייה יורשת אותו. הריצה השלישית יורשת שתי ריצות שווה. עד הריצה החמישית או השישית, ה-skill הוא ספרייה קטנה של “דברים שנשכו אותי, ממוינים לפי מתי הם נושכים”, והעבודה האנושית מצטמצמת לבחירת ה-feature ולמתן תשובה לשאלות ההבהרה. שום דבר קסום. רק פסקאות.
למה זה שונה מ-documentation
Documentation לוכדת מה שהמערכת עושה. Skill לוכד מה שה-workflow עושה. אלה artifacts שונים.
Documentation מתישנת כשהמערכת משתנה. Skills מתישנים כשה-workflow משתנה — ו-workflows משתנים הרבה פחות מאשר מערכות. הפסקה על quoting של עברית למעלה לא אכפת לה איזה feature אתה מתעד. אכפת לה שאתה מפעיל chrome-cdp מ-Mac עם zsh, מה שנכון לכל ריצה של ה-workflow הזה במכונה שלי.
לכן skills עושים compound ו-documentation לא. Documentation היא תצלום של העולם; skills הם הפרוצדורה למשלוח בו. כל עוד הפרוצדורה נשארת זהה, כל gotcha שאתה מקודד כנגד הפרוצדורה משלם את עצמו על כל ריצה עתידית.
שלוש צורות של compounding, לא אחת
אני רוצה להיזהר פה, כי קל לקרוא את כל מה שכתבתי עד עכשיו ולהבין “compounding עובד כשאתה עושה בדיוק את אותה עבודה פעמיים”. זו הגרסה הצרה ביותר של הטענה והיא לא היחידה.
Compounding של workflow הוא מה שדוגמת ה-runbook הראתה. שתי ריצות של עבודה דומה מבנית, השנייה זולה מהראשונה כי הפרוצדורה קוטלגה. זה מה ש-skills הכי טובים בו. זה דורש שהעבודה תחזור בצורה, גם אם התוכן שונה.
Compounding של ידע רחב יותר. כל gotcha שאתה מקודד הוא עובדה על המערכת שאתה מפעיל בתוכה — ה-shell שלך, ה-DB, ה-deploy pipeline, הדומיין — והעובדה הזו נשארת נכונה גם כשהמשימה הבאה היא בצורה שונה לגמרי. הפסקה על quoting של עברית מקודם לא חלה רק על runbooks. היא חלה על כל workflow עתידי שמפעיל chrome-cdp מהמכונה הזו. ידע מצטבר על פני workflows, לא רק בתוך אחד.
Compounding של למידה רחב עוד יותר. כל פעם שאתה מושיט יד ל-tool, הפעם הבאה אתה מושיט יד אליו קצת יותר מהר ועם תחושה ברורה יותר של למה הוא טוב. זה קורה בין אם העבודה חוזרת ובין אם לא. Skills הם דרך אחת ללכוד את זה; קבצי context הם דרך אחרת; האינטואיציה של המהנדס לאורך זמן היא שלישית. אף אחד מהם לא דורש שהמשימה הבאה תיראה כמו הקודמת.
אז “skill it” הוא הימור ספציפי. הוא מהמר שה-workflow יחזור. כשההימור הזה צודק, אתה מקבל את כל ההאצה של דוגמת ה-runbook. כשלא — מחקר, design מקורי, עבודה שבה כל instance באמת חדש — אתה לא מקבל אותה, ו-skill it היה עולה יותר תשומת לב משהוא חוסך. אבל ידע ולמידה עדיין עושים compound מתחת, בקבצי context, ב-gotchas שאתה כותב, בדפוסים שאתה מפנים. ה-compounding לא נעצר. ה-artifact שאתה בונה כדי ללכוד אותו פשוט משנה צורה.
המבחן אם לעשות skill ל-workflow פשוט. אחרי ריצה, שאל: אם הייתי צריכה לעשות אותו סוג עבודה שוב בשבוע הבא, האם רוב מה שזה עתה גיליתי יחול, או שהייתי מתחילה מאפס? אם התשובה היא “רוב זה חל”, skill it. אם התשובה היא “הייתי מתחילה מאפס”, אל תעשה skill ל-workflow — אבל כתוב מה שלמדת איפשהו שהריצה הבאה תראה.
השאלה הזו היא בעצמה דוגמה לסוג השלישי. למדתי אותה דרך כך שעשיתי skill לדברים שלא הייתי צריכה, ולא עשיתי skill לדברים שהיה צריך, עד שהשאלה הנכונה התגבשה. ההיוריסטיקה גרה אצלי בראש ולא ב-SKILL.md, אבל היא עושה compound באותו אופן — שולמה פעם אחת, מיושמת בכל פעם. רוב העבודה שמרגישה חדשה מתבררת כאותה צורה שחוזרת, והשאלה היא מה שאומר לי מתי אני מולכת.
הצורה הרחבה יותר
Agentic efficiency אינה תכונה של המודל. מודלים משתפרים, אבל עקומת ההאצה ממודל טוב יותר היא לוגריתמית. עקומת ההאצה מ-artifact עשיר יותר בינך לבין ה-agent היא משהו אחר — כל gotcha שאתה מקודד הוא עלות קבועה ששולמה פעם אחת ומופחתת על כל ריצה עתידית.
לכן הריצה השנייה חשובה יותר מהראשונה. הריצה הראשונה מפיקה artifact אמיתי, וזה הכרחי, אבל הריצה הראשונה היא גם איפה שהעלות הכי גבוהה והגילוי הכי מבולגן. הריצה השנייה היא איפה שאתה מגלה אילו מהגילויים שלך מתכלים. ה-skill שרץ היום הוא ה-skill שה-session של אתמול הפיקה — וה-session של מחר, על איזה feature שלא יבוא, ירוץ גרסה מעט טובה יותר שלה, כי היום מצאה שני gotchas חדשים שלא היו ב-SKILL.md של אתמול.
Skill it, אל תריץ את זה מחדש. קטלג את ה-workflow כשהעבודה מספיק טובה שאתה רוצה שכל instance עתידי יקבל את אותו טיפול. תן לריצה השנייה לבחון תחת לחץ את מה שהריצה הראשונה החליקה עליו. קודד כל gotcha כפסקה. ה-agent לא משתפר; ה-artifact בינך ל-agent כן. שם ה-compounding גר.
ה-agent לא משתפר. ה-artifact בינך לבין ה-agent כן.