close menu

הנדסת פרומפטים – Prompt Engineering

הנדסת פרומפטים או בשמה האמיתי In-Context Prompting או פשוט “להתנסח”. מתארת דרכי תקשורת עם מודלי שפה לומדים על להכווין את התנהגותם לתוצאה רצויה מבלי לאמן אותם.

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

תופעה זו הולכת להכחד בקרוב. הפתרון הוא לא “לקמבן את המודל יותר חזק” – הפתרון הוא לאמן מודל טוב יותר. כל הנוגעים בדבר יודעים זאת היטב. שמועות שהגיעו אלי: GPT-5 כבר מתאמן. [לא מאומת, בערבון מוגבל]

———-

פעם התחום שלנו היה חכם..

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

  • טוויטר מפוצץ בשימושי “AI” שנשמעים מגניב אבל דבילים לחלוטין ולא עובדים.
  • חבילות קוד פתוח שלא עושות שום דבר מגייסות עשרות מיליוני דולרים.
  • חברות סטארט-אפ מוסיפות “GPT” לשם שלהן על מנת להקל בסבבי הגיוסים.
  • מאמרים אקדמים שאפשר לסכם במשפט אחד נמרחים על פני עשרות עמודי טקסט סתם.

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

———-

הבעיה עם הנדסת הפרומפטים

כרגע רוב שיטות הנדסת הפרומפטים מבוססת על “זה עבד לי פעם”.

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

בנצ’מארק מדויק שאפשר לכמת לציון מספרי.

דוגמה טובה:

  • מאמר “Let’s think step-by-step” הוא מאמר מפורסם שגילה שאם מבקשים ממודל שפה לפתור בעיות חשבון פשוטות: הוא לא ממש מצליח.

אבל!!

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

יחודיות המאמר היא לא בתגלית “לחשוב צעד-אחד-צעד” – היא שבמסגרת אותו המחקר, נמדדו מספר ניסוחים שונים מספרית (ציון. כמה פעמים ענה נכון?).

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

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

בסוף, את רוב הטריקים האלה אפשר להסביר במשפט אחד בודד.

———-

מקורות לימוד נורמלים:

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

להלן רשימת מקורות מידע אמינים, חינמיים ואיכותיים:

  • ל-OpenAI יש מדריך המכיל דוגמאות רבות ומעמיקות איך להשתמש במודלים ביעילות.

לינק: https://langchain.readthedocs.io/en/latest/

  • הספריה: LangChain – מאפשרת לשלב מודלי שפה עם רכיבים אחרים לצורך בנית תהליכים מורכבים.

לינק: https://langchain.readthedocs.io/en/latest/

  • האתר: Prompt Engineering Guide – אוסף מקיף של מדריכים איכותיים בנושאי תקשורת מול מודלים.

לינק: https://github.com/dair-ai/Prompt-Engineering-Guide

  • האתר: learnprompting.org

לינק: https://learnprompting.org/docs/intro

  • האתר: PromptPerfect

– לינק: https://promptperfect.jina.ai/

  • האתר: Semantic Kernel

לינק: https://github.com/microsoft/semantic-kernel

———-

רקע בסיסי

המודלים הראשונים

מודלי שפה מאומנים “לנחש” את המילה הבאה בטקסט.

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

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

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

גישה זו נקראת Few-Shot על שם כמות הדוגמאות המתוייגות הקטנה (Few) שאנו מראים למודל.

———-

יישור מודלי שפה לשפה אנושית

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

גישה זו נקראת Zero-Shot על שם “אפס” הדוגמאות הפתורות שאנו מראים למודל בזמן הפעלתו.

***

דגש חשוב: אימון מודלים לZero-Shot אינו פוגע ביכולות הFew-Shot של מודלי השפה (בדקתי את זה בעצמי כמה פעמים).

המודלים החדישים ביותר כמו GPT-4 גם הם מסוגלים לפעול בתצורת Few-Shot, ממשק המשתמש הוא המגבלה העיקרית.

אם מנסים מספיק חזק גם את ChatGPT אפשר לשכנע לעבוד בFew-Shot בניגוד לרצונות ממשק המשתמש [נבדק בגרסאות קודמות – כנראה שגם בגרסה הנוכחית].

לסיכום, תקשורת מול מודלי שפה מתחלקת לשני סוגים עיקריים:

  • להראות למודל כמה דוגמאות פתורות תחילה (Few Shot)
  • לבקש מהמודל ישירות (Zero Shot)

מה בדיוק משפיע על המודל?

מחקרים רבים מצאו שבחירת הדוגמאות, הניסוחים ואפילו סדר הדוגמאות יכול להוביל להבדלים אדירים בתוצאה הסופית – מ”רנדום מוחלט” לState-of-the-art במקרים מסויימים.

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

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

על מנת להתמודד עם בעיה זו הציעו במאמר תחילה לכייל את הסתברות מחלקות המודל כאשר הדוגמאות המתוייגות חסרות טקסט (“N\A”)

