محدودیت توکن در پرامپت نویسی یکی از آن قیدهای فنی است که تا وقتی به آن برنخورده‌اید، به‌نظر trivial می‌آید؛ اما وقتی اولین بار پاسخ یک مدل زبانی را در میانه جمله بریده می‌بینید یا متوجه می‌شوید بخشی از سند شما هرگز به مدل نرسیده، تازه معنا پیدا می‌کند. این محدودیت نه فقط یک قید ورودی، بلکه یک محدودیت معماری است که سراسر سیستم شما را تحت تأثیر قرار می‌دهد: از انتخاب استراتژی قطعه‌بندی متن (Chunking)، تا طراحی پنجره زمینه، تا نحوه مدل‌سازی هزینه و تأخیر.

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

چکیده‌ای از آنچه پیش رو دارید

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

توکن چیست و چرا محدودیت وجود دارد؟

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

دلیل وجود محدودیت، سه چیز است: نخست، پیچیدگی محاسباتی توجه (Attention) که به‌صورت درجه دوم با طول توالی رشد می‌کند؛ دوم، مصرف حافظه برای نگهداری حالت‌های میانی و کش کلید-مقدار (KV Cache)؛ سوم، هزینه استنتاج که مستقیماً با تعداد توکن‌های پردازش‌شده گره خورده است. هر یک از این سه عامل به تنهایی کافی است که محدودیت توکن به یک قید بنیادین تبدیل شود.

چرا توکن‌سازی فارسی مسئله را جدی‌تر می‌کند

در توکنایزرهای مبتنی بر BPE، واژگان فارسی که با نیم‌فاصله یا پسوند و پیشوند ترکیبی نوشته می‌شوند، اغلب به چند توکن شکسته می‌شوند. این یعنی یک پاراگراف فارسی می‌تواند تا ۱.۵ برابر پاراگراف انگلیسی معادل، توکن مصرف کند. اگر روی پروژه‌ای کار می‌کنید که پرامپت‌های آن فارسی است، این نکته را در برآورد هزینه و طراحی محدودیت‌ها لحاظ کنید.

انواع محدودیت توکن که در عمل با آن‌ها روبه‌رو می‌شوید

در مواجهه با مدل‌های زبانی بزرگ، با چند سطح مختلف محدودیت سر و کار دارید که هر یک رفتار متفاوتی ایجاد می‌کند:

نوع محدودیتمحدودهپیامد نقض
سقف ورودی (Prompt Limit)حداکثر توکنی که می‌توانید در پرامپت بفرستیدپاسخ خطا یا برش خاموش
سقف خروجی (Max Output)حداکثر توکنی که مدل تولید می‌کندپاسخ نیمه‌کاره، قطع ناگهانی
پنجره زمینه (Context Window)مجموع ورودی + خروجی قابل پردازشبیش از ظرفیت، هم ورودی و هم خروجی محدود می‌شود
سقف توکن در یک پیاممحدودیت برخی APIها در هر پیام جداگانهخطای اعتبارسنجی در سطح درخواست
سقف توکن در ثانیه (TPM)محدودیت نرخ مصرفخطای Rate Limit

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

پنجره زمینه (Context Window) و تفاوت آن با سقف خروجی

پنجره زمینه یعنی مجموع توکن‌هایی که مدل در یک نشست می‌تواند ببیند و تولید کند. اگر پنجره زمینه ۱۲۸K توکن باشد و شما ۱۲۸ هزار توکن ورودی بفرستید، عملاً فضایی برای تولید خروجی نمی‌ماند. این خطای رایجی است که در پروژه‌های حجیم رخ می‌دهد و مخصوصاً در سیستم‌های RAG که حجم بازیابی‌شده بالا است، خطر جدی محسوب می‌شود.

در طراحی معماری پرامپت، همیشه باید یک بودجه توکن (Token Budget) مشخص برای هر بخش تعریف کنید: مثلاً ۶۰٪ برای زمینه بازیابی‌شده، ۱۵٪ برای پرامپت سیستمی، ۵٪ برای تاریخچه گفت‌وگو، و ۲۰٪ باقی‌مانده به‌عنوان سقف خروجی. این عدد‌ها صرفاً یک مثال است، اما وجود داشتنشان در ذهن، جلوی خطاهای فاحش را می‌گیرد.

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

تأثیر محدودیت توکن بر کیفیت پاسخ

محدودیت توکن فقط یک قید کمی نیست؛ به‌طور مستقیم بر کیفیت پاسخ اثر می‌گذارد. سه الگوی رفتاری رایج وجود دارد:

۱. افت توجه در توالی‌های طولانی

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

۲. تنزل دقت در استدلال چندمرحله‌ای

وقتی پنجره زمینه نزدیک به اشباع می‌شود، مدل کمتر می‌تواند بین بخش‌های مختلف متن ارتباط برقرار کند. اگر پرامپت شما شامل چندین سند و درخواست پیچیده است، بهتر است با تکنیک‌هایی مثل Least-to-Most Prompting مسئله را به مراحل کوچک‌تر بشکنید تا هر مرحله در پنجره راحت‌تری پردازش شود.

۳. افزایش احتمال توهم در حاشیه‌ها

وقتی فضای زمینه تنگ است، مدل برای پر کردن شکاف‌ها، به تولید محتوای تخیلی یا نادقیق روی می‌آورد. برای کاهش این ریسک، از استراتژی‌های grounded generation استفاده کنید و خروجی را با ارزیابی مبتنی بر بنچمارک‌های وظیفه‌محور بسنجید.

