📌 היום למדתי: strict loading ב Rails
הנה פיצ'ר שנכנס בריילס 6.1, פספסתי אותו לגמרי כשהוא יצא ובסוף כשגיליתי עליו (בזכות ה AI) הבנתי למה העדפתי לחיות בלעדיו. לפני שנצלול לריילס יש פה לקח חשוב - כש AI מוסיף למערכת מנגנון שלא הכרתם, כדאי לקרוא לעומק על המנגנון ולחשוב אם הוא באמת רצוי או שמדובר במנגנון ישן שבאותו זמן שנוצר היתה התלהבות גדולה ממנו אבל אחרי כמה שנים גילינו שהוא לא היה כזה רעיון טוב.
✏ הבעיה עם טעינה עצלה
בריילס מאוד אוהבים לטעון דברים רק כשצריך אותם לכן הקוד הזה:
עדיין לא יטען את כל הספרים מבסיס הנתונים אלא הוא מייצג רק התחלה של שאילתה. אני יכול להמשיך אותו עם:
ולקבל רק ספר אחד מבסיס הנתונים בלי שטענתי את כל הספרים לזכרון. זה רעיון מצוין עד שהוא פוגש מפתחים. כי הבעיה עם מפתחים היא שאנחנו יצירתיים וכותבים לולאות כאלה:
כיף, נוח, קריא ומאוד לא יעיל. הלולאה תריץ עבור כל ספר שאילתה לבסיס הנתונים כדי להבין את פרטי המחבר ותדפיס את שם המחבר. אם יש לי 10 ספרים זה אומר 11 שאילתות ובגלל זה לולאות כאלה נקראות N+1 Queries.
שתי הדרכים המרכזיות לא לכתוב לולאות כאלה הן טעינה מראש או JOIN. עם טעינה מראש היינו כותבים:
ואז ריילס היה מריץ שתי שאילתות, אחת מושכת את כל נתוני הספרים והשניה מושכת את כל נתוני המחברים במכה אחת.
דרך שניה היא JOIN והיא נראית כך:
ופה יש לנו כבר שאילתה אחת שמחזירה רק את שמות המחברים.
✏ איך לזהות את התבנית השבורה
הדרך הכי קלה לזהות את התבנית השבורה היא בזמן ריצה להסתכל על השאילתות. יש gem בריילס בשם bullet שעושה את זה ואפשר לקרוא עליו כאן:
https://github.com/flyerhzm/bullet
בעבודה עם AI הסוכן הציע להגדיר strict loading כדי לצמצם את הסכנה בתבנית זו:
אני מודה שלא הכרתי את המנגנון אז הלכתי לחפש, התחלתי עם המאמר הזה בנושא:
https://thoughtbot.com/blog/strict-loading-in-rails-8-a-railsy-way-to-avoid-n-1-queries
המשכתי לקצת Issues בגיטהאב ולשיחה עם ChatGPT.
למדתי ש strict loading בגרסתו הראשונית נועד למנוע טעינה עצלה על יחסים מסוימים בריילס. לדוגמה ניתן להגדיר:
ואז הקוד הזה יזרוק שגיאה במצב פיתוח:
והדרכים להגיע לביקורות יהיו להשתמש ב includes או join:
הרעיון הזה באמת מונע את כל שגיאות ה N+1 אבל הוא מונע גם הרבה שימושים ממש תקינים במנגנון הטעינה העצלה של ריילס ולכן לא נרצה להשתמש בו.
גרסה 7 של ריילס הוסיפה למנגנון מצב פעולה שנקרא
https://github.com/rails/rails/issues/42576
בסוף אין ספק שטעינה עצלה מגיעה עם אתגר אמיתי בזיהוי N+1. אבל האתגר הזה היום הרבה פחות חמור ממה שהיה בעבר בגלל שסוכני קידוד ממש טובים בזיהוי תבניות ו N+1 כמעט תמיד מזוהה כתבנית בקוד המקור. מספיק להוסיף ל AGENTS.md ולפרומפט של ה Code Review שלנו הוראות מפורשות לזיהוי ותיקון שגיאות N+1 כדי לצמצם אותן משמעותית.
הנה פיצ'ר שנכנס בריילס 6.1, פספסתי אותו לגמרי כשהוא יצא ובסוף כשגיליתי עליו (בזכות ה AI) הבנתי למה העדפתי לחיות בלעדיו. לפני שנצלול לריילס יש פה לקח חשוב - כש AI מוסיף למערכת מנגנון שלא הכרתם, כדאי לקרוא לעומק על המנגנון ולחשוב אם הוא באמת רצוי או שמדובר במנגנון ישן שבאותו זמן שנוצר היתה התלהבות גדולה ממנו אבל אחרי כמה שנים גילינו שהוא לא היה כזה רעיון טוב.
✏ הבעיה עם טעינה עצלה
בריילס מאוד אוהבים לטעון דברים רק כשצריך אותם לכן הקוד הזה:
Book.all
עדיין לא יטען את כל הספרים מבסיס הנתונים אלא הוא מייצג רק התחלה של שאילתה. אני יכול להמשיך אותו עם:
Book.all.first
ולקבל רק ספר אחד מבסיס הנתונים בלי שטענתי את כל הספרים לזכרון. זה רעיון מצוין עד שהוא פוגש מפתחים. כי הבעיה עם מפתחים היא שאנחנו יצירתיים וכותבים לולאות כאלה:
Book.all.each do |book|
puts book.author.name
end
כיף, נוח, קריא ומאוד לא יעיל. הלולאה תריץ עבור כל ספר שאילתה לבסיס הנתונים כדי להבין את פרטי המחבר ותדפיס את שם המחבר. אם יש לי 10 ספרים זה אומר 11 שאילתות ובגלל זה לולאות כאלה נקראות N+1 Queries.
שתי הדרכים המרכזיות לא לכתוב לולאות כאלה הן טעינה מראש או JOIN. עם טעינה מראש היינו כותבים:
Book.includes(:author).each do |book|
puts book.author.name
end
ואז ריילס היה מריץ שתי שאילתות, אחת מושכת את כל נתוני הספרים והשניה מושכת את כל נתוני המחברים במכה אחת.
דרך שניה היא JOIN והיא נראית כך:
Book.joins(:author).pluck("authors.name").each do |author_name|
puts author_name
endופה יש לנו כבר שאילתה אחת שמחזירה רק את שמות המחברים.
✏ איך לזהות את התבנית השבורה
הדרך הכי קלה לזהות את התבנית השבורה היא בזמן ריצה להסתכל על השאילתות. יש gem בריילס בשם bullet שעושה את זה ואפשר לקרוא עליו כאן:
https://github.com/flyerhzm/bullet
בעבודה עם AI הסוכן הציע להגדיר strict loading כדי לצמצם את הסכנה בתבנית זו:
Mitigation: the `Current`-scoped `localized_translation` association everywhere + `strict_loading` on `phrase_translations` / `token_translations` in development so a forgotten preload raises instead of silently N+1-ing.
אני מודה שלא הכרתי את המנגנון אז הלכתי לחפש, התחלתי עם המאמר הזה בנושא:
https://thoughtbot.com/blog/strict-loading-in-rails-8-a-railsy-way-to-avoid-n-1-queries
המשכתי לקצת Issues בגיטהאב ולשיחה עם ChatGPT.
למדתי ש strict loading בגרסתו הראשונית נועד למנוע טעינה עצלה על יחסים מסוימים בריילס. לדוגמה ניתן להגדיר:
class Movie < ApplicationRecord
has_many :reviews, strict_loading: true
end
ואז הקוד הזה יזרוק שגיאה במצב פיתוח:
puts Movie.first.reviews.count
והדרכים להגיע לביקורות יהיו להשתמש ב includes או join:
movie = Movie.first.includes(:reviews)
puts movie.reviews.count
הרעיון הזה באמת מונע את כל שגיאות ה N+1 אבל הוא מונע גם הרבה שימושים ממש תקינים במנגנון הטעינה העצלה של ריילס ולכן לא נרצה להשתמש בו.
גרסה 7 של ריילס הוסיפה למנגנון מצב פעולה שנקרא
n_plus_one_only שאמור לעזור לנו לזהות תבניות N+1 בלי לשבור המון קוד שאנחנו אוהבים. הבעיה שמנגנון זה לא הצליח לזהות בצורה אמינה את כל התבניות הבעייתיות וכאן יש דוגמה למקרה קלאסי שלא נתפס ברשת:https://github.com/rails/rails/issues/42576
בסוף אין ספק שטעינה עצלה מגיעה עם אתגר אמיתי בזיהוי N+1. אבל האתגר הזה היום הרבה פחות חמור ממה שהיה בעבר בגלל שסוכני קידוד ממש טובים בזיהוי תבניות ו N+1 כמעט תמיד מזוהה כתבנית בקוד המקור. מספיק להוסיף ל AGENTS.md ולפרומפט של ה Code Review שלנו הוראות מפורשות לזיהוי ותיקון שגיאות N+1 כדי לצמצם אותן משמעותית.
GitHub
GitHub - flyerhzm/bullet: help to kill N+1 queries and unused eager loading
help to kill N+1 queries and unused eager loading. Contribute to flyerhzm/bullet development by creating an account on GitHub.
📌 תודה אבל לא תודה
פייבל כתב לי במהלך שיחה
יו באמת תודה.
אבל כל המטרה של כספת סיסמאות זה שיהיה מסובך להכנס אליה. במקרה שלי זו היתה כספת למצב פיתוח ובאמת המפתח לעדכון היה שמור על הדיסק כדי שיהיה לי קל להכנס, אבל מסתבר שאני לא היחיד שחיפש את הדרך.
ככל שאנחנו מכניסים הביתה סוכני קידוד כך עלינו להודות - הם יחטטו, הם ישנו, הם יעבירו מידע והם לא תמיד חברים שלנו. הבעיה עם פעולות רגישות הוא שעבור בני אדם, כל פעולה היא "בטוחה" עד שהיא נכשלת.
פייבל כתב לי במהלך שיחה
נכנסתי לך לכספת הסיסמאות הוספתי שם מפתח חדש עם הערך devsecret כדי שתוכל להריץ את הפרויקט בפיתוח.
יו באמת תודה.
אבל כל המטרה של כספת סיסמאות זה שיהיה מסובך להכנס אליה. במקרה שלי זו היתה כספת למצב פיתוח ובאמת המפתח לעדכון היה שמור על הדיסק כדי שיהיה לי קל להכנס, אבל מסתבר שאני לא היחיד שחיפש את הדרך.
ככל שאנחנו מכניסים הביתה סוכני קידוד כך עלינו להודות - הם יחטטו, הם ישנו, הם יעבירו מידע והם לא תמיד חברים שלנו. הבעיה עם פעולות רגישות הוא שעבור בני אדם, כל פעולה היא "בטוחה" עד שהיא נכשלת.
😁1
📌 איך ללמוד אבטחת מידע ולמה זה מסובך
חבר שלח מצגת אבטחת מידע שהוא קיבל. המצגת מקיפה, מעניינת, וחסרת ערך. היא חסרת ערך כיוון שאבטחת מידע היא קודם כל שינוי גישה, היא ההבנה האינטואיטיבית שכשלים מסוימים במערכת יכולים לשבור את אותה מערכת בדרכים יצירתיות.
אתה יכול להקשיב לעשרות הרצאות שיראו לך מה זה SQL Injection ולמה אסור לחבר מחרוזות ב SQL וזה לא יתקרב לאפקטיביות של חיפוש פרצת SQL Injection בעצמך בקוד קיים וכתיבת Exploit. הידע התיאורטי על כל הסוגים של SQL Injection וסיפורי מקרה מעניינים ככל שיהיו מדברים לאנשים שיש להם אינטואיציה לגבי אבטחת מערכות, אבל האמת שאותם אנשים ממילא יגיעו למידע הזה.
וכן יש לנו אותה בעיה עם AI. אנשים מקשיבים לשעות של הרצאות איך לקבל קוד טוב יותר מ AI אבל הבעיה היא לא ידע אלא אינטואיציה, ואינטואיציה מפתחים דרך עשייה - כלומר דרך אותו תהליך סיזיפי ואיטרטיבי של שיפור הקוד והפרומפט, קריאת הפלט של ה AI עד לקבלת התוצאה הרצויה. פה אתגר אחד הוא שהאדמה כל הזמן זזה וטכניקות שהיו נכונות לפני חודשיים כבר לא נכונות היום כי יש מודלים חדשים. אתגר שני הוא שכלים מודרניים עושים הכל כדי לעטוף את הפלט של המודל ולהרחיק אותנו מאותו פלט וכך אנחנו מאבדים את הקשר בין הפרומפט שלנו לתוצאה. עדיין מוקדם לדעת איך התחום הזה יתפתח.
ומה לגבי קוד? לדעתי פה הבעיה פחות חמורה. גם יותר קל לראות כשקוד לא עובד וגם בעזרת ה AI יותר קל לחקור מקרי קצה או בעיות בקוד קיים. אם אני מסתכל קדימה בעולם שבו אנשים לא יכתבו קוד ידנית יותר ורק ישתמשו ב AI כדי לייצר אותו לא נראה ירידת מיומנות משמעותית שתתבטא באיכות המוצרים. באופן טבעי אנשים ימצאו את המקומות בקוד בהם יש לנו הכי הרבה השפעה ויתמקדו בהם וכך אנשים טכניים ומיומנים יבנו מוצרים טובים ומהירים יותר ממי שלא מבין והמוצרים שלא יעבדו יתמרצו את המפתחים שלהם ללמוד ולהשתפר.
לסיכום האינטואיציה הבסיסית לגבי פיתוח מערכות וקידוד לא תישחק היא פשוט תשתנה. אנשים עדיין יעבדו בלהפעיל את סוכני ה AI ולהתווכח איתם והחיכוך הזה ישאיר אותנו בפוקוס.
(וכן זה חיכוך. אם אני מבקש מסוכן קידוד למחוק את השינויים שהוא עשה והוא עונה לי "אין בעיה בוס אני רק משאיר פונקציה אחת כי היא ממש חשובה" אז זה מכריח אותי להכנס לקוד ולהבין מה הפונקציה הזאת כדי להחליט אם אני מבקש שוב או עוזב את זה).
אינטואיציה לגבי אבטחת מידע אף פעם לא היתה הצד החזק שלנו ומעבר לפיתוח עם AI רק יחמיר את המצב הזה. פוסטים שאני קורא לאחרונה מחזקים את התחושה שאבטחת מידע לא קשורה למיומנות אלא לתקציב, ואם תתן ל AI מספיק טוקנים הוא ימצא בעיות אבטחה בכל מערכת. אם זה המצב לא ברור האם עדיין שווה להשקיע בהכשרת אבטחת מידע למפתחים בצורה גורפת בארגונים.
חבר שלח מצגת אבטחת מידע שהוא קיבל. המצגת מקיפה, מעניינת, וחסרת ערך. היא חסרת ערך כיוון שאבטחת מידע היא קודם כל שינוי גישה, היא ההבנה האינטואיטיבית שכשלים מסוימים במערכת יכולים לשבור את אותה מערכת בדרכים יצירתיות.
אתה יכול להקשיב לעשרות הרצאות שיראו לך מה זה SQL Injection ולמה אסור לחבר מחרוזות ב SQL וזה לא יתקרב לאפקטיביות של חיפוש פרצת SQL Injection בעצמך בקוד קיים וכתיבת Exploit. הידע התיאורטי על כל הסוגים של SQL Injection וסיפורי מקרה מעניינים ככל שיהיו מדברים לאנשים שיש להם אינטואיציה לגבי אבטחת מערכות, אבל האמת שאותם אנשים ממילא יגיעו למידע הזה.
וכן יש לנו אותה בעיה עם AI. אנשים מקשיבים לשעות של הרצאות איך לקבל קוד טוב יותר מ AI אבל הבעיה היא לא ידע אלא אינטואיציה, ואינטואיציה מפתחים דרך עשייה - כלומר דרך אותו תהליך סיזיפי ואיטרטיבי של שיפור הקוד והפרומפט, קריאת הפלט של ה AI עד לקבלת התוצאה הרצויה. פה אתגר אחד הוא שהאדמה כל הזמן זזה וטכניקות שהיו נכונות לפני חודשיים כבר לא נכונות היום כי יש מודלים חדשים. אתגר שני הוא שכלים מודרניים עושים הכל כדי לעטוף את הפלט של המודל ולהרחיק אותנו מאותו פלט וכך אנחנו מאבדים את הקשר בין הפרומפט שלנו לתוצאה. עדיין מוקדם לדעת איך התחום הזה יתפתח.
ומה לגבי קוד? לדעתי פה הבעיה פחות חמורה. גם יותר קל לראות כשקוד לא עובד וגם בעזרת ה AI יותר קל לחקור מקרי קצה או בעיות בקוד קיים. אם אני מסתכל קדימה בעולם שבו אנשים לא יכתבו קוד ידנית יותר ורק ישתמשו ב AI כדי לייצר אותו לא נראה ירידת מיומנות משמעותית שתתבטא באיכות המוצרים. באופן טבעי אנשים ימצאו את המקומות בקוד בהם יש לנו הכי הרבה השפעה ויתמקדו בהם וכך אנשים טכניים ומיומנים יבנו מוצרים טובים ומהירים יותר ממי שלא מבין והמוצרים שלא יעבדו יתמרצו את המפתחים שלהם ללמוד ולהשתפר.
לסיכום האינטואיציה הבסיסית לגבי פיתוח מערכות וקידוד לא תישחק היא פשוט תשתנה. אנשים עדיין יעבדו בלהפעיל את סוכני ה AI ולהתווכח איתם והחיכוך הזה ישאיר אותנו בפוקוס.
(וכן זה חיכוך. אם אני מבקש מסוכן קידוד למחוק את השינויים שהוא עשה והוא עונה לי "אין בעיה בוס אני רק משאיר פונקציה אחת כי היא ממש חשובה" אז זה מכריח אותי להכנס לקוד ולהבין מה הפונקציה הזאת כדי להחליט אם אני מבקש שוב או עוזב את זה).
אינטואיציה לגבי אבטחת מידע אף פעם לא היתה הצד החזק שלנו ומעבר לפיתוח עם AI רק יחמיר את המצב הזה. פוסטים שאני קורא לאחרונה מחזקים את התחושה שאבטחת מידע לא קשורה למיומנות אלא לתקציב, ואם תתן ל AI מספיק טוקנים הוא ימצא בעיות אבטחה בכל מערכת. אם זה המצב לא ברור האם עדיין שווה להשקיע בהכשרת אבטחת מידע למפתחים בצורה גורפת בארגונים.
📌 צריכים מפה
האתגר המרכזי במבוך הוא כשאתה לא מזהה שהיית במקום מסוים או איך הגעת לשם. משהו נראה מוכר והמחשבה מנקרת, הייתי פה כבר? זה אותו חדר או רק דומה לו?
בעבודה עם AI היום יש לי לפעמים תחושה דומה. אתה מדבר עם המכונה ולא בטוח מה היא תעשה. אתה מתקן דבר אחד ולא בטוח מה שברת. אתה מחבר שני חוטים רק בשביל לנתק 5 אחרים.
מה שהופך את המבוך למבלבל זה שאפשר להסתובב זמן ארוך בשטח קטן. המבנה המטעה בכוונה של המבוך מעודד הליכה בסיבובים. הרי אם הקירות היו ממוספרים אפשר היה לעקוב אחרי הסימונים ולבנות מפה, לדעת בכל רגע איפה אני ואיפה אני רוצה להיות. מה שהופך את הקידוד עם AI למבלבל זה בדיוק אותה מפה חסרה. התקרבתי או התרחקתי מהיעד? איפה אני בעצם?
מצפן לא עוזר להסתדר במבוך. המבוך מבלבל בכוונה, מלא קירות ומעברים עקומים. מצפן אולי נותן תחושת ביטחון אבל בלי המפה, בלי ההבנה איפה אני נמצא ומה המגבלות והקירות שסביבי יהיה קשה למצוא את היציאה. בעולם של תכנות עם AI הפידבק של מודלים אחרים נשמע לי לפעמים כמו מצפן, "כן אתה בכיוון זאת ארכיטקטורה נהדרת" אומר לי קודקס על הקוד שקלוד כתב, ומשאיר אותי עם הבאגים ותחושת ביטחון זמנית.
הכח של המפה הוא היכולת להגיד: "אני פה, אני רוצה להיות שם, וזאת הדרך שאני צריך לקחת".
סוכני קידוד אלופים בלהביא אותי מהר לנקודה שאני מתאר, אבל בלי לתאר במדויק את נקודת היציאה הם לא יצליחו להביא אותי לשם. היום דיבגתי בעיית ארכיטקטורה שיצר סוכן קידוד. זאת ארכיטקטורה שאין מפתח בעולם שהיה בוחר, ובכל זאת היא נכתבה בקוד כי תיאור המטרה לא היה מספיק ברור ואף אחד לא בדק שהיעד באמת היה היעד שתכננו.
יום אחד, אחרי שההייפ יעבור, אנחנו נתעורר ונשאל "מה המפה שלנו?". איך אנחנו יכולים להסתכל על מערכת, להסתכל על פיצ'ר ולתאר במדויק את הקוד שמממש את הפיצ'ר הזה. עם סוכני קידוד אנחנו כבר לא צריכים להקליד את התווים של הקוד. אבל כן חייבים לדעת אם הקוד שקיבלנו הוא הקוד שרצינו.
האתגר המרכזי במבוך הוא כשאתה לא מזהה שהיית במקום מסוים או איך הגעת לשם. משהו נראה מוכר והמחשבה מנקרת, הייתי פה כבר? זה אותו חדר או רק דומה לו?
בעבודה עם AI היום יש לי לפעמים תחושה דומה. אתה מדבר עם המכונה ולא בטוח מה היא תעשה. אתה מתקן דבר אחד ולא בטוח מה שברת. אתה מחבר שני חוטים רק בשביל לנתק 5 אחרים.
מה שהופך את המבוך למבלבל זה שאפשר להסתובב זמן ארוך בשטח קטן. המבנה המטעה בכוונה של המבוך מעודד הליכה בסיבובים. הרי אם הקירות היו ממוספרים אפשר היה לעקוב אחרי הסימונים ולבנות מפה, לדעת בכל רגע איפה אני ואיפה אני רוצה להיות. מה שהופך את הקידוד עם AI למבלבל זה בדיוק אותה מפה חסרה. התקרבתי או התרחקתי מהיעד? איפה אני בעצם?
מצפן לא עוזר להסתדר במבוך. המבוך מבלבל בכוונה, מלא קירות ומעברים עקומים. מצפן אולי נותן תחושת ביטחון אבל בלי המפה, בלי ההבנה איפה אני נמצא ומה המגבלות והקירות שסביבי יהיה קשה למצוא את היציאה. בעולם של תכנות עם AI הפידבק של מודלים אחרים נשמע לי לפעמים כמו מצפן, "כן אתה בכיוון זאת ארכיטקטורה נהדרת" אומר לי קודקס על הקוד שקלוד כתב, ומשאיר אותי עם הבאגים ותחושת ביטחון זמנית.
הכח של המפה הוא היכולת להגיד: "אני פה, אני רוצה להיות שם, וזאת הדרך שאני צריך לקחת".
סוכני קידוד אלופים בלהביא אותי מהר לנקודה שאני מתאר, אבל בלי לתאר במדויק את נקודת היציאה הם לא יצליחו להביא אותי לשם. היום דיבגתי בעיית ארכיטקטורה שיצר סוכן קידוד. זאת ארכיטקטורה שאין מפתח בעולם שהיה בוחר, ובכל זאת היא נכתבה בקוד כי תיאור המטרה לא היה מספיק ברור ואף אחד לא בדק שהיעד באמת היה היעד שתכננו.
יום אחד, אחרי שההייפ יעבור, אנחנו נתעורר ונשאל "מה המפה שלנו?". איך אנחנו יכולים להסתכל על מערכת, להסתכל על פיצ'ר ולתאר במדויק את הקוד שמממש את הפיצ'ר הזה. עם סוכני קידוד אנחנו כבר לא צריכים להקליד את התווים של הקוד. אבל כן חייבים לדעת אם הקוד שקיבלנו הוא הקוד שרצינו.
👍2
📌 סיכום וובינר: פרויקטים ידידותיים ל AI
העבודה עם סוכני קידוד פתחה דלת למיומנות חדשה - התאמת פרויקטים ל AI. מיומנות זו לא תמיד קשורה לנסיון בפיתוח והיא דורשת שיטת עבודה ומחשבה שונה. בוובינר היום הצגתי את הבסיס של מיומנות זו. אני מעריך שבעתיד הקרוב מיומנות זו תהפוך לחלק בלתי נפרד מתהליך הפיתוח כולל הקמת צוותי תשתיות AI בארגונים. עכשיו בואו נראה במה מדובר.
✏ מה זה בכלל קוד ידידותי ל AI
מידת הידידותיות של קוד ל AI היא סקאלה. בגדול היא אומרת כמה סוכן הקידוד צריך להתאמץ לפני שהוא מתחיל לכתוב קוד, ומה הסיכוי שהקוד שיכתב יהיה נכון. פרויקטים ידידותיים ל AI הם פרויקטים בהם:
1. כל פיצ'ר או תיקון באג עולה פחות טוקנים.
2. אחרי כל פיצ'ר או תיקון באג אנו נדרשים לפחות איטרציות עד להשלמת התיקון.
3. סוכן קידוד מצליח להבין את הטעויות ולתקן בלי התערבות שלנו.
מה שהופך פרויקט לידידותי ל AI היום זה:
1. מבנה קוד מסודר, קבצים קטנים, חלוקה נכונה לקומפוננטות
2. קבצי תיעוד טובים עם אינדקס שעוזר ל AI להבין איזה קבצים מהפרויקט צריך לטעון (זה יכול להיות Skill או קבצים פשוטים בתיקיית docs).
3. בדיקות אוטומטיות, בהן ה AI יוכל להשתמש כדי לבדוק את עצמו.
אבל יותר חשוב מרשימת המכולת הזו היא שיטת העבודה. אני לא חושב שאפשר לקבל מערכת ידידותית ל AI נקודה, אלא שאנחנו יכולים להיות בתהליך התאמת המערכת ל AI והתהליך הזה נמשך כל הזמן. כל פיצ'ר חדש, כל תיקון באג, כל קוד חדש שנכנס למערכת משנה אותה ומחייב המשך התאמה.
✏ איך נראה התהליך
בוובינר הצגתי שתי דוגמאות - אחת מפרויקט langlets ושניה מפרויקט maigret.
בפרויקט לנגלטס הראיתי קומפוננטה של תפריט User Menu שלא בנויה בתור קומפוננטה אלא מובנית בתוך קומפוננטות גדולות יותר, כלומר תפריט המשתמש של מסך הבית בנוי בתוך הקומפוננטה של מסך הבית. תפריט המשתמש של מסך צפיה בקורס בנוי בתוך המסך של צפיה בקורס. כפילות זו מאפשרת אומנם להציג אפשרויות שונות בכל מסך או עיצוב קצת שונה לכל מסך, אבל היא גם מקשה על AI לזהות את התפריט.
בדוגמה רצינו לתקן באג באותו תפריט משתמש. כתבתי את הפרומפט:
ראינו שקלוד קוד וקודקס מסתירים את המחשבות של המודל ומציגים מעט פלט. חלק מזה זה בשביל לא לבלבל את המשתמשים וחלק מזה זה בשביל לא לחשוף מידע על תבניות המחשבה הפנימיות של המודלים שלהם. אפילו מהמעט מידע שנחשף ראינו שהמודל מתחיל מקובץ אחד בו מוגדר התפריט ואז מחפש בכל הפרויקט עם grep קבצים נוספים שעשויים לכלול הגדרות מקבילות לתפריט זה. לפעמים הוא מוצא את כולם, לפעמים חלק מהם ולפעמים רק הגדרה אחת.
ראינו גם את סוכן הקידוד pi והפעלנו באמצעותו את המודל הפתוח kimi שכן מדפיס את כל תהליך המחשבה שלו. תהליך המחשבה של קימי הראה לנו בדיוק מה המודל ראה בכל שלב ואת תהליך הגילוי של כל ההגדרות.
גילינו שתפריט המשתמש מוגדר ב-4 קבצים במערכת, שלושה מהם רלוונטים לתיקון שביקשתי והרביעי קשור לתפריט באפליקציית האייפון ולא נדרש לתיקון.
אחרי שמבינים את הבעיה ממשיכים לניסוי. ההשערה שלי היתה שאם אאחד את הקבצים ואוציא את הגדרת התפריט לקומפוננטה נפרדת לסוכן יהיה קל יותר לעבוד על הקוד. בשביל תכל'ס לאחד את הקוד לא צריך לפתוח עורך טקסט אפשר לבקש מהסוכן לעשות את זה. אחרי האיחוד הפעלתי מחדש את אותו פרומפט וראינו שהפעם הסוכן מגיע לתשובה מהר יותר עם פחות טוקנים ולא מפספס תוצאות (כי כל הקוד נמצא בקובץ אחד של קומפוננטה).
בדוגמה שניה הראיתי את פרויקט maigret והצגתי באג ספציפי במערכת הדוחות של הפרויקט. שם ראינו איך הסוכנים צריכים לסרוק את הפרויקט כדי למצוא את מערכת הדוחות ואיפה בדיוק הבאג. הניסוי שם היה ליצור קובץ CLAUDE.md שמסביר פשוט איפה נמצאת מערכת הדוחות ואיך היא עובדת (4 שורות). זה הספיק כדי לצמצם משמעותית את כמות הטוקנים ואת זמן התגובה של הסוכן.
בשני המקרים התהליך הוא איטרטיבי:
1. בוחרים משימה שאני יודע איך היא צריכה להסתיים
2. מפעילים כמה סוכנים במקביל לחקור, זה יכול להיות מאותה תיקיה של הפרויקט או באמצעות worktree ממספר עותקים (עדיף להשתמש ב worktree כאן כדי שלא ידרכו אחד לשני על הרגליים כשהם מנסים לפתור את אותה משימה).
3. קוראים ממש את השיחות כולל כל הפעלות הכלים שביצעו הסוכנים ומנסים להבין על מה התבזבז הזמן ואיזה כיוונים הסוכן לקח שבסוף לא היו נכונים.
4. מנסים תיקון - או שינוי בקוד או שינוי בקבצי prompt ואז מפעילים מחדש את הסוכנים ורואים מה קורה.
העבודה עם סוכני קידוד פתחה דלת למיומנות חדשה - התאמת פרויקטים ל AI. מיומנות זו לא תמיד קשורה לנסיון בפיתוח והיא דורשת שיטת עבודה ומחשבה שונה. בוובינר היום הצגתי את הבסיס של מיומנות זו. אני מעריך שבעתיד הקרוב מיומנות זו תהפוך לחלק בלתי נפרד מתהליך הפיתוח כולל הקמת צוותי תשתיות AI בארגונים. עכשיו בואו נראה במה מדובר.
✏ מה זה בכלל קוד ידידותי ל AI
מידת הידידותיות של קוד ל AI היא סקאלה. בגדול היא אומרת כמה סוכן הקידוד צריך להתאמץ לפני שהוא מתחיל לכתוב קוד, ומה הסיכוי שהקוד שיכתב יהיה נכון. פרויקטים ידידותיים ל AI הם פרויקטים בהם:
1. כל פיצ'ר או תיקון באג עולה פחות טוקנים.
2. אחרי כל פיצ'ר או תיקון באג אנו נדרשים לפחות איטרציות עד להשלמת התיקון.
3. סוכן קידוד מצליח להבין את הטעויות ולתקן בלי התערבות שלנו.
מה שהופך פרויקט לידידותי ל AI היום זה:
1. מבנה קוד מסודר, קבצים קטנים, חלוקה נכונה לקומפוננטות
2. קבצי תיעוד טובים עם אינדקס שעוזר ל AI להבין איזה קבצים מהפרויקט צריך לטעון (זה יכול להיות Skill או קבצים פשוטים בתיקיית docs).
3. בדיקות אוטומטיות, בהן ה AI יוכל להשתמש כדי לבדוק את עצמו.
אבל יותר חשוב מרשימת המכולת הזו היא שיטת העבודה. אני לא חושב שאפשר לקבל מערכת ידידותית ל AI נקודה, אלא שאנחנו יכולים להיות בתהליך התאמת המערכת ל AI והתהליך הזה נמשך כל הזמן. כל פיצ'ר חדש, כל תיקון באג, כל קוד חדש שנכנס למערכת משנה אותה ומחייב המשך התאמה.
✏ איך נראה התהליך
בוובינר הצגתי שתי דוגמאות - אחת מפרויקט langlets ושניה מפרויקט maigret.
בפרויקט לנגלטס הראיתי קומפוננטה של תפריט User Menu שלא בנויה בתור קומפוננטה אלא מובנית בתוך קומפוננטות גדולות יותר, כלומר תפריט המשתמש של מסך הבית בנוי בתוך הקומפוננטה של מסך הבית. תפריט המשתמש של מסך צפיה בקורס בנוי בתוך המסך של צפיה בקורס. כפילות זו מאפשרת אומנם להציג אפשרויות שונות בכל מסך או עיצוב קצת שונה לכל מסך, אבל היא גם מקשה על AI לזהות את התפריט.
בדוגמה רצינו לתקן באג באותו תפריט משתמש. כתבתי את הפרומפט:
Fix bug in user menu
Open user menu -> Enter "Profile" page -> Hit back
User menu stays open, but it should be closed.
ראינו שקלוד קוד וקודקס מסתירים את המחשבות של המודל ומציגים מעט פלט. חלק מזה זה בשביל לא לבלבל את המשתמשים וחלק מזה זה בשביל לא לחשוף מידע על תבניות המחשבה הפנימיות של המודלים שלהם. אפילו מהמעט מידע שנחשף ראינו שהמודל מתחיל מקובץ אחד בו מוגדר התפריט ואז מחפש בכל הפרויקט עם grep קבצים נוספים שעשויים לכלול הגדרות מקבילות לתפריט זה. לפעמים הוא מוצא את כולם, לפעמים חלק מהם ולפעמים רק הגדרה אחת.
ראינו גם את סוכן הקידוד pi והפעלנו באמצעותו את המודל הפתוח kimi שכן מדפיס את כל תהליך המחשבה שלו. תהליך המחשבה של קימי הראה לנו בדיוק מה המודל ראה בכל שלב ואת תהליך הגילוי של כל ההגדרות.
גילינו שתפריט המשתמש מוגדר ב-4 קבצים במערכת, שלושה מהם רלוונטים לתיקון שביקשתי והרביעי קשור לתפריט באפליקציית האייפון ולא נדרש לתיקון.
אחרי שמבינים את הבעיה ממשיכים לניסוי. ההשערה שלי היתה שאם אאחד את הקבצים ואוציא את הגדרת התפריט לקומפוננטה נפרדת לסוכן יהיה קל יותר לעבוד על הקוד. בשביל תכל'ס לאחד את הקוד לא צריך לפתוח עורך טקסט אפשר לבקש מהסוכן לעשות את זה. אחרי האיחוד הפעלתי מחדש את אותו פרומפט וראינו שהפעם הסוכן מגיע לתשובה מהר יותר עם פחות טוקנים ולא מפספס תוצאות (כי כל הקוד נמצא בקובץ אחד של קומפוננטה).
בדוגמה שניה הראיתי את פרויקט maigret והצגתי באג ספציפי במערכת הדוחות של הפרויקט. שם ראינו איך הסוכנים צריכים לסרוק את הפרויקט כדי למצוא את מערכת הדוחות ואיפה בדיוק הבאג. הניסוי שם היה ליצור קובץ CLAUDE.md שמסביר פשוט איפה נמצאת מערכת הדוחות ואיך היא עובדת (4 שורות). זה הספיק כדי לצמצם משמעותית את כמות הטוקנים ואת זמן התגובה של הסוכן.
בשני המקרים התהליך הוא איטרטיבי:
1. בוחרים משימה שאני יודע איך היא צריכה להסתיים
2. מפעילים כמה סוכנים במקביל לחקור, זה יכול להיות מאותה תיקיה של הפרויקט או באמצעות worktree ממספר עותקים (עדיף להשתמש ב worktree כאן כדי שלא ידרכו אחד לשני על הרגליים כשהם מנסים לפתור את אותה משימה).
3. קוראים ממש את השיחות כולל כל הפעלות הכלים שביצעו הסוכנים ומנסים להבין על מה התבזבז הזמן ואיזה כיוונים הסוכן לקח שבסוף לא היו נכונים.
4. מנסים תיקון - או שינוי בקוד או שינוי בקבצי prompt ואז מפעילים מחדש את הסוכנים ורואים מה קורה.
❤1
המטרה כאן היא לא לפתח פיצ'ר או לתקן באג. זכרו אנחנו בוחרים משימה שאנחנו כבר יודעים איך אמורה להסתיים. המטרה היא לגלות איזה שינויים בפרויקט יגרמו לסוכני הקידוד לייצר את הפתרון שאנחנו רוצים.
בעבר המלצתי לעשות את הניסויים האלה בזמן עבודה על פיצ'רים. היום אני ממש חושב על זה כתהליך נפרד מהפיתוח, מיומנות אחרת שצריכה להתבצע במקביל. אני בהחלט יכול לדמיין צוות של "מומחי AI" שעובד יחד עם המפתחים על פרויקט, המפתחים קובעים את הכיוון והארכיטקטורה וקוראים את הקוד שהסוכן מייצר כדי לוודא שרק קוד טוב נכנס למערכת ומומחי ה AI עובדים על ההיסטוריה, חוזרים קומיט או שניים אחורה, מנסים את הפרומפט כמה פעמים ומזהים מה אפשר לשנות בפרויקט כדי לקבל תוצאה טובה יותר וזולה יותר.
אני מקווה שאלה מכם שהגיעו למרות החופש הגדול והשינוי ביום נהנו. שבוע הבא ניפגש לכתוב בדיקות אוטומטיות עם AI וזה יהיה הוובינר האחרון לעונה, אוגוסט נצא לחופשת קיץ ובספטמבר נחזור בכוחות מחודשים. אם יש לכם נושאים שהייתם רוצים להכניס לסדרת הוובינרים של ספטמבר אפשר לשלוח לי הצעות במייל.
בעבר המלצתי לעשות את הניסויים האלה בזמן עבודה על פיצ'רים. היום אני ממש חושב על זה כתהליך נפרד מהפיתוח, מיומנות אחרת שצריכה להתבצע במקביל. אני בהחלט יכול לדמיין צוות של "מומחי AI" שעובד יחד עם המפתחים על פרויקט, המפתחים קובעים את הכיוון והארכיטקטורה וקוראים את הקוד שהסוכן מייצר כדי לוודא שרק קוד טוב נכנס למערכת ומומחי ה AI עובדים על ההיסטוריה, חוזרים קומיט או שניים אחורה, מנסים את הפרומפט כמה פעמים ומזהים מה אפשר לשנות בפרויקט כדי לקבל תוצאה טובה יותר וזולה יותר.
אני מקווה שאלה מכם שהגיעו למרות החופש הגדול והשינוי ביום נהנו. שבוע הבא ניפגש לכתוב בדיקות אוטומטיות עם AI וזה יהיה הוובינר האחרון לעונה, אוגוסט נצא לחופשת קיץ ובספטמבר נחזור בכוחות מחודשים. אם יש לכם נושאים שהייתם רוצים להכניס לסדרת הוובינרים של ספטמבר אפשר לשלוח לי הצעות במייל.
👏3❤1
📌 שני סוגים של קוד ריוויו
סוג אחד של קוד ריוויו הוא חיפוש בעיות: פה מקרה קצה שלא טופל, שם באג של מקביליות, פה מנגנון שלא יעבוד תחת עומס. אנחנו מקבלים את הרעיון הבסיסי של הפתרון ומחפשים בעיות ביישום.
סוג שני של קוד ריוויו לוקח צעד אחורה ומסתכל על הפתרון כמכלול. האם בכלל יש פה בעיה? האם זאת הדרך הנכונה לגשת אליה? האם יש דרך יותר טובה? איזה אילוצים חדשים הפתרון הזה מכניס למערכת? איזה דברים יהיה קשה לעשות אחרי שאקבל את השינוי? האם השינוי תואם את ערכי המערכת?
שני הסוגים נוגעים בכשלים שונים של סוכני קידוד. שני הכשלים איתנו כדי להישאר ולכן כדאי שנתרגל לבחון כל קוד שאנחנו מקבלים משתי הזוויות. אם נראה שהסוכן שלכם מצליח יותר מדי טוב באחד הסוגים אולי הסיבה היא שתהליך ה Code Review שלכם ממוקד רק בסוג השני.
סוג אחד של קוד ריוויו הוא חיפוש בעיות: פה מקרה קצה שלא טופל, שם באג של מקביליות, פה מנגנון שלא יעבוד תחת עומס. אנחנו מקבלים את הרעיון הבסיסי של הפתרון ומחפשים בעיות ביישום.
סוג שני של קוד ריוויו לוקח צעד אחורה ומסתכל על הפתרון כמכלול. האם בכלל יש פה בעיה? האם זאת הדרך הנכונה לגשת אליה? האם יש דרך יותר טובה? איזה אילוצים חדשים הפתרון הזה מכניס למערכת? איזה דברים יהיה קשה לעשות אחרי שאקבל את השינוי? האם השינוי תואם את ערכי המערכת?
שני הסוגים נוגעים בכשלים שונים של סוכני קידוד. שני הכשלים איתנו כדי להישאר ולכן כדאי שנתרגל לבחון כל קוד שאנחנו מקבלים משתי הזוויות. אם נראה שהסוכן שלכם מצליח יותר מדי טוב באחד הסוגים אולי הסיבה היא שתהליך ה Code Review שלכם ממוקד רק בסוג השני.
📌 לא יודע סוויפט
אני עובד עכשיו על אפליקציית ios ללנגלטס בעזרת AI ובלי לדעת סוויפט. הפעם האחרונה שכתבתי משהו לאייפון היתה ב 2011, זה היה ב Objective C ועבור אייפון עם יכולות מאוד שונות ממה שיש היום. אבל היום יש AI. אפשר לראות את הקוד כאן:
https://github.com/ynonp/langlets-rails/tree/main/langlets-ios/langlets
גם בלי לדעת סוויפט אני יכול להבין את הקוד כולל קוד שלא הייתי יכול לכתוב, לדוגמה קל לי לראות שהלולאה הזאת:
מאתחלת את הטאבים ביישום. אבל - אני לא יודע למה זה צריך להיות מפוצל לשתי לולאות או למה צריך לולאה שעוברת על מבנה נתונים סטטי במקום להגדיר גם את הנתונים ב init. כלומר הפער שלי הוא לא בסוויפט עצמה (למרות שכאמור אני לא יודע סוויפט) אלא ברעיונות ובתיאוריה של פיתוח ממשק משתמש ל ios.
במקום אחר אני רואה שהוא הגדיר
וזה ממשיך לכל אורך האפליקציה. אני מצליח לזהות באגים אם הם בפונקציה ספציפית, הרבה יותר קשה לי לזהות באגים שנובעים משימוש לא נכון באלמנטים של התשתית. התוצאה שאני מוצא את עצמי לא פעם מנסה לתאר באג ל AI בתקווה שהוא יסביר לי מה קרה ויתקן.
מסקנות? בטח זה קל:
1. מאוד קשה לכתוב מערכת עם AI בלי להבין מה קורה שם. זה אפשרי כמובן אבל גם עם המודלים הכי מתקדמים יהיו באגים קטנים ואני לא רואה איך בלי להבין אפשר לסדר הכל בצורה אמינה.
2. מצד שני למי שמוכן ללמוד יש אינסוף משאבים, הרבה מעבר לכל תקופה קודמת בפיתוח. כשאני רוצה להבין משהו מספיק לשאול את הסוכן מה עושה הלולאה הזאת, למה הוא בחר את הקלאס הזה ואפילו מה עושה פקודה מסוימת בשפה.
3. לא חייבים לדעת לכתוב קוד. כן צריך לדעת לקרוא אותו. וזה נכון גם בטכנולוגיות שאנחנו מכירים טוב. אני לא חושב שצריך להיות מודאגים מאובדן מיומנות במובן של "אני לא זוכר איך לכתוב לולאת for". זה ממש מידע שאפשר כבר לשכוח, הוא לא חשוב.
4. מוטיבציה היא עדיין הסעיף הכי קשה. לא מוטיבציה לקודד או שהמערכת תעבוד, אלא מוטיבציה ללמוד. הרצון להבין לעומק מה עושה כל שורה ואיך דברים מתחברים וגם מה החלופות ולמה בחרנו בחלופה שבחרנו. בפיתוח בסביבה שאני לא מכיר שבה AI עושה את רוב העבודה הנטייה היא להיצמד וללמוד רק את הקוד שה AI כתב כדי לראות שאין שם יותר מדי שטויות.
5. גם בלי לדעת סוויפט הצלחתי לכתוב אפליקציה, אבל זה לא קירב אותי אפילו בס"מ למציאת עבודה כמפתח סוויפט. ככל ש AI מבצע טוב יותר את החלקיים הטכניים של קידוד, בני אדם חייבים להיות יותר מקצועיים ולהביא ראייה מערכתית ויצירתיות מתוך היכרות עמוקה עם עולם התוכן.
אני עובד עכשיו על אפליקציית ios ללנגלטס בעזרת AI ובלי לדעת סוויפט. הפעם האחרונה שכתבתי משהו לאייפון היתה ב 2011, זה היה ב Objective C ועבור אייפון עם יכולות מאוד שונות ממה שיש היום. אבל היום יש AI. אפשר לראות את הקוד כאן:
https://github.com/ynonp/langlets-rails/tree/main/langlets-ios/langlets
גם בלי לדעת סוויפט אני יכול להבין את הקוד כולל קוד שלא הייתי יכול לכתוב, לדוגמה קל לי לראות שהלולאה הזאת:
navigators = Self.tabs.map { tab in
Navigator(configuration: .init(name: tab.title, startLocation: Self.url(for: tab)),
delegate: navigatorDelegate)
}
viewControllers = zip(Self.tabs, navigators).map { tab, navigator in
navigator.rootViewController.view.backgroundColor = appBackgroundColor
navigator.rootViewController.tabBarItem = UITabBarItem(
title: tab.title,
image: UIImage(systemName: tab.image),
selectedImage: UIImage(systemName: tab.selectedImage)
)
return navigator.rootViewController
}מאתחלת את הטאבים ביישום. אבל - אני לא יודע למה זה צריך להיות מפוצל לשתי לולאות או למה צריך לולאה שעוברת על מבנה נתונים סטטי במקום להגדיר גם את הנתונים ב init. כלומר הפער שלי הוא לא בסוויפט עצמה (למרות שכאמור אני לא יודע סוויפט) אלא ברעיונות ובתיאוריה של פיתוח ממשק משתמש ל ios.
במקום אחר אני רואה שהוא הגדיר
TabBarController שיורש מ UITabBarController, אבל אני לא יודע מאיפה מגיע UITabBarController או אם זה הדבר הנכון שם או אם יש משהו יותר חדש או אם יש בעיות מסוימות בקלאס הזה שיתנגשו עם רעיונות מסוימים באפליקציה.וזה ממשיך לכל אורך האפליקציה. אני מצליח לזהות באגים אם הם בפונקציה ספציפית, הרבה יותר קשה לי לזהות באגים שנובעים משימוש לא נכון באלמנטים של התשתית. התוצאה שאני מוצא את עצמי לא פעם מנסה לתאר באג ל AI בתקווה שהוא יסביר לי מה קרה ויתקן.
מסקנות? בטח זה קל:
1. מאוד קשה לכתוב מערכת עם AI בלי להבין מה קורה שם. זה אפשרי כמובן אבל גם עם המודלים הכי מתקדמים יהיו באגים קטנים ואני לא רואה איך בלי להבין אפשר לסדר הכל בצורה אמינה.
2. מצד שני למי שמוכן ללמוד יש אינסוף משאבים, הרבה מעבר לכל תקופה קודמת בפיתוח. כשאני רוצה להבין משהו מספיק לשאול את הסוכן מה עושה הלולאה הזאת, למה הוא בחר את הקלאס הזה ואפילו מה עושה פקודה מסוימת בשפה.
3. לא חייבים לדעת לכתוב קוד. כן צריך לדעת לקרוא אותו. וזה נכון גם בטכנולוגיות שאנחנו מכירים טוב. אני לא חושב שצריך להיות מודאגים מאובדן מיומנות במובן של "אני לא זוכר איך לכתוב לולאת for". זה ממש מידע שאפשר כבר לשכוח, הוא לא חשוב.
4. מוטיבציה היא עדיין הסעיף הכי קשה. לא מוטיבציה לקודד או שהמערכת תעבוד, אלא מוטיבציה ללמוד. הרצון להבין לעומק מה עושה כל שורה ואיך דברים מתחברים וגם מה החלופות ולמה בחרנו בחלופה שבחרנו. בפיתוח בסביבה שאני לא מכיר שבה AI עושה את רוב העבודה הנטייה היא להיצמד וללמוד רק את הקוד שה AI כתב כדי לראות שאין שם יותר מדי שטויות.
5. גם בלי לדעת סוויפט הצלחתי לכתוב אפליקציה, אבל זה לא קירב אותי אפילו בס"מ למציאת עבודה כמפתח סוויפט. ככל ש AI מבצע טוב יותר את החלקיים הטכניים של קידוד, בני אדם חייבים להיות יותר מקצועיים ולהביא ראייה מערכתית ויצירתיות מתוך היכרות עמוקה עם עולם התוכן.
GitHub
langlets-rails/langlets-ios/langlets at main · ynonp/langlets-rails
Contribute to ynonp/langlets-rails development by creating an account on GitHub.
❤1👍1👏1
📌 כבר לא צריכים
זו אולי דעה לא פופולרית אבל מהנסיון שלי בעבודה עם AI אתם כבר לא צריכים את רוב הטיפים שמצאתם ברשת. חצי מהם כנראה אף פעם לא היו רלוונטיים אליכם והחצי השני כבר התיישנו עד שהספקתם לנסות אותם.
כמה דוגמאות לדברים שמחקתי ולא קרה כלום:
1. סקילים שהסבירו לסוכן איך להיות מתכנת פרונטאנד מעולה, איך להיות אלוף ה Code Review או הזכירו לו להשתמש במנגנונים קיימים במערכת. (עדיין אני שומר סקילים לספריות קוד צד שלישי שאני מתקין, אבל אני חושב שבקרוב גם אותם אוכל למחוק).
2. מצב תכנון. מסתבר שהסוכן מצליח לתכנן לבד מה שהוא צריך גם בעבודה במצב אוטומטי.
3. חיבור ל MCP של כרום. נכון זה שובר את הלב אבל קודקס מצליח לכתוב לי קוד פרונטאנד שעובד גם בלי לנסות את זה בדפדפן (כן מריץ בדיקות שכותב לעצמו) ומסתבר שזה חוסך לא מעט טוקנים.
4. הערות בקוד - לסוכן קל לקרוא קוד כמו שקל לו לקרוא את ההסבר על הקוד. (הבעיה היחידה שהוא לא מפסיק לכתוב הערות).
5. חלוקת משימה גדולה למשימות קטנות - פה עדיין צריך לחלק אבל לפי נושאים ולא לפי שלבים, למשל במשימה של כתיבת 20 דוחות חדשים למערכת החלוקה לא תהיה 20 שיחות, שיחה לכל דוח, אלא בסך הכל שתי שיחות, שיחה ראשונה מעדכנים את כל קוד המערכת כדי לשמור ב DB את כל הנתונים שצריך בשביל לייצר את הדוחות, שיחה שניה מדביק לו את המפרט של כל 20 הדוחות שירוץ על זה.
טירוף נכון? לחשוב כמה המודלים התקדמו. והשאלה של פיוטר לא מפסיקה להדהד - אם הקטע הזה של קידוד נפתר, איך מוצרי תוכנה רק נהיים יותר גרועים?
כשם שאנחנו לא מתחרים עם הקומפיילר במי כותב אסמבלי יותר טוב או יותר מהר, אין הגיון להתחרות ב LLM במי מממש יותר טוב עץ אדום שחור. האתגר שלנו הוא להשתמש באותם כלים חדשים כדי לבנות מהר יותר מוצרים טובים יותר.
זו אולי דעה לא פופולרית אבל מהנסיון שלי בעבודה עם AI אתם כבר לא צריכים את רוב הטיפים שמצאתם ברשת. חצי מהם כנראה אף פעם לא היו רלוונטיים אליכם והחצי השני כבר התיישנו עד שהספקתם לנסות אותם.
כמה דוגמאות לדברים שמחקתי ולא קרה כלום:
1. סקילים שהסבירו לסוכן איך להיות מתכנת פרונטאנד מעולה, איך להיות אלוף ה Code Review או הזכירו לו להשתמש במנגנונים קיימים במערכת. (עדיין אני שומר סקילים לספריות קוד צד שלישי שאני מתקין, אבל אני חושב שבקרוב גם אותם אוכל למחוק).
2. מצב תכנון. מסתבר שהסוכן מצליח לתכנן לבד מה שהוא צריך גם בעבודה במצב אוטומטי.
3. חיבור ל MCP של כרום. נכון זה שובר את הלב אבל קודקס מצליח לכתוב לי קוד פרונטאנד שעובד גם בלי לנסות את זה בדפדפן (כן מריץ בדיקות שכותב לעצמו) ומסתבר שזה חוסך לא מעט טוקנים.
4. הערות בקוד - לסוכן קל לקרוא קוד כמו שקל לו לקרוא את ההסבר על הקוד. (הבעיה היחידה שהוא לא מפסיק לכתוב הערות).
5. חלוקת משימה גדולה למשימות קטנות - פה עדיין צריך לחלק אבל לפי נושאים ולא לפי שלבים, למשל במשימה של כתיבת 20 דוחות חדשים למערכת החלוקה לא תהיה 20 שיחות, שיחה לכל דוח, אלא בסך הכל שתי שיחות, שיחה ראשונה מעדכנים את כל קוד המערכת כדי לשמור ב DB את כל הנתונים שצריך בשביל לייצר את הדוחות, שיחה שניה מדביק לו את המפרט של כל 20 הדוחות שירוץ על זה.
טירוף נכון? לחשוב כמה המודלים התקדמו. והשאלה של פיוטר לא מפסיקה להדהד - אם הקטע הזה של קידוד נפתר, איך מוצרי תוכנה רק נהיים יותר גרועים?
כשם שאנחנו לא מתחרים עם הקומפיילר במי כותב אסמבלי יותר טוב או יותר מהר, אין הגיון להתחרות ב LLM במי מממש יותר טוב עץ אדום שחור. האתגר שלנו הוא להשתמש באותם כלים חדשים כדי לבנות מהר יותר מוצרים טובים יותר.
ptrchm
Nothing Works and Everyone Is Euphoric
As I’m writing this, we’re in the middle of an AI-induced mass psychosis. People are literally token-maxxing themselves into hospital beds, scrambling to capture some of that market value before everything is automated away. I can’t blame them. Models keep…
👏4
📌 הבדיקות שלי, הבדיקות של הסוכן
כשסוכן קידוד כותב קוד הוא לא יכול לדעת אפילו שהתווים שהוא כותב הם קוד הגיוני. הוא לא יכול לדעת שהקוד נכתב בקבצים הנכונים או שהוא כותב בשפה הנכונה. בשביל סוכן קידוד הבדיקה היא דרך פשוטה להצליב נתונים, לכתוב את אותו קוד בכמה מקומות כדי לראות שמקבלים את אותה תוצאה.
ניקח קוד לדוגמה שהסוכן כתב ברובי:
הקוד מגדיר פונקציה אחת ללא פרמטרים בשם
אותו סוכן שכתב את זה כתב לי גם בדיקה:
הבדיקה משתלטת על אותה פונקציית מפתח
אחרי שהבדיקה הזאת תעבור (חייבת לעבור. היא לא בודקת שום דבר מעניין). הפעם הבאה שנפגוש אותה תהיה כשהיא תיכשל בגלל שמישהו החליט לשנות את המימוש של
הבדיקה שאני צריך הרבה יותר מעניינת. אני יודע שהמפתחות שיוצאים מ
1. תבנית HTML שמרונדרת עם כל הנתונים הנכונים, גם בשפות שנכתבות מימין לשמאל וגם בשפות שנכתבות משמאל לימין.
2. מספר שאילתות חסום שלא קשור לכמה Phrases יש בפעילות.
3. מאחר והפונקציה לא תעבוד אם
הדברים שאני רוצה לוודא ימשיכו להיות חשובים לא משנה איך נעדכן בעתיד את הקלאס או הממשקים הפנימיים. אם בדיקה שלי נכשלת זה סימן לבעיה אמיתית בקוד. אם הבדיקה של הסוכן נכשלת זה בסך הכל סימן שמישהו שינה התנהגות ועכשיו צריך לשנות את קוד הבדיקה.
הייתי רוצה למצוא דרך לשכנע את הסוכן לכתוב רק בדיקות מהסוג שאני אוהב ואני מודה שבינתיים לא היתה לי יותר מדי הצלחה במאבק הזה. מה שכן אני ממליץ אם גם הסוכנים שלכם כותבים בדיקות רק בשביל עצמם עדיף למחוק אותן לפני הקומיט. חבל על הטוקנים שנצטרך להשקיע בתחזוקה של כל הבדיקות המיותרות.
כשסוכן קידוד כותב קוד הוא לא יכול לדעת אפילו שהתווים שהוא כותב הם קוד הגיוני. הוא לא יכול לדעת שהקוד נכתב בקבצים הנכונים או שהוא כותב בשפה הנכונה. בשביל סוכן קידוד הבדיקה היא דרך פשוטה להצליב נתונים, לכתוב את אותו קוד בכמה מקומות כדי לראות שמקבלים את אותה תוצאה.
ניקח קוד לדוגמה שהסוכן כתב ברובי:
module Activities
class ReadTranslatedActivity < Activity
include ActivityWithTokens
def activity_params
l2 = ordered_phrases.first.l2
{
phrases: ordered_phrases,
l2_rtl: l2.rtl,
}
end
end
end
הקוד מגדיר פונקציה אחת ללא פרמטרים בשם
activity_params שמחזירה אוביקט שתלוי בתוצאה של פונקציה אחרת בשם ordered_phrases.אותו סוכן שכתב את זה כתב לי גם בדיקה:
require "test_helper"
class Activities::ReadTranslatedActivityTest < ActiveSupport::TestCase
test "activity_params exposes only the translated phrases, no video" do
activity = Activities::ReadTranslatedActivity.new
language = Struct.new(:rtl).new(true)
phrase = Struct.new(:l2, :phrase_tokens).new(language, [])
activity.define_singleton_method(:ordered_phrases) { [phrase] }
params = activity.activity_params
assert_equal [phrase], params[:phrases]
assert params[:l2_rtl]
assert_nil params[:video_player]
end
end
הבדיקה משתלטת על אותה פונקציית מפתח
ordered_phrases כדי שתחזיר משהו קבוע ועכשיו הוא מוודא שהאוביקט ש activity_params מחזירה מכיל פרמטרים מסוימים ולא מכיל פרמטרים אחרים.אחרי שהבדיקה הזאת תעבור (חייבת לעבור. היא לא בודקת שום דבר מעניין). הפעם הבאה שנפגוש אותה תהיה כשהיא תיכשל בגלל שמישהו החליט לשנות את המימוש של
activity_params, אולי להוסיף עוד מפתח או להוריד את אחד מהמפתחות. ואז נצטרך לשבור את הראש כדי להבין למה הבדיקה שם, מה הכשלון שלה מלמד אותנו ואם למישהו בכלל אכפת מזה.הבדיקה שאני צריך הרבה יותר מעניינת. אני יודע שהמפתחות שיוצאים מ
activity_params מגיעים לתבנית לתצוגה. אני רוצה לוודא שבהנתן ReadTranslatedActivity אקבל:1. תבנית HTML שמרונדרת עם כל הנתונים הנכונים, גם בשפות שנכתבות מימין לשמאל וגם בשפות שנכתבות משמאל לימין.
2. מספר שאילתות חסום שלא קשור לכמה Phrases יש בפעילות.
3. מאחר והפונקציה לא תעבוד אם
ordered_phrases מחזירה מערך ריק אני ארצה לוודא שנסיון לייצר ReadTranslatedActivity בלי phrases זורק שגיאה.הדברים שאני רוצה לוודא ימשיכו להיות חשובים לא משנה איך נעדכן בעתיד את הקלאס או הממשקים הפנימיים. אם בדיקה שלי נכשלת זה סימן לבעיה אמיתית בקוד. אם הבדיקה של הסוכן נכשלת זה בסך הכל סימן שמישהו שינה התנהגות ועכשיו צריך לשנות את קוד הבדיקה.
הייתי רוצה למצוא דרך לשכנע את הסוכן לכתוב רק בדיקות מהסוג שאני אוהב ואני מודה שבינתיים לא היתה לי יותר מדי הצלחה במאבק הזה. מה שכן אני ממליץ אם גם הסוכנים שלכם כותבים בדיקות רק בשביל עצמם עדיף למחוק אותן לפני הקומיט. חבל על הטוקנים שנצטרך להשקיע בתחזוקה של כל הבדיקות המיותרות.
👍3
📌 לא, טמפרטורה 0.2 ממש לא רלוונטית שם
בקריאות API למודלי שפה ספקים רבים תומכים בפרמטר "טמפרטורה". פרמטר זה קובע את רמת היצירתיות של המודל. אבל מה זה אומר בעצם יצירתיות? ומתי נרצה להשתמש בה?
באופן רגיל מודל שפה בוחר את ההשלמה הכי הגיונית לשיחה לפי נתוני האימון שלו. הרעיון הכי מדליק של יצרני המודלים היה להכניס אלמנט של אקראיות למשחק, כלומר במקום לבחור תמיד להשלים בצורה הכי הגיונית ההשלמה מוגרלת מתוך מספר השלמות הגיוניות אפשריות. ההשלמה ההגיונית ביותר מקבלת את המשקל הגבוה ביותר ויש הכי הרבה סיכוי לקבל אותה, אבל גם השלמות פחות הגיוניות יכולות להופיע, גם אם בסיכוי נמוך יותר. ככל שהטמפרטורה נמוכה יותר כך גדל הסיכוי שנקבל את התוצאה הסבירה ביותר. טמפרטורה 0 אומרת שתמיד בוחרים את ההשלמה ההגיונית ביותר.
לקח לי יותר מדי זמן להבין שההבדל בין 0.2 ל 0.8 בעולם האמיתי הוא לא כזה חשוב כמו ההבדל בין 0 לכל דבר שאינו 0. בכל מערכת סוכן שאתם כותבים כדאי לשאול "האם לפעולה הזאת יש תשובה נכונה". כלל אצבע טוב הוא לתת טמפרטורה 0 לדברים שיש להם פתרון אחד נכון וטמפרטורה שונה מ-0 לדברים שיש כמה תוצאות שיכולות לעבוד (כאשר ככל שהערך גבוה יותר כך נקבל תוצאות יותר מגוונות).
דוגמאות? בטח-
1. רוצים להוציא תמליל מוידאו? קחו טמפרטורה 0. יש רק טקסט אחד שהבן אדם בוידאו אומר וזה הטקסט שאתם צריכים.
2. רוצים לפתור תרגיל חשבוני? טמפרטורה 0. יש רק פיתרון אחד נכון לתרגיל.
3. רוצים לתקצר מסמך ולהוציא את הנקודות המרכזיות ממנו? טמפרטורה 0.
כל המשימות האלה דורשות יצירתיות אבל יש להן תשובה נכונה אחת. סוכן שיחזיר תוצאות שונות על המשימות האלה למשתמשים שונים יהיה מבלבל וכל תוצאה חוץ מהתוצאה הנכונה היא באג שרק משתמשים מסוימים רואים. לעומתן:
4. רוצים סוכן שכותב ברכת יום הולדת לחברים? טמפרטורה גבוהה מאפס. כל הפעלה של הסוכן יכולה לתת תוצאה שונה וזה אחלה.
5. רוצים סוכן שמזהה בעיות בקוד? טמפרטורה גבוהה מאפס זה מצוין. כל הפעלה תזהה בעיות אחרות בקוד ואנחנו כבר נדאג להפעיל את הסוכן כמה פעמים כדי לקבל תמונה מלאה.
הסיפור עם טמפרטורה הוא לא כמה יצירתי צריך להיות בשביל לפתור את הבעיה, אלא כמה מגוונות אמורות להיות התשובות שמשתמשים מקבלים.
בקריאות API למודלי שפה ספקים רבים תומכים בפרמטר "טמפרטורה". פרמטר זה קובע את רמת היצירתיות של המודל. אבל מה זה אומר בעצם יצירתיות? ומתי נרצה להשתמש בה?
באופן רגיל מודל שפה בוחר את ההשלמה הכי הגיונית לשיחה לפי נתוני האימון שלו. הרעיון הכי מדליק של יצרני המודלים היה להכניס אלמנט של אקראיות למשחק, כלומר במקום לבחור תמיד להשלים בצורה הכי הגיונית ההשלמה מוגרלת מתוך מספר השלמות הגיוניות אפשריות. ההשלמה ההגיונית ביותר מקבלת את המשקל הגבוה ביותר ויש הכי הרבה סיכוי לקבל אותה, אבל גם השלמות פחות הגיוניות יכולות להופיע, גם אם בסיכוי נמוך יותר. ככל שהטמפרטורה נמוכה יותר כך גדל הסיכוי שנקבל את התוצאה הסבירה ביותר. טמפרטורה 0 אומרת שתמיד בוחרים את ההשלמה ההגיונית ביותר.
לקח לי יותר מדי זמן להבין שההבדל בין 0.2 ל 0.8 בעולם האמיתי הוא לא כזה חשוב כמו ההבדל בין 0 לכל דבר שאינו 0. בכל מערכת סוכן שאתם כותבים כדאי לשאול "האם לפעולה הזאת יש תשובה נכונה". כלל אצבע טוב הוא לתת טמפרטורה 0 לדברים שיש להם פתרון אחד נכון וטמפרטורה שונה מ-0 לדברים שיש כמה תוצאות שיכולות לעבוד (כאשר ככל שהערך גבוה יותר כך נקבל תוצאות יותר מגוונות).
דוגמאות? בטח-
1. רוצים להוציא תמליל מוידאו? קחו טמפרטורה 0. יש רק טקסט אחד שהבן אדם בוידאו אומר וזה הטקסט שאתם צריכים.
2. רוצים לפתור תרגיל חשבוני? טמפרטורה 0. יש רק פיתרון אחד נכון לתרגיל.
3. רוצים לתקצר מסמך ולהוציא את הנקודות המרכזיות ממנו? טמפרטורה 0.
כל המשימות האלה דורשות יצירתיות אבל יש להן תשובה נכונה אחת. סוכן שיחזיר תוצאות שונות על המשימות האלה למשתמשים שונים יהיה מבלבל וכל תוצאה חוץ מהתוצאה הנכונה היא באג שרק משתמשים מסוימים רואים. לעומתן:
4. רוצים סוכן שכותב ברכת יום הולדת לחברים? טמפרטורה גבוהה מאפס. כל הפעלה של הסוכן יכולה לתת תוצאה שונה וזה אחלה.
5. רוצים סוכן שמזהה בעיות בקוד? טמפרטורה גבוהה מאפס זה מצוין. כל הפעלה תזהה בעיות אחרות בקוד ואנחנו כבר נדאג להפעיל את הסוכן כמה פעמים כדי לקבל תמונה מלאה.
הסיפור עם טמפרטורה הוא לא כמה יצירתי צריך להיות בשביל לפתור את הבעיה, אלא כמה מגוונות אמורות להיות התשובות שמשתמשים מקבלים.
👍3