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

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

ואולי AI בכלל מאט אותך?

13/07/2025

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

התוצאות מעניינות ובמספר מימדים:

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

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

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

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

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

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

שטויות שלקח לי יותר מדי זמן להבין על LangGraph

12/07/2025

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

  1. כדאי להתחיל עם LangChain. זה לא אחד במקום השני אלא שאחד מרחיב את השני.

  2. נוח לפתח את ה Nodes אחד אחרי השני, כל Node בצורה עצמאית עם בדיקות משלו.

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

  4. יש המון חבילות הרחבה ל LangGraph רק בשביל לדבר עם ה LLM-ים השונים. אותם LLM-ים מופיעים בכמה חבילות. לפעמים צריך לנסות כמה עד שמוצאים את החבילה הנכונה.

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

  6. אפשר וכדאי להשתמש ב State Class שונה לכל נוד (וכך פלט של נוד אחד הוא הקלט של הנוד הבא). את הסטייט אפשר לכתוב בתור TypedDict או pydantic. אני מעדיף pydantic.

  7. תחברו את LangSmith. זה שווה את השתי לחיצות.

  8. כל קריאה ל graph.stream שולחת את הסטייט הראשוני למסע בגרף ומסתיימת כשהגרף מסתיים עם הסטייט מהנוד האחרון.

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

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

להביא את הפיצה

11/07/2025

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

  1. הגדרת יעדים ברורים - איך נראית הצלחה.

  2. שיפור היכולות - איך אפשר לעשות יותר עם הצוות והמשאבים הקיימים.

  3. שיפור המערכת - זיהוי הזדמנויות "להוריד עלויות" ולשפר תהליכים.

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

והמשבר - אם זה המצב מה נשאר למתכנתים לעשות? מעבר לחלומות של להביא את הפיצה בואו ניקח את שלושת המשימות של מנהלי Agile ונתאים אותן לעולם שלנו:

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

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

  3. שיפור תהליכים מערכתיים - זיהוי תבניות בעייתיות בקוד ש AI מייצר, ריפקטורינג של המערכת כדי של AI יהיה יותר קל, בניית AI Friendly Codebase, שיפור הבדיקות.

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

שקרן שקרן

10/07/2025

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

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

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

גם את זה נצטרך לשנות.

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

הטמעת AI במוצר קיים

09/07/2025

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

המשך קריאה

לא מבין את ה Hack

08/07/2025

הבעיה עם האק גאוני שפותר את הבעיה בדרך שאף אחד לא חשב עליה קורית שנה אחרי:

  1. כשאני משדרג גירסה ולא מבין "איך זה עבד עד עכשיו?"

  2. כשאני מעדכן פיצ'ר לא קשור בכלל ופתאום דברים מוזרים נשברים.

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

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

הסוכן החדש של גיטהאב הוא לא מהעולם הזה

07/07/2025

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

עכשיו בואו נדבר על קופיילוט.

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

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

  2. הם חיברו לו MCP של פליירייט כדי שיוכל להריץ דפדפן ובטח עוד כמה כלים כדי שיוכל לשלוט במחשב שהוא קיבל.

  3. הם בנו סביבו Workflow שלוקח Issue, מפרק אותו למשימות ועוקב אחרי התקדמות.

  4. ואז חיברו את הכל לסוכן אחד שכותב קוד בזמן שאנחנו ישנים.

הנה דוגמה לתוצאה שקיבלתי על פרויקט חדש. זה היה ה Issue שפתחתי:

Create a PR implementing a snake game:

1. Use valtio for state management
2. Use industry best practices React/Next Project with multiple files, client side components, client side storage using context provider pattern.
3. Game mechanics:
  - Snake has to eat apples.
  - Game has 2 types of apples, regular and special (gold) apples. Gold apples are worth more points.
  - As the snake eats more apples it grows.
  - When the snake hits a wall or itself the game is over. User can restart.

4. Pay attention to performance. Use `requestAnimationFrame` for movement and control the FPS. Actual snake speed depends on the user's progress in the game.

5. Do not write tests but write the code using testing best practices so it'll be easy to add tests in the future.

קישור:

