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

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

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

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

גם המאמר Limitations of vibe coding in production של Domino השפיע על המחשבה שלי בנושא. הוא מתאר את ה־production gap, הפער בין פרוטוטייפ שעובד לבין מערכת שאפשר להפעיל עבור משתמשים אמיתיים. זה התחבר לי בדיוק לתחושה מול המנוע לציור מפות. הדמו הראה לי מה אפשר לבנות, אבל נשארה השאלה מה נדרש כדי שאוכל לקחת עליו אחריות.

1. גם בפרויקט צדדי יש אנשים בצד השני

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

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

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

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

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

אלה כבר שאלות על מה שאני מבקש מאנשים לסמוך עליו.

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

2. לסטארטאפ יש חלון שבו קל יותר לזרוק הכול

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

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

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

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

אני רוצה לשמור על היכולת לעשות שינויים גדולים גם בשלב הזה. בשביל זה אני צריך דרך טובה יותר לדעת שהם עובדים.

3. אני צריך לדעת גם מה נכנס לפרויקט

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

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

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

4. מספיק בדיקות טובות מאפשרות לי להעז יותר

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

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

ויש כאן שתי מילים שחשובות לי: מספיק וטובות.

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

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

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

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

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

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

ניסוי קטן · באג אמיתי
כל הטסטים ירוקים. איפה המלבן שלכם?
לחצו על המפה כדי להוסיף או להסיר מלבנים. שמרו וטענו מחדש, ואז בדקו איזו בדיקה מגלה את הבאג.
מנוע השמירה
המפה שלכם3 מלבנים
אחרי שמירה וטעינהממתין לשמירה
נסו קודם לשמור עם הבאג, ואז עם המנוע התקין.
בדיקה חלשה
האם פונקציית השמירה נקראה פעם אחת?
expect(saveCalls).toBe(1)
טרם הורצה
בדיקה טובה
האם המפה שנטענה זהה למפה ששמרנו?
expect(loadedMap).toEqual(originalMap)
טרם הורצה
שתי הבדיקות בודקות את אותה שמירה. רק אחת בודקת אם המפה שרדה אותה.

5. ומה אני אעשה עם הקוד הזה בעוד שנתיים?

אני עובד על פרויקט בן 12 שנים. אני לא צריך לדמיין מה קורה כשצריך לתחזק קוד שאף אחד לא מבין ושקשה להרחיב. אני מכיר את זה מהעבודה.

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

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

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

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

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

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

סיכום

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

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

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