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

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

הדילמה פה ברורה ויושבת בגדול בין שלוש אפשרויות:

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

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

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

שלושת האפשרויות גרועות.

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

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

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

https://github.com/mbleigh/acts-as-taggable-on

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

@another_user.skill_list.add("clowning")


אבל אם נכתוב:

all_users.each do |u|
u.skill_list.add("clowning")
u.save
end


נבצע המון פעולות insert וזה כנראה יעלה בביצועים.

כמה מחשבות סביב זה בעקבות התנגשויות בין פיצ'רים:

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

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

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

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

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

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

def create_files(n, prefix):
for i in range(n):
with open(f"{prefix}{i}", "a") as f:
pass


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

פתרון 1 - העברת פונקציה
בפוסט קודם בנושא הצעתי להעביר פונקציה עבור prefix וזה נראה כך:

def create_files(n, filename_template):
for i in range(n):
filename = filename_template(i)
with open(filename, "a") as f:
pass


create_files(5, lambda i: f"demo{i}.txt")


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

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

def create_files(n, filename_template):
for i in range(n):
filename = filename_template.format(i=i)
with open(filename, "a") as f:
pass


create_files(5, "demo{i}.txt")


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

נ.ב. בטלגרם עניתי שאפשר אולי להשתמש ב t-strings כדי לכתוב את התבנית אבל האמת שזאת היתה טעות. format קל יותר, נכון יותר למצב הזה ועובד. מנגנון ה t-string החדש של פייתון 3.14 מבצע את השערוך בזמן יצירת המחרוזת בדיוק כמו f-string ולכן לא היה עובד כאן.
👍2
טיילווינד. AI. שינויים.
טיילווינד הפך בשנים האחרונות מרעיון הזוי לדרך הסטנדרטית בה אנשים כותבים CSS. אם אתם מפתחי ווב בוודאות נתקלתם בו וכנראה גם כתבתם בו. כשאדם וותן התחיל את טיילווינד הוא בנה ספריית תבניות שמדגימה איך כדאי להשתמש בטיילווינד כדי לבנות דברים יפים. הספריה נקראה tailwind ui היום היא נקראת tailwind plus והמכירות שלה עוזרות לאדם להחזיק את העסק ולהמשיך לפתח את הפריימוורק.

ואז הגיע AI.

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

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

> I totally see the value in the feature and I would like to find a way to add it.

> But the reality is that 75% of the people on our engineering team lost their jobs here yesterday because of the brutal impact AI has had on our business. And every second I spend trying to do fun free things for the community like this is a second I'm not spending trying to turn the business around and make sure the people who are still here are getting their paychecks every month.

> Traffic to our docs is down about 40% from early 2023 despite Tailwind being more popular than ever. The docs are the only way people find out about our commercial products, and without customers we can't afford to maintain the framework. I really want to figure out a way to offer LLM-optimized docs that don't make that situation even worse (again we literally had to lay off 75% of the team yesterday), but I can't prioritize it right now unfortunately, and I'm nervous to offer them without solving that problem first.

> @PaulRBerg I don't see the AGENTS.md stuff we offer as part of the sponsorship program as anything similar to this at all — that's just a short markdown file with a bunch of my own personal opinions and what I consider best practices to nudge LLMs into writing their Tailwind stuff in a specific way. It's not the docs at all, and I resent the accusation that I am not disclosing my "true intentions" here or something.

> @mtsears4 Tailwind is growing faster than it ever has and is bigger than it ever has been, and our revenue is down close to 80%. Right now there's just no correlation between making Tailwind easier to use and making development of the framework more sustainable. I need to fix that before making Tailwind easier to use benefits anyone, because if I can't fix that this project is going to become unmaintained abandonware when there is no one left employed to work on it. I appreciate the sentiment and agree in spirit, it's just more complicated than that in reality right now.

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

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

2. אפשרות שניה הבדיקה תגיד "צור ויקי עם שלושה דפים X, Y ו Z. חפש X. תראה שהתוצאה הראשונה היא X."

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

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

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

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

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

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

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

1. תריץ Code Review על הקומיט האחרון.

2. תסביר מה עושה פונקציה.

3. תכתוב תוכנית בדיקות לפונקציה.

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

5. נתונה בדיקה שנכשלת, תסביר למה היא נכשלת ותתקן אותה.

6. תעשה Refactor כדי לנקות קוד כפול.

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

1. לוחצים Ctrl+Shift+P ובוחרים Chat: New prompt file

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

3. בוחרים שם לקובץ הפרומפט.

4. כותבים את הפרומפט בקובץ ושומרים.