https://github.com/ynonp/snake-agent/issues/1

ופה אפשר לראות את ה PR שנוצר:

https://github.com/ynonp/snake-agent/pull/2

וכאן לוג של כל ה Session שקרה ללא מגע יד:

https://github.com/ynonp/snake-agent/actions/runs/16096719029/job/45420480907

ה PR כלל 12 קבצים וכמעט 700 שורות של diff. בזכות החיבור ל playwright קופיילוט באמת הריץ את הפרויקט כדי לוודא שהמשחק עובד. נכון על הארכיטקטורה הוא החליט לבד ואני לא בטוח שאני מסכים עם כל הבחירות שלו, אבל זה בדיוק המשחק שלנו עם AI - אנחנו לא חייבים לקבל את ה PR ואין שום בעיה לזרוק את הקוד, לעדכן את קוד ה Issue בצורה שתגרום להחלטות ארכיטקטורה אחרות ולנסות שוב.

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

פקודת Bash קצרה לפתרון Spelling Bee

06/07/2025

דבורת האיות הוא משחק חמוד המכיל אות אחת באמצע ועוד 6 אותיות מסביב והמשימה שלנו היא למצוא כמה שיותר מילים מהאותיות האלה עם הכללים:

  1. האות שבאמצע חייבת להופיע.

  2. אורך המילה לפחות 4 אותיות.

אפשר לשחק בו כאן: https://6mal5.com/wortendo/

ובטח בעוד המון מקומות ברשת.

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

אתחיל עם הפיתרון שלי והוא נראה כך:

#!/bin/bash -e

center=$1
rest=$2

cat /usr/share/dict/words | grep $center | grep .... | egrep "^[${rest}{$center}]+$" | awk '{ print length "\t" $0 }' | sort -n | cut -f2-

וכן זה שורה אחת:

  1. לוקחים קובץ מילים.
  2. משאירים רק את המילים עם האות שבאמצע.
  3. משאירים רק מילים עם 4 אותיות.
  4. משאירים רק מילים שמורכבות אך ורק מהאותיות של המשחק.
  5. מסדרים את הכל לפי האורך כך שמילים ארוכות יופיעו בתחתית הרשימה (שיהיה קל לראות אותן).

מיטיבי לכת יכולים להוסיף שם head -1 כדי לקבל רק רמז אחד.

ועכשיו למימוש של קלוד:

#!/bin/bash -e

center=$1
rest=$2

# Check if arguments are provided
if [ -z "$center" ] || [ -z "$rest" ]; then
    echo "Usage: $0 <center_letter> <other_letters>"
    echo "Example: $0 a bcdefg"
    exit 1
fi

# Combine all available letters
all_letters="${center}${rest}"

# Convert to lowercase for consistency
center=$(echo "$center" | tr '[:upper:]' '[:lower:]')
rest=$(echo "$rest" | tr '[:upper:]' '[:lower:]')
all_letters=$(echo "$all_letters" | tr '[:upper:]' '[:lower:]')

# Word list file (common locations)
word_files=(
    "/usr/share/dict/words"
    "/usr/dict/words"
    "/usr/share/dict/american-english"
    "/usr/share/dict/web2"
)

word_file=""
for file in "${word_files[@]}"; do
    if [ -f "$file" ]; then
        word_file="$file"
        break
    fi
done

if [ -z "$word_file" ]; then
    echo "Error: No word dictionary found. Please install a word list."
    echo "On Ubuntu/Debian: sudo apt-get install wamerican"
    echo "On macOS: Word lists are usually in /usr/share/dict/"
    exit 1
fi

echo "Solving Spelling Bee with center letter: $center"
echo "Available letters: $all_letters"
echo "Using word list: $word_file"
echo "----------------------------------------"

# Find valid words
valid_words=()
total_score=0