———

בחירת דוגמאות בצורה מסודרת:

  • במאמר מסוים [2] הציעו לבחור את הדוגמאות על פי קלאסטרינג במרחב הסמנטי.
  • לאחר מכן [3] הוצע לבנות גרף המבוסס על היצוגים הסמנטים כשהקשתות בין הדוגמאות השונות מכילות דמיון קוסינוס בין הדגימות, כשהרעיון הוא לבחור קבוצה הממזערת את הדמיון לשכנותיה כמה שרק אפשר וכך לבחור טקסטים מגוונים.
  • מאמרים נוספים [4] אפילו הציעו להשתמש בRL לבחירת הדוגמאות.
  • מאמר מעניין נוסף [5] הציע להשתמש במודל עצמו ולנסות לבחור דוגמאות הממקסמות את אנטרופית ההסתברויות של המודל – כלומר ש”הכי הפתיעו” את המודל.

——–

בחירת סדר הדוגמאות

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

——–

פרומפטים לביצוע הוראות

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

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

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

לדוגמה:

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

טקסט: “למה גם בשנת 2023 עדיין יוצאים סרטי “הצעקה” חדשים?!”

סנטימנט:

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

——–

מבנה הפרומפט באופן כללי

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

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

להלן כל האפשרויות:

———-

משימה: [המשימה]

[קלט]

———-

[קלט]

משימה: [המשימה]

———-

משימה: [המשימה]

[קלט]

תשובה:

———-

קלט ארוך במיוחד

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

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

משימה [המשימה]

[קלט ארוך]

משימה [המשימה]

טיפ זה יהפוך רלוונטי לכולם בחודשים הקרובים כשאורך GPT-4 המלא יפתח לשימוש חופשי.

———-

מבנה פרומפט המכיל דוגמאות

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

למשל:

משימה: [משימה]

[קלט]

[פלט]

[קלט]

[פלט]

[קלט]

[פלט]

[קלט]

תוספות נלוות לפרומפט

  • קהל יעד

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

הסבר כיצד נגזרת פונקציית סופטמקס לילד בן 6.

  • אוצר מילים

ניתן (ואף רצוי) לבקש מהמודל להשתמש או לא להשתמש במילים מסויימות בחלק מהמקרים.

“השתמש בשפה בטוחה בלבד.”

  • אורך התשובה

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

  • “ענה במשפט אחד”
  • “כתוב פסקה ארוכה”
  • “כתוב כתבה ארוכה בפורמט Markdown המכילה מספר פסקאות, ראשי פרקים ותתי פרקים.”
  • פורמט (Format)

כולנו יודעים שהמודלים יודעים לכתוב עבורינו “מייל” או “ציוץ לטוויטר”.

אך ניתן להשתמש באותו הרעיון גם על מנת לקבל את התשובות בjson למשל [לצורך טעינה פשוטה בקוד] או בMarkdown [לצורך פרסום פשוט באינטרנט]

  • חידוד טקסט

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

למשל “מה הם המשפטים הקשים ביותר להבנה בתשובה?”

ואז “נסח מחדש את התשובה כשאותם המשפטים מוסברים בפשטות”

  • סגנון כתיבה על פי דוגמה

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

סרקסטיות, שבירת הקיר הרביעי, “בדיחה פרטית”..

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

  • מטרה נוספת “מאחורי הקלעים”

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

“..שממחיש מבלי לציין במפורש שאני לא מרוצה מהמצב.”

  • במה לפרסום

פשוט וקל: “כתוב פוסט ללינקדאין”, “כתוב Bio לטינדר”

  • סגנון דיבור

“כתוב כמו אח.”, “הטקסט צריך להיות חברותי”, “סמכותי ובבטחון עצמי.”

———-

פרומפטים “כבדים”: משימות קריטיות במיוחד

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

מצאתי שצירוף פסקה קצרה המתארת למודל:

  • את הרקע הנוסף למשימה.

“אני מדען נתונים..”

  • הסיבות שמשימה זו חשובה עבורי באופן מיוחד ולאילו דגשים עליו לשים לב.

“בהודעה זו חשוב לי להעביר (מבלי לציין זאת במפורש) שאני לא מתכוון לוותר”

  • קביעת “מקצועו” של המודל כ”מקצוע” האנושי המתאים ביותר לביצוע המשימה.

“אתה עוזר המחקר האישי שלי. אתה מומחה ביעוץ..”

לדוגמה: פרומפט אמיתי (מתורגם):

“””

אני מדען נתונים. אני חוקר אימון מודלים גדולים.

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

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

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

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

– אתה חייב! לכתוב קוד כמה שיותר קצר ומינימליסטי המבצע אך ורק את המשימה הנדרשת בלבד.

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

– אתה חייב! להמנע מתיעוד הקוד והסברים מיותרים על אופן פעולת החלקים השונים בקוד. במידה ויהיו לי שאלות לגבי הקוד, אשאל אותך בהמשך.

להלן דוגמה:

