הבלוג של ינון פרק

טיפים קצרים וחדשות למתכנתים

לא יודע סוויפט

25/07/2026

אני עובד עכשיו על אפליקציית 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 מבצע טוב יותר את החלקיים הטכניים של קידוד, בני אדם חייבים להיות יותר מקצועיים ולהביא ראייה מערכתית ויצירתיות מתוך היכרות עמוקה עם עולם התוכן.

שני סוגים של קוד ריוויו

24/07/2026

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

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

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

סיכום וובינר: פרויקטים ידידותיים ל AI

23/07/2026

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

המשך קריאה

צריכים מפה

22/07/2026

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

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

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

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

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

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

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

איך ללמוד אבטחת מידע ולמה זה מסובך

21/07/2026

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

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

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

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

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

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

תודה אבל לא תודה

20/07/2026

פייבל כתב לי במהלך שיחה

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

יו באמת תודה.

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

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

היום למדתי: strict loading ב Rails

19/07/2026

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

המשך קריאה

סיכום וובינר: גיט וסוכני קידוד

18/07/2026

בוובינר השבוע דיברנו על גיט מנקודת המבט של עבודה עם סוכני קידוד. ראינו שתי תבניות עבודה פופולריות עם סוכנים, Spec Driven Development ו Step By Step Prompts ואיך גיט משתלב בכל אחת. בואו ניזכר מה היה שם.

המשך קריאה

הדרך פנימה

17/07/2026

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

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

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

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

קלוד קוד ותכנות הגנתי

16/07/2026

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

data = {"x": 10}
if "x" in data:
    print(data["x"])

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

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

ניקח דוגמה יותר מעניינת מפרויקט maigret. בקובץ report.py של הפרויקט אני מוצא שתי פונקציות: get_plaintext_report ו generate_report_context. הפונקציה generate_report_context מייצרת מילון עם נתונים והפונקציה get_plaintext_report לוקחת את הנתונים ובונה מהם דוח.

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

Search by username Dr.
Evil returned 0 accounts.
Extended info extracted from 0 accounts.

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

output = (context['brief'] + " ").replace('. ', '.\n')

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

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

if "brief_lines" in context:
    output = "\n".join(context['brief_lines'])
else:
    output = (context['brief'] + " ").replace('. ', '.\n')

זה מיותר כיוון שאנחנו יוצרים את המילון וברור שאם יש בו את brief יהיה בו גם את המפתח החדש brief_lines.

הניסיון הראשון שלי לתקן את זה היה עם התוספת הבאה לקובץ CLAUDE.md:

Project Philosophy

- When we replace a mechanism in code don't keep the old one for record or backward compatibility
- Implement minimalistic solutions
- Consider what data is actually in a dictionary and use the correct key, don't cover too much ground

זה לא עבד.

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

בניסיון השלישי הוספתי את הטקסט הבא ל CLAUDE.md ונראה שזה עובד:

Dictionary Defensive Programming

- When you read a key from a dict/object we construct ourselves, access it directly never .get() with a fallback. Fallbacks and defensive access are only for data crossing a trust boundary we don't control: user input, network responses, parsed files

וכן זה מאוד ספציפי למילונים. אבל אולי פה הקסם.

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