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

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

מה למדתי מלקרוא את הקוד

03/08/2026

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

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

כשהוא מתחיל להסביר לי על התיקון שהוא בנה שמפענח טוב יותר את ההודעות שחוזרות מהסוכן אני שואל "ולמה לא השתמשנו לפני כן ב Structured Output"?

כשהוא מדבר בשבחי מנגנון ה Cache שהוא הוסיף עכשיו כדי שהמידע יחזור מהשרת מהר יותר אני שואל "אבל למה השאילתה עד עכשיו לקחה כל כך הרבה זמן"?

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

כל תיקון כשלעצמו אולי הכי מדויק שיכול להיות - אבל במערכת טובה זו התמונה המלאה שקובעת.

מה לוקח זמן בפיתוח עם AI

02/08/2026

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

המשך קריאה

תראה מה קלוד הסביר לי

01/08/2026

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

ומצד שני החיים האמיתיים.

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

Not only did I get sidetracked by a bunch of useless suggestions but I also had to put up with others dumping their raw AI output at me as if it was somehow a meaningful contribution.

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

"אי אפשר להחליף מטכנולוגיה X ל Y" - ואז הסבר ארוך מודבק מ AI.

"יש בעיית אבטחה אם עושים X" - ואז הסבר ארוך מודבק מ AI.

"יהיה יותר נכון להוסיף redis" - ואז הסבר ארוך מודבק מ AI.

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

מה קרה עם Prompt Engineering

30/07/2026

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

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

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

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

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

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

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

פרומפט אנג'ינירינג אולי התיישן מהר. הטכניקה שהולידה אותו תישאר איתנו להרבה זמן.

איפה אני גר?

29/07/2026

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

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

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

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

הנה דוגמה מהיום. סוכן מייצר קוד כזה:

else
  slug = generate_slug_with_video_id(title, video_id)
  course = create_course_with_unique_slug(user: user, name: title, slug: slug, main_media_url: progress.youtubeurl, language: language, cover: cover_attributes(video))
end

ואז בהמשך הקובץ:

  def create_course_with_unique_slug(user:, name:, slug:, main_media_url:, language:, cover: {}, max_retries: 10)
    retries = 0
    begin
      course = Course.new(
        name: name,
        slug: slug,
        main_media_url: main_media_url,
        language: language,
        user: user,
        status: :processing,
        **cover
      )

      course.save!
      course

    rescue ActiveRecord::RecordNotUnique => e
      retries += 1
      if retries < max_retries
        Rails.logger.warn "Slug collision for '#{slug}', adding suffix (attempt #{retries})..."
        slug = "#{slug}-#{retries}"
        retry
      else
        raise
      end
    end
  end

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

course = Course.create!(...)

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

לא, טמפרטורה 0.2 ממש לא רלוונטית שם

28/07/2026

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

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

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

דוגמאות? בטח-

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

  2. רוצים לפתור תרגיל חשבוני? טמפרטורה 0. יש רק פיתרון אחד נכון לתרגיל.

  3. רוצים לתקצר מסמך ולהוציא את הנקודות המרכזיות ממנו? טמפרטורה 0.

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

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

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

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

הבדיקות שלי, הבדיקות של הסוכן

27/07/2026

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

ניקח קוד לדוגמה שהסוכן כתב ברובי:

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 זורק שגיאה.

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

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

כבר לא צריכים

26/07/2026

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

כמה דוגמאות לדברים שמחקתי ולא קרה כלום:

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

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

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

  4. הערות בקוד - לסוכן קל לקרוא קוד כמו שקל לו לקרוא את ההסבר על הקוד. (הבעיה היחידה שהוא לא מפסיק לכתוב הערות).

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

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

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

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

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