مهندسی پرامپت

نوشته حسین بهنودی در ۲۴ فروردین ۱۴۰۳

مهندسی پرامپت (Prompt Engineering) یک دانش نسبتاً جدید است. هدفش ساختن و بهتر کردن «پرامپت‌ها» است. این کار کمک می‌کند تا از مدل‌های زبانی (LM) در انواع کارها و پژوهش‌ها به بهترین شکل استفاده کنیم. داشتن مهارت در مهندسی پرامپت باعث می‌شود توانایی‌ها و محدودیت‌های مدل‌های زبانی بزرگ (LLMs) را بهتر بشناسیم.

پژوهشگران با استفاده از مهندسی پرامپت، توانایی LLMs را در انجام کارهای گوناگون، از ساده تا پیچیده، مثل پاسخ به پرسش‌ها یا استدلال‌های ریاضی، افزایش می‌دهند. برنامه‌نویس‌ها هم از این دانش برای طراحی روش‌های پرامپت‌دهی (Prompting Techniques) قوی و مؤثری استفاده می‌کنند که با LLMs و ابزارهای دیگر به‌خوبی کار کنند.

مهندسی پرامپت فقط طراحی و ساخت پرامپت نیست؛ بلکه شامل مهارت‌ها و روش‌های مفید زیادی برای کار کردن و ساختن چیزهای جدید با LLMs می‌شود. این یک مهارت کلیدی است تا بتوانیم با این مدل‌ها کار کنیم، به کمکشان ابزار بسازیم و توانایی‌هایشان را بهتر درک کنیم. با مهندسی پرامپت می‌توانیم امنیت LLMs را بیشتر کنیم و حتی قابلیت‌های جدیدی به آن‌ها اضافه کنیم؛ مثلاً آن‌ها را با دانش تخصصی در یک زمینه خاص (domain knowledge) یا با ابزارهای دیگر تقویت کنیم.


تنظیمات LLM

هنگامیکه می‌خواهید پرامپت‌هایتان را طراحی و آزمایش کنید، معمولاً از طریق یک API (رابط برنامه‌نویسی کاربردی، که مثل یک پل ارتباطی بین شما و مدل عمل می‌کند) با LLMs صحبت می‌کنید. شما می‌توانید چند «پارامتر» یا تنظیمات را دستکاری کنید تا برای پرامپت‌های خود، جواب‌های متفاوتی بگیرید. تغییر دادن دقیق این تنظیمات خیلی مهم است تا جواب‌هایی که مدل می‌دهد هم قابل اعتمادتر باشند و هم به چیزی که شما می‌خواهید نزدیک‌تر شوند. برای اینکه بفهمید بهترین تنظیمات برای کار شما کدام‌ها هستند، باید کمی آزمون و خطا کنید. در ادامه، با تنظیمات رایجی آشنا می‌شوید که موقع کار با LLMs شرکت‌های مختلف، احتمالاً با آن‌ها برخورد خواهید کرد:

دما (Temperature): خیلی ساده بگوییم، هر چه «دما» پایین‌تر باشد، پاسخ‌های مدل قابل‌پیش‌بینی‌تر می‌شوند. یعنی مدل همیشه محتمل‌ترین «توکن» (token یا کوچکترین واحد کلمه یا عبارت که مدل پردازش می‌کند) بعدی را انتخاب می‌کند. بالا بردن دما باعث می‌شود جواب‌ها کمی شانسی‌تر و در نتیجه متنوع‌تر یا خلاقانه‌تر شوند. انگار که شما به کلمه‌ها یا عبارت‌های دیگر هم شانس بیشتری برای انتخاب شدن می‌دهید. مثلاً، اگر می‌خواهید مدل به سؤال‌هایی که پاسخ مشخصی دارند (مثل سؤالات اطلاعات عمومی یا علمی) پاسخ دهد، بهتر است دما را پایین بیاورید تا جواب‌ها دقیق‌تر و کوتاه‌تر باشند. اما برای کارهای خلاقانه مثل شعر گفتن یا داستان‌نویسی، بالا بردن دما می‌تواند بهتر باشد.

Top P: این هم یک روش دیگر برای انتخاب کلمه‌هاست که همراه با «دما» استفاده می‌شود و به آن «نمونه‌برداری هسته‌ای» (nucleus sampling) هم می‌گویند. با Top P می‌توانید کنترل کنید که جواب‌های مدل چقدر قابل پیش‌بینی باشند. اگر جواب‌های دقیق و واقعی می‌خواهید، این عدد را پایین نگه دارید. اگر دنبال جواب‌های متنوع‌ترید، آن را بالا ببرید. وقتی از Top P استفاده می‌کنید، مدل فقط از بین آن دسته از «توکن»‌ها انتخاب می‌کند که مجموع احتمالِ انتخاب شدنشان در یک محدوده مشخص (که شما با Top P تعیین می‌کنید) قرار دارد. پس، اگر Top P پایین باشد، مدل کلمه‌هایی را انتخاب می‌کند که از انتخابشان خیلی مطمئن است. اگر Top P بالا باشد، مدل کلمات بیشتری را در نظر می‌گیرد، حتی آن‌هایی که احتمال انتخابشان کمتر است، و در نتیجه جواب‌های متنوع‌تری به شما می‌دهد.

معمولاً توصیه می‌شود که یا «دما» را تغییر دهید یا «Top P» را، اما نه هر دو را با هم.

حداکثر طول (Max Length): با تنظیم «حداکثر طول»، می‌توانید تعداد «توکن»‌هایی (همان کلمه‌ها یا عبارت‌های کوچک) را که مدل تولید می‌کند، کنترل کنید. مشخص کردن حداکثر طول کمک می‌کند تا جواب‌های خیلی طولانی یا بی‌ربط نگیرید و همچنین مراقب باشید که استفاده از مدل خیلی هزینه‌بر نشود.

توالی‌های توقف (Stop Sequences): «توالی توقف» یک کلمه یا عبارت خاص (مثلاً یک نقطه یا یک علامت سوال) است که وقتی مدل به آن می‌رسد، دیگر «توکن» جدیدی تولید نمی‌کند و جوابش را تمام می‌کند. مشخص کردن این توالی‌ها یک راه دیگر برای کنترل کردن طول و شکل و شمایل جواب مدل است. به عنوان مثال، می‌توانید به مدل بگویید یک لیست درست کند و با قرار دادن عدد «۱۱» به عنوان توالی توقف، مطمئن شوید که لیست شما بیشتر از ۱۰ مورد نخواهد داشت (یعنی وقتی به مورد یازدهم می‌رسد، متوقف می‌شود).

جریمه تکرار (Frequency Penalty): «جریمه تکرار» کمک می‌کند تا مدل کلمات را کمتر تکرار کند. چطور؟ وقتی یک «توکن» قبلاً در جواب مدل یا حتی در پرامپت شما آمده باشد، این تنظیم یک جریمه برای آن در نظر می‌گیرد تا احتمال استفاده دوباره از آن کمتر شود. هرچقدر آن توکن بیشتر تکرار شده باشد، جریمه‌اش هم سنگین‌تر می‌شود. در نتیجه، هرچه جریمه تکرار بیشتر باشد، احتمال اینکه یک کلمه دوباره در جواب بیاید، کمتر است. این کار باعث می‌شود کلماتی که زیاد استفاده شده‌اند، در جواب مدل کمتر تکرار شوند.

جریمه حضور (Presence Penalty): «جریمه حضور» هم شبیه جریمه تکرار است و به «توکن»‌های تکراری جریمه می‌دهد. اما یک فرق مهم دارد: در «جریمه حضور»، مقدار جریمه برای همه توکن‌های تکراری یکسان است. یعنی فرقی نمی‌کند یک کلمه دو بار تکرار شده باشد یا ده بار، جریمه‌اش یکی است. این تنظیم کمک می‌کند تا مدل یک عبارت را پشت سر هم در جوابش تکرار نکند. اگر دوست دارید مدل متن‌های متنوع یا خلاقانه بنویسد، بهتر است جریمه حضور را بیشتر کنید. اما اگر می‌خواهید مدل روی یک موضوع خاص تمرکز کند و از آن خارج نشود، جریمه حضور را کمتر کنید.

مثل «دما» و «Top P»، اینجا هم معمولاً توصیه می‌شود که یا «جریمه تکرار» را تنظیم کنید یا «جریمه حضور» را، نه هر دو را با هم.

قبل از اینکه چند مثال ساده را با هم ببینیم، یادتان باشد که جوابی که از مدل می‌گیرید، ممکن است با توجه به نسخه‌ای از LLMs که استفاده می‌کنید، کمی فرق داشته باشد.


مبانی پرامپت نویسی

با پرامپت‌های ساده هم می‌شود کارهای بزرگی کرد. اما کیفیت نتیجه به دو چیز بستگی دارد: چقدر اطلاعات به مدل می‌دهید و اینکه پرامپت شما چقدر خوب طراحی شده باشد. پرامپت می‌تواند شامل دستور یا سؤالی باشد که به مدل می‌دهید. همچنین می‌تواند جزئیات بیشتری مثل «زمینه» (context)، «ورودی‌ها» (inputs) یا «مثال‌ها» (examples) را هم داشته باشد. با استفاده از این بخش‌ها، می‌توانید مدل را بهتر راهنمایی کنید تا نتایج باکیفیت‌تری بگیرید.

بیایید با یک مثال ساده شروع کنیم:

پرامپت:

آسمان

خروجی:

آبی است.

همان‌طور که در مثال بالا دیدید، مدل زبانی با کنار هم گذاشتن «توکن‌ها» (token، یعنی واحدهای کوچک متنی که مدل پردازش می‌کند) به پرامپت «آسمان» جواب می‌دهد و سعی می‌کند یک عبارت بامعنی بسازد. البته ممکن است خروجی آن چیزی نباشد که انتظار دارید یا با هدفی که در ذهن دارید، فاصله داشته باشد. این مثال ساده نشان می‌دهد که چقدر مهم است که به مدل، اطلاعات یا دستورالعمل‌های دقیق‌تری بدهیم تا دقیقاً همان کاری را که می‌خواهیم، انجام دهد. این دقیقاً همان کاری است که «مهندسی پرامپت» انجام می‌دهد.

بیایید سعی کنیم پرامپت قبلی را کمی بهتر کنیم:

پرامپت:

جمله را کامل کنید: آسمان

خروجی:

در طول روز آبی و در شب تاریک است.

بهتر شد، نه؟ در این پرامپت، شما از مدل خواستید جمله را کامل کند. نتیجه هم خیلی بهتر شد، چون مدل دقیقاً همان کاری را انجام داد که از او خواسته بودید (یعنی «جمله را کامل کن»). همین روش طراحی پرامپت‌های خوب برای اینکه مدل کار مورد نظر ما را انجام دهد، در این نوشته «مهندسی پرامپت» نامیده می‌شود.

این مثال‌ها فقط گوشه‌ای از توانایی‌های امروزی LLMها را نشان می‌دهند. این مدل‌ها می‌توانند کارهای پیشرفته‌تری مثل خلاصه‌سازی متن، استدلال ریاضی و حتی تولید کد کامپیوتری انجام دهند.

قالب‌بندی پرامپت

تا اینجا پرامپت‌های خیلی ساده‌ای را دیدیم. یک پرامپت استاندارد معمولاً به یکی از این دو شکل است:

<سؤال>؟

یا

<دستورالعمل>

می‌توانید این ساختار را به شکل «سؤال و جواب» (Question Answering یا QA) هم در بیاورید. این فرمت در خیلی از مجموعه داده‌های آموزشیِ پرسش و پاسخ رایج است:

س: <سؤال>؟
ج:

