Chain of thought prompting מבקש ממודל שפה לכתוב את שלבי הביניים של בעיה לפני שהוא נותן את התשובה הסופית. בבעיות שדורשות כמה שלבים, כמו בעיות מילוליות, חידות היגיון ולוחות זמנים, עבודה גלויה נוטה להפיק יותר תשובות נכונות מאשר מענה מיידי, והיא משאירה לכם שלבים שאפשר לבדוק. הגרסה הקצרה ביותר היא משפט אחד שמוסיפים לפרומפט: "בוא נחשוב שלב אחרי שלב."
למה כתיבת השלבים עוזרת
מודל מפיק את התשובה שלו טוקן אחד בכל פעם, וכל מה שהוא כבר כתב הופך לקלט עבור הטוקן הבא. אם פרומפט דורש את התשובה מיד, המודל צריך להפיק אותה לפני שקיימת בדף תוצאת ביניים כלשהי. אם הוא כותב קודם "מכירות הקפה ביום שני הסתכמו ב-$168", המספר הזה נמצא עכשיו בהקשר, והשלב הבא יכול להישען עליו במקום להחזיק אותו במובלע.
זו האינטואיציה. הראיות הגיעו משני מאמרים מ-2022. Wei et al., "Chain-of-Thought Prompting Elicits Reasoning in Large Language Models", הראו שדוגמאות פתורות עם הנימוק כתוב בהן שיפרו מודלים גדולים במשימות חשבון, היגיון יומיומי וחשיבה סימבולית. הם גם מצאו שהתועלת תלויה בגודל: מודלים קטנים יותר לא הרוויחו, ולעיתים קרובות כתבו נימוק רהוט שהוביל לתשובות שגויות. Kojima et al., "Large Language Models are Zero-Shot Reasoners", הראו אחר כך שמשפט אחד בלי דוגמאות, "Let's think step by step", שיפר גם הוא את התוצאות באופן משמעותי, אם כי בדרך כלל פחות מדוגמאות פתורות.
תשובה ישירה מול chain of thought
שתי הלשוניות שואלות את אותה שאלה. הראשונה דורשת רק את הסכום; השנייה מבקשת את הפתרון ושמה את התשובה בשורה אחרונה קבועה.
$258
התשובה הישירה מראה טעות טיפוסית: 168 של קפה מיום שני ועוד $90 של מאפינס מיום שלישי, כלומר היא שכחה שביום שלישי נמכרו 10 כוסות קפה פחות. התשובה שלב אחרי שלב נותנת למספר כוסות הקפה של יום שלישי שורה משלו, כך שאי אפשר לדלג על השלב הזה בשקט. מודל עדכני אולי יפתור נכון גם את הגרסה הישירה; הפער גדל ככל שהבעיות מתארכות והשלבים תלויים זה בזה יותר.
לשלבים הכתובים יש יתרון נוסף: כשתשובה שגויה, אפשר לראות איזה שלב נשבר, ולתקן את הפרומפט או את הקלט בנקודה הזו.
Few-shot chain of thought
הטכניקה המקורית של Wei et al. שמה בפרומפט דוגמאות פתורות שהתשובות שלהן מראות את הנימוק, והמודל עונה על השאלה החדשה באותה דרך. הדוגמה שלמטה מבוססת על האיור הראשון במאמר שלהם; השאלה שאחריה חדשה. שנו את השאלה כדי לנסות משלכם.
בספרייה היו בהתחלה 120 ספרים. אחרי השאלת 45 נשארו 75 על המדפים. קבלת 18 בחזרה הביאה ל-93. התרומה של 30 הביאה ל-123. התשובה היא 123.
Few-shot CoT נותן לכם שליטה על צורת הנימוק: כמה הוא ארוך, מה הוא מפרט ואיך התשובה מנוסחת. "התשובה היא 11" בדוגמה הוא סיום קבוע, והתשובה העתיקה אותו. את zero-shot CoT מהיר יותר לכתוב, אבל הוא משאיר את הבחירות האלה למודל. למידע נוסף על בניית סטים של דוגמאות, ראו few-shot prompting; לגרסה שכוללת רק הוראה, ראו zero-shot prompting.
לשים את התשובה בשורה משלה
ברגע שהתשובה מכילה נימוק, התוצאה נמצאת איפשהו בתוך פסקה, וזו בעיה כשתוכנה צריכה לקרוא אותה. בקשו את התשובה בצורה קבועה בשורה האחרונה, כמו שהפרומפט של בית הקפה עושה עם "Answer: $X" (תווית קבועה שכדאי להשאיר כמו שהיא, כי אותה הקוד מחפש), וקראו את השורה הזו בקוד:
import re
matches = re.findall(r"^Answer:\s*(.+)$", reply, re.MULTILINE)
answer = matches[-1] if matches else None
לקחת את ההתאמה האחרונה חשוב, כי הנימוק עצמו עשוי להכיל שורה שמתחילה ב-"Answer:" לפני שהמודל מתקן את עצמו. אם המשתמשים צריכים לראות רק את התשובה, בקשו את הנימוק בתוך זוג תגיות אחד ואת התשובה בתוך זוג אחר, והציגו רק את השני. בדף פלט מובנה מוסבר איך לבקש JSON כשצריך יותר משדה אחד.
מודלי חשיבה
חלק מהמודלים העדכניים בנויים לחשוב לפני שהם עונים: הם מייצרים נימוק פנימי, לעיתים קרובות מוסתר או מסוכם, לפני התשובה הגלויה. אצלם "בוא נחשוב שלב אחרי שלב" חשוב הרבה פחות, כי השלבים קורים בין אם תבקשו ובין אם לא. הוספת הביטוי בדרך כלל רק מאריכה את התשובה הגלויה.
מה שעדיין עוזר עם מודל חשיבה הוא כל מה שסביב הנימוק: הצגה מלאה של הבעיה, האילוצים שתשובה נכונה חייבת לעמוד בהם, והפורמט של התשובה הסופית. תארו איך תשובה טובה נראית במקום לתסרט כל שלב; מתכון קבוע של שלבים עלול להרחיק את המודל מדרך טובה יותר שהיה מוצא בעצמו.
מתי לא להשתמש ב-chain of thought
Chain of thought עולה בטוקנים ובזמן, והוא משתלם רק כשלמשימה יש שלבים שתלויים זה בזה. בחיפוש מידע, תרגום, שכתוב או סיווג פשוט, הוא רק מאריך את התשובה. מודל יכול גם לכתוב נימוק שנראה הגיוני ועדיין להגיע לתשובה שגויה, אז בדקו את התוצאה הסופית בפני עצמה, ולא רק את השלבים שהובילו אליה.
לבעיות קשות שבהן שרשרת אחת עלולה להשתבש, יש שתי הרחבות שנבנות עליה. Self-consistency prompting דוגם כמה שרשראות ולוקח את התשובה שרובן מגיעות אליה, ו-tree of thought prompting בוחן ומשווה כמה קווי נימוק חלקיים לפני שהוא מתחייב לאחד מהם.
שאלות נפוצות
מה זה chain of thought prompting?
Chain of thought (CoT) prompting מבקש ממודל שפה לכתוב את שלבי הביניים של בעיה לפני התשובה הסופית, או על ידי דוגמאות פתורות שכוללות את הנימוק שלהן, או על ידי הוספת הוראה כמו "בוא נחשוב שלב אחרי שלב". בבעיות מרובות שלבים זה נוטה להפיק יותר תשובות נכונות, וזה מאפשר לבדוק כל שלב.
האם "בוא נחשוב שלב אחרי שלב" עדיין עובד?
עם מודלי צ'אט רגילים זה עדיין עוזר בבעיות שדורשות כמה שלבים, במיוחד כשהפרומפט היה דוחף אחרת לתשובה מיידית. מודלי חשיבה, שחושבים לפני שהם עונים, כבר עושים את זה בפנים, כך שהביטוי מוסיף להם מעט מלבד תשובה ארוכה יותר. במודלים האלה עדיף להציג את הבעיה ואת פורמט התשובה בבירור.
מתי chain of thought עוזר, ומתי לא?
הוא עוזר במשימות שדורשות כמה שלבים תלויים זה בזה: בעיות מילוליות, חשבון, חידות היגיון, תזמון עם אילוצים ומעקב אחרי מה שקוד עושה. הוא מוסיף מעט לחיפוש מידע, תרגום, שכתוב או סיווג פשוט, שבהם הוא רק מאריך ומאט את התשובה.
מה ההבדל בין zero-shot ל-few-shot chain of thought?
Few-shot CoT, שהוצג על ידי Wei et al. ב-2022, שם בפרומפט דוגמאות פתורות עם הנימוק שלהן, והמודל מחקה את סגנון החשיבה הזה. Zero-shot CoT, מ-Kojima et al. 2022, לא משתמש בדוגמאות ופשוט מוסיף הוראה כמו "בוא נחשוב שלב אחרי שלב". את zero-shot מהיר יותר לכתוב; few-shot נותן יותר שליטה על איך השלבים נראים.
האם הנימוק הכתוב הוא הדרך שבה המודל באמת הגיע לתשובה?
לא בהכרח. השלבים הם טקסט שהמודל מייצר, והם יכולים להיראות הגיוניים בזמן שהתשובה הסופית יצאה שגויה, או להכיל טעות בזמן שהתשובה במקרה נכונה. התייחסו לנימוק כמשהו שצריך לבדוק, לא כהוכחה, ובדקו את התשובה הסופית בפני עצמה.