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

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

ואיך את יודעת מה המערכת עושה?

31/10/2026

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

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

class IssueInvitation
  class Rejected < StandardError; end

  def self.call(email:, admin:)
    raise Rejected, I18n.t("admin.forbidden") unless admin.admin?

    token = SecureRandom.urlsafe_base64(32)
    invitation = nil
    # Serialize issue/resend calls, including invitations without an existing row.
    admin.with_lock do
      invitation = Invitation.find_or_initialize_by(email: email.to_s.strip.downcase)
      raise Rejected, I18n.t("admin.invitations.existing_user") if User.exists?(email: invitation.email)
      if invitation.accepted_at?
        raise Rejected, I18n.t("admin.invitations.already_accepted")
      end
      if invitation.last_sent_at && invitation.last_sent_at > 1.minute.ago
        raise Rejected, I18n.t("admin.invitations.cooldown")
      end
      invitation.assign_attributes(invited_by: admin, token_digest: Invitation.digest(token),
        expires_at: 7.days.from_now, last_sent_at: Time.current)
      invitation.save!
    end
    InvitationDeliveryJob.perform_later(invitation.id, token)
    invitation
  end
end

הסוכן יצר מנגנון קירור כדי לוודא שאני לא שולח יותר מדי הזמנות, אלה השורות:

if invitation.last_sent_at && invitation.last_sent_at > 1.minute.ago
  raise Rejected, I18n.t("admin.invitations.cooldown")
end

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

token = SecureRandom.urlsafe_base64(32)
...
invitation.assign_attributes(invited_by: admin, token_digest: Invitation.digest(token),
        expires_at: 7.days.from_now, last_sent_at: Time.current)

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

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

היום למדתי: git intent to add

30/10/2026

בואו נשחק עם גיט. יש לי ריפו ויצרתי בו קובץ חדש בשם demo.py. רואים את זה:

ynonp@ynons-MacBook-Air ~/tmp/blog/git (main?) $ git status
On branch main
Untracked files:
  (use "git add <file>..." to include in what will be committed)
        demo.py

nothing added to commit but untracked files present (use "git add" to track)
ynonp@ynons-MacBook-Air ~/tmp/blog/git (main?) $

עכשיו אני רוצה לראות מה יש בקובץ. קודם כל אני מנסה git diff - אבל הוא לא מדפיס כלום כי אין שינויים בקבצים של הפרויקט (הקובץ demo.py הוא חדש ומבחינת גיט לא חלק מהפרויקט עדיין).

אז אני מנסה להוסיף אותו עם git add . ועכשיו הוא חלק מהפרויקט:

ynonp@ynons-MacBook-Air ~/tmp/blog/git (main?) $ git add .
ynonp@ynons-MacBook-Air ~/tmp/blog/git (main+) $ git status
On branch main
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        new file:   demo.py

ynonp@ynons-MacBook-Air ~/tmp/blog/git (main+) $ git diff
ynonp@ynons-MacBook-Air ~/tmp/blog/git (main+) $

אבל עדיין git diff לא מדפיס כלום כי אין הבדל בין תוכן הקובץ לתוכן הקובץ ב Staging Area. שוב ברור, git add הוסיף את הקובץ ל staging area.

עד היום השתמשתי ב git diff HEAD או git diff --cached כדי לראות את השינויים אחרי add לדוגמה:

ynonp@ynons-MacBook-Air ~/tmp/blog/git (main+) $ git status
On branch main
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        new file:   demo.py

ynonp@ynons-MacBook-Air ~/tmp/blog/git (main+) $ git diff
ynonp@ynons-MacBook-Air ~/tmp/blog/git (main+) $ git diff HEAD
diff --git a/demo.py b/demo.py
new file mode 100644
index 0000000..d77c663
--- /dev/null
+++ b/demo.py
@@ -0,0 +1 @@
+print("hello world from python")