while IFS= read -r word; do
    # Convert word to lowercase and remove any non-alphabetic characters
    clean_word=$(echo "$word" | tr '[:upper:]' '[:lower:]' | sed 's/[^a-z]//g')

    # Skip if word is less than 4 letters
    if [ ${#clean_word} -lt 4 ]; then
        continue
    fi

    # Check if word contains the center letter
    if [[ "$clean_word" != *"$center"* ]]; then
        continue
    fi

    # Check if word only uses available letters
    valid=true
    for ((i=0; i<${#clean_word}; i++)); do
        letter="${clean_word:$i:1}"
        if [[ "$all_letters" != *"$letter"* ]]; then
            valid=false
            break
        fi
    done

    if [ "$valid" = true ]; then
        # Calculate score
        word_length=${#clean_word}
        if [ $word_length -eq 4 ]; then
            score=1
        else
            score=$word_length
        fi

        # Check if it's a pangram (uses all letters)
        is_pangram=true
        for ((i=0; i<${#all_letters}; i++)); do
            letter="${all_letters:$i:1}"
            if [[ "$clean_word" != *"$letter"* ]]; then
                is_pangram=false
                break
            fi
        done

        if [ "$is_pangram" = true ]; then
            score=$((score + 7))
            echo "$clean_word ($score points) - PANGRAM!"
        else
            echo "$clean_word ($score points)"
        fi

        valid_words+=("$clean_word")
        total_score=$((total_score + score))
    fi
done < "$word_file"

echo "----------------------------------------"
echo "Found ${#valid_words[@]} valid words"
echo "Total score: $total_score points"

נשים לב להמון דברים כאן:

  1. קלוד חישב ניקוד של כל המילים שהוא מצא. זה מאוד סיבך לו את המימוש.

  2. קלוד השתמש רק בפקודות bash לסינונים בעוד שאני שמחתי להשתמש ב grep.

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

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

Use a one line pipeline giving just word suggestions (without score)

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

#!/bin/bash -e

center=$1
rest=$2

grep -E "^[${center}${rest}]+$" /usr/share/dict/words | grep "$center" | awk 'length >= 4' | sort -u

שכבר מאוד דומה לפיתרון שלי מלבד סדר הפעולות, המיון בסוף, והבחירה להשתמש ב awk במקום ב grep כדי לבדוק אורך.

לא עומד בקצב

05/07/2025

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

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

  1. איך לבנות פרומפט.

  2. איך לחלק את העבודה עם ה AI.

  3. איזה דברים AI יודע לעשות טוב, ומה עדיף לעשות לבד.

  4. איך לשים לב שה AI מפשל ולעצור אותו לפני שיעשה נזק.

  5. למה חשוב לשים לב בקוד ש AI מייצר.

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

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

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

היום למדתי: פרוטוטייפ ופונקציות חץ

04/07/2025

עזרתי לחבר עם איזה באג שהביא אותי לקוד הבא מתוך ספריית JavaScript ישנה:

/**
 * Used to determine we'll call be calling React.createElement on the component of if this is a
 * generator function used return a function that takes props to return a React element
 * @param component
 * @returns {boolean}
 */
function generatorFunction(component) {
  if (!component.prototype) {
    return false;
  }

  // es5 or es6 React Component
  return !component.prototype.isReactComponent;
}

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

  1. העברת React Component ל API.

  2. העברת פונקציה שמחזירה React Component ל API.

האנטי תבנית כאן היא ברורה - שפת JavaScript לא עושה חיים קלים למי שרוצה להבדיל בין טיפוסים בזמן ריצה. כן יש את typeof אבל גם את Array.isArray וגם את Number.isNaN ויש הרבה כללים לזכור. ועכשיו נסו להבדיל בין "פונקציה שהיא React Component" ל"פונקציה שמחזירה React Component". לא ככה מתכננים API.

עכשיו מה היה הבאג? שימו לב:

> generatorFunction(function() { 10 })
true
> generatorFunction(() => 10)
false

פונקציה שמוגדרת עם המילה function מכילה prototype ריק, ולכן ה isReactComponent שלו הוא שקר ואנחנו מקבלים חזרה ערך "אמת". פונקציית חץ מגיעה בלי prototype ולכן נופלת בתנאי הראשון ומחזירה false. זו כמובן לא היתה כוונת המשורר, אבל לזכותם נגיד שעברו 8 שנים והיום הם בטוח מתכננים ממשקים ברורים יותר.