وقتی به این شکل پرامپت می‌دهید، به آن «پرامپت‌دهی بدون نمونه» (zero-shot prompting) می‌گویند. یعنی شما مستقیماً از مدل جواب می‌خواهید، بدون اینکه از قبل هیچ مثال یا الگویی از کاری که می‌خواهید انجام شود به او بدهید. بعضی از مدل‌های زبانی بزرگ می‌توانند این کار را انجام دهند، اما موفقیت آن به سختیِ کار و اطلاعاتی که برای آن لازم است، و همچنین به اینکه مدل چقدر برای انجام کارهای مشابه آموزش دیده، بستگی دارد.

مثلاً یک پرامپت می‌تواند این شکلی باشد:

پرامپت:

س: مهندسی پرامپت چیست؟

در بعضی از مدل‌های جدیدتر، حتی لازم نیست «س:» را اول سؤال بگذارید. مدل خودش از ساختار جمله می‌فهمد که این یک سؤال است. به عبارت دیگر، پرامپت می‌تواند این‌طور ساده شود:

پرامپت:

مهندسی پرامپت چیست؟

علاوه بر این، یک روش خیلی رایج و کارآمد دیگر، «پرامپت‌دهی با چند نمونه» (few-shot prompting) است. در این روش، شما چند «نمونه» یا مثال به مدل نشان می‌دهید. پرامپت‌های چند نمونه‌ای را می‌توانید به این شکل بنویسید:

<سؤال>؟
<جواب>
<سؤال>؟
<جواب>
<سؤال>؟
<جواب>
<سؤال>؟

اگر بخواهیم همین را در قالب پرسش و پاسخ بنویسیم، این شکلی می‌شود:

س: <سؤال>؟
ج: <جواب>
س: <سؤال>؟
ج: <جواب>
س: <سؤال>؟
ج: <جواب>
س: <سؤال>؟
ج:

یادتان باشد که لازم نیست حتماً از فرمت پرسش و پاسخ استفاده کنید. شکل پرامپت به کاری که می‌خواهید انجام دهید بستگی دارد. مثلاً برای یک کار ساده مثل «طبقه‌بندی» (classification) – یعنی دسته‌بندی کردن چیزها – می‌توانید چند مثال برای راهنمایی مدل بیاورید:

پرامپت:

این فوق‌العاده است! // مثبت
این بد است! // منفی
وای اون فیلم عالی بود! // مثبت
چه نمایش وحشتناکی! //

خروجی:

منفی

پرامپت‌های چند نمونه‌ای به مدل‌ها کمک می‌کنند تا از طریق «یادگیری در متن» (in-context learning) کارها را یاد بگیرند. یعنی مدل با دیدن همان چند مثالی که به او می‌دهید، یاد می‌گیرد که چطور کار مورد نظر را انجام دهد. در بخش‌های بعدی، بیشتر درباره پرامپت‌دهی بدون نمونه و با چند نمونه صحبت خواهیم کرد.


اجزای یک پرامپت

هرچه بیشتر با مثال‌ها و کاربردهای گوناگون در زمینه مهندسی پرامپت (Prompt Engineering) آشنا می‌شویم، متوجه می‌شویم که هر پرامپت از اجزای مشخصی تشکیل شده است.

یک پرامپت می‌تواند شامل اجزای زیر باشد:

  • دستور کار (Instruction): کار مشخصی که از مدل می‌خواهید انجام دهد.
  • زمینه (Context): اطلاعات یا داده‌های پیرامونی که به مدل کمک می‌کند تا پاسخ‌های بهتری تولید کند.
  • داده ورودی (Input Data): ورودی یا پرسشی که می‌خواهیم مدل به آن پاسخ دهد.
  • نشانگر خروجی (Output Indicator): نوع یا ساختار خروجی دلخواه.

برای اینکه با اجزای پرامپت بهتر آشنا شوید، به این نمونه‌ی ساده نگاه کنید. هدف این پرامپت، دسته‌بندی یک متن است:

پرامپت:

متن را به مثبت، منفی یا خنثی دسته‌بندی کن.
متن: فکر می‌کنم غذا معمولی بود.
احساسات:

در نمونه‌ی بالا، دستور همان وظیفه‌ی دسته‌بندی است: «متن را به مثبت، منفی یا خنثی دسته‌بندی کن.» داده ورودی همان جمله‌ی «فکر می‌کنم غذا معمولی بود.» است و نشانگر خروجی هم «احساسات:» است. دقت کنید که این نمونه‌ی ساده، عنصر زمینه را ندارد، اما می‌توان زمینه را هم به پرامپت اضافه کرد. مثلاً، برای همین پرامپتِ دسته‌بندی متن، می‌توانیم چند نمونه‌ی دیگر هم به عنوان زمینه به آن اضافه کنیم. این کار به مدل کمک می‌کند تا وظیفه را بهتر بفهمد و خروجی‌هایی شبیه به چیزی که ما می‌خواهیم، تولید کند.

لازم نیست یک پرامپت حتماً شامل همه‌ی این چهار جزء باشد. شکل و اجزای آن به کاری که می‌خواهید انجام دهید بستگی دارد. در درس‌های آینده، با نمونه‌های کاربردی‌تری آشنا خواهیم شد.


نکات کلی برای طراحی پرامپت‌ها

ساده شروع کنید

وقتی می‌خواهید پرامپت طراحی کنید، یادتان باشد که این کار یک فرایند تکراری است و برای رسیدن به بهترین نتیجه، باید حسابی آزمایش و خطا کنید. استفاده از یک محیط آزمایش ساده (که به آن playground هم می‌گویند)، می‌تواند شروع خیلی خوبی باشد.

می‌توانید با پرامپت‌های ساده کارتان را آغاز کنید و برای گرفتن نتایج بهتر، کم‌کم جزئیات و اطلاعات بیشتری به آن اضافه کنید. به همین دلیل، مرور و بهتر کردن پرامپت‌تان در این مسیر خیلی مهم است. در این نوشته، مثال‌های زیادی می‌بینید که نشان می‌دهد چطور دقیق بودن، ساده بودن و کوتاه و مفید بودن معمولاً نتایج بهتری به شما می‌دهد.