“””

———-

גישה אחרת: “ללמד” את המודל

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

לדוגמה פרומפט אמיתי (מתורגם):

“””

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

דגשים חשובים:

  1. את הקוד יש לכתוב אך ורק בתוך פונקציות קצרות. כשאורך כל אחת מהן אינו עולה על מספר שורות בודד.
  2. הקוד צריך להכתב מבפנים החוצה: כתוב תחילה פונקציות קטנות ופשוטות הקלות למימוש אך נדרשות על מנת לממש את הניסוי כולו.
  3. מטרת הקוד היא בחינת הרעיון בתנאי מעבדה ולכן אין צורך לטפל באף מקרה קצה לא צפוי.
  4. על הקוד להיות קצר וממוקד ככל שרק אפשר ולהכיל רעיון אחד ויחיד אותו אנו מעוניינים לבחון בלבד.
  5. עליך להסתמך כמה שפחות על חבילות קוד חיצוניות ובמיוחד לא על חבילות קטנות ולא סטנדרטיות.
  6. בשום פנים ואופן אין לכתוב קוד מיותר או להגדיר משתנים שניתן להסתדר בלעדיהם. על הקוד להיות קצר ככל שאפשר.

אני אתאר לך את הרעיון ואתה תממש אותו.

האם אתה מבין?

“””

———-

יציבות פרומפטים

במאמר מעניין [6] הוצע הרעיון המעניין הבא: דגימה של כמה תשובות אפשריות ובחירת התשובה הנפוצה ביותר.

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

———-

שימוש בChain-Of-Thought

כמוזכר למעלה, התגלה שLet’s-think-step-by-step גורם למודלי שפה כתוב את כל הידוע להם על פתרון משימה מסויימת.

בנוסף התגלה let’s think from first principles גורם למודל לרשום את כל ציר הזמן של ההיסטוריה האנושית מהאדם הקדמון ועד הרגע הזה ממש שאנו יושבים מול הפייסבוק.

אבל באותו הרעיון אפשר להשתמש על מנת לאפשר למודל לבצע למשל “חישובי עזר”.

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

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

ואני רק רוצה להזכיר שוב, שיא הLet’s-think-step-by-step נשבר ממש לא מזמן [8]. הפרופט החזק ביותר כרגע הוא: “Let’s work this out it a step by step to be sure we have the right answer”

———-

שיפורים לChain-Of-Thought

  • דגימה עם יציבות עצמית יכולה לשפר את דיוק המודל על ידי שימוש בהצבעה. [10]
  • ולכן גם דגימה מספר פעמים כשסדר הדוגמאות שונה או עם כמה הסברי COT שונים יכול לעזור לייצוב הפתרון. [10]
  • התגלה לא מזמן שפרומפטי Chain-Of-Thought ארוכים יותר נוטים להוביל לתשובות מדוייקות יותר. [9]
  • ואפשר גם לשלב את זה עם Top-K של הPerplexity על הטוקנים. [11]
  • אבל גם מסתבר שלתת למודל רק דוגמאות חכמות ומתוחכמות הופכות אותו גם לדביל בבעיות קלות מידי. [12]
  • שינוי Q לQuestion מועיל. [13]
  • גם לבקש מהמודל לשאול שאלות המשך בלולאה מוביל את המודל להסביר לעצמו איך לפתור את הבעיה. [14]

———-

רפרנסים:

[1] – מאמר: אימון לביצוע הוראות: https://openai.com/research/instruction-following

[2] – מאמר: בחירת דוגמאות עם קלאסטרינג” https://arxiv.org/abs/2101.06804

[3] – מאמר: בחירת דוגמאות עם גרף https://arxiv.org/abs/2209.01975

[4] – מאמר: בחירת דוגמאות עם RL כאן: https://arxiv.org/abs/2211.04486

[5] – מאמר: בחירת דוגמאות שמפתיעות את המודל: https://arxiv.org/abs/2302.12246

[6] – מאמר: יציבות פרומפטים: https://arxiv.org/abs/2203.11171

[7] – מאמר: מאמר חישובי עזר: https://arxiv.org/abs/2201.11903

[8] – מאמר: הפרופמט המוצלח ביותר שיש לנו כרגע. https://arxiv.org/abs/2211.01910

[9] – מאמר: אורך הפרומפט כפרוקסי לדיוק הפרומפט. https://arxiv.org/abs/2210.00720

[10] – מאמר: יציבות עצמית: https://arxiv.org/abs/2207.00747

[11] – מאמר: שימוש בהסתברויות המודל לבחירת COT לנימוקים: https://arxiv.org/abs/2210.00720

[12] – מאמר: חשוב לגוון גם בקושי הבעיה https://arxiv.org/abs/2302.12822

[13] – מאמר: שינוי Q לQuestion מועיל: https://arxiv.org/abs/2210.00720

[14] – מאמר: לשאול שאלות המשך: https://arxiv.org/abs/2210.03350

 

עוד בנושא: