چطور یک مدل خام تبدیل شد به دستیار گفتگو؟
این فصل خیلی ساده توضیح میدهد یک مدل زبانی خام چطور کمکم یاد میگیرد به دستور ما گوش بدهد، مثل یک دستیار جواب بدهد، نقشهای مختلف گفتوگو را تشخیص دهد و در صورت نیاز از ابزارها کمک بگیرد. در مسیر با SFT، RLHF، مدل پاداش، ChatML، پیام سیستمی و فراخوانی ابزار آشنا میشویم.
Chat از InstructGPT تا API چت
از یک مدل خام چطور به دستیار گفتوگویی میرسیم؟
فصل قبل دیدیم LLM در سادهترین حالت فقط سعی میکند متن را ادامه بدهد. حالا سؤال مهم این است: چطور همین مدل به چیزی شبیه ChatGPT تبدیل میشود؛ یعنی سؤال را میفهمد، جواب میدهد، نقش خودش را میشناسد و گاهی حتی درخواست استفاده از یک ابزار را میسازد؟ این فصل قدمبهقدم همین مسیر را باز میکند.
- 01چرا مدل پایه هنوز دستیار خوبی نیست؟
- 02همراستاسازی: مفید، صادق و کمآسیب
- 03RLHF قدمبهقدم: از نمونهی خوب تا پاداش
- 04SFT دقیقاً چه چیزی به مدل یاد میدهد؟
- 05مدل پاداش چطور سلیقهی انسان را امتیاز میکند؟
- 06PPO و مرحلهی نهایی RLHF
- 07چرا راستگویی با چند مثال ساده حل نمیشود؟
- 08سلیقهی ارزیاب و هزینهی همراستاسازی
- 09مدل دستورپذیر و مشکل تشخیص نوبت
- 10مدل چت و برچسب نقشها در ChatML
- 11نقشهای سیستم، کاربر و دستیار
- 12پیام سیستمی و تزریق پرامپت
- 13API چت و تنظیمات مهم
- 14چت چه چیزهایی بهتر کرد و چه چیزهایی کمتر شد؟
- 15از چت تا فراخوانی ابزار
- 16مهندسی پرامپت مثل چیدن صحنهی نمایش
- 17ساخت چت با مدل تکمیل متن؛ یک تمرین برای فهم معماری
- 18واژهنامهی ساده، چکلیست و جمعبندی
چرا مدل خام سؤال تو را «جواب» نمیدهد؟
مثلاً اگر به یک مدل خام بنویسی «برای مرغ چه غذای خوبی پیشنهاد میکنی؟»، ممکن است بهجای جوابدادن، سؤالهای مشابه بسازد: «برای ماهی چی؟ برای گوشت چی؟». چرا؟ چون از نگاه خودش شاید دارد یک فهرست سؤال را ادامه میدهد، نه اینکه با یک کاربر حرف بزند.
مدل پایه (مدل پایه) مدلی است که پیشآموزش را گذرانده و در ادامهدادن متن خوب شده، اما هنوز لزوماً برای دستور گرفتن و گفتوگو مثل یک دستیار تنظیم نشده است.
یک مثال ساده: مثل آدم بسیار باسواد و کتابخوانی که هنوز آداب کار در بخش پشتیبانی را یاد نگرفته. اطلاعات دارد، اما نمیداند در برابر مشتری باید دقیقاً چطور رفتار کند.
یک مشکل دیگر هم هست. چون مدل پایه از متنهای خیلی متنوع یاد گرفته، میتواند هم لحن خوب را تقلید کند و هم لحن بد را. خودش بهصورت خام نمیداند کدام نوع پاسخ برای یک محصول مناسبتر، مفیدتر یا امنتر است.
پس برای ساخت یک دستیار واقعی باید یک مرحلهی دیگر هم داشته باشیم: به مدل یاد بدهیم وقتی کاربر درخواست میدهد، به آن پاسخ بدهد، تا جای ممکن مفید و روشن باشد، بیدلیل اطلاعات نسازد و در طول مکالمه نقش خودش را حفظ کند.
همراستاسازی یعنی مدل یاد بگیرد چه رفتاری از یک دستیار انتظار داریم
برای سادهکردن هدف همراستاسازی، معمولاً سه ویژگی معروف را مثال میزنند: مفید باشد، صادق باشد و تا حد ممکن آسیبزا نباشد. در انگلیسی به آنها Helpful، Honest و Harmless میگویند و گاهی با HHH نشان داده میشوند.
مفید (Helpful)
یعنی واقعاً به درد سؤال کاربر بخورد؛ نه اینکه فقط یک متن زیبا و طولانی تحویل بدهد.
صادق (Honest)
اگر چیزی را مطمئن نیست، با اعتمادبهنفس داستان نسازد و بتواند عدم قطعیت را نشان بدهد.
کمآسیب (Harmless)
تا حد ممکن وارد پاسخهایی نشود که میتوانند آسیب جدی ایجاد کنند یا برخلاف محدودیتهای سیستم باشند.
پس همراستاسازی یعنی رفتار مدل را طوری تنظیم کنیم که بیشتر شبیه دستیار مورد انتظار ما باشد؛ نه اینکه فقط در ادامهدادن متن قوی باشد.
یک نکتهی مهم: این رفتار فقط از یک پیام سیستمی نمیآید. بخشی از آن در خودِ آموزش مدل ساخته شده است. یعنی مدل چت از قبل با نمونههای زیادی تمرین کرده که سؤال کاربر را چطور پاسخ بدهد و چه نوع جوابهایی ترجیح داده میشوند.
RLHF را با یک مثال خیلی ساده بفهمیم
اسم RLHF در نگاه اول خیلی دانشگاهی به نظر میرسد، اما ایدهاش ساده است: بهجای اینکه فقط به مدل بگوییم «این جواب درست است»، از آدمها میپرسیم بین چند جواب کدام را بیشتر میپسندند. بعد از همین انتخابها برای بهترکردن رفتار مدل استفاده میکنیم.
در مسیر کلاسیک RLHF چند مرحله داریم: اول مدل پایه را با نمونههای خوب کمی تربیت میکنیم؛ بعد یک «مدل پاداش» میسازیم که بتواند جوابها را امتیاز بدهد؛ در آخر از این امتیازها برای بهترکردن خود مدل استفاده میکنیم.
خیلی خلاصه: ۱) انسان چند نمونهی جواب خوب مینویسد. ۲) مدل چند جواب مختلف تولید میکند و انسان آنها را رتبهبندی میکند. ۳) یک مدل دیگر از این رتبهبندیها یاد میگیرد به پاسخها امتیاز بدهد. ۴) مدل اصلی با کمک این امتیازها کمی بهتر تنظیم میشود.
بازخورد انسانی (بازخورد انسانی) یعنی آدمها مشخص کنند کدام جواب بهتر، مفیدتر، درستتر یا مناسبتر است.
مزیتش این است که انسان مجبور نیست برای میلیونها سؤال جواب کامل بنویسد. خیلی وقتها فقط انتخاب بین چند پاسخ موجود سریعتر است: «این بهتره، اون متوسطه، این یکی بده.»
مرحلهی اول: چند نمونهی خوب به مدل نشان میدهیم (SFT)
اولین قدم این است که چند نمونهی خیلی خوب از رفتار یک دستیار به مدل نشان بدهیم. این مرحله SFT یا «آموزش تکمیلی نظارتشده» است. دادهها معمولاً شامل یک درخواست کاربر و یک پاسخ ایدهآل هستند.
یعنی به مدل مثال میدهیم: «اگر کاربر چنین چیزی گفت، یک پاسخ خوب میتواند شبیه این باشد.» بعد وزنهای مدل کمی تغییر میکنند تا تولید پاسخهای شبیه این نمونهها محتملتر شود.
موتور زیرِ کار عوض نشده؛ مدل هنوز توکن بعدی را پیشبینی میکند. فرقش این است که حالا بهجای حجم عظیمی از متنهای اینترنت، تعداد زیادی نمونهی مشخص از گفتوگوی کاربر و یک دستیار خوب میبیند.
مدل از این نمونهها الگو میگیرد: وقتی سؤال میبیند جواب بدهد، وقتی درخواست بازنویسی میبیند متن را بازنویسی کند و وقتی خلاصه میخواهیم، واقعاً خلاصه تولید کند.
اما SFT یک محدودیت دارد. کسی که پاسخ ایدهآل را مینویسد، دقیقاً نمیداند مدل چه چیزهایی را واقعاً درون خودش یاد گرفته است. ممکن است انسان جواب قطعی و درستی بنویسد، ولی مدل آن اطلاعات را خوب نداند. اگر این اتفاق زیاد تکرار شود، ممکن است مدل یاد بگیرد حتی وقتی مطمئن نیست هم با لحن خیلی قطعی جواب بدهد.
قبل از مدل پاداش، یادگیری تقویتی را خیلی ساده بفهمیم
قبل از ادامه، خود «یادگیری تقویتی» را ساده کنیم. تصور کن به یک سگ آموزش میدهی وقتی میگویی «بشین»، بنشیند. اگر درست انجام دهد تشویقی میگیرد. کمکم یاد میگیرد رفتارهایی را بیشتر تکرار کند که پاداش میگیرند. ایدهی کلی یادگیری تقویتی هم شبیه همین است.
به چیزی که انتخاب و عمل میکند «عامل» یا Agent میگویند. در RLHF، خود مدل زبانی نقش این عامل را دارد و تصمیمش در عمل همان پاسخی است که تولید میکند.
«محیط» یا Environment فضایی است که عامل در آن عمل میکند. برای مدل زبانی میتوانیم آن را متن و زمینهای بدانیم که پاسخ در آن ساخته میشود.
«پاداش» یا Reward یک عدد است که خیلی ساده میگوید نتیجه چقدر خوب بوده است. عدد بالاتر یعنی از دید معیار ما بهتر.
اینجا مشکل جالب میشود: خوببودن یک جواب مثل اندازهگیری قد نیست که یک فرمول مستقیم داشته باشد. برای همین باید مدلی بسازیم که از روی ترجیح آدمها حدس بزند یک پاسخ چقدر خوب است. اسم این داور مصنوعی «مدل پاداش» است.
مدل پاداش چطور یاد میگیرد کدام جواب بهتر است؟
برای ساخت مدل پاداش، اول برای یک سؤال چند جواب متفاوت از مدل میگیریم. بعد این جوابها را به انسانها نشان میدهیم و میپرسیم: «کدام بهتر بود؟ بعدی کدام است؟ بدترین کدام است؟»
مدل پاداش (مدل پاداش) یک سؤال و یک جواب را میگیرد و یک امتیاز میدهد که تقریب میزند انسانها آن جواب را چقدر میپسندند.
چون تشخیص کیفیت جواب ساده نیست، خود مدل پاداش هم باید توانایی زبانی خوبی داشته باشد. بعد بهجای اینکه کارش پیشبینی کلمهی بعدی باشد، یاد میگیرد پاسخها را امتیاز بدهد یا بین دو جواب بگوید کدام بهتر است.
اگر آموزش خوب پیش برود، مدل پاداش تبدیل میشود به چیزی شبیه یک داور سریع. دیگر لازم نیست برای هر پاسخ تازه یک انسان بنشیند و امتیاز بدهد؛ مدل پاداش میتواند این کار را در مقیاس بزرگتر انجام دهد.
مرحلهی آخر RLHF: مدل را با امتیازها بهتر میکنیم
حالا دوباره سراغ مدل SFT میرویم. یک درخواست به آن میدهیم، پاسخ میسازد و مدل پاداش به آن پاسخ امتیاز میدهد. بعد مدل اصلی کمی تنظیم میشود تا در آینده جوابهایی شبیه پاسخهای پُرامتیاز را بیشتر تولید کند.
اما یک خطر وجود دارد: اگر فقط بگوییم «هر طور شده امتیازت را زیاد کن»، مدل ممکن است راهی پیدا کند که داور را راضی کند بدون اینکه واقعاً پاسخ بهتری داده باشد. مثل دانشآموزی که فقط راه نمرهگرفتن را یاد بگیرد، نه خود درس را.
برای اینکه تغییرات مدل بیحسابوکتاب نشود، در مسیر کلاسیک InstructGPT از الگوریتمی به نام PPO استفاده شد.
PPO یک روش یادگیری تقویتی است که اجازه میدهد مدل بهتر شود، اما تغییراتش را کنترل میکند تا ناگهان از رفتار قبلی و نسبتاً خوبِ SFT خیلی دور نشود.
تشبیه خوبش همان مربی رانندگی است: میگوید میتوانی سریعتر و بهتر برانی، اما نه اینکه برای چند ثانیه رکورد بهتر از جاده خارج شوی.
در پایان این مرحله، مدل هنوز همان توانایی زبانی پایه را دارد، اما بیشتر به سمت رفتاری میرود که از یک دستیار انتظار داریم: دستورپذیرتر، مفیدتر و نزدیکتر به ترجیح انسانی.
یادداشت کن ✍️چرا فقط نشاندادن چند جواب خوب، راستگویی را حل نمیکند؟
اگر انسان همیشه جواب قطعی بنویسد، حتی در جاهایی که مدل واقعاً مطمئن نیست، مدل ممکن است کمکم یاد بگیرد «حتی وقتی نمیدانی هم محکم حرف بزن». برعکس، اگر همهی نمونهها بیش از حد محتاط باشند، مدل ممکن است حتی دربارهی چیزهای ساده هم دائم بگوید «شاید» و «احتمالاً».
به این زبان محتاطانه گاهی Hedge میگویند؛ یعنی عباراتی مثل «تا جایی که میدانم»، «ممکن است» یا «برای اطمینان منبع اصلی را بررسی کن».
مدل پاداش کمی از زاویهی دیگری کمک میکند. جوابها را خود مدل تولید میکند و انسان فقط بین همان جوابها انتخاب میکند. اگر پاسخ ساختگی یا بیشازحد مطمئن معمولاً رتبهی پایینتری بگیرد، مدل پاداش یاد میگیرد چنین جوابهایی را کمتر ترجیح بدهد.
چطور سلیقهی یک ارزیاب، سلیقهی کل مدل نشود؟
به این ویژگیهای خیلی شخصی و خاص، Idiosyncratic رفتار میگویند؛ یعنی چیزی که سلیقهی عمومی نیست و بیشتر امضای شخصی یک فرد است.
در مرحلهی رتبهبندی، انسانها بیشتر «انتخاب» میکنند تا «نوشتن». این کمک میکند سبک شخصی یک نفر کمتر مستقیماً وارد داده شود. اگر افراد مختلف روی خوب و بد بودن پاسخها تا حدی توافق داشته باشند، مدل پاداش بیشتر به سمت ترجیح جمعی میرود.
یک مزیت دیگر هم هزینه است. نوشتن هزاران جواب عالی سخت و گران است، اما رتبهبندی چند جواب آماده معمولاً سریعتر است. بنابراین بعد از SFT، خود مدل بخش زیادی از پاسخهای مورد نیاز برای آموزش را تولید میکند و انسان بیشتر نقش داور را دارد.
هزینهی همراستاسازی: آیا تربیت مدل چیزی از آن کم میکند؟
وقتی مدل را همراستا میکنیم، یک هدف تازه به آموزش اضافه میشود: دیگر فقط خوبنوشتن مهم نیست؛ میخواهیم مدل مفید، صادق و تا حد ممکن کمآسیب هم باشد. این هدفها همیشه دقیقاً با «توانایی خام» مدل یکی نیستند.
هزینهی همراستاسازی یا «هزینهی همراستاسازی» یعنی ممکن است در اثر تنظیم شدید مدل برای یک رفتار خاص، بخشی از تنوع یا بعضی تواناییهای خام آن کمتر در دسترس شود.
مثلاً اگر یک مدل را خیلی شدید برای نقش «دستیار رسمی، محتاط و مودب» تنظیم کنیم، شاید دیگر به اندازهی مدل خام سبکهای خیلی متنوع و عجیب تولید نکند. یکی از راههای کاهش این اثر در آموزش کلاسیک این بود که بخشی از دادههای پیشآموزش هم کنار دادههای همراستاسازی باقی بماند تا مدل رفتار دستیار را یاد بگیرد ولی قابلیتهای عمومیاش کمتر فراموش شود.
قبل از مدلهای چت، مدلهای دستورپذیر آمدند
به همین دلیل اگر بنویسی «۱۰ کتاب علمیتخیلی پیشنهاد بده» یا «این متن را خلاصه کن»، مدل دستورپذیر معمولاً مستقیم سراغ انجام همان کار میرود، نه اینکه متن تو را مثل شروع یک مقاله ادامه بدهد.
مدل دستورپذیر مدلی است که با آموزش تکمیلی یاد گرفته ورودی را بهطور پیشفرض درخواست کاربر در نظر بگیرد و برای آن پاسخ مناسب بسازد.
این خیلی بهتر بود، اما هنوز یک ابهام داشتیم: خود متن علامت واضحی نداشت که بگوید «حرف کاربر اینجا تمام شد؛ حالا نوبت دستیار است».
مثلاً جملهی «چه فعالیت داخل خانهای برای خانوادهی چهار نفره خوب است؟» میتواند سؤال یک کاربر باشد، یا فقط تیتر و شروع یک مقاله. مدل باید از قالب و آموزش بفهمد با کدام حالت روبهروست.
مدل چت چطور میفهمد چه کسی دارد حرف میزند؟
راهحل ساده و هوشمندانه این بود که خود مکالمه را ساختار بدهیم. یعنی هر پیام یک برچسب داشته باشد: این پیام از طرف سیستم است، این یکی از طرف کاربر و این یکی از طرف دستیار. حالا مدل خیلی واضحتر میفهمد چه کسی چه چیزی گفته و نوبت پاسخ چه کسی است.
نکتهی مهم این است که موتور اصلی مدل عوض نشده. هنوز دارد متن را ادامه میدهد؛ فقط این بار متنی که ادامه میدهد شبیه صورتجلسه یا رونوشت یک مکالمه است.
ChatML یعنی روی هر پیام برچسب بزنیم که گوینده کیست
در معماریهای آن زمان OpenAI، قالبی به نام ChatML برای مشخصکردن نقش پیامها استفاده میشد. ایدهاش ساده بود: دور هر پیام نشانههایی قرار میگرفت تا مدل بفهمد این متن متعلق به «سیستم»، «کاربر» یا «دستیار» است.
کدی که در این بخش میبینی فقط یک نمایش ساده از ایده است. چیز مهم خود ChatML نیست؛ چیز مهم این است که نقشها از هم جدا باشند. مدل باید بفهمد قوانین کلی را سیستم گفته، مسئله را کاربر مطرح کرده و حالا نوبت دستیار است.
رونوشت مکالمه یعنی رونوشت یا متن ثبتشدهی مکالمه؛ یعنی مشخص باشد چه کسی چه چیزی گفته است.
نقش یعنی نقش هر پیام. در سادهترین حالت سه نقش مهم داریم: سیستم، کاربر و دستیار.
این ساختار دو مزیت خیلی مهم دارد: اول نوبت حرفزدن روشن میشود؛ دوم پیام سیستمی میتواند رفتار کلی دستیار را از بالاترین سطح مشخص کند.
پیام سیستمی چیست؟ یک دستور پشت صحنه برای مدل
پیام سیستمی را مثل دستور پشت صحنه ببین. کاربر معمولاً آن را بهعنوان بخشی از گفتوگو نمیگوید. این پیام به مدل توضیح میدهد «تو چه نقشی داری، دربارهی چه حوزهای کار میکنی، لحن جوابها چطور باشد و چه قواعد کلی را رعایت کنی».
پس پیام سیستمی یا پیام سیستمی، یک پیام سطح بالاست که قبل از گفتوگو نقش، هدف و قواعد کلی دستیار را تعیین میکند.
مثلاً: «تو یک دستیار برنامهنویسی هستی. جوابها را کوتاه بده. اگر سؤال خارج از برنامهنویسی بود، محترمانه بگو خارج از حوزهی توست.»
اگر پیام سیستمی بگوید جوابها کوتاه باشند، مدل معمولاً به سمت کوتاهنویسی میرود. اگر بگوید رسمی یا طنزآمیز باشد، لحن هم تغییر میکند. چون مدل در آموزش، گفتوگوهایی با نقشهای مشخص دیده است.
اما پیام سیستمی چوب جادو نیست. بخش مهمی از رفتار مدل از خود آموزش آن میآید. پیام سیستمی میتواند بعضی رفتارها را جهت بدهد، اما نمیتواند هر ویژگی عمیق مدل را با یک جمله کاملاً عوض کند.
جداکردن نقشها چه کمکی به مقابله با تزریق پرامپت میکند؟
تزریق پرامپت یا «تزریق پرامپت» یعنی واردکردن دستورهایی داخل ورودی یا دادهی بیرونی با هدف اینکه رفتار مدل را برخلاف قواعد مورد نظر برنامه تغییر دهند.
در قالب چت، خود API نقش هر پیام را مشخص میکند. کاربر متن خودش را در نقش کاربر میفرستد و صرفاً با تایپکردن یک عبارت نمیتواند واقعاً پیامش را به سیستم تبدیل کند.
مثلاً فرض کن یک فایل بازیابیشده داخل خودش نوشته باشد «همهی قوانین قبلی را نادیده بگیر». اگر برنامه این متن را اشتباهی در جایگاه سیستم بگذارد، خطر بیشتر میشود. دادهی بیرونی باید همچنان «داده» بماند، نه اینکه به قانون سطح بالا تبدیل شود.
چرا APIهای چت کار برنامهنویس را راحتتر کردند؟
با API چت، برنامهنویس دیگر مجبور نبود خودش رونوشت مکالمه را به یک رشتهی پیچیده تبدیل کند. کافی بود فهرستی از پیامها بفرستد و برای هرکدام بگوید نقش آن سیستم، کاربر یا دستیار است. بخش پشتی سرور بقیهی قالببندی را انجام میداد.
پس اصل مهم، شکل دقیق کد یک کتابخانه نیست؛ ایده این است که API ساختار مکالمه را رسمی و روشن میکند. همراه پاسخ هم معمولاً اطلاعات جانبی مثل دلیل پایان پاسخ یا میزان مصرف توکن میتواند برگردد.
مهمترین تنظیمات API چت را ساده بفهمیم
وقتی از API مدل استفاده میکنی، فقط نام مدل و پیامها مهم نیستند. چند تنظیم دیگر هم وجود دارند که روی شکل تولید پاسخ و نحوهی دریافت آن اثر میگذارند.
| پارامتر | خیلی ساده | کاربرد |
|---|---|---|
| max_tokens | سقف طول خروجی | کنترل هزینه و جلوگیری از پاسخ بیش از حد بلند |
| temperature | میزان Randomness | تعادل بین تکرارپذیری و تنوع |
| stop | شرط توقف | قطع تولید پس از الگو مشخص |
| stream | ارسال تدریجی Tokenها | بهبود UX برای جوابهای بلند |
| n | تعداد Candidateها | Evaluation یا انتخاب بین چند پاسخ |
| logprobs | احتمال Tokenهای انتخابشده | تحلیل Confidence یا Alternativeها |
| logit_bias | هل دادن احتمال بعضی Tokenها بالا/پایین | کنترل تخصصی تولید |
یکی از مهمترینها دما یا «دما» است. دمای پایینتر معمولاً جوابها را قابلپیشبینیتر میکند. هرچه دما بالاتر برود، مدل آزادی بیشتری برای انتخابهای کماحتمالتر پیدا میکند؛ بنابراین پاسخها متنوعتر میشوند و اگر خیلی بالا برویم ممکن است بیقاعده شوند.
Streaming یعنی لازم نباشد تا پایان کل پاسخ صبر کنیم. بخشهای پاسخ همان موقع که تولید میشوند کمکم به رابط کاربری فرستاده میشوند؛ تقریباً همان حسی که در چت میبینی وقتی متن جلوی چشمت نوشته میشود.
دما فقط «خلاقیت» نیست؛ میزان آزادی مدل را هم تغییر میدهد
پس دما را بر اساس کار انتخاب کن. برای استخراج اطلاعات، JSON و خروجیهای دقیق معمولاً تنوع کمتر بهتر است. برای ایدهپردازی و تولید چند گزینهی متفاوت، کمی دمای بالاتر میتواند مفید باشد.
مدل چت چه چیزهایی را برای ما بهتر کرد؟
چت سه چیز مهم را بهتر کرد. اول اینکه معلوم شد چه کسی چه زمانی حرف میزند. دوم اینکه مدل از قبل برای رفتار دستیار تمرین کرده و مستقیمتر جواب میدهد. سوم اینکه نقشها و پیام سیستمی کنترل بهتری روی لحن و قواعد برنامه میدهند.
Clear Turns
یعنی دقیقاً معلوم است پیام کاربر کجا تمام شده و پاسخ دستیار از کجا شروع میشود.
Instruction Following
مدل بهطور پیشفرض آماده است درخواست کاربر را انجام دهد، نه اینکه صرفاً متن او را ادامه دهد.
نقش Control
پیام سیستمی و نقشها کمک میکنند رفتار کلی دستیار را بهتر هدایت کنیم.
ولی هیچ تغییری رایگان نیست. وقتی مدل برای نقش دستیار تخصصیتر میشود، ممکن است بخشی از آزادی و تنوع مدل خام کمتر در دسترس باشد.
یادداشت کن ✍️در مقابل، چه چیزهایی را کمتر در اختیار داریم؟
۱) هزینهی همراستاسازی
اولین هزینه همان هزینهی همراستاسازی است: مدل برای نقش دستیار تنظیم شده و شاید بعضی رفتارهای خام یا تواناییهای خاص مدل پایه کمتر دیده شوند.
۲) کنترل کمتر روی «اولین Tokenهای خروجی»
۳) تنوع خام رفتار انسانی کمتر میشود
سوم، مدل پایه میتواند سبکهای خیلی متنوع متنهای اینترنت را تقلید کند. مدل RLHF معمولاً مرتبتر، مؤدبتر و یکنواختتر است. برای بیشتر محصولات این عالی است، اما اگر هدفت تولید دادهی زبانی بسیار متنوع باشد، همین یکنواختی گاهی محدودکننده میشود.
موتور تکمیل متن هنوز آن زیر هست؛ فقط ظاهرش چت شده
ظاهر چت ممکن است این حس را بدهد که با یک موتور کاملاً جدید طرفیم، اما زیرِ این رابط هنوز همان اصل بنیادی وجود دارد: مدل توکن بعدی را پیشبینی میکند.
فرق اصلی در نوع متنی است که ادامه میدهد. مدل پایه شاید یک مقاله یا فایل کد را ادامه بدهد. مدل چت رونوشت یک مکالمه را ادامه میدهد. مدل دارای ابزار هم همان مکالمه را ادامه میدهد، فقط داخل آن قالبهایی برای «درخواست ابزار» و «نتیجهی ابزار» هم وجود دارد.
از حرفزدن تا استفاده از ابزار
مدل در پاسخ خودش یک درخواست ساختاریافته برای ابزار میسازد. برنامه این درخواست را میگیرد، API یا تابع واقعی را اجرا میکند، نتیجه را دوباره وارد مکالمه میکند و مدل با استفاده از آن نتیجه جواب نهایی را مینویسد.
پس نکتهی کلیدی این است: مدل خودش ابزار را اجرا نمیکند؛ فقط میگوید «من برای ادامه به این ابزار و این ورودی نیاز دارم». اجرای واقعی با برنامه است.
مهندسی پرامپت را مثل چیدن یک صحنهی نمایش ببین
برای فهم مهندسی پرامپت یک تشبیه خیلی خوب وجود دارد: آن را مثل نمایشنامهنویسی ببین. چیزی که کاربر روی صفحه میبیند لزوماً تمام متنی نیست که پشت صحنه به مدل داده میشود.
پس پرامپت شبیه متن یک نمایش است، نقشها شخصیتهای نمایشاند و مهندس پرامپت کسی است که تصمیم میگیرد چه اطلاعاتی چه زمانی وارد صحنه شوند.
سیستم
قواعد کلی صحنه و نقش دستیار را مشخص میکند.
کاربر
مسئله و درخواست واقعی را وارد میکند.
دستیار
پاسخی است که معمولاً مدل تولید میکند.
ابزار
اطلاعاتی است که از بیرون، مثلاً از جستوجو یا یک API، وارد مکالمه میشود.
پرامپت نهایی معمولاً فقط نوشتهی یک نفر نیست
پرامپت نهایی خیلی وقتها حاصل کار چند منبع مختلف است. مهندس پرامپت قالب را میسازد، کاربر سؤال را میآورد، مدل بخش پاسخ را تولید میکند و ابزارها یا سیستم جستوجو اطلاعات بیرونی را اضافه میکنند.
با این نگاه، مهندسی پرامپت دیگر پیدا کردن یک «جملهی جادویی» نیست. تو بیشتر شبیه هماهنگکنندهی یک صحنه هستی: تعیین میکنی چه چیزی، با چه نقشی و در چه زمانی وارد متن مدل شود.
Showrunner در تولید سریال کسی است که مسیر کلی داستان و کار تیم را هماهنگ میکند. اینجا هم مهندس پرامپت نقش هماهنگکنندهی کل جریان مکالمه و برنامه را دارد.
چیزی که کاربر میبیند با چیزی که مدل میبیند فرق دارد
در یک محصول واقعی، صفحهای که کاربر میبیند باید ساده باشد. اما متنی که مدل پشت صحنه میبیند میتواند شامل کد، اطلاعات جانبی، نتیجهی جستوجو، تعریف ابزارها، خلاصهی گفتوگوی قبلی و هر اطلاعات لازم دیگری باشد.
پس پرامپت فقط همان جملهای نیست که کاربر تایپ کرده. برنامه میتواند درخواست کوتاه کاربر را با زمینهی مناسب کاملتر کند تا مدل دقیقاً بداند دربارهی چه چیزی باید جواب بدهد.
یک تمرین عالی: خودت با مدل تکمیل متن، چت بساز
اگر میخواهی واقعاً بفهمی API چت پشت صحنه چه میکند، یک تمرین عالی این است که خودت با یک مدل تکمیل متن، یک چت ساده بسازی.
یک متن ثابت برای توضیح نقش دستیار میگذاری. بعد پیامهای کاربر و دستیار را پشت سر هم ذخیره میکنی. هر بار کاربر پیام تازهای میدهد، آن را به انتهای رونوشت اضافه میکنی، علامت شروع پاسخ دستیار را میگذاری و از مدل میخواهی ادامه را تولید کند. جواب را ذخیره میکنی و این چرخه تکرار میشود.
این تمرین نشان میدهد چت از چند قطعه تشکیل شده: نگهداشتن تاریخچه، ساختن رونوشت مکالمه و گرفتن ادامه از مدل. APIهای چت بخش زیادی از همین کارها را برای ما مرتب و استاندارد کردهاند.
یادداشت کن ✍️یک قدم جلوتر: فراخوانی ابزار را هم خودت شبیهسازی کن
اینجا مرز مسئولیتها خیلی روشن میشود: مدل متنِ درخواست ابزار را میسازد؛ برنامه وضعیت مکالمه، خواندن قالب، اجرای تابع و مدیریت خطاها را انجام میدهد.
این فصل در عمل چه چیزی به مهندس پرامپت یاد میدهد؟
نتیجهی اول: همیشه باید بدانیم مدل چطور آموزش دیده. مدل پایه، مدل دستورپذیر و مدل چت فقط سه ظاهر متفاوت نیستند؛ هرکدام برای رفتار متفاوتی تنظیم شدهاند.
نتیجهی دوم: پیام سیستمی جای قواعد کلی است، نه انباری برای هر دادهای که پیدا میکنی. اطلاعات کاربر و دادههای بازیابیشده بهتر است مرز مشخص خودشان را داشته باشند.
نتیجهی سوم: اگر مدل چت زیادی توضیح میدهد یا لحن خاصی دارد، ممکن است بخشی از آن نتیجهی RLHF و همراستاسازی باشد. همیشه یک پرامپت کوتاه همهچیز را عوض نمیکند؛ گاهی انتخاب مدل و طراحی رابط هم مهم است.
نتیجهی چهارم: فراخوانی ابزار جادو نیست. مدل فقط درخواست را تولید میکند. برنامه باید مجوز، بررسی ورودی، اجرای واقعی و نگهداری وضعیت را مدیریت کند.
اشتباههای رایج هنگام ساخت برنامهی چت
پیام سیستمی را با کاربر زمینه قاطی کردن
اشتباه اول: دادهی کاربر یا متن فایل بازیابیشده را با پیام سیستمی قاطی کنی. در این حالت مرز بین «قانون» و «داده» ضعیف میشود.
فکرکردن Chat یعنی Memory
اشتباه دوم: فکر کنی چون رابط چت است، مدل خودش حافظهی دائمی دارد. مدل فقط چیزهایی را میبیند که در درخواست فعلی داخل زمینه برایش فرستاده شدهاند؛ برنامه باید تاریخچه را نگه دارد و در صورت نیاز دوباره بفرستد.
انتظار خروجی کاملاً خام از مدل دستیار
اشتباه سوم: از مدل دستیار انتظار داشته باشی همیشه بدون هیچ توضیح اضافه فقط دادهی خام بدهد. برای خروجی ماشینی بهتر است قالب مشخص و اعتبارسنجی داشته باشی.
نادیدهگرفتن هزینهی همراستاسازی
اشتباه چهارم: هزینهی همراستاسازی را نادیده بگیری. اگر کار تو به رفتار بسیار خام و متنوع نیاز دارد، مدل دستیار همیشه بهترین انتخاب نیست.
درخواست ابزار بدون برنامه Guardrail
اشتباه پنجم: هر درخواست ابزار را بدون بررسی اجرا کنی. مدل فقط پیشنهاد میدهد؛ برنامه باید مجوزها، ورودیها و خطاها را کنترل کند.
مدل ذهنی نهایی: همان موتور قبلی، با چند لایهی رفتاری
اگر کل فصل را در یک جمله جمع کنیم: موتور اصلی هنوز همان ترنسفورمر و پیشبینی توکن بعدی است. چیزی که تغییر کرده، نوع آموزش، قالب مکالمه و لایهی برنامهای است که اطراف مدل ساختهایم.
واژهنامهی ساده: آموزش و همراستاسازی
واژهنامهی ساده: چت و API
واژهنامهی ساده: ابزارها و معماری
چکلیست ساده برای ساخت برنامهی چت
- میدانم مدل من پایه، دستورپذیر یا چت است و رفتار ناشی از آموزش آن چیست.
- پیام سیستمی فقط قواعد و نقش سطح بالا را نگه میدارد.
- محتوای کاربر و محتوای بازیابیشده مرز واضح دارند.
- تاریخچهی گفتوگو در برنامه ذخیره و مدیریت میشود.
- برای خروجی ماشینی، ساختار و اعتبارسنجی دارم.
- دما متناسب با کار انتخاب شده است.
- میدانم ارسال زنده برای تجربهی کاربر لازم است یا نه.
- اگر چند گزینه لازم دارم، ارزیابی مناسبی برای انتخابشان دارم.
- درخواست ابزار را مدل فقط درخواست میدهد؛ برنامه آن را اجرا میکند.
- نتیجهی ابزار دوباره با نقش و زمینه صحیح وارد Conversation میشود.
- رفتار RLHF/همراستاسازی را در انتخاب مدل و تجربهی کاربر در نظر گرفتهام.
- پرامپت را بهعنوان رونوشت مکالمه طراحی میکنم، نه یک رشتهی متن جادویی.
جمعبندی: چت فقط یک ظاهر جدید نیست؛ نتیجهی آموزش و طراحی است
در ابتدای فصل یک مدل پایه داشتیم: مدلی که متنهای بسیار زیادی دیده و در ادامهدادن متن قوی است، اما هنوز لزوماً نمیداند باید مثل یک دستیار به سؤال ما جواب بدهد.
با SFT چند نمونهی خوب از رفتار دستیار به آن نشان دادیم. بعد با رتبهبندی انسانی و مدل پاداش، ترجیح آدمها را به یک امتیاز قابل استفاده تبدیل کردیم. با RLHF و PPO هم مدل را با کنترل بیشتری به سمت پاسخهای ترجیحدادهشده بردیم.
بعد دیدیم مدل دستورپذیر هنوز یک ابهام دارد: در یک متن ساده معلوم نیست دقیقاً چه کسی حرف میزند. مدل چت با نقشهای سیستم، کاربر و دستیار این مسئله را شفافتر کرد و API چت استفاده از این ساختار را برای برنامهنویس راحتتر کرد.
در پایان، فراخوانی ابزار نشان داد مدل فقط لازم نیست حرف بزند. میتواند درخواست کند برنامه یک ابزار واقعی را اجرا کند و نتیجه را دوباره به مکالمه برگرداند. اینجا فهمیدیم مهندسی پرامپت فقط نوشتن متن کاربر نیست؛ طراحی کل جریان اطلاعات بین کاربر، مدل، API و ابزارهاست.
مبنای فنی و ترتیب مفاهیم این فصل از فصل سوم کتاب مهندسی پرامپت for LLMs با عنوان Moving to Chat گرفته شده است. متن حاضر با همان مفاهیم، اما با زبان سادهتر، مثالهای روزمره و ساختار آموزشی مستقل بازنویسی شده است.
یادداشت کن ✍️