נקודות כשל (או: אולי כבר לא צריך ללמוד פייתון)
המדרגה הבאה של תכנות נראית פחות ופחות כמו קוד ובאותו זמן יותר ויותר טכנית.
כל החלטה טכנית שאנחנו מקבלים בזמן הפיתוח או שאנחנו משאירים ל AI לקבל קובעת מה יצליח, מה לא יצליח וכמה זמן דברים יקחו. הערכת זמנים הפכה למשחק של ידע, לשאלה הפשוטה "האם פיצ'ר X מתאים למבנה של המערכת".
אם המערכת שלי צריכה למלא טפסים למשתמשים, האם אני מייבא את הטפסים לפורמט פנימי שלי, ממיר אותם ל HTML או כותב ישירות על ה PDF? כל בחירה מגיעה עם יתרונות וחסרונות שלה. אני אולי לא צריך יותר לדעת איך נקראת הפונקציה שכותבת על PDF, אבל כדאי מאוד שאני אדע שבשביל לכתוב על PDF צריך קואורדינטות, ובשביל לכתוב על HTML צריך לקרוא מבנה של עץ.
ב Langlets בניתי סוכן AI שמייצר תרגילי אוצר מילים בשפה. ההחלטות על היכולות של הסוכן - האם הוא מייצר HTML מלא? האם הוא מייצר אפליקציה מלאה (כולל צד שרת)? האם הוא מייצר את התרגיל בפורמט פנימי שלי, איך יישמרו התרגילים ואיך יישמרו התשובות, כל אלה קובעות מה אפשר יהיה לבצע בתרגילים. ההחלטות יוצרות את המסגרת, הסוכן מצייר בתוך הקווים.
כשאני מחליט לפתור בעיה בדרך מסוימת יש דברים מסוימים שיהיו קלים ואחרים שיהיו קשים. וזה נכון בהחלטות גדולות וקטנות, כשאני בוחר לשמור מידע מסוים בבסיס נתונים, ב Cookie, בפרמטר של ה URL. כשאני בוחר באיזה אירועים לטפל. אין בעיה להוסיף לדוח עמודה שמציגה ערך ששמור בבסיס הנתונים בצורה נכונה. אבל אם המידע לא שמור או לא שמור נכון אנחנו בבעיה.
בתוך ערימה של קוד יש תמיד מספר קטן של נקודות החלטה או נקודות כשל. נקודות שקובעות מה יהיה קל ומה יהיה קשה בהמשך. הן קשורות לקוד ושמורות בו, אבל הן לא הקוד. הקוד שכותב לקובץ כולל את ההחלטה לשמור מידע לקובץ. הקוד שמושך מידע מבסיס נתונים עם SQL Window Function כולל בתוכו את ההחלטה לקרוא ולכתוב את המידע בצורה מסוימת בבסיס הנתונים.
דוגמה קטנה מ Langlets להמחשה - יצרתי פעילות של סידור מילים במשפט, לדוגמה
ביקשתי מה AI לעדכן את הקוד שבונה קורס כדי שישתמש בפעילות הזאת רק במשפטים שלא עוברים את העשר מילים, אחרת זה ארוך מדי ולא כיף. אז הוא כתב קוד כזה:
def word_order_phrases(phrases)
phrase_list = phrases.is_a?(ActiveRecord::Relation) ? phrases.to_a : phrases
phrase_list.select do |phrase|
words = phrase.text_l1.to_s.split(/\s+/).reject(&:empty?)
words.any? && words.size <= MAX_WORD_ORDER_WORDS
end
end
כדי להחזיר את המשפטים האפשריים. הקוד כולל בעיות לא חשובות, למשל גם למערך ברובי יש פונקציית to_a ולכן אם החלטת שאתה ממש חייב מערך אתה יכול פשוט תמיד לקרוא ל to_a ואם זה מערך ממילא זה יחזיר את עצמו. אבל יש פה גם החלטות ממש חשובות וטפשיות שה AI לקח:
הבחירה לכתוב את הפונקציה הזאת בקובץ שבונה את הקורס במקום בקובץ של פעילות סידור המילים אומרת שיהיה קשה לזהות אותה ולהשתמש בה במקומות אחרים במערכת.
יותר חשוב הבחירה לממש חלוקה למילים בתוך הקוד בתור split לפי רווחים היא מאוד נאיבית, לא נכונה ולא מתאימה לאתגרים של המערכת. מה שמעניין אותנו זה המילים שצריך לסדר בפעילות ולא כמה מילים יש במשפט וכשיש צירוף מילים כמו The United States למרות שיש בו רווחים אנחנו מסתכלים עליו כמילה אחת.
מצד אחד לא צריך לדעת לכתוב לולאות ב Ruby ולא צריך לזכור אם זה filter או select או reject ואם צריך לבדוק שמערך גדול מאפס או שיש פונקציה בשם any? שמחזירה את זה ואפילו לא יקרה כלום אם נדלג על ה to_a או התנאי בשורה הראשונה. אבל פיצול שורה למילים לפי רווחים כבר ישבור את ההגיון הפנימי של המערכת וזו החלטה לא נכונה. גם אם זה יעבוד היום זה מהר מאוד יישבר.
(ושלא תתחילו עם "פשוט תכניס את כל החוכמה הזאת ל AGENTS.md. הגיון של החלטות משתנה ויש כל הזמן החלטות חדשות. ברור שצריך להשתמש ב AGENTS.md אבל הוא לא מחליף את קריאת הקוד).
קלוד קוד מנסה לחשוף את ההחלטות אבל זה לא הצד החזק שלו. קשה לדעת אם בעתיד זה יתאפשר. שפות תכנות עתידיות אולי יוכלו לתת מענה טוב יותר באמצעות הפרדה בין הקוד להחלטות מאחוריו. נחכה ונראה. בינתיים כדאי להתרגל לזהות נקודות כשל. נקודות של איזון בהן הבחירה קובעת את ההמשך ולהתרגל לראות את העתיד מתוך ההחלטות באותם צמתים.
המדרגה הבאה של תכנות היא לא כתיבת קוד. היא קבלת החלטות טכניות על המבנה הפנימי של המערכת. האילוץ הוא כבר לא כמה מהר אפשר לכתוב את הקוד אלא העולם האמיתי. האם הקוד שרצית לכתוב יכול לפתור את הבעיה שאתה צריך לפתור.