ru
Feedback
ToCode

ToCode

Открыть в Telegram

טיפים קצרים למתכנתים מאת ינון פרק

Больше
1 419
Подписчики
-124 часа
-17 дней
-130 день
Архив постов
ToCode
1 419
📌 מתי נוכל להפסיק לקרוא את הקוד? ההבטחה של Spec Driven Development היא פשוטה - במקום לכתוב ולקרוא קוד נעבור לכתוב ולקרוא איפיונים. במאמר ארוך בנושא ראיתי את ההמלצה הבאה:
Don’t kill the code reviews; just move the human checkpoint upstream to reviewing intent, specs, plans, constraints, and acceptance criteria. Code is actually the least important part of the reviews.
אין ספק שהתעשייה וגם המפתחים עצמם רוצים להגיע לשם. הרבה יותר מעניין לתכנן ארכיטקטורת מערכת ולשחק עם אילוצים מאשר לקודד לולאות ולהיזכר בשמות מדויקים של פונקציות. ועדיין אני חושב שטכנית אנחנו עוד לא שם. אלה הסיבות בגללן אני עדיין קורא את הקוד: 1. סוכן קידוד לא תמיד מייצר את הקוד באיפיון - זאת לדעתי הבעיה הכי משמעותית עם SDD. שינוי קטן בקוד יכול לגרום למערכת להתנהג אחרת ממה שהתכוונתי באיפיון, ובלי לקרוא את הקוד אין לי איך לדעת על הבעיה. (לא קל לבדוק 100% מהפונקציונאליות במערכת מעניינת). 2. איפיונים לא תמיד מדויקים - אולי עם השנים נלמד לכתוב אפיונים יותר מדויקים. בינתיים אני רואה הרבה פעמים שאני כותב איפיון שנראה לי מאוד מדויק אבל כשהוא הופך לקוד אני מגלה שפספסתי מקרים חשובים. זה לא משהו שהייתי רואה בלי לקרוא את הקוד שנוצר. הקוד בעצם ממקד ומחזק את האפיון. דוגמה קטנה מ langlets - ביקשתי מהסוכן פיצ'ר שכשלוחצים על מילה בטקסט יקפוץ פופאפ עם התרגום שלה. הסוכן הוסיף onclick על המילה אבל בגלל שמדובר ב JavaScript רגיל (לא ריאקט) בעמוד שהכיל הרבה טקסט נוצרו המון Event Handlers. לכל מילה היה את ה onclick שלה. כמובן שיכולתי לכתוב באיפיון לייצר רק Event Listener אחד על הקונטיינר. לא חשבתי על זה כשכתבתי את האיפיון. אולי גם יכולתי לשים לב לבעיה כשהסתכלתי על האפליקציה עובדת אבל בדף הבדיקה שלי לא היה מספיק טקסט בשביל לגרום לעומס. העומס נוצר רק בדף ארוך במיוחד שנפתח מתוך דפדפן מוטמע מתוך אפליקציה. בקריאת הקוד רואים מיד את הטעות ואפשר להחליט מה לעשות איתה. בלי קריאה של הקוד צריך להתמודד עם משתמשים שבסיטואציה מסוימת המערכת לא עובדת להם בלי להבין למה. יכול להיות שבעוד כמה שנים המודלים יהיו כל כך טובים שלא נצטרך לקרוא את הקוד. כרגע אני לא רואה איך זה יקרה. קריאת הקוד היא עדיין הדרך הטובה ביותר שיש לי להבין את המערכת. שאלה שחוזרת בהקשר הזה היא על ההבדל בין קריאת קוד של AI לקריאת קוד של קומפיילר. למה חשוב לקרוא את הקוד ש AI מייצר בעוד שאין צורך לקרוא את קוד המכונה שהקומפיילר מייצר? התשובה עונה לנו בדיוק על השאלה בכותרת. מתי נוכל להפסיק לקרוא קוד? כשכבר לא נצטרך. כשנוכל לקבל הבנה מלאה של המערכת רק מקריאת האיפיונים והתיעוד שכותב הסוכן. בינתיים אנחנו לא שם.