محدودیت توکن یک قید ظرفیتی نیست؛ یک قید کیفی است. هر توکنی که در ورودی مصرف می‌کنید، بخشی از توان مدل برای استدلال را قرض می‌گیرد.

برش‌خوردگی ورودی و رفتار خاموش مدل

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

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

راهبردهای مدیریت محدودیت توکن

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

الف) بودجه‌بندی صریح

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

ب) قطعه‌بندی معنایی (Semantic Chunking)

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

ج) خلاصه‌سازی تدریجی

برای گفت‌وگوهای طولانی، به‌جای نگه‌داشتن همه پیام‌ها، نسخه خلاصه‌ای از پیشینه نگه دارید. این تکنیک که به‌عنوان rolling summary شناخته می‌شود، در سیستم‌های چت‌بات عملیاتی بسیار مؤثر است.

د) بازیابی هدفمند

در سیستم‌های RAG، تعداد اسناد بازیابی‌شده را بر اساس کیفیت امتیاز شباهت محدود کنید. بازیابی ده سند با امتیاز متوسط، اغلب بدتر از بازیابی سه سند با امتیاز بالا عمل می‌کند.

ه) فشرده‌سازی معنایی

محتوای بازیابی‌شده را قبل از تزریق در پرامپت، با یک مدل کوچک‌تر خلاصه کنید. این روش که گاهی contextual compression نامیده می‌شود، می‌تواند مصرف توکن را تا ۴۰٪ کاهش دهد بدون افت محسوس کیفیت.

تعامل محدودیت توکن با RAG و بازیابی اطلاعات

در معماری RAG (Retrieval-Augmented Generation)، محدودیت توکن نقش تعیین‌کننده‌ای دارد. هر سند بازیابی‌شده حجمی از توکن مصرف می‌کند و این‌جا نمی‌توان بی‌محابا بازیابی کرد. سه تصمیم کلیدی وجود دارد:

  • تعداد اسناد بازیابی‌شده
  • حجم هر سند یا قطعه
  • نحوه ادغام اسناد در پرامپت نهایی

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

قطعه‌بندی هوشمند متن برای عبور از سقف توکن

قطعه‌بندی (Chunking) یکی از تصمیم‌های معماری است که هم بر کیفیت بازیابی و هم بر هزینه اثر می‌گذارد. اندازه قطعه به‌طور معمول بین ۲۰۰ تا ۱۰۰۰ توکن توصیه می‌شود، اما انتخاب دقیق آن به ماهیت متن و نیاز کاربرد بستگی دارد.

استراتژی قطعه‌بندیمناسب براینقطه ضعف
ثابت (Fixed-size)پردازش سریع و سادهبریدن جملات وسط معنا
جمله‌محورمتون ساخت‌یافتهقطعات بسیار کوچک
پاراگراف‌محوراسناد رسمیناهمگونی اندازه
معنایی (Semantic)کیفیت بالاهزینه محاسباتی بیشتر
سلسله‌مراتبیاسناد طولانیپیچیدگی پیاده‌سازی

فشرده‌سازی معنایی پرامپت

فشرده‌سازی پرامپت یعنی کاهش تعداد توکن بدون حذف اطلاعات معنایی کلیدی. سه تکنیک اصلی:

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

اشتباهات رایج در مواجهه با محدودیت توکن

  • نادیده گرفتن تفاوت زبان فارسی و انگلیسی در شمارش توکن
  • طراحی نکردن بودجه توکن برای هر بخش پرامپت
  • اتکا به برش خودکار ورودی در کد واسط
  • افزایش سقف خروجی بدون مدیریت طول ورودی
  • استفاده نکردن از خلاصه‌سازی برای گفت‌وگوهای طولانی
  • بازیابی همه اسناد مرتبط بدون فیلتر بر اساس امتیاز شباهت
  • پرهیز از تست شمارش توکن پیش از ارسال در محیط تولید

مثال‌های عملی و شمارش توکن

شمارش توکن قبل از ارسال، ساده‌ترین و مؤثرترین راه برای پیشگیری از مشکلات است. برای مدل‌های سری GPT می‌توانید از کتابخانه tiktoken استفاده کنید:

import tiktoken

enc = tiktoken.encoding_for_model("gpt-4o")
text = "پرامپت شما این‌جا قرار می‌گیرد"
tokens = enc.encode(text)
print(len(tokens))

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

پرسش‌های پرتکرار درباره محدودیت توکن

محدودیت توکن چقدر بر کیفیت پاسخ اثر می‌گذارد؟

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

آیا می‌توان با خلاصه‌سازی، محدودیت را دور زد؟

خلاصه‌سازی یک راه‌حل مؤثر است اما رایگان نیست؛ بخشی از اطلاعات را حذف می‌کند و اگر خلاصه به‌درستی ساخته نشود، می‌تواند مدل را به مسیر نادرست ببرد.

آیا مدل‌های با پنجره بزرگ‌تر بهتر هستند؟

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

چطور متوجه شوم ورودی من بریده شده است؟

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

آیا برای زبان فارسی محدودیت زودتر می‌رسد؟

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

نگاهی دقیق‌تر به معماری توکن

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

تکنیک‌هایی مانند sliding window attention، پیکربندی مجدد کش و chunked prefill در سطح زیرساخت، به کاهش این فشار کمک می‌کنند، اما در سطح پرامپت، مسئولیت کاهش مصرف توکن بر عهده شماست. اینکه بدانید چه بخشی از پرامپت را می‌توان حذف کرد، یعنی تفاوت بین یک سیستم مقیاس‌پذیر و یک سیستم پرهزینه.

تجربه شما چیست؟

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