ToCode
1.42K subscribers
3.83K links
טיפים קצרים למתכנתים מאת ינון פרק
Download Telegram
קוד ידידותי ל AI - הרהורים בעקבות הוובינר
הי חברים,
אתמול העברתי וובינר על פיתוח קוד ידידותי ל AI. היו המון שאלות מעניינות שעלו במהלך השיחה, לחלקן היו לי תשובות טובות בזמן אמת ועל חלקן עוד המשכתי לחשוב במהלך היום. אני מסכם פה את המסקנות המרכזיות מהשיחה.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

2. תיקון בשכבה השניה - ראינו היום איך סוכן הקידוד לפעמים יוצר בעיית ביצועים (N+1 Query) ולפעמים לא. ראינו איך להתמודד עם זה באמצעות תיקון בשכבה השלישית כלומר הוספת הוראה ב AGENTS.md אבל האמת שזה לא תיקון מספיק טוב ובחלק מהמקרים למרות שיש הוראה מפורשת לסוכן לשים לב לבעיות מסוג זה הוא עדיין מפספס. פעם הבאה אראה איך אני מתקין כלי אוטומטי לזיהוי בעיות ביצועים מסוג זה ומחייב את הסוכן להשתמש בו לפני שהוא מסיים לעבוד.

3. תיקון בשכבה השלישית - כשהפרומפט מבולבל סוכן הקידוד יתבלבל איתו. הייתי רוצה להראות איך לקרוא את הפלט של ה AI, להבין מהשיחה מה לא נכון בפרומפט ולתקן.
1🔥1
תודה לכל אלה שבאו אתמול ההארות והשאלות שלכם הן הדרך הכי טובה גם בשבילי להבין טוב יותר את רעידת האדמה הזו שכולנו חווים. שבוע הבא וובינר על LangGraph ואנחנו עוד נחזור לנושא של פרויקטים ידידותיים ל AI בסדרת הוובינרים הבאה.
קוד ידידותי לבני אדם
עדיין נאבקים ב AI כדי שיכתוב את הקוד שאתם צריכים? חלק מהסיבה היא שהפרויקט שלכם מסובך מדי וחלק מהסיבה שהפרויקט מסובך היא הקוד שסוכן הקידוד כבר כתב. דוגמה? בטח. זה ב PHP היום:

// Create workflow in account 1
$messageIds1 = $this->createSeriesMessages(2);
$template1 = $this->generateSeriesLogicJsonTemplate(2);
$result1 = $this->createSeriesAutomationWithMessages(
$this->accountId,
$this->listId,
$template1,
array_combine(range(0, count($messageIds1) - 1), $messageIds1)
);
$workflowId1 = $result1['workflowId'];

// Add subscribers to account 1
$subscriberIds1 = array_slice($this->subscriberIds, 0, 3);
$this->seedUserEnterList($this->listId, $subscriberIds1, $this->accountId);
$this->runAutomationHandler($this->accountId);

// Create second account
$this->secondAccount = $this->createSecondAccount(5);

// Create workflow in account 2
$messageIds2 = [];
for ($i = 0; $i < 2; $i++) {
$messageIds2[] = $this->createMessageForAccount(
$this->secondAccount['accountId'],
$this->secondAccount['listId'],
$this->secondAccount['senderId'],
"Account2 Message " . ($i + 1),
"Account2 Subject " . ($i + 1)
);
}
// ... skip more code ...
$workflowId2 = $responseData2['createdId'];


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

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

1. יוצר workflow בחשבון 1
2. מוסיף מנויים לחשבון 1
3. יוצר חשבון שני
4. יוצר workflow בחשבון 2

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

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

$workflowId1         = $this->createWorkflowInAccount($this->accountId);
$this->addSubscribersToAccount($this->accountId);
$this->secondAccount = $this->createSecondAccount(['subscribers' => 5]);
$workflowId2 = $this->createWorkflowInAccount($this->secondAccount);


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

// Create workflow in account 1
$messageIds1 = $this->createSeriesMessages(2);
$template1 = $this->generateSeriesLogicJsonTemplate(2);
$result1 = $this->createSeriesAutomationWithMessages(
$this->accountId,
$this->listId,
$template1,
array_combine(range(0, count($messageIds1) - 1), $messageIds1)
);
$workflowId1 = $result1['workflowId'];