اگر یک کار بزرگ دارید که از چند بخش کوچک‌تر تشکیل شده، می‌توانید آن را به بخش‌های ساده‌تر تقسیم کنید و هر بار که در یک بخش نتیجه بهتری گرفتید، سراغ بخش بعدی بروید تا کار کامل شود. اینطوری، فرایند طراحی پرامپت از همان اول خیلی پیچیده نمی‌شود.

دستورالعمل

با دادن دستورهای مشخص به مدل، می‌توانید به او بگویید دقیقاً چه کاری انجام دهد و به این ترتیب پرامپت‌های کارآمدی برای کارهای ساده طراحی کنید؛ دستورهایی مثل «بنویس»، «طبقه‌بندی کن»، «خلاصه کن»، «ترجمه کن»، «مرتب کن» و غیره.

یادتان باشد برای اینکه بفهمید چه روشی بهترین نتیجه را می‌دهد، باید حسابی آزمایش کنید. دستورهای مختلف را با کلمات کلیدی، اطلاعات پس‌زمینه و داده‌های گوناگون امتحان کنید تا ببینید کدام‌یک برای کار و هدف خاص شما بهتر جواب می‌دهد. معمولاً، هرچقدر اطلاعات پس‌زمینه‌ای که برای انجام یک کار به مدل می‌دهید، دقیق‌تر و مرتبط‌تر باشد، نتیجه هم بهتر می‌شود. در بخش‌های بعدی، بیشتر در مورد اهمیت نمونه‌دهی (sampling – یعنی ارائه چند مثال به مدل) و ارائه اطلاعات زمینه بیشتر صحبت خواهیم کرد.

بعضی‌ها پیشنهاد می‌کنند که دستورها را در ابتدای پرامپت بنویسید. یک پیشنهاد دیگر هم این است که از یک جداکننده مشخص مثل «###» برای جدا کردن دستور از اطلاعات پس‌زمینه استفاده کنید.

برای مثال:

پرامپت:

### دستورالعمل ###
متن زیر را به اسپانیایی ترجمه کن:
متن: “hello!”

خروجی:

¡Hola!

دقت و صراحت

وقتی به مدل دستور می‌دهید یا از او کاری می‌خواهید، خیلی دقیق و واضح منظورتان را بگویید. هرچقدر پرامپت شما جزئیات بیشتری داشته باشد و توصیفی‌تر باشد، نتیجه بهتری می‌گیرید. این نکته مخصوصاً وقتی مهم است که دنبال یک خروجی یا سبک خاصی از جواب هستید. کلمات یا عبارت‌های جادویی خاصی (که به آن‌ها توکن هم می‌گویند) وجود ندارند که خودبه‌خود نتیجه را بهتر کنند. مهم‌تر این است که یک قالب خوب و یک پرامپت پر از جزئیات مفید داشته باشید. اتفاقاً، اگر توی پرامپت مثال بزنید، خیلی راحت‌تر می‌توانید به مدل بفهمانید که دقیقاً چه نوع جوابی و با چه قالبی می‌خواهید.

موقع طراحی پرامپت، حواستان به طول آن هم باشد، چون پرامپت‌ها نمی‌توانند بی‌نهایت طولانی باشند و محدودیت دارند. باید فکر کنید که چقدر نیاز است دقیق باشید و جزئیات بدهید. اینکه کلی جزئیات غیرضروری به پرامپت اضافه کنید، لزوماً فکر خوبی نیست. جزئیات باید به کارتان مربوط باشند و به مدل کمک کنند تا وظیفه‌اش را بهتر انجام دهد. این چیزی است که باید با آزمون و خطا یاد بگیرید. ما خیلی تشویقتان می‌کنیم که برای بهتر کردن پرامپت‌هایتان، حسابی آزمایش و تکرار کنید.

به عنوان مثال، بیایید یک پرامپت ساده را برای استخراج اطلاعات خاص از یک متن امتحان کنیم.

پرامپت:

نام مکان‌ها را از متن زیر استخراج کن.
فرمت دلخواه:
مکان: <لیست_مکان‌ها_با_کاما_جدا_شوند>

ورودی: اگرچه این پیشرفت‌ها برای محققان دلگرم‌کننده است، اما هنوز بخش زیادی از آن یک راز باقی مانده است. هنریک ویگافرناندز، عصب‌شناس ایمنی در مرکز ناشناخته‌های شامپالیمو در لیسبون، می‌گوید: «ما اغلب با یک جعبه سیاه بین مغز و اثری که در محیط پیرامونی می‌بینیم، مواجه هستیم. اگر بخواهیم از آن در زمینه درمانی استفاده کنیم، واقعاً باید سازوکار آن را بفهمیم.»

خروجی:

مکان: مرکز ناشناخته‌های شامپالیمو, لیسبون

از ابهام بپرهیزید

با توجه به نکاتی که در مورد ارائه جزئیات و بهتر کردن فرمت گفتیم، ممکن است وسوسه شوید که در نوشتن پرامپت‌ها خیلی خلاقیت به خرج دهید و در نتیجه، توضیحاتتان مبهم شود. معمولاً بهتر است که دقیق و سرراست باشید. این دقیقاً مثل حرف زدن خودمان است؛ هرچقدر مستقیم‌تر منظورتان را بگویید، پیام شما بهتر منتقل می‌شود.

مثلاً، فرض کنید می‌خواهید مفهوم مهندسی پرامپت را یاد بگیرید. شاید اولش چیزی شبیه این بنویسید:

مفهوم مهندسی پرامپت را توضیح بده. توضیح را کوتاه نگه دار، فقط چند جمله، و خیلی توصیفی نباش.