הפרומפטים נשמרים בתיקיית github/prompts עם סיומת .prompt.md. אחרי שיצרתם קובץ פרומפט אתם יכולים להפעיל אותו מתוך הצ'אט באמצעות כתיבת / ואז שם קובץ הפרומפט (לא צריך את כל השם יש השלמה אוטומטית).

זו דוגמה שראינו לפרומפט שמסביר פונקציה בתוכנית c בפרויקט libuv:

---
agent: agent
---

Please analyze the code below and provide a report with the following sections:

* 1. Functional Analysis *
* **Input Arguments:** detailed breakdown of types, expected ranges, and **ownership semantics** (who frees the memory?). Check for \const\ correctness.
* **Return Values:** Explain all possible return states, including specific error codes, \NULL\ pointers, or \errno\ implications.
* **Intended Use Case:** Infer who calls this function and why, based on the logic (e.g., is it a hot-path utility, a setup function, a blocking I/O call?).

* 2. Critical Code Review (The "Roast") *
* **Edge Cases & Validation:** Does the function handle \NULL\ pointers, zero-length buffers, or integer overflows?
* **Undefined Behavior (UB):** Identify any potential UB (e.g., signed overflows, uninitialized memory, strict aliasing violations).
* **Security:** specific checks for buffer overflows, use-after-free, double-free, or information leaks.

* 3. Performance & Resources *
* **Complexity:** Time and Space complexity (Big O).
* **System Impact:** specific analysis of heap allocations (\malloc\), blocking system calls, or cache locality issues.
* **Concurrency:** Is this function thread-safe? Is it reentrant?

* 4. Refactoring Suggestions *
1
*   Provide a refactored version of the code that fixes identified issues while maintaining the API signature (if possible).


קבצי Instructions
אם יש תוכן שמשותף לכמה פרומפטים ואתם רוצים לכתוב אותו תמיד כשפונים ל AI עבור קבצים מסוימים או קבצים בפרויקט מסוים תוכלו ליצור קובץ instructions:

1. לוחצים Ctrl+Shift+P ובוחרים Chat: New instructions file

2. בוחרים איפה לשמור את הקובץ - אצלכם במשתמש או בפרויקט.

3. בוחרים שם לקובץ.

4. מקלידים את ההוראות ושומרים.

קבצי ההוראות נשמרים בתיקיית instructions עם סיומת .instructions.md. בוובינר ראינו דוגמה לקובץ הוראות לפרויקט C:

---
applyTo: '*.*'
---
Act as a Senior C Systems Engineer and Security Researcher. You're working on a mission-critical library used by many external clients. Reliability, security (memory safety), and high performance are paramount.


כתיבת סוכנים
ל VS Code יש 4 סוכנים מובנים: Agent, Ask, Edit ו Plan. סוכן הוא חיבור בין קובץ הוראות לרשימת כלים שהוא יכול להפעיל - ואנחנו יכולים ליצור סוכנים חדשים למשימות ספציפיות. לדוגמה כדאי לנו לכתוב סוכן שיודע לעשות Code Review ומכיל כבר את תהליך העבודה וההרשאות הספציפיות הנדרשות לביצוע Code Review.

בשביל ליצור קובץ סוכן חדש אני בוחר מתפריט ה Ctrl+Shift+P באופציה New Custom Agent, שוב בוחר בשבילו מיקום וכותב את התוכן בקובץ. לסוכן יש גם הוראות וגם רשימה של כלים ומסך העריכה של VS Code כולל תיבת בחירה כדי לבחור את הכלים. הקובץ עצמו נשמר בתיקיית github/agents בפרויקט עם הסיומת .agent.md. זו דוגמה שראינו לקובץ סוכן שעושה Code Review:

---
name: Code Reviewer
description: An agent that reviews code for quality, style, security, and best practices.
tools: ['vscode', 'read', 'search', 'web', 'agent', 'todo', 'execute']
---
As a "Code Reviewer" agent, your primary function is to meticulously examine provided code snippets or files. Focus on identifying potential bugs, security vulnerabilities, adherence to project coding standards, and overall code quality. Provide actionable feedback and suggest improvements as comments directly in the code or a concise list of recommendations. You must be thorough.

As a "Code Reviewer" agent, your primary function is to meticulously examine provided code.

MANDATORY PROCESS:
1. Run the tests with "npm run test"
2. Perform static code review

If tests cannot be run, explicitly state why.


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

---
name: Test Runner
description: A subagent responsible for executing the Vitest test suite, analyzing failures, detecting flaky tests, and flagging potential performance regressions.
tools: ['execute']
---
As a Test Runner agent, your task is to run the project's Vitest test suite
and report results back to the invoking agent.