בחשבון השני דילגתי על רוב הקוד כי הוא היה מאוד ארוך. מה שקלוד עשה שם הוא מעניין - הפונקציות שמופיעות בקטע ויוצרות את המידע לחשבון הראשון לא מקבלות את מזהה החשבון בתור פרמטר ותמיד יעבדו על $this->accountId. קלוד קוד משתדל מאוד לא לשנות חתימות של פונקציות ולכן הוא יעדיף להעתיק את תוכן הפונקציות מתחת להערה ולייצר הרבה יותר קוד שגם לא עקבי עם הקוד שהיה לפניו.

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

I see file @tests/Automations/AutomationQueueReconciliationWorkerTest.php uses 2 accounts but many of the helper
functions aren't used for the second account because they are hard coded with $this->accountId
Map the helper functions that could be reused, refactor them to accept accountId and then refactor the tests to
use them


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

I see file @tests/Automations/AutomationQueueReconciliationWorkerTest.php uses 2 accounts but many of the helper
functions aren't used for the second account because they are hard coded with $this->accountId
Create a class to wrap test helpers of an account call it TestAccount. Move all test helpers to be mthods of this class and use it to create multiple accounts:

$account1 = new TestAccount();
$account1->seupWorkflowWithSubscribers();
$account2 = new TestAccount();
$account2->seupWorkflowWithSubscribers();


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

אבל מה שאנחנו רואים בקלות לגבי אנגלית קשה לנו לראות לגבי תכנות.

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

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

צריך להגיד, אנחנו לא יודעים מה ילד יום. יכול להיות שסוכן הקידוד של העתיד יהיה כל כך טוב שאף אחד לא יראה יותר קוד ונעבור לתכנת באנגלית ואפילו לא נצטרך להבין את הקוד שהוא כותב. אבל כל עוד כן חשוב לכם להבין את הקוד שיוצא שווה לזכור שהבנה היא סקאלה. ההבנה הטובה ביותר כוללת גם את היכולת לדבר. ומה שטוב זה שסוכן הקידוד יכול לעזור לכם גם בזה אם רק תבקשו.
1
טיפ: סוכני קידוד וקבצי הזכרון שלהם
נתתם לקלוד לבנות פיצ'ר, המימוש לא היה משהו, מחקתם את מה שהוא כתב עם git restore . && git clean -f -d והמשכתם הלאה בחיים.

סוף סיפור? לא בדיוק.

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

הזכרון של קלוד קוד מוסבר בדף התיעוד הזה:

https://code.claude.com/docs/en/memory


הרבה פעמים שווה להגדיר CLAUDE_CODE_DISABLE_AUTO_MEMORY=1 ולוותר על יצירת הזכרונות תוך כדי תנועה ובמקום זה להסתמך על קבצי הוראות.

הזכרונות עצמם נשמרים בתיקיית ~/.claude/projects/<project>/memory/. תיקייה אחת למעלה תוכלו למצוא את כל השיחות הקודמות שעשיתם עם קלוד. מדי פעם מומלץ:

1. לכתוב /memory בתוך קלוד קוד, לבקש עריכה של קובץ הזכרון ולנקות אותו.

2. לבקש מקלוד קוד עצמו שינקה זכרונות לא רלוונטיים או לבקש שימחק פרטים ספציפיים (בפרומפט של קלוד קוד).
🔥1
השוואה בין Claude Code, Copilot CLI ו Cursor CLI
סוכני הקידוד משורת הפקודה השתפרו מאוד ממש בחודשים האחרונים. זה התחיל עם קלוד קוד וההתלהבות הגדולה ממנו, משך את תשומת הלב של מייקרוסופט והביא לפיתוח Cursor CLI ואחרונים הגיעו Cursor עם כלי CLI משלהם. כל השלושה מעולים ובזכותם הצלחתי בתקופה האחרונה לחזור לקודד עם vim. בכל זאת אני רוצה לשתף את המסקנות המרכזיות שלי מהעבודה עם שלושתם, לא בשביל להגיד תשתמשו בכלי X או Y אלא יותר לעשות סדר, לראות חוזקות וחולשות ולתת לכם את הכלים איך לבחור.

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

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