در این پرامپت، مشخص نیست که توضیح باید چند جمله باشد یا چه سبکی داشته باشد. شاید با همین پرامپت هم جواب‌های نسبتاً خوبی بگیرید، اما یک پرامپت خوب، خیلی دقیق، خلاصه و سرراست است. چیزی شبیه این:

مفهوم مهندسی پرامپت را در ۲-۳ جمله برای یک دانش‌آموز دبیرستانی توضیح بده.

چه باید کرد یا چه نباید کرد

یک نکته مهم دیگر در طراحی پرامپت این است که به جای اینکه بگویید چه کاری «نباید» انجام شود، بگویید چه کاری «باید» انجام شود. اینطوری مدل را تشویق می‌کنید دقیق‌تر باشد و روی جزئیاتی تمرکز کند که به جواب‌های خوب منجر می‌شوند.

اینجا مثالی از یک چت‌بات (chatbot) که فیلم پیشنهاد می‌دهد آورده شده که دقیقاً همان کاری را می‌کند که از او خواسته‌ام نکند، چون من در دستوری که به او داده‌ام، روی کارهایی تمرکز کرده‌ام که «نباید» انجام دهد.

پرامپت:

ربات زیر، فیلم به مشتری پیشنهاد می‌دهد. از او در مورد علاقه‌مندی‌هایش نپرس. اطلاعات شخصی نخواه.

مشتری: لطفاً بر اساس علاقه‌مندی‌هایم یک فیلم پیشنهاد بده.
عامل (Agent):

خروجی:

حتماً، می‌توانم بر اساس علاقه‌مندی‌هایتان یک فیلم پیشنهاد بدهم. چه نوع فیلمی دوست دارید تماشا کنید؟ اکشن، کمدی، عاشقانه یا چیز دیگری را ترجیح می‌دهید؟

حالا یک پرامپت بهتر را ببینید:

پرامپت:

ربات زیر فیلم به مشتری پیشنهاد می‌دهد. این ربات وظیفه دارد از بین فیلم‌های پرطرفدار روز دنیا فیلم پیشنهاد بدهد. نباید از کاربران در مورد سلیقه‌شان بپرسد یا اطلاعات شخصی درخواست کند. اگر ربات فیلمی برای پیشنهاد نداشت، باید جواب بدهد: «متأسفم، امروز فیلمی برای پیشنهاد پیدا نکردم.»

مشتری: لطفاً بر اساس علاقه‌مندی‌هایم یک فیلم پیشنهاد بده.
عامل (Agent):

خروجی:

متأسفم، من هیچ اطلاعاتی درباره علاقه‌مندی‌های شما ندارم. با این حال، در اینجا لیستی از پرطرفدارترین فیلم‌های روز دنیا در حال حاضر آمده است: [لیست فیلم‌ها]. امیدوارم چیزی پیدا کنید که دوست داشته باشید!


نمونه‌هایی از پرامپت‌ها

در بخش پیش، یک نمونه ساده از چگونگی استفاده از پرامپت‌ها برای LLMs را دیدیم.
این بخش، نمونه‌های بیشتری از کاربرد پرامپت‌ها برای انجام کارهای مختلف را به شما نشان می‌دهد و همزمان مفاهیم کلیدی را هم معرفی می‌کند. اغلب، بهترین راه برای یادگیری یک مفهوم، دیدن مثال‌های عملی است. مثال‌های زیر به شما نشان می‌دهند که چطور با نوشتن پرامپت‌های خوب و دقیق (well-crafted)، می‌توانید کارهای گوناگونی را به کمک LLMs انجام دهید.

خلاصه‌سازی متن

یکی از کارهای رایج برای «تولید زبان طبیعی» (یعنی وقتی کامپیوتر متن می‌سازد)، خلاصه‌کردن متن است. خلاصه‌کردن متن می‌تواند انواع و کاربردهای مختلفی در زمینه‌های گوناگون داشته باشد. در حقیقت، یکی از جالب‌ترین کارهایی که مدل‌های زبانی می‌توانند انجام دهند، همین است که مقاله‌ها و مطالب پیچیده را به خلاصه‌هایی کوتاه و روان تبدیل کنند. بیایید یک خلاصه‌سازی ساده را با کمک پرامپت‌ها امتحان کنیم.

فرض کنید دوست دارید درباره آنتی‌بیوتیک‌ها اطلاعات کسب کنید. می‌توانید پرامپتی شبیه این بنویسید:

پرامپت:

آنتی‌بیوتیک‌ها را توضیح بده.
A:

خروجی:

آنتی‌بیوتیک‌ها نوعی دارو هستند که برای درمان عفونت‌های باکتریایی استفاده می‌شوند. آن‌ها با کشتن باکتری‌ها یا جلوگیری از تکثیرشان عمل می‌کنند و به این ترتیب به سیستم ایمنی بدن فرصت می‌دهند تا با عفونت مبارزه کند. آنتی‌بیوتیک‌ها معمولاً به صورت خوراکی (قرص، کپسول یا شربت) مصرف می‌شوند، اما گاهی هم به صورت وریدی (تزریق در رگ) تجویز می‌شوند. این داروها روی عفونت‌های ویروسی اثری ندارند و استفاده نادرست از آن‌ها می‌تواند باعث ایجاد مقاومت آنتی‌بیوتیکی (یعنی بی‌اثر شدن آنتی‌بیوتیک‌ها) شود.

عبارت «A:» یک روش واضح برای نوشتن پرامپت است که معمولاً وقتی می‌خواهید به سؤالی جواب دهید، از آن استفاده می‌کنید. اینجا از «A:» استفاده کردیم تا به مدل بگوییم منتظر یک جواب باشد. البته در این مثال، شاید خیلی فرقی نکند که از «A:» استفاده کنیم یا نه، اما فعلاً این بحث را برای مثال‌های بعدی می‌گذاریم. حالا فرض کنید این توضیحات خیلی طولانی است و می‌خواهید آن را خلاصه‌تر کنید. در واقع، می‌توانید از مدل بخواهید کل متن را در یک جمله خلاصه کند، این‌طوری:

