ניתוח פרומפט - הוספת וולידציה למסך
אם בשנים הקרובות אנחנו הולכים לעשות Prompt Driven Development כדאי שנלמד לשים לב לפרומפטים שאנחנו כותבים. אני רוצה לשתף פה דוגמה לפרומפט אמיתי שכתבתי היום ומה הוא עשה אחרת ממה שהתכוונתי.
זה היה הפרומפט:
plan the validation
extract the logic from <file:lines> and the validation in a
common concern so we can use it from the 3 relevant controllers (automation rules, advanced webhook and
macro)
verify frontend shows the correct proper error
1. מה כבר ביקשתי
המטרה של הפרומפט היתה לבנות מנגנון וולידציה לפרמטר שהמערכת מקבלת. הפרמטר מופיע ב-3 מסכים ויש להשתמש באותה וולידציה קצת מורכבת בשלושתם. גרסה בסיסית של הוולידציה היתה קיימת במקום אחד אותו הדבקתי לפרומפט.
בשביל להבין טוב יותר פרומפט שנכשל אני אוהב להשתמש ב AI חכם כמו ג'מיני ומדביק פרומפט בסגנון הזה:
Run a prompt review on the following prompt:
plan the validation
extract <file:lines> and the validation in a
common concern so we can use it from the 3 relevant controllers (automation rules, advanced webhook and
macro)
verify frontend shows the correct proper error
Explain:
1. Its goal
2. Its strenghts
3. Its weaknesses
4. What would a typical AI agent implement in a rails system
5. Rate the prompt
לפי ג'מיני המטרה של הפרומפט היא ביצוע משימת ריפקטור בצד השרת ביישום Ruby On Rails:
יש לזהות לוגיקת וולידציה בסיסית שנמצאת בקונטרולר אחד.
להזיז אותה לרכיב משותף.
להשתמש בלוגיקה המשותפת ב-3 קונטרולרים ביישום.
לוודא שהריפקטורינג לא שובר את ההתנהגות ובפרט הצגת הודעות שגיאה.
ג'מיני מציין שהפרומפט טוב, ספציפי, מסביר איך לבצע את המשימה, מגדיר בדיוק את ה scope ומכוון מטרה. בצד השלילי ג'מיני היה מעדיף אם הייתי מציין את השם של אותו רכיב משותף שאני רוצה שיבנה ושהמשפט מנוסח בצורה מבולבלת (מה שנכון).
2. איפה הבעיה בפרומפט
מה שלא הופיע בפרומפט הוא מה טיב הוולידציה שאנחנו בונים, או למה בעצם היא מסובכת. ריילס כפריימוורק מעודדת לשים את הקוד המסובך במודלים ולהשתמש בקונטרולרים רק כדי להוציא מידע מפרמטרים שנשלחו מהדפדפן או לארגן את המידע חזרה לדפדפן. קוד יצירת פריט טיפוסי בקונטרולר בריילס נראה כך:
def create
@post = Post.new(post_params)
if @post.save
redirect_to @post
else
render :new
end
end
private
def post_params
params.require(:post).permit(:title, :body)
end```
הוולידציה של post נמצאת בתוך המודל. זיהוי פרמטרים לא נכונים מבוצע באותה קריאה ל `@post.save` שמופיעה בתחילת הפונקציה. הצגת הודעת השגיאה למשתמש מופיעה בתוך התבנית של `:new` שתקרא את הודעות השגיאה מתוך המודל `@post` שמועבר אליה בגלל שהוא מוגדר כמשתנה מחלקה של הקונטרולר. ככה זה עובד בריילס.
כשאני כותב פרומפט שאומר שאני רוצה לקחת וולידציה מסובכת מקונטרולר ולהשתמש בה שוב במספר קונטרולרים אני מדלג על השאלה הכי חשובה - למה הוולידציה בקונטרולר? והאם זה המקום הנכון עבורה?
3. מה נשבר
קלוד לא התבלבל וכמו ג'מיני גם הוא הבין מהפרומפט שלי שצריך לקחת קוד מקונטרולר, לשים אותו במקום משותף ולהשתמש בו מ-3 קונטרולרים. הבעיה היא שהקונטרולרים כבר כללו לוגיקה בסיסית של שמירת מודל ומבנה די פשוט של קונטרולרים בריילס.
זה מייצר לקלוד שתי בעיות:
מאחר והוולידציה בקונטרולר צריך למצוא דרך אחרת להעביר את הודעות השגיאה לדפדפן (כי המנגנון המובנה של ריילס מתבסס על זה שהוולידציה היא במודל).
מאחר והוולידציה בקונטרולר צריך למצוא איפה לכתוב אותה בצורה מפורשת ולעדכן הרבה קוד קיים.
עכשיו לקלוד אין בעיה לכתוב יותר מדי קוד וזה באמת מה שהוא עשה, כלומר הוא שינה את הפונקציות של הקונטרולרים, הוסיף את הוולידציה והגדיר משתנה חדש שיחזיק את השגיאות מאותה וולידציה מיוחדת, ואז בתבנית :new הוא חיפש את המשתנה הזה כדי להציג למשתמש. הקוד עבד אבל הכיל PR הרבה יותר ארוך ממה שצריך ויצר מנגנונים שאי אפשר יהיה להשתמש בהם שוב במקומות אחרים במערכת. כל זה רק כי קלוד היה בטוח שאני רציתי לשים את הוולידציה בקונטרולר.
4. איך אפשר לשפר לפעם הבאה
ג'מיני טוען שהבעיה היא במשפט:
"...so we can use it from the 3 relevant controllers"
משפט כזה דוחף את סוכן הקידוד לכיוון מימוש רכיב משותף ושלושה קונטרולרים שירשו אותו. ג'מיני מציע את הגרסה המשופרת הבאה:
Refactor the validation logic at <file:line>.
Extract this logic into a Model Concern (e.g., WebhookValidatable) included in the relevant models.
Requirements:
1. Transform the controller-specific logic (params/rendering) into standard Model validation errors.
2. Ensure the 3 relevant controllers (automation rules, advanced webhooks, macro) no longer need explicit validation checks—they should just rely on @model.save.
3. Verify the frontend still receives the same error messages via the model's errors object.
הלקח הוא שאם בשביל לבנות את הפיצ'ר נדרש שינוי ארכיטקטורה יש לציין את אותו שינוי במפורש בפרומפט אחרת אתם עלולים לקבל שינוי אחר שיותר קל למודל אבל לא מה שהתכוונתם.