ToCode
1 419
📌 הקפיצה הבאה בין 2015 ל 2018 לימדתי קורסים בפיתוח Web ו Mobile Web. למרות שאנגולר יצאה לשוק כבר ב 2010 וריאקט ב 2013, רק באזור 2015 הטכנולוגיות האלה הבשילו ושינו את שוק העבודה. באותן שנים פגשתי המון מפתחי PHP ו jQuery שידעו הרבה יותר ממני על דפדפנים ובמיוחד על דפדפנים ישנים ובכל זאת התקשו למצוא עבודה. באותו הזמן חברות השקיעו מאמצים אדירים בגיוס מפתחי Front End. כולם שאלו את כולם מי מכיר ויכול להמליץ על מפתחים, אפילו בוגרי קורסים טריים מצאו עבודה יחסית בקלות. כולם חוץ מאנשי ה PHP וה jQuery. רק לרשום את המילים האלה בקורות החיים היה יכול לעלות לך בפסילה מראיונות. מישהו היה יכול לחשוב שמדובר באיזו התנגדות של אותם אנשי PHP לטכנולוגיה החדשה אבל האמת יותר מורכבת. הבעיה של אותם מפתחים למצוא עבודה היתה שגם כשהם למדו את הכלים החדשים הם המשיכו להשתמש בהם באותה גישה של הכלים הישנים. זה לא התחביר השונה שהיה קשה אלא ההתרגלות לשיטת העבודה - לחיפוש חבילות מוכנות ב npm, למימוש קוד גם כשהוא לא נראה אותו דבר או אפילו עובד על כל הדפדפנים, להתמקדות בביצועים כי עכשיו זה אפשרי. ועכשיו אנחנו על סף קפיצה נוספת וכל רעידת אדמה כזו מביאה איתה שינויים, פיטורים, קידומים ותיאוריות שמשתנות חדשות לבקרים. למרות שזה נראה כאילו אנחנו רק רוצים לרוץ מהר ולדלוור עוד פיצ'רים, הסיפור של ה AI הוא יותר מורכב: 1. המפתחים של העתיד ישימו דגש על פיתוח תשתיות חזקות ויסודות חזקים שיוכלו לאפשר ל AI לבנות פיצ'רים ולשנות דברים מהר. 2. המפתחים של העתיד יהיו הרבה יותר טובים בלקרוא קוד ויהיו הרבה יותר רגישים כשהקוד לא תואם לתבניות ול Best Practices שהם הכתיבו. 3. המפתחים של העתיד ינהלו מערכות שבונות מערכות ויצטרכו לנטר את השינויים בקוד ואירועים בלוגים בזמן אמת. 4. המפתחים של העתיד יצטרכו לסנכרן ולבצע אופטימיזציה לצוותים של סוכנים תוך שיפור איכות הקוד, מהירות הפיתוח וצמצום עלויות. כן זאת הנדסה. שלא נטעה - בניגוד לרושם שאולי היה באותה תקופה ולסטראוטיפים עקב פרשיות כמו leftpad, אנשי הפרונטאנד לא "התקינו כל חבילה מ npm בלי לחשוב", ידעו לכתוב קוד גם בעצמם ולמעשה השקיעו המון מאמץ בכתיבת קוד, פשוט קוד אחר מזה שכתבו אנשי ה PHP שבאו לפניהם. גם היום בעבודה עם AI בשביל להתקדם עלינו להבין איך להשתמש במיומנות ובידע שלנו ולשלב בינו לבין הכלים החדשים. בסוף הקפיצה מערכות תוכנה וצוותי פיתוח יראו אחרת ממה שהם נראים היום. המעבר ל FrontEnd הוציא אותנו מהמונוליט, פתח את הדלת לפיתוח Micro Services ובמידה רבה לתשתיות ענן. אף אחד לא יודע איך יראה הפיתוח בעתיד ואיזה מיומנויות נצטרך, מה שבטוח הוא שהדרך היא לא להבין איך להשתמש בכלים החדשים כדי לעשות את אותו דבר שעשית עד עכשיו. הדרך קדימה היא להשתמש בכלים החדשים ובאמצעותם לגלות רעיונות חדשים שאי אפשר היה לממש קודם.

ToCode
1 419
📌 בואו נספור טוקנים - CLI מול MCP השבוע בוובינר נדבר על כלכלת טוקנים כלומר איך לבזבז פחות טוקנים כשבונים דברים עם AI. יש המון כלים שאמורים לחסוך את הטוקנים אוטומטית אבל אני חושב שיותר מעניין להיות ספציפיים ולשים לב לטוקנים שאנחנו מבזבזים בכל פעולה. אם בנוסף לזה בסוף נרצה גם כלי לכיווץ טוקנים תמיד אפשר להוסיף. אחד הדברים שנראו לי הגיוניים כשהתחלתי לבדוק את הנושא הזה של כלכלת טוקנים זה שהמעבר מ MCP ל CLI יעזור לנו לחסוך. זה נראה נכון תיאורטית אבל בניסוי נראה שהמצב קצת יותר מורכב. בואו נראה את הדוגמה עם neon. נאון הוא ספק של בסיסי נתונים בענן. יש להם ממשק שורת פקודה וגם ממשק MCP. לפני שנלך ל AI בואו נראה איך משתמשים בשני החיבורים כדי לענות על שאלה פשוטה "האם יש למשתמש בסיס נתונים בשם X". בכלי שורת הפקודה זה די פשוט. הפקודה neon projects list מחזירה את כל הפרויקטים בתור טבלה. אני יכול להוסיף --output json כדי לקבל את הפלט בתור JSON ואז אפשר לחבר אליו כלי כמו jq כדי להריץ שאילתה ספציפית. אז אם אני מחפש האם קיים פרויקט בשם goomba אוכל להריץ:
neon projects list --output json | jq '.projects[] | select(.name == "goomba") | {id, name}'
התוצאה - אם יש כזה פרויקט נקבל JSON קטן עם ה id וה name של הפרויקט. אם אין יגיע פלט ריק. ומה קורה ב MCP? הבעיה ב MCP היא שאין לי אופציה להעביר את הפלט לכלי נוסף כמו jq. ב MCP בשביל לענות על השאלה אני מפעיל את כלי רשימת הפרויקטים וצריך להעביר ל AI את כל הרשימה כדי להבין אם יש או אין פרויקט בשם מסוים. תיאורטית הפעלה של הפקודה מה CLI אמורה לחסוך טוקנים - במקום להכניס ל AI את כל הפרויקטים הוא יפעיל את הפקודה ויקבל רק את הפרטים של הפרויקט שאני מחפש. עכשיו בואו ננסה את זה מתוך סוכן קידוד כדי לראות צריכת טוקנים. הפעלתי את קלוד בקופיילוט ושאלתי:
use neon MCP and check if I have a project named goomba
התשובה שאין כזה עלתה 4.9 קרדיטים (כי ככה הם קוראים לטוקנים בקופיילוט היום). בשיחה שניה ביקשתי:
use neon CLI tool and check if I have a project named goomba
קלוד בתוך הקופיילוט לא התרגש מהבקשה וענה:
The user wants to use the Neon CLI tool to check if they have a project named "goomba". Let me search for the Neon MCP tool that's configured in their workspace.