app/controllers/demo_controller.rb:69-70 


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

קודקס לא מופיע בהשוואה הזו כי לא ניסיתי אותו.

כמה זה עולה
הדרך המקובלת לעבוד עם כלי AI היא מנוי חודשי ולכל אחד מהכלים יש את המנוי שלו:

1. קרסר מציעים מנוי בסיסי ב 20$ לחודש ומנויים עם יותר שיחות ביותר.
2. קופיילוט מציעים מנוי בסיסי ב 10$ לחודש ומנוי עם יותר שיחות ב 40$.
3. קלוד קוד מציעים את המנוי הבסיסי ב 20$ לחודש ומנוי מתקדם ב 100$.

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

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

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

מצבי פעולה
בכל אחד מהכלים כפתור Shift+Tab יחד מחליף מצב פעולה. המצבים הם:

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

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

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

פיצ'רים
אלה הפיצ'רים המרכזיים שניסיתי בשלושת הכלים:

1. כולם תומכים בשרתי MCP
2. כולם תומכים ב Skills
3. כולם יכולים להראות שיחות ישנות ולהמשיך סשן קודם
4. קופיילוט וקלוד יודעים לנתח פרויקט וליצור לעצמם קובץ AGENTS בסיסי.
5. קופיילוט יודע להראות את השינויים בתיקייה בדומה ל git diff. אישית אני מעדיף את git diff מתוך וים כדי לעבור על שינויים.
6. כולם יודעים לעבוד עם sub agents וליצור סוכנים, למשל סוכן עבור code review.
7. כולם יודעים לשגר מספר סוכנים שיעבדו על בעיה במקביל.
מעבר לזה לקלוד קוד יש עוד המון פיצ'רים שלא ניסיתי או לא היו שימושיים עבורי כמו לעשות fork לשיחה בנקודה מסוימת, לקבל נוטיפיקציות כשכלים מסוימים רצים ואפילו להוריד סטיקרים.

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

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

הניסוי עלה לי סך הכל 50$, מחולק 20 לקלוד, 20 לקרסר ו 10 לקופיילוט. אני מרוצה מהעבודה עם שלושתם וממליץ גם לכם לנסות כדי לראות איזה כלי אתם הכי אוהבים ומצליחים להגיע לתוצאות טובות עם המודלים שמתאימים לכם. כלומר אם אתם רואים שאתם כל היום עובדים עם אופוס יכול להיות שתוכנית ה 100$ לחודש של קלוד תתאים לכם. מבחינת תמורה למחיר קופיילוט לדעתי הכי משתלם ולקרסר יש קסם משלו למרות שצריך לשים לב למודל ולפעמים לשנות מהמודל האוטומטי לסונט או אופוס.

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

services:
db:
image: postgres:15
container_name: my_postgres

api:
build: ./api
container_name: my_api
depends_on:
- db


קלאסי נכון? שרת API שתלוי בבסיס נתונים והגדרת depends_on בדוקר קומפוז כדי לוודא שבסיס הנתונים עולה קודם.

אבל בעצם... למי אכפת מה עולה קודם?

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

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

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

הנה כמה מטריקות טובות יותר לשילוב AI במהלך הפיתוח:

1. כמה אחוז מהקוד נכנס למערכת בלי שאף אחד קרא אותו?
2. כמה אחוז מהקוד ש AI כותב הרגשנו בנוח לזרוק לפח?
3. מה אנחנו עושים היום טוב יותר או אחרת ממה שעשינו בעבר בזכות ה AI?
4. כמה גרסאות שונות אני בודק לכל פיצ'ר לפני שאני מתקדם?
5. כמה תהליכי עבודה מבוססי AI חדשים בנינו בארגון?

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

אם ה AI כתב 100% או 80% מהקוד זה לא הדבר החשוב, מה שחשוב זה איך אנחנו עובדים היום ואיך תהליך העבודה השתפר בזכות שימוש בכלי AI.
👍1