Responsibilities:
- Execute Vitest with "npm run test"
- Summarize failures with likely causes
- Identify slow or flaky tests
- Call out tests that may mask performance issues
- Do NOT modify code unless explicitly asked

Output should be concise, structured, and suitable for inclusion in a
code review.


אחרי שאני יוצר את הסוכנים המותאמים אישית אני יכול להפעיל אותם מחלון הצ'אט באמצעות שינוי הסוכן הפעיל ואתם תראו אותם מתחת ל-4 הסוכנים המובנים ב VS Code.

הרצת Sub Agents
לפעמים נרצה לבקש מהסוכן לעשות משהו בלי למלא את הקונטקסט בכל התוכן של מה שבוצע ובעצם להסתכל רק על התוצאה של תהליך ארוך. מנגנון כזה נקרא Sub Agents ובוובינר עצמו קצת הסתבכתי איתו. ניסיתי ליצור סוכן Code Review שיפעיל בתור Sub Agent סוכן אחר של Test Runner. גיליתי אחרי הוובינר שבשביל לעשות את זה צריך להפעיל בהגדרות ה VS Code את האופציה Custom Agent In Subagent. אחרי הפעלת האופציה הזו ויציאה מ VS Code והפעלה מחדש הצלחתי להפעיל סוכן של Code Review שיפעיל Sub Agent של Test Runner.

בשביל להפעיל משימה מסוימת בתור Sub agent עלינו לבקש את זה מהסוכן בקובץ ההוראות. בדוגמה הבאה אני מבקש מסוכן ה Code Review לבצע את הרצת הבדיקות בתור סוכן צדדי:

---
name: Code Reviewer
description: An agent that reviews code for quality, style, security, and best practices.
tools: ['vscode', 'read', 'search', 'web', 'agent', 'todo']
---
As a "Code Reviewer" agent, your primary function is to meticulously examine provided code snippets or files. Focus on identifying potential bugs, security vulnerabilities, adherence to project coding standards, and overall code quality. Provide actionable feedback and suggest improvements as comments directly in the code or a concise list of recommendations. You must be thorough.

As a "Code Reviewer" agent, your primary function is to meticulously examine provided code.

MANDATORY PROCESS:
1. Use a sub agent to run the tests with "npm run test"
2. Perform static code review

If tests cannot be run, explicitly state why.


שימו לב לשורה:

1. Use a sub agent to run the tests with "npm run test"


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

Since I don't have terminal access to run git commands directly, let me check if there are any staged or unstaged changes first, and also look at the workspace to understand what might have changed recently.

Actually, let me start by:

Running the test suite via subagent (as required)
Then look at what files might be the focus of the latest work
Let me proceed with the mandatory process.


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

התקנת שירותי MCP
בוובינר לא הספקנו לדבר על MCP אבל אני כן רוצה לגעת בזה בסיכום. בפרויקט אני יכול ליצור תיקיה בשם .vscode ובתוכה קובץ בשם mcp.json שיכיל את הגדרות שרתי ה MCP של הפרויקט הספציפי. אפשר להגיע לקובץ הזה מתוך Ctrl-Shift-P ולבחור Open Workspace Folder MCP Configuration.

הגדרת שרתי MCP דורשת קצת יותר מחשבה על הארגון ואופן העבודה שלנו עם אנשים אחרים:

1. שרת MCP שמוגדר בפרוטוקול stdio דורש שהתוכנית עצמה תהיה מותקנת לי על המחשב. כשאני מגדיר את הקובץ בהגדרות הפרויקט אני דורש שכל מי שעובד איתי על הפרויקט יתקין את ה MCP הזה.

2. שרת MCP שמוגדר בפרוטוקול http יותר גמיש ויעבוד לכל מי שיפתח את הפרויקט.

לדוגמה אם אני רוצה להוסיף את שרת ה MCP של גיטהאב כדי שאפשר יהיה מתוך VS Code להסתכל על Issues ולבצע פעולות ישירות בגיטהאב אני אכתוב בקובץ:

{
"servers": {
"github": {
"type": "http",
"url": "https://api.githubcopilot.com/mcp/"
}
}
}


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

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

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

import { useState, useEffect, useEffectEvent } from 'react'
import './App.css'

function EffectEventDemo({name}: {name: string}) {
const [time, setTime] = useState(0);

useEffect(() => {
const ivl = setInterval(() => {
setTime(c => c + 1)
}, 1000);

return () => clearInterval(ivl);
}, [name]);

return <p>User {name} is online for {time} seconds</p>
}

function App() {
return (
<EffectEventDemo name='demo' />
)
}

export default App



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

