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

برای ساخت سیستم‌هایی که قابل اعتماد و پاسخگو باقی بمانند، باید سه اصل اساسی را درک کنید: توکن‌ها (tokens)، پنجره‌های کانتکست (context windows) و تفاوت بین کانتکست و حافظه.

توکن‌ها ارز واقعی هستند

یک توکن، یک کلمه نیست. وقتی متنی را به یک مدل می‌فرستید، یک توکنایزر (tokenizer) آن را به قطعات کوچک‌تر تقسیم می‌کند. کلمات کوتاه و رایج مانند "cat" یا "the" ممکن است هر کدام یک توکن را پر کنند. یک اصطلاح فنی فشرده مانند "internationalization" به چندین بخش تقسیم می‌شود. علائم نگارشی، فاصله‌ها و کاراکترهای خاص نیز همگی محاسبه می‌شوند. این موضوع اهمیت دارد زیرا توکن‌ها همه چیز را کنترل می‌کنند: صورت‌حساب API شما، سرعت پاسخ‌دهی و کیفیت خروجی.

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

پنجره کانتکست، یک وایت‌برد با ابعاد ثابت است

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

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

کانتکست، حافظه نیست

در اینجا تمایزی وجود دارد که حتی سازندگان با تجربه را هم به اشتباه می‌اندازد. خودِ مدل "stateless" (بدون وضعیت) است. مدل شما را از دیروز، هفته گذشته یا ده دقیقه پیش در یک نشست (session) دیگر به یاد نمی‌آورد. وقتی به نظر می‌رسد یک هوش مصنوعی به خاطر می‌آورد که شما Python را به JavaScript ترجیح می‌دهید، یا پاسخ‌های کوتاه را دوست دارید، این حافظه در لایه اپلیکیشن قرار دارد، نه در مدل.

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

چرا کانتکستِ بیشتر می‌تواند نتیجه معکوس داشته باشد

عقل سلیم می‌گوید که اطلاعات پس‌زمینه بیشتر باید پاسخ‌های بهتری تولید کند، اما اغلب عکس این اتفاق می‌افتد. کانتکستِ بیش از حد، باعث ایجاد نویز می‌شود. اگر زمانی که فقط نیاز به اصلاح یک تابع دارید، کل یک پایگاه کد (codebase) را به مدل بدهید، آن را مجبور می‌کنید تا در میان نویزها به دنبال سیگنال بگردد. محققان اثر «گم شدن در میان» (Lost in the Middle) را شناسایی کرده‌اند: مدل‌ها اغلب توجه بیشتری به جزئیات در ابتدا و انتهای یک پرامپت دارند، در حالی که اطلاعات دفن شده در مرکز، رقیق یا نادیده گرفته می‌شوند. این باگی نیست که بتوانید با کلمات هوشمندانه آن را اصلاح کنید؛ این یک رفتار ساختاری در معماری‌های مبتنی بر ترنسفورمر (transformer-based) است.

پرامپت‌های حجیم همچنین از جایی که درد دارد، به شما ضربه می‌زنند. هر توکن اضافی مستلزم محاسبات است. تأخیر (latency) افزایش می‌یابد، هزینه‌ها بالا می‌رود و صبر کاربر کاهش می‌یابد. پرامپتی که با اسناد بی‌ربط پر شده باشد، تضاد ایجاد می‌کند، مدل را با جزئیات حاشیه‌ای منحرف می‌کند و احتمال اینکه پاسخ بر روی مشکل اشتباه تمرکز کند را افزایش می‌دهد. حجم، دشمنِ دقت است.

چگونه کانتکست بهتری مهندسی کنیم

مهندسی کانتکستِ خوب، تمرینی در ویرایش بی‌رحمانه است. در اینجا نحوه اجرای آن آورده شده است.

فقط آنچه را که وظیفه ایجاب می‌کند ارسال کنید. اگر کاربر درباره سیاست بازگشت وجه شما سوال کرد، دفترچه راهنمای کارکنان، مستندات API و متن بازاریابی فصل گذشته را شامل نکنید. مرتبط بودن بر جامع بودن برتری دارد.

از RAG برای بازیابی اسناد مرتبط استفاده کنید. تولید تقویت‌شده با بازیابی (Retrieval-Augmented Generation) به شما اجازه می‌دهد در یک پایگاه دانش بزرگ جستجو کنید و تنها بخش‌های بسیار مرتبط را به پرامپت تزریق کنید. به جای ریختن یک دفترچه راهنمای هزار صفحه‌ای در پنجره گفتگو، اسناد خود را جاسازی (embed) کنید، یک جستجوی معنایی (semantic search) روی پرسش کاربر انجام دهید و سه پاراگراف مرتبط‌ترین را بگنجانید. مدل دقیقاً همان چیزی را که نیاز دارد دریافت می‌کند و بودجه توکن‌های شما نیز حفظ می‌شود.

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

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

استفاده از توکن را در محیط عملیاتی نظارت کنید. جهش‌های تأخیر (latency spikes) اغلب مستقیماً با تورم بافت (context bloat) در ارتباط هستند. زمانی که درخواست‌ها به محدودیت مدل شما نزدیک می‌شوند، هشدار تنظیم کنید. لاگ‌ها را بررسی کنید تا پرامپت‌هایی که بار اضافی دارند را شناسایی کنید. بهینه‌سازی هر بار با یک سوال شروع می‌شود: چه چیزی را می‌توانیم بدون مختل کردن وظیفه حذف کنیم؟

نکته اصلی

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

منبع: AI Context Engineering: Tokens, Context Windows, & Memory

جامعه: GyaanSetu AI on Telegram