מסתבר ש git add מגיע עם מתג מיוחד בדיוק למקרים האלה, המתג -N או --intent-to-add. מתג זה מסמן לגיט שאנחנו מתכוונים להוסיף את הקובץ הזה לפרויקט בלי להוסיף את התוכן שלו ל Staging בדיוק בשביל שנוכל לראות את ה diff. ככה זה נראה:

ynonp@ynons-MacBook-Air ~/tmp/blog/git (main?) $ git add -N demo.py
ynonp@ynons-MacBook-Air ~/tmp/blog/git (main+*) $ git status
On branch main
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        new file:   demo.py

no changes added to commit (use "git add" and/or "git commit -a")
ynonp@ynons-MacBook-Air ~/tmp/blog/git (main+*) $ git diff
diff --git a/demo.py b/demo.py
new file mode 100644
index 0000000..d77c663
--- /dev/null
+++ b/demo.py
@@ -0,0 +1 @@
+print("hello world from python")
ynonp@ynons-MacBook-Air ~/tmp/blog/git (main+*) $

הקובץ מסומן בתור new file אבל התוכן שלו עדיין לא נשמר וכך אנו רואים אותו ב git diff רגיל.

זה יהיה במבחן?

29/10/2026

״אני רוצה לכתוב את הקוד נכון אבל המנהל שלי דורש שאעלה גרסה אתמול״.

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

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

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

כל המשפטים האלה הם גרסה של אותה שאלה מבית הספר: ״זה יהיה במבחן?״

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

האלטרנטיבה היא סקרנות.

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

״מעניין איך הקוד מטפל במקרי קצה ומה קורה כשהוא נשבר״.

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

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

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

היתרונות של ריאקט נשמעים לי הרבה פחות משכנעים היום

28/10/2026

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

  1. אני חושב על ה State ועל התרגום שלו ל UI פעם אחת במקום בכל פעולה.

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

בואו נפתח את זה.

המשך קריאה

תהליך, סכנה, התמודדות

27/10/2026

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

דוגמאות? ברור.

המשך קריאה

מה כבר ביקשתי - אוטומציה עם AI

26/10/2026

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

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

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

  3. בחירת ספק ומודל לטוקנים - דוט מגיע עם ChatGPT, גרוק בוט עם גרוק, קלוד דואט עם קלוד ואינסטינקט אפילו לא מספרים מי המודל שלהם. רוצה להשתמש ב API Key שלך? שיהיה בהצלחה.

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

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

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

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

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

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

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

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

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

המפגש יתקיים בחמישי בעשר בבוקר ואם אתם עדיין לא בקבוצת הוובינרים שלנו אז מוזמנים להצטרף כאן ולקבל את הקישור לכניסה למייל: https://www.tocode.co.il/talking_ai

למי מתאים קורס ה AI החדש

25/10/2026

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

ואנחנו חושבים שאפשר לעשות את זה טוב יותר.

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

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

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

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

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

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

תאריכים, מחיר, סילבוס מלא וכל שאר הפרטים מחכים לכם בדף הקורס: https://www.tocode.co.il/genai_course

רמה 1

24/10/2026

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

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

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

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

  4. הסוכן כותב לי שהוא סיים עבודה אבל בבדיקה שלי הפיצ'ר לא עובד.

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

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

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

לא תחרות

23/10/2026

סת׳ גודין כותב:

AI gives bosses a cheaper (and often more compliant) alternative to hiring humans to do some tasks.

סת׳ רואה מה שאני רואה ומה שאתם רואים. המשימה שלנו היא לא להיות יותר מהירים מ AI, לא יותר זולים מ AI, לא יותר צייתנים מ AI ולא יותר מדויקים מ AI.

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

זה כבר לא נשמע כל כך מסובך.

האם יש טעם להתאמן על פתרון בעיות ביצועים במערכת?

22/10/2026

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

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

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

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

  2. מטמון יאיץ את החיפוש אבל עלול להחזיר נתונים שגויים (stale) או בקירוב. האם אנחנו מוכנים לחיות עם ההתנהגות השונה?

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

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

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

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