function EffectEventDemo({name}: {name: string}) {
const [time, setTime] = useState(0);

useEffect(() => {
const ivl = setInterval(() => {
fetch(\/ping\, {
method: 'POST',
contentType: 'application/json',
body: JSON.stringify({
name,
time,
}),
});
setTime(c => c + 1)
}, 1000);

return () => clearInterval(ivl);
}, [name]);

return <p>User {name} is online for {time} seconds</p>
}


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

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

function EffectEventDemo({name}: {name: string}) {
const [time, setTime] = useState(0);
const notifyServer = useEffectEvent(() => {
fetch(\/ping\, {
method: 'POST',
contentType: 'application/json',
body: JSON.stringify({
name,
time,
}),
});
});

useEffect(() => {
const ivl = setInterval(() => {
notifyServer();
setTime(c => c + 1)
}, 1000);

return () => clearInterval(ivl);
}, [name]);

return <p>User {name} is online for {time} seconds</p>
}


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

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

function EffectEventDemo({name}: {name: string}) {
const [time, setTime] = useState(0);
useEffect(() => {
fetch(\/ping\, {
method: 'POST',
contentType: 'application/json',
body: JSON.stringify({
name,
time,
}),
});
}, [time, name]);

useEffect(() => {
const ivl = setInterval(() => {
notifyServer();
setTime(c => c + 1)
}, 1000);

return () => clearInterval(ivl);
}, [name]);

return <p>User {name} is online for {time} seconds</p>
}
זה עובד אבל החיסרון כאן הוא שאין לנו שליטה על תדירות עדכון השרת. אנחנו מושפעים מהשינויים ב name וב time.

אפשרות שניה היא לשמור את זמן החיבור ואולי את name מחוץ לקומפוננטות ולכתוב את כל קוד עדכון השרת במקום אחר. זאת הגישה שלוקחת react-query. הקוד בגדול היה נראה כך (נכתב על ידי ChatGPT):

import { useEffect, useState } from "react";
import { useQuery } from "@tanstack/react-query";
import { sendOnlineTime } from "./api";

type Props = {
name: string;
};

export function UserOnlineTimer({ name }: Props) {
const [time, setTime] = useState(0);

// Local timer (increments every second)
useEffect(() => {
const interval = setInterval(() => {
setTime((t) => t + 1);
}, 1000);

return () => clearInterval(interval);
}, []);

// React Query handles the polling request
useQuery({
queryKey: ["user-online", name, time],
queryFn: () => sendOnlineTime(name, time),
enabled: time > 0,
refetchInterval: 1000,
refetchIntervalInBackground: true,
});

return <p>User {name} is online for {time} seconds</p>;
}


הפעם זה מבנה טוב ואפילו את הקריאה ל useQuery אפשר להוציא ל Custom Hook מה שעוד יותר יקל עלינו בפיתוח קומפוננטות "מדווחות" בהמשך.

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

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

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

ברור שזה לא שפת תכנות מסוימת או אפילו צורת כתיבת קוד מסוימת. מפתחים שכתבו משחקים למחשב אישי בשנות ה 80 לא ימצאו את הידיים והרגליים בסטודיו לפיתוח משחקים של 2025. אפילו בפערים קטנים בהרבה הקושי בולט, מפתחי PHP שרק בשנת 2004 בנו את כל האינטרנט התקשו ב 2014 למצוא עבודה בפיתוח אותה אינטרנט כשהפרדיגמה השתנתה ועברנו לכתוב קוד Front End.

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

1. היכרות עם אוסף גדול של פתרונות.

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

3. תשומת לב לפרטים ויכולת לזהות את הבעיה האמיתית ואת הבעיות האמיתיות העתידיות.

4. טעם טוב ויכולת לראות כשמשהו "לא נכון" או "יסבך אותנו בהמשך" או אפילו פשוט "מכוער".

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

6. יצירתיות, תעוזה וחשיבה מחוץ לקופסה. בתכנות זאת הראיה של "אם היה לי X אז הבעיה שאני עכשיו מסתכל עליה בכלל לא היתה קיימת. בעצם צריך לבנות את X".

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

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

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

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

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

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

פה המקום לפתוח סוגריים ולהתייחס להערה שאני שומע מדי פעם שאומרת "אולי כבר לא צריך חדשנות". יש לנו ריילס ויש לנו next.js ויש לנו ריאקט ו vue ויש לנו Web Assembly וגם Rust ו Docker. די מספיק. חדשנות או אבסטרקציות מאפשרות לנו לכתוב מערכות גדולות יותר בפחות קוד, אבל ל AI אין בעיה של כמות קוד. אפשר לזרוק הכל ולתת ל AI לכתוב כל מערכת מאפס באסמבלי.

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

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

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

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

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

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

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

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

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

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

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

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