پرامپت:

آنتی‌بیوتیک‌ها نوعی دارو هستند که برای درمان عفونت‌های باکتریایی استفاده می‌شوند. آن‌ها با کشتن باکتری‌ها یا جلوگیری از تکثیرشان عمل می‌کنند و به این ترتیب به سیستم ایمنی بدن فرصت می‌دهند تا با عفونت مبارزه کند. آنتی‌بیوتیک‌ها معمولاً به صورت خوراکی (قرص، کپسول یا شربت) مصرف می‌شوند، اما گاهی هم به صورت وریدی (تزریق در رگ) تجویز می‌شوند. این داروها روی عفونت‌های ویروسی اثری ندارند و استفاده نادرست از آن‌ها می‌تواند باعث ایجاد مقاومت آنتی‌بیوتیکی (یعنی بی‌اثر شدن آنتی‌بیوتیک‌ها) شود.
متن بالا را در یک جمله توضیح بده:

خروجی:

آنتی‌بیوتیک‌ها داروهایی برای درمان عفونت‌های باکتریایی هستند که باکتری‌ها را می‌کشند یا جلوی رشدشان را می‌گیرند، اما روی ویروس‌ها بی‌اثرند و استفاده زیاد از آن‌ها باعث مقاومت دارویی می‌شود.

فعلاً خیلی به دقیق بودن جواب مدل کاری نداریم. مهم این است که مدل سعی کرد پاراگراف را در یک جمله خلاصه کند. شما می‌توانید با دادن دستورهای هوشمندانه‌تر، نتایج بهتری بگیرید، اما این را هم در فصل بعدی بررسی می‌کنیم. اگر دوست دارید، همین‌جا کمی مکث کنید و خودتان امتحان کنید ببینید می‌توانید جواب بهتری از مدل بگیرید یا نه.

استخراج اطلاعات

مدل‌های زبانی فقط برای «تولید زبان طبیعی» (ساختن متن) و کارهای شبیه به آن آموزش ندیده‌اند. آن‌ها در انجام کارهایی مثل طبقه‌بندی متن و خیلی از وظایف دیگر «پردازش زبان طبیعی» (NLP یا Natural Language Processing، یعنی فهم و تحلیل زبان انسان توسط کامپیوتر) هم خیلی قوی هستند.

این هم یک نمونه پرامپت که اطلاعات خاصی را از یک پاراگراف بیرون می‌کشد:

پرامپت:

در مقالات پژوهشی، بخش‌های «مشارکت نویسندگان» و «قدردانی» باید به روشنی و با جزئیات مشخص کنند که نویسندگان مقاله تا چه حد از فناوری‌های هوش مصنوعی مثل ChatGPT برای نوشتن مقاله و تحلیل‌هایشان استفاده کرده‌اند. همچنین باید بگویند از کدام LLMs کمک گرفته‌اند. این کار به ویراستارها و داورها کمک می‌کند تا مقالات را با دقت بیشتری از نظر احتمال وجود سوگیری، اطلاعات نادرست و ذکر ناقص منابع بررسی کنند. به همین شکل، مجلات علمی هم باید در مورد استفاده خودشان از LLMs شفاف باشند، مثلاً وقتی می‌خواهند از بین مقالات ارسال‌شده، تعدادی را برای چاپ انتخاب کنند.
محصول مبتنی بر LLMs که در پاراگراف بالا به آن اشاره شده، کدام است؟

خروجی:

محصول مبتنی بر LLMs که در پاراگراف بالا به آن اشاره شده، ChatGPT است.

البته راه‌های زیادی برای بهتر کردن این جواب‌ها وجود دارد، اما همین نتیجه هم خیلی کاربردی است.

تا اینجا حتماً متوجه شده‌اید که فقط با دستور دادن به مدل، می‌توانید از آن بخواهید کارهای گوناگونی برایتان انجام دهد. این یک توانایی فوق‌العاده است! برنامه‌نویس‌ها و سازندگان محصولات هوش مصنوعی همین الان هم از این قابلیت برای ساختن ابزارها و تجربه‌های کاربری شگفت‌انگیز استفاده می‌کنند.

پاسخ به پرسش

یکی از بهترین کارها برای اینکه مدل جواب‌های دقیق و مشخصی به ما بدهد، این است که «قالب پرامپت» را بهتر کنیم. همان‌طور که قبلاً گفتیم، یک پرامپت خوب می‌تواند شامل دستور، اطلاعات زمینه، داده ورودی و حتی فرمتی برای خروجی باشد تا به نتایج بهتری برسیم. این اجزا همیشه ضروری نیستند، اما استفاده از آن‌ها یک عادت خوب است. چرا؟ چون هرچه در پرامپت‌هایتان دقیق‌تر باشید، جواب‌های بهتری هم می‌گیرید. در ادامه، یک نمونه از پرامپتی را می‌بینید که ساختار منظم‌تری دارد:

پرامپت:

بر اساس اطلاعات زیر به سؤال پاسخ بده. جوابت باید کوتاه و خلاصه باشد. اگر جواب را نمی‌دانی، بنویس: «مطمئن نیستم».

اطلاعات زمینه: داستان داروی تپلیزومَـب (Teplizumab) به یک شرکت داروسازی در نیوجرسی به نام اُرتو فارماسیوتیکال (Ortho Pharmaceutical) برمی‌گردد. دانشمندان آن شرکت، نسخه اولیه‌ای از این پادتن (آنتی‌بادی) را ساختند و نامش را OKT3 گذاشتند. این مولکول که ابتدا از بدن موش‌ها به‌دست آمده بود، می‌توانست به سطح سلول‌های T (نوعی گلبول سفید) بچسبد و توانایی آن‌ها در کشتن سلول‌های دیگر را کم کند. در سال ۱۹۸۶، این دارو برای جلوگیری از پس زدن عضو پیوندی بعد از پیوند کلیه تأیید شد و به این ترتیب، اولین پادتن درمانی بود که اجازه استفاده انسانی گرفت.

سؤال: OKT3 در ابتدا از چه موجودی به‌دست آمده بود؟

پاسخ:

خروجی:

موش‌ها.

طبقه‌بندی متن

تا اینجا، از دستورهای ساده‌ای برای انجام کارها استفاده کردیم. به عنوان یک «مهندس پرامپت»، شما باید در نوشتن دستورهای بهتر و دقیق‌تر ماهر شوید. اما همه‌چیز به دستور خلاصه نمی‌شود! کم‌کم متوجه می‌شوید که برای کارهای سخت‌تر، فقط دادن دستور کافی نیست. اینجاست که باید بیشتر به «اطلاعات زمینه» (Context) و چیزهای دیگری که می‌توانید در پرامپت بیاورید، فکر کنید. مثلاً می‌توانید داده‌های ورودی یا چند مثال هم به پرامپت اضافه کنید.

بیایید این موضوع را با یک مثال از طبقه‌بندی متن ببینیم.

پرامپت:

این متن را به یکی از دسته‌های مثبت، منفی یا خنثی طبقه‌بندی کن.
متن: به نظرم غذا معمولی بود.
احساس:

خروجی:

خنثی

شما دستور دادید که متن طبقه‌بندی شود و مدل هم جواب خنثی را داد که درست است. تا اینجا مشکلی نیست. اما فرض کنید شما می‌خواهید LLM، برچسب را دقیقاً با فرمت خاصی که مدنظرتان است، به شما بدهد. مثلاً به جای خنثی، می‌خواهید کلمه «خنثی» (داخل گیومه) را تحویل بگیرید. چطور این کار را انجام دهیم؟ راه‌های مختلفی وجود دارد. اینجا «دقت» برای ما مهم است، پس هرچه اطلاعات بیشتری به پرامپت بدهیم، نتیجه بهتری هم می‌گیریم. یکی از راه‌ها این است که با چند مثال، به مدل نشان دهیم دقیقاً چه می‌خواهیم. بیایید دوباره امتحان کنیم:

پرامپت:

این متن را به یکی از دسته‌های مثبت، منفی یا خنثی طبقه‌بندی کن.
متن: به نظرم تعطیلات معمولی بود.
احساس: «خنثی»
متن: به نظرم غذا معمولی بود.
احساس:

خروجی:

«خنثی»

عالی! این بار مدل کلمه «خنثی» را برگرداند، یعنی دقیقاً همان برچسبی که ما می‌خواستیم. به نظر می‌رسد مثالی که در پرامپت آوردیم، به مدل کمک کرد تا در خروجی‌اش دقیق‌تر عمل کند.

برای اینکه بهتر بفهمیم چرا «دقت» این‌قدر مهم است، به مثال زیر نگاه کنید و سعی کنید مشکلش را پیدا کنید:

پرامپت:

این متن را به یکی از دسته‌های مثبت، منفی یا خنثا طبقه‌بندی کن.
متن: به نظرم تعطیلات معمولی بود.
احساس:

خروجی:

خنثی

مشکل کجاست؟ راهنمایی: مدل، برچسب ساختگی خنثا (که ما عمداً غلط نوشتیم) را کاملاً نادیده گرفته است. به جای آن، مدل کلمه خنثی را خروجی داده، چون به این برچسب «سوگیری» (bias) دارد یا آن را ترجیح می‌دهد. حالا فرض کنید ما واقعاً همان خنثا را می‌خواهیم. چطور این مشکل را حل کنیم؟ شاید بتوانیم برای برچسب‌ها توضیحاتی اضافه کنیم، یا مثال‌های بیشتری در پرامپت بیاوریم. اگر مطمئن نیستید، نگران نباشید! در بخش‌های بعدی چند راهکار را با هم بررسی می‌کنیم.

گفتگو

شاید یکی از جالب‌ترین کارهایی که با مهندسی پرامپت می‌توان انجام داد، این است که به مدل زبانی بزرگ یاد بدهیم چطور رفتار کند، چه قصدی داشته باشد و چه هویتی را تقلید کند. این ویژگی مخصوصاً موقع ساختن سیستم‌های گفتگو محور (مثل چت‌بات‌ها برای پشتیبانی مشتریان) خیلی به کار می‌آید.

مثلاً، بیایید یک سیستم گفتگو طراحی کنیم که بتواند به پرسش‌ها و پاسخ‌های فنی‌تر و علمی‌تری بدهد. دقت کنید که چطور با دستور دادن، به طور واضح به مدل می‌گوییم که چگونه رفتار کند. به این کار گاهی «تعیین نقش در پرامپت» (Role Prompting) هم می‌گویند.

پرامپت:

هوش مصنوعی در نقش یک دستیار پژوهشی است. لحن این دستیار، فنی و علمی است.

انسان: سلام، شما کی هستی؟
هوش مصنوعی: درود! من یک دستیار پژوهشی هوش مصنوعی هستم. امروز چطور می‌توانم کمکتان کنم؟
انسان: می‌توانی درباره شکل‌گیری سیاه‌چاله‌ها برایم توضیح بدهی؟
هوش مصنوعی:

خروجی:

حتماً! سیاه‌چاله‌ها مناطقی در فضا-زمان هستند که نیروی گرانش در آن‌ها آن‌قدر زیاد است که هیچ‌چیز، حتی نور، نمی‌تواند از آن فرار کند. سیاه‌چاله‌ها وقتی به وجود می‌آیند که یک ستاره خیلی بزرگ می‌میرد و هسته‌اش در خودش فرو می‌ریزد. این اتفاق یک «تکینگی» (singularity) با چگالی بی‌نهایت به وجود می‌آورد. گرانش شدید این تکینگی، تمام مواد و تشعشعات اطرافش را به داخل می‌کشد و سیاه‌چاله را ایجاد می‌کند.