Looking at the mcp.json file, they have a Neon MCP server configured at https://mcp.neon.tech/mcp. Let me search for tools related to Neon.
לאחר מכן הוא הצליח למצוא כלי בשם neonctl והפעיל אותו כדי לקבל את כל רשימת הפרויקטים בתור טבלה וסיים עם ההודעה שאין לי כזה פרויקט והחיפוש עלה לי 4.7 קרדיטים - קצת פחות מה MCP אבל עדיין לא סיבה למסיבה. בואו ננסה לעזור לו. כתבתי את הפרומפט הבא:
use neon CLI tool (called neon, it's already installed) and check if I have a project named goomba
  The CLI tool has --output json flag to get output as JSON. It returns an {"projects": [{"name": ...}, { ... }]}
  can use 'jq' to focus your query
הפעם הוא הריץ את הפקודה הנכונה:
neon projects list --output json | jq '.projects[] | select(.name == "goomba")'
והחזיר את התשובה שאין פרויקט במחיר מבצע של 3.8 קרדיטים בלבד, קרדיט שלם פחות ממה שעלה החיפוש דרך ה MCP או ירידה של 22% בעלות. מצד אחד תמיד כיף לחסוך. מצד שני החסכון הזה קורה רק אם יש לי הסבר ברור בפרומפט איך להשתמש ב CLI, הסבר שכנראה נצטרך לשים באיזשהו קובץ תיעוד או skill. לא בטוח שיש פה חסכון אמיתי. בטוח שכדאי להתרגל לקרוא את הפלט של הסוכן ולהבין מה קרה שם - אפילו אם ביקשתם משהו לא בטוח שה AI ילך לפי התוכנית.

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

ToCode
1 419
📌 כזה ניסיתי: חשבונות זמניים בקלאודפלייר קלאודפלייר הוסיפו מנגנון חדש של חשבונות זמניים לסוכנים וזאת הזדמנות מצוינת לנסות עוד פלטפורמת Deployment - בואו נראה על מה מדובר ואיך זה עובד. ✏ מה הם בנו קלאודפלייר רוצים להיות ברירת המחדל אליה סוכנים יעלו ניסויים ודוגמאות ולכן הם מורידים כל חיכוך שיכול להאט את הסוכן. הצעד הנוכחי הוא פתיחת אפשרות ליצור חשבון קלאודפלייר בלי הרשמה, בלי אימייל, בלי קאפצ'ה ובלי שאלות. זה עובד ככה: 1. סוכן מפעיל wrangler deploy --temporary כדי לדחוף את הפרויקט. 2. במקום להתלונן קלאודפלייר יוצר לו במקום חשבון. 3. כל פקודת wrangler נוספת מאותה תיקייה תתחבר לאותו חשבון זמני. 4. אחרי שעה החשבון נמחק, אלא אם כן בא בן אדם (משתמש של קלאודפלייר) והצהיר שזה הסוכן שלו וכך לקח בעלות על החשבון. ✏ ניסוי - יצירת דף נחיתה ואיסוף לידים חשבון קלאודפלייר מאפשר ליצור מערכת Full Stack מלאה במיני ענן של קלאודפלייר, כן כי לכולם יש עננים היום. זה אומר מערכת עם: 1. קוד צד שרת ב TypeScript, Python או Rust 2. מידע בבסיס נתונים SQLite 3. מידע במחסן מידע KV Store 4. תעודת SSL אז בשביל המשחק התקנתי את wrangler שלהם, פתחתי פרויקט hono חדש בתיקייה ריקה עם:
$ npm create hono@latest .
ואז הפעלתי קלוד עם הפרומפט הבא:
Cloudflare worker landing page
Build a landing page for a new secret project
Save leads to an SQLite3 DB on the worker
Create an admin page protected by hardcoded password "leads" to show the saved leads
Deploy to cloudflare and give me the URL
קלוד התחיל לרוץ ובנה את הדף ואז הגיע הרגע שצריך להעלות את המערכת לאוויר. בשביל זה קלוד ביקש ממני להתחבר בשבילו לקלאודפלייר, כנראה כי קלוד עדיין לא הכיר את מנגנון החשבונות הזמניים. כתבתי את פרומפט ההמשך:
continue with a temp account
וזה כבר הספיק. שימו לב איך קלוד מגלה על האופציה של החשבון הזמני:
⏺ Let me check what the temporary-deploy flow supports.

⏺ Bash(npx wrangler deploy --help 2>&1 | grep -iA1 -e temporary -e "x-provision" -e provision || echo "no temporary flag found"; echo "---versions upload
  help---"; npx wrangler versions upload --help 2>&1 | grep -i temporary || true)
  ⎿  no temporary flag found
     ---versions upload help---

                                                                                                                          05:00 PM claude-opus-4-8
⏺ No --temporary flag exists in this wrangler version (that message from whoami was generic). Let me see exactly what an unauthenticated deploy does here.

⏺ Bash(echo "" | timeout 25 npx wrangler deploy 2>&1 | head -40; echo "EXIT: ${PIPESTATUS[1]}")
  ⎿  npm warn Unknown user config "email". This will stop working in the next major version of npm.

      ⛅️ wrangler 4.103.0
     ────────────────────

     ✘ [ERROR] In a non-interactive environment, it's necessary to set a CLOUDFLARE_API_TOKEN environment variable for wrangler to work. Please go to
     https://developers.cloudflare.com/fundamentals/api/get-started/create-token/ for instructions on how to create an api token, and assign its value to
     CLOUDFLARE_API_TOKEN.


       To continue without logging in, rerun this command with `--temporary`. Wrangler will use a temporary account and print a claim URL.


     🪵  Logs were written to "/Users/ynonp/Library/Preferences/.wrangler/logs/wrangler-2026-06-21_14-00-32_913.log"
     EXIT:

                                                                                                                          05:00 PM claude-opus-4-8
⏺ --temporary does exist (just hidden from help). It uses a temporary account and prints a claim URL. Now I need D1 to work under that temp account. Let
  me check if d1 create supports it.
אנחנו רואים שבנסיון הראשון קלוד חשב שאין אופציה --temporary אבל קלאודפלייר הוסיפו את התיעוד על האופציה הזאת לפלט של wrangler וכך קלוד "מבין" את המנגנון ומשתמש בו. מכאן ללא צורך בפרומפט נוסף קלוד סיים לבנות את דף הנחיתה והעלה אותו ל URL זמני על קלאודפלייר לבדיקה.

ToCode
1 419
4. gallery shows all creations of all users

No need to create a users system or authentication, let anyone save whatever they make.

Create the DB and all required resources and push
וזה הספיק בשביל לקבל את האפליקציה שלנו בענן, מחוברת לבסיס נתונים חדש שנוצר על neon וסביבת שמירת קבצים על vercel. ✏ סיכום - פיתוח Vibe Code מקומי סך הכל הפיתוח המקומי עובד די טוב. אפשר לחבר את קלוד קוד המקומי לשירותי ענן ברשת דרך MCP או כלי CLI. כשמתקינים כלי CLI כדאי להתקין גם את התיעוד שלו בתור Agent Skill. אני ממליץ להשתמש בכמה שיותר שירותים שכבר מובנים ולא להמציא מחדש גלגלים, במיוחד בפיתוח Vibe Coding כשאנחנו לא רוצים להסתכל על הקוד ומחפשים מוצר באוויר כמה שיותר מהר. בעבודה מקומית יש לנו יותר שליטה על המוצר וה Deployment שלו וגם על בחירת סוכן הקידוד - אפשר לבחור כל סוכן ולעבוד עם טוקנים מתוכנית המנוי שלכם.

ToCode
1 419
📌 סיכום וובינר: וייב קודינג מקומי עם קלוד קוד בחודשים האחרונים יותר ויותר מפתחים מעדיפים לפתח מערכות מאפס על המחשב המקומי שלהם בעזרת כלים כמו Claude Code במקום בעזרת פלטפורמות ענן כמו Lovable. בוובינר השבוע דיברנו על התהליך הזה, הראיתי את הפערים בין פיתוח מקומי לפיתוח בענן ואיך לסגור אותם. ✏ אקוסיסטם הכח של פלטפורמות פיתוח מערכות בענן הוא קודם כל היותן מרכז שליטה וחיבור לכלים חיצוניים. מערכת ב Lovable או Base44 נותנת אוטומטית מהפלטפורמה את היכולת להריץ את האפליקציה בענן, כלומר שהיא תהיה נגישה לכולם, ובנוסף: 1. ניהול משתמשים. 2. בסיס נתונים. 3. תשלומים. 4. שליחת סמסים, אימיילים, ווטסאפ, טלגרם. 5. שמירת קבצים. ועוד אינסוף אינטגרציות כפי שמתועד בעמוד ה Connectors של Lovable. המעבר לפיתוח מקומי לא אומר שאנחנו מוותרים על אותן היכולות אלא פותח לנו יותר אופציות: מצד אחד אנחנו יכולים עדיין לחבר את הפיתוח המקומי לפלטפורמה כמו Lovable דרך שרת ה MCP שלהם. שרת ה MCP מתועד כאן ואם נחבר אליו את קלוד קוד או כל סוכן מקומי הוא יוכל לבנות לנו את הפרויקט מקומי ולדחוף ל Lovable כשזה מוכן. מצד שני פלטפורמות ענן נוספות זיהו את הפוטנציאל ומציעות אחסון של אפליקציות בממשק נוח לסוכן מקומי ועם חיבורים שונים - לדוגמה val.town מציעה אחסון מהיר לאפליקציות בענן, חיבור לאימייל, חיבור לבסיס נתונים, אחסון קבצים ואפילו חיבור ל AI. ורסל מציעה אחסון של אפליקציית next.js ואחסון קבצים בענן. וכמובן פלטפורמות הענן הוותיקות AWS, GCP ו Azure מאפשרות לסוכן המקומי לדחוף אליהן את המוצר. אפשרות נוספת שעלתה בוובינר היא לבקש מהסוכן המקומי לבנות את הפיצ'רים שאנחנו צריכים כחלק מהמערכת. אני לא ממליץ ללכת בכיוון הזה כי יותר קוד זה רק יותר באגים ויותר תחזוקה ואיפה שאפשר למקד את המוצר זה עדיף. ✏ מה בונים בעבודה עם Lovable התחלנו תמיד עם ה Template שלהם - אפליקציית next.js עם אוסף קומפוננטות מובנה. המעבר לפיתוח עם סוכן מקומי שוב פותח אפשרויות חדשות: 1. אפשר להשתמש בפריימוורק כמו next.js ולבחור את שיטת העבודה שמתאימה לנו. 2. אפשר להשתמש בתבנית בסיס כמו תבנית הבסיס של Lovable. 3. אפשר להתחיל לגמרי מאפס ולבחור כל שפת תכנות או פריימוורק. סוכני קידוד עובדים טוב יותר ככל שיש יסודות חזקים יותר ולכן אני ממליץ לבחור פריימוורק יציב ורצוי גם שאתם מכירים. נקסט הוא אופציה מצוינת. גם Rails ו Django מעולים כאן והיתרון הגדול של עבודה מקומית הוא כשבונים מוצר לסביבה אחרת מ Web למשל כשבונים אפליקציית מובייל ואפשר לבחור ב Swift ובתבנית הבסיס של פרויקט חדש מתוך ה Xcode. הדבר החשוב הוא להשתמש ביסודות חזקים מהם תוכלו לבנות את האפליקציה שלכם. לאבבל נתנה לנו את זה בפיתוח ווב ועכשיו בפיתוח מקומי אנחנו יכולים לבחור כל פריימוורק ותבנית בסיס. ✏ דוגמה: פיתוח קלוד קוד מקומי והעלאה לרשת בוובינר הראיתי דוגמה של פיתוח Next.js מקומי עם העלאה ל Vercel, שמירת קבצים ב Vercel Blob ושמירת בסיס נתונים על Neon. בשביל להתחיל את הפרויקט פתחתי תיקייה חדשה ויצרתי פרויקט next.js חדש:
$ npx create-next-app@latest .
לאחר מכן התקנתי את כלי שורת הפקודה של vercel ו neon. כלי שורת הפקודה מספקים ממשק לסוכן להתחבר לשירותי הענן ולבצע בהם פעולות כמו להעלות את הפרויקט ל vercel או לפתוח בסיס נתונים חדש על neon. חברות רבות מעדיפות להפיץ כלי שורת פקודה במקום MCP כי הרבה יותר קל לעבוד איתם. את כלי שורת הפקודה של Vercel מתקינים מכאן: https://vercel.com/docs/cli כדאי גם להתקין את התיעוד של כלי שורת הפקודה בתור Agent Skill ועבור הכלי של vercel ההתקנה היא כאן: https://www.skills.sh/vercel/vercel/vercel-cli אותו דבר נעשה עם neon נתקין את כלי שורת הפקודה מכאן: https://neon.com/docs/cli ואת התיעוד בתור Agent Skill מכאן: https://github.com/neondatabase/agent-skills אחרי ההתקנות נרצה לחבר את המחשב שלנו גם ל vercel וגם ל neon דרך כלי שורת הפקודה שהתקנו:
$ vercel login
$ neon auth
ואנחנו מוכנים. נפעיל את קלוד קוד באותה תיקיה בה יש כבר בסיס של פרויקט next.js ונכתוב את הפרומפט:
Create a coloring app with rainbows and unicorns
אחרי שהאפליקציה מוכנה המשכתי עם הפרומפט הבא כדי להעלות אותה לאוויר:
push to vercel as a new project
וזה הספיק בשביל לפרסם את האפליקציה בענן. אבל אנחנו לא רוצים לעצור פה - אפליקציית צביעה צריכה גם גלריית תמונות אז המשכנו עם:
update the app:
1. users can "save" their creations in the gallery
2. saved creations are saved as vercel blobs
3. info about saved blobs is saved in a neon DB

ToCode
1 419
📌 שלוש בעיות בקוד AI ותפקיד המפתחים האנושיים במשחק בוובינר השבוע דיברנו על Vibe Coding עם קלוד קוד וראינו איך הוא בונה אפליקציית צביעה בלי שאנחנו צריכים לקרוא שורת קוד אחת ואפילו מפרסם אותה אונליין. העליתי את קוד האפליקציה שנוצר לגיטהאב מוזמנים לראות אותה כאן: https://github.com/ynonp/webinar-demo-coloring-app בימים הקרובים אעלה סיכום מסודר של אותו וובינר אבל בינתיים בואו נקרא את הקוד ונשים לב למבנים המרכזיים שנוצרו. ✏ בעיה 1: ריכוזיות הנטיה הראשונה של סוכני קידוד היא ריכוזיות. אולי זה קשור לאיך שעובד מנגנון הפעלת כלים ואולי יותר קל להם לכתוב יותר קוד בקובץ אחד, אבל זה משהו שקל לראות בכל קוד ש AI יוצר ללא השגחה. במערכת שלנו נוכל לראות שהקוד שקורא מבסיס הנתונים יושב באותו קובץ גלריה כמו הקוד שמציג את התמונות: https://github.com/ynonp/webinar-demo-coloring-app/blob/main/app/gallery/page.tsx הגלריה עצמה בנויה כקובץ אחד בלי חלוקה לקומפוננטות ובלי טיפול גנרי בדברים שיחזרו על עצמם. דוגמה שקופצת מיד לעין היא הטיפול במספרים (להוסיף s ברבים) עם הקוד הזה בתוך הקומפוננטה:
{creations.length} masterpiece{creations.length === 1 ? "" : "s"} and counting!
קובץ נוסף שהיה לי קשה לקרוא הוא הקובץ הראשי של האפליקציה: https://github.com/ynonp/webinar-demo-coloring-app/blob/main/app/page.tsx זה קובץ של כמעט 600 שורות עם כל קוד הציור, פונקציות ארוכות וקומפוננטה שאין לה סוף. ✏ בעיה 2: טיפול במקרים לא רלוונטים נשים לב באותו קובץ לבלוק:
<a
  href={c.download_url ?? c.blob_url}
  download
  className="shrink-0 px-3 py-1.5 rounded-full text-sm font-bold text-white bg-gradient-to-r from-indigo-500 to-blue-500 hover:opacity-90"
>
  ⬇️ Download
</a>
הקוד מטפל במצב ש download_url לא קיים ואם זה null מחזיר את blob_url אבל מצב כזה לא הגיוני במערכת שלנו - העלאה ל Vercel יוצרת את הבלוב ושומרת בבסיס הנתונים את שתי העמודות. ✏ בעיה 3: חוסר טיפול בכשלונות רלוונטים נעבור לקובץ ה API https://github.com/ynonp/webinar-demo-coloring-app/blob/main/app/api/creations/route.ts שמירת תמונה חדשה לגלריה צריכה לעשות שני דברים: גם להעלות את התמונה ל Vercel Blob וגם להוסיף שורה בבסיס הנתונים שמתאימה לאותה תמונה. אם הפעולה הראשונה הצליחה והשניה נכשלה אנחנו תקועים עם תמונה על ורסל בלי שאפשר להגיע אליה. הבעיה המרכזית עם קוד AI שנכתב ללא השגחה היא שהקוד מתפתח בצורה אקראית ללא יד מכוונת או ראייה של התמונה הכוללת. היחסים בין מפתחים אנושיים ל AI הופכים ברורים ככל שרואים יותר קוד שנוצר על ידי AI - תפקיד המפתחים האנושיים לקחת אחריות על הקוד, לבנות יסודות חזקים, להבין את התמונה הכוללת ולייצר מערכת ש AI יוכל לרוץ איתה. ככל שנקדים לחזור לכסא המהנדסים ולהפרד מפטיש הפועלים כך נוכל לייצר מערכות טובות יותר ומהר יותר.

ToCode
1 419
📌 אפילו לא הייתי צריך להסתכל על הקוד ביקשתי מקלוד להכין דוגמה לקורס שתראה איך להשתמש ב Celery בפייתון בשביל להוריד פוסטים מהבלוג מתוך כמה מכונות במקביל. נתתי את כל הפירוט הטכני וקלוד באמת יצר docker-compose.yml עם קונטיינרים לרדיס ולפייתון, הריץ כמה פעמים ותיקן באגים עד שהכל עבד והפוסטים נשמרו. אני נכנסתי לקוד רק כשהכל עבד ורק בשביל לסדר את הקוד עצמו: פונקציות קטנות ומדויקות יותר, חלוקה לקבצים, ממש בקטנה. ואז המשכנו לחלק השני וביקשתי מקלוד לייצר דוגמה נוספת באותו פרויקט שעושה אותו דבר רק להחליף את celery ב repid כדי להשוות להורדה אסינכרונית. אפילו לא הייתי צריך להסתכל על הקוד כדי לדעת שתוכן הדוגמה הראשונה הולך לקלקל לו את הדבר הכי חשוב בדוגמה השניה. שאלתי אחרי שהקוד עבד "וכמה הורדות במקביל יש בדוגמה השניה?" וקלוד מיד התנצל והסביר שבעצם למרות ש repid הוא אסינכרוני הוא השתמש ב API חוסם גם לדוגמה השניה כך שמספר ההורדות במקביל זהה למספר המכונות. "רק תגיד את המילה ואשכתב את זה כדי להשתמש בהורדה אסינכרונית". הרבה אנשים רוצים לקבל AI שיכול גם לקודד פתרון עובד וגם לבחור את הפתרון הטוב ביותר כדי שנוכל ללמוד מהפתרון שלו איך צריך לכתוב. נכון להיום המודלים עוד לא שם. הם יודעים ללמד אותנו על קוד, הם יכולים לענות על כל שאלה, הם יכולים להציף בדיוק את האינפורמציה הרלוונטית, הם יכולים לזהות בעיות בקוד ולעשות Code Review ולשים לב לדברים שאני בקלות מפספס. הם גם יכולים לבנות פתרונות שעובדים ולרוץ בלולאה עד שזה מצליח, לא מתעייפים ונותנים לי להסתכל רק על קוד גמור. זה מדהים והרבה יותר טוב מאיפה שהיינו לפני שנה. יכול להיות שבעתיד הם גם יוכלו לבחור לבד את הפתרון הטוב ביותר תוך כדי שהם כותבים את הקוד, בינתיים כדאי להתאמן על: 1. להבין מראש איפה הסוכן כנראה ייפול ולדעת לבדוק את הנקודות האלה במימוש (או אפילו יותר טוב - לציין לסוכן מראש לשים לב לנקודות כשל צפויות). 2. לקרוא קוד ולהשתמש בסוכן כדי לסדר אותו שיהיה עוד יותר קל לקריאה. 3. להשתמש בסוכנים כדי להציף את אותן נקודות כשל דרך Code Review. בדוגמה שלי יש כמה דרכים שהייתי יכול לקבל את הפתרון הנכון מההתחלה וכך לחסוך זמן וטוקנים: 1. פרומפט יותר טוב או מצב תכנון. 2. מימוש בפרויקט חדש (בלי דוגמת הסלרי הסינכרונית שמבלבלת את הסוכן). 3. מימוש בשלבים - קודם לבקש לכתוב את הקוד האסינכרוני שמוריד פוסט כולל בדיקות עליו ואז להמשיך ל Runner של רפיד.

ToCode
1 419
📌 מאיפה מגיעים ה thread-ים של asyncio.to_thread בפייתון הפונקציה asyncio.to_thread משתמשת ב Thread Pool הדיפולטי של המערכת כדי להפעיל קוד סינכרוני בצורה שנראית אסינכרונית. היא עשויה להיראות כמו פתרון קסם כשיש לנו קוד אסינכרוני שצריך להפעיל פונקציה סינכרונית ארוכה ואנחנו לא רוצים לתקוע את ה Main Loop. לדוגמה נניח שכתבנו פונקציה ping_ip עם הקוד הבא:
def ping_ip(ip: str, count: int = 4) -> tuple[str, float]:
    """Ping an IP address `count` times and return (ip, success_percent)."""
    if sys.platform == "win32":
        cmd = ["ping", "-n", str(count), ip]
    else:
        cmd = ["ping", "-c", str(count), ip]

    result = subprocess.run(
        cmd,
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE,
        text=True,
        errors="replace",
    )
    output = result.stdout + result.stderr

    # Parse packet loss percentage from output like "0.0% packet loss"
    match = re.search(r"(\d+(?:\.\d+)?)%\s+packet\s+loss", output, re.IGNORECASE)
    if match:
        loss_percent = float(match.group(1))
        success_percent = 100.0 - loss_percent
    else:
        # Could not parse output; assume total failure
        success_percent = 0.0

    print(f"IP = {ip}; success = {success_percent}")
    return ip, success_percent
ונניח שאנחנו רוצים להשתמש בה מתוכנית אסינכרונית באופן הבא:
    ips = [...]
    tasks = [ping_ip(ip) for ip in ips]
    results = await asyncio.gather(*tasks, return_exceptions=True)

    for result in results:
        if isinstance(result, Exception):
            print(f"Error: {result}")
        else:
            ip, success = result
            print(f"{ip}: {success:.1f}% successful pings") 
זה כמובן לא יעבוד כי ping_ip היא לא פונקציה אסינכרונית. היא לא מחזירה את השליטה ל Main Loop בזמן ביצוע ה ping והקוד פשוט ירוץ בצורה סדרתית בדיקה אחרי בדיקה. במצב כזה מישהו יכול להציע להשתמש ב asynio.to_thread ואז לכתוב:
    tasks = [asyncio.to_thread(ping_ip, ip) for ip in ips]    
    results = await asyncio.gather(*tasks, return_exceptions=True)

    for result in results:
        if isinstance(result, Exception):
            print(f"Error: {result}")
        else:
            ip, success = result
            print(f"{ip}: {success:.1f}% successful pings")
עובד? בטח. אבל. ההבדל בין Thread Pool ל Asyncio הוא בדיוק הסיבה בגללה רצינו להשתמש ב asyncio. הבעיה עם Threads היא שיש מספר מוגבל מהם כי מערכת ההפעלה לא אוהבת כשיוצרים יותר מדי. ה Default Thread Pool מכיל או 32 threads או מספר הליבות + 4, הקטן מביניהם. לעומת זאת ב asyncio אין לנו הגבלה על כמה משימות רצות במקביל. איך זה מתורגם לביצועים? נשווה בין שתי הגרסאות. בתוכנית אחת אני משתמש ב to_thread כדי להפעיל את פונקציית ה ping שכבר יש לי. זמן הריצה 20 שניות:
uv run ping_ips_to_thread.py  0.12s user 0.22s system 1% cpu 20.283 total
בתוכנית שניה כתבתי מחדש את פונקציית ה ping בגישה אסינכרונית עם asyncio.create_subprocess_shell. הפעם זמן הריצה ירד ל 14 שניות לאותה רשימת כתובות:
uv run ping_ips.py  0.13s user 0.21s system 2% cpu 14.203 total
ככל שרשימת הכתובות תתארך כך גם ההפרש בין התוכניות יגדל.

ToCode
1 419
📌 הבעיה היא לא הטוקנים אלא היעילות שלהם למכור יותר לא עוזר אם אתה מפסיד על כל מכירה. אם איש הארטיקים בחוף קונה מהספק שלו ארטיק בעשרה שקלים ומוכר אותו ב-5, אז ברור שהוא לעולם לא יתחיל להיות רווחי. וגם ההיפך, אם אותו איש ארטיקים קונה ארטיק ב-2 ש"ח מהספק ומוכר בעשר, אז ברור שכדאי לו למכור כמה ארטיקים שהוא רק יכול ואפילו לקחת הלוואה כדי לקנות יותר ארטיקים. מי שמרוויח על כל מכירה ירצה למכור עוד ועוד. עכשיו בואו נדבר על טוקנים. אם 100$ של טוקנים מתורגמים ל 200$ במכירות של החברה לא ייגמרו לכם לעולם הטוקנים. ואם 100$ של טוקנים לא תורמים כלום למכירות אז ברור שאין טעם להשתמש בסוכני קידוד וגם פה אין לנו בעיה. אבל אנחנו חיים באמצע וצריכים למצוא שיווי משקל בין שמירה על הוצאות פיתוח נמוכות, התקדמות מהירה בפיתוח ושמירה על איכות המוצר. וכשמתחילים לדבר על איזון בין צרכים ואילוצים אנחנו נכנסים לעולם ההנדסה. בחברות פיתוח, בניגוד לארטיקים בחוף הים או אצל סוחרי הטוקנים אנחנו יכולים לזהות את התופעות הבאות: 1. המחיר שאני משלם על טוקנים צריך להתאים לקצב הפיתוח וצריך להתאים לרווחיות של המוצר. 2. אפשר לשלם יותר מדי על טוקנים או פחות מדי. מדיניות חברה יכולה מאוד להשפיע על צריכת הטוקנים, בלי קשר לתמורה שמקבלים מהם. לדוגמה אם חברה מחליטה לתת בונוס לעובדים שגומרים את מכסת הטוקנים שלהם סיכוי טוב שנראה צריכה יותר גבוהה. 3. חוסר ידע מעלה את צריכת הטוקנים בלי לקבל תמורה משמעותית. זה נכון בכל תחום, כשלא בטוחים "הולכים על בטוח". בוחרים את המודל הכי טוב, מתקינים המון כלים ומחפשים לפתור בעיות באמצעות "עוד קצת דבק". בשביל פתרונות מדויקים אנחנו רוצים להבין איך דברים עובדים. 4. כולם רוצים לפתור את הבעיה ברמת התשתית. אין עדיין פתרון טוב שם. כלים של "כיווץ טוקנים" או הוראות לדבר כמו איש מערות מבטיחים לתת לנו טוקנים ללא הגבלה. יש משהו מפתה בהבטחה הזו ואולי עוד נגיע לשם. אני לא חושב שאנחנו שם עכשיו. 5. תהליכי עבודה אג'נטיים וסוכנים אוטונומיים הם האתגר הכי גדול היום מבחינת טוקנים. תהליך עבודה או סוכן אוטונומי יעבדו לפי תוכנית ולכן כל חוסר יעילות במנגנון שלהם מתורגם לצריכה מיותרת בטוקנים. מפתחים אנושיים עוד יכולים לשים לב שקופיילוט מתחיל להשתולל עם הטוקנים ולדייק אותו. עם כלים אוטומטיים אנחנו שמים לב לזה רק כשכבר מאוחר מדי. מה עושים? חוקרים. אם יש לכם בעיה של עלות טוקנים לפני שאתם רצים להתקין כלי תשתית שיתקנו את העולם שבו על השיחות, שימו לב מה הסוכן עושה, מה גומר את הטוקנים ואיך לדייק את העבודה. לא הכל אפשר להשיג. כן כדאי לבחור בצורה מודעת את אופן השימוש בטוקנים בתהליך הפיתוח, ולמצוא את האיזון שמתאים לצוות שלכם.