به نظر می‌رسد دستیار پژوهشی هوش مصنوعی ما کمی زیادی تخصصی صحبت می‌کند، نه؟ بسیار خب، بیایید این رفتارش را عوض کنیم و به سیستم بگوییم جواب‌هایی بدهد که فهمیدنشان راحت‌تر باشد.

پرامپت:

هوش مصنوعی در نقش یک دستیار پژوهشی است. جواب‌های دستیار باید آن‌قدر ساده باشد که حتی بچه‌های دبستانی هم متوجه شوند.

انسان: سلام، شما کی هستی؟
هوش مصنوعی: درود! من یک دستیار پژوهشی هوش مصنوعی هستم. امروز چطور می‌توانم کمکتان کنم؟
انسان: می‌توانی درباره شکل‌گیری سیاه‌چاله‌ها برایم توضیح بدهی؟
هوش مصنوعی:

خروجی:

حتماً! سیاه‌چاله‌ها وقتی درست می‌شوند که یک ستاره خیلی خیلی بزرگ سوختش تمام می‌شود و توی خودش فرو می‌ریزد. کشش گرانش این ستاره آن‌قدر قوی است که هیچ‌چیز، حتی نور، نمی‌تواند از دستش فرار کند. این اتفاق یک نقطه در فضا-زمان با نیروی گرانش خیلی شدید درست می‌کند که به آن می‌گویند سیاه‌چاله.

کمی بهتر شد، اما هنوز هم جا برای بهتر شدن دارد. اگر مثال‌های بیشتری به پرامپت اضافه کنید، احتمالاً نتایج باز هم بهتر می‌شوند.

تولید کد

یکی از کاربردهایی که مدل‌های زبانی بزرگ در آن خیلی خوب عمل می‌کنند، «تولید کد» است. ابزار Copilot (کمک خلبان) نمونه بسیار خوبی از این قابلیت است. با پرامپت‌های هوشمندانه، می‌توانید انواع و اقسام کدهای برنامه‌نویسی را تولید کنید. بیایید چند مثال ببینیم.

اول، یک برنامه ساده را امتحان می‌کنیم که به کاربر خوشامد می‌گوید.

پرامپت:

/*
Ask the user for their name and say “Hello”
*/

خروجی:

let name = prompt(“What is your name?”);
console.log(`Hello, ${name}!`);

جالب است، نه؟ حتی لازم نشد بگوییم از چه زبان برنامه‌نویسی استفاده کند!

حالا بیایید کمی سطح کار را بالاتر ببریم. مثال زیر نشان می‌دهد که اگر کمی بیشتر برای طراحی پرامپت وقت بگذاریم، مدل‌های زبانی بزرگ چقدر می‌توانند قدرتمند باشند.

پرامپت:

“`
Table departments, columns = [DepartmentId, DepartmentName]
Table students, columns = [DepartmentId, StudentId, StudentName]
Create a MySQL query for all students in the Computer Science Department
“`

خروجی:

SELECT StudentId, StudentName
FROM students
WHERE DepartmentId IN (SELECT DepartmentId FROM departments WHERE DepartmentName = ‘Computer Science’);

واقعاً تأثیرگذار است! در این مثال، ما اطلاعاتی درباره «ساختار جدول‌های پایگاه داده» (database schema) به مدل دادیم و از آن خواستیم یک کوئری (دستور جستجو) معتبر MySQL برایمان بنویسد.

استدلال

شاید یکی از سخت‌ترین کارهایی که یک مدل زبانی بزرگ امروزه با آن مواجه است، کارهایی باشد که به نوعی نیاز به «استدلال» دارند. استدلال یکی از جذاب‌ترین حوزه‌هاست، چون می‌تواند منجر به ساخت برنامه‌های کاربردی بسیار پیچیده و جالبی با استفاده از LLMs شود.

در زمینه توانایی‌های ریاضی، پیشرفت‌هایی دیده شده است. با این حال، مهم است بدانید که LLMs فعلی هنوز در انجام کارهای استدلالی با چالش روبرو هستند و این کارها نیاز به روش‌های حرفه‌ای‌تری برای نوشتن پرامپت دارند. ما این روش‌های پیشرفته را در نوشته‌های بعدی بررسی خواهیم کرد. فعلاً، چند مثال ساده می‌بینیم تا توانایی‌های محاسباتی (مثلاً جمع و ضرب) این مدل‌ها را نشان دهیم.

پرامپت:

حاصل ۹٬۰۰۰ ضربدر ۹٬۰۰۰ چند می‌شود؟

خروجی:

۸۱٬۰۰۰٬۰۰۰

حالا بیایید یک مسئله کمی سخت‌تر را امتحان کنیم.

پرامپت:

مجموع اعداد فرد این گروه، یک عدد زوج است: ۱۵، ۳۲، ۵، ۱۳، ۸۲، ۷، ۱.
A:

خروجی

خیر، مجموع اعداد فرد این گروه یک عدد فرد است: ۱۱۹.

این جواب اشتباه است! بیایید سعی کنیم با بهتر کردن پرامپت، این مشکل را حل کنیم.

پرامپت:

مجموع اعداد فرد این گروه، یک عدد زوج است: ۱۵، ۳۲، ۵، ۱۳، ۸۲، ۷، ۱.
برای حل مسئله، آن را به چند مرحله تقسیم کن. اول، اعداد فرد را مشخص کن. بعد، آن‌ها را با هم جمع کن و در آخر بگو که حاصل جمع، عددی فرد است یا زوج.

خروجی:

اعداد فرد: ۱۵، ۵، ۱۳، ۷، ۱
مجموع: ۴۱
عدد ۴۱ یک عدد فرد است.

خیلی بهتر شد، قبول دارید؟ البته ما این مسئله را چند بار امتحان کردیم و گاهی اوقات مدل اشتباه می‌کند. اگر دستورهای بهتری بدهید و در کنارش مثال هم بیاورید، احتمالاً به نتایج دقیق‌تری می‌رسید.