بسیاری از تیمهای توسعه پس از راهاندازی سامانههای مبتنی بر مدلهای زبانی (LLM) یا خطوط لولهی RAG متوجه میشوند که هزینهی فراخوانی API به شکل سرسامآوری رشد میکند، بدون اینکه کارایی سیستم تغییری کرده باشد. فعال کردن کش پرامپت (Prompt Caching) روی کاغذ ساده به نظر میرسد، اما تلههای رایجی مثل قرار دادن متغیرهای پویا (مانند تاریخ لحظهای یا شناسه درخواست) در پرامپت سیستم، نرخ اصابت (Hit Rate) را تا مرز صفر پایین میآورند و فاکتور نهایی را دستنخورده باقی میگذارند.
از طرف دیگر، با توجه به اینکه کارتهای بانکی ایرانی امکان پرداخت مستقیم به سرویسهایی مثل OpenAI و Anthropic را ندارند و شارژ حسابهای خارجی با چالشهای ارزی همراه است، هدررفت توکن به معنای تحمیل هزینههای سنگین و غیرضروری به پروژههاست. شناخت تفاوت معماری کش لایهی L1 (کش معنایی در سطح برنامه) و L2 (کش پیشوند در سطح ارائهدهنده) اولین گام برای کنترل این مخارج است.
در این درس یاد میگیرید که چگونه ساختار پرامپتهای خود را اصلاح کنید، از خطای کشنده موازیسازی ناهمگام اجتناب ورزید و با اعمال الگوهای استاندارد کش، تا 90 درصد در هزینهی ورودی توکنها و 85 درصد در تاخیر پاسخدهی صرفهجویی کنید.
اسنپشات قیمتها مربوط به تاریخ 04-2026 است. ادعاهای عددی زیر بر اساس تعرفههای ارائهدهندگان در زمان انتشار این درس ثبت شدهاند؛ پیش از استناد به آنها در مراحل بعدی، حتماً با مستندات لینکشده بررسی مجدد انجام دهید.
کش کردن در دو لایه اتفاق میافتد. لایهی L2 (در سطح ارائهدهنده) با عنوان کش پیشوند/پرامپت، مقادیر KV اتنشن را برای پیشوندهای تکراری مجدداً استفاده میکند — مستندات کش کردن پرامپت Anthropic تا 90% کاهش هزینه و 85% کاهش تاخیر را برای پرامپتهای طولانی وعده میدهد؛ برای Claude 3.5 Sonnet، هزینهی خواندن از کش 0.30 دلار به ازای هر میلیون توکن در برابر 3.00 دلار برای درخواست تازه است، با TTL پنجدقیقهای و هزینهی اضافی نوشتن 2 برابری برای گزینهی TTL یکساعته (docs.anthropic.com، تاریخ 04-2026). کش کردن پرامپت OpenAI بهطور خودکار برای پرامپتهای 1024 توکن یا بیشتر اعمال میشود و برای ورودیهای کششده حدود 90% تخفیف نسبت به ورودی تازه در نظر میگیرد (platform.openai.com، تاریخ 04-2026)؛ نرخ دقیق کش به ازای هر مدل به جدول تعرفهی زنده بستگی دارد. لایهی L1 (در سطح برنامه) با کش معنایی، در صورت تطابق شباهت امبدینگ، مدل زبانی را کاملاً دور میزند. ادعای «دقت 95 درصدی» ارائهدهندگان به درستی پاسخِ منطبق اشاره دارد، نه نرخ اصابت (hit rate) — نرخ اصابت گزارششده در محیط عملیاتی بین 10% (چت آزاد) تا 70% (پرسشوپاسخ ساختاریافته) متغیر است، و برای ایجنتهای صوتی با مجموعهپرامپت ثابت بین 50 تا 80 درصد گزارش شده است؛ هیچیک از ارائهدهندگان خط مبنای رسمی منتشر نکردهاند، بنابراین این ارقام را تلهمتری جامعهی کاربری بدانید نه تضمین قطعی. دامهای محیط عملیاتی: موازیسازی کش را نابود میکند (ارسال N درخواست موازی پیش از تکمیل اولین نوشتن در کش میتواند هزینهها را چند برابر کند)، و وجود محتوای پویا درون پیشوند مانع اصابت به کش میشود. تیم ProjectDiscovery گزارش داده است که با انتقال متن پویا به خارج از پیشوندِ قابل کش، نرخ اصابت را از 7% به 74% رسانده است (11-2025).
نوع درس: یادگیری
زبانها: Python (کتابخانهی استاندارد، شبیهساز سادهی کش دو لایهای)
پیشنیازها: فاز 17 · درس 04 (معماری داخلی موتور سرویسدهی)، فاز 17 · درس 06 (RadixAttention در SGLang)
مدت زمان: حدود 60 دقیقه
اهداف یادگیری
- تمایز قائل شدن میان کش پرامپت/پیشوند L2 (استفادهی مجدد از KV در سمت ارائهدهنده) و کش معنایی L1 (دور زدن LLM در پرامپتهای مشابه).
- درک نشانهگذاری صریح
cache_controlدر Anthropic و دو گزینهی TTL (5 دقیقه در برابر 1 ساعت) به همراه ضرایب قیمتی آنها. - محاسبهی صرفهجویی ماهانهی مورد انتظار بر اساس نرخ اصابت، ترکیب پرامپت/پاسخ و قیمت توکنها.
- شناخت الگوی نامناسب (anti-pattern) موازیسازی که صورتحساب را 5 تا 10 برابر افزایش میدهد و الگوی نامناسب محتوای پویا که نرخ اصابت را به صفر میرساند.
صورت مسئله
قابلیت کش کردن پرامپت را به سرویس RAG خود اضافه میکنید، اما مبلغ صورتحساب تغییری نمیکند. نرخ اصابت را اندازه میگیرید: فقط 7% است. پرامپتهای شما در ظاهر ایستا به نظر میرسند ولی در واقعیت اینطور نیستند — پرامپت سیستم شامل تاریخ فعلی با فرمت دقیقهای، یک شناسهی درخواست (request ID) و چینش تصادفی مثالها برای ایجاد تنوع است. هر درخواست یک ورودی کش جدید مینویسد و خواندن از کش عملاً صفر است.
از طرف دیگر، ایجنت شما به ازای هر سوال کاربر، ده فراخوانی ابزار موازی انجام میدهد. هر ده درخواست پیش از اتمام اولین نوشتن در کش به ارائهدهنده میرسند؛ نتیجه: ده بار نوشتن، صفر بار خواندن. صورتحساب شما 5 تا 10 برابر بیشتر از هزینهای میشود که قرار بود «با کش کردن» بپردازید.
کش کردن یک پروتکل است، نه صرفاً یک فلگ تنظیمی. دو لایه وجود دارد و هر کدام حالتهای شکست متفاوتی دارند.
مفاهیم پایه
لایهی L2 — کش پرامپت/پیشوند در سمت ارائهدهنده
ارائهدهنده مقادیر KV اتنشن را برای پیشوندِ قابل کش ذخیره میکند و در درخواست بعدی که پیشوند یکسانی دارد، دوباره آن را به کار میگیرد. شما یک بار هزینهی نوشتن را میپردازید و خواندنها تقریباً رایگان تمام میشوند.
سرویس Anthropic (سریهای Claude 3.5 / 3.7 / 4): نشانهگذاری صریح با cache_control در درخواست. شما تعیین میکنید کدام بلوکها قابل کش شدن هستند. زمان بقا (TTL): 5 دقیقهای (هزینهی نوشتن 1.25 برابر پایه) یا 1 ساعته (هزینهی نوشتن 2 برابر پایه). خواندن از کش: 0.30 دلار به ازای هر میلیون توکن در Claude 3.5 Sonnet در برابر 3.00 دلار برای ورودی تازه — یعنی 10 برابر ارزانتر (docs.anthropic.com، تا تاریخ 04-2026). نرخها برای هر مدل متفاوت است (Opus/Haiku جداگانه اعلام میشوند)؛ همیشه صفحهی قیمتگذاری زنده را بررسی کنید.
سرویس OpenAI: کش خودکار برای پرامپتهای 1024 توکن یا بیشتر (platform.openai.com، تاریخ 04-2026). هیچ فلگ صریحی وجود ندارد. در تعرفههای فعلی gpt-4o/gpt-5، ورودی کششده حدوداً 10 برابر ارزانتر از ورودی تازه است. نه در مستندات و نه در یادداشتهای انتشار، خط مبنای رسمی برای نرخ اصابت اعلام نشده است؛ گزارشهای جامعهی کاربری در صورت طراحی دقیق پرامپت، اعدادی بین 30 تا 60 درصد را نشان میدهند. برای سنجش وضعیت خودتان، مقدار usage.cached_tokens را پایش کنید.
سرویس Google (مدل Gemini): کش کانتکست از طریق API صریح؛ پنجرهی کانتکست 1 میلیون توکنی باعث میشود صرفهجویی کش کردن باز هم بیشتر به چشم بیاید.
میزبانی شخصی (vLLM، SGLang): در فاز 17 · درس 06 سازوکار RadixAttention را بررسی کردیم — همین الگو روی سختافزار محاسباتی خودتان پیاده میشود.
لایهی L1 — کش معنایی در سطح برنامه
پیش از آنکه اصلاً مدل را فراخوانی کنید، پرامپت را هش و امبدینگ آن را محاسبه میکنید، سپس به دنبال درخواستی مشابه در کش میگردید (شباهت کسینوسی بالاتر از آستانه، معمولاً 0.95 به بالا). در صورت اصابت به کش، همان پاسخ ذخیرهشده را برمیگردانید. در صورت عدم اصابت، مدل را صدا میزنید و خروجی را کش میکنید.
ابزارهای متنباز: Redis Vector Similarity، GPTCache، Qdrant. سرویسهای تجاری: Portkey Cache، Helicone Cache.
ادعای ارائهدهندگان دربارهی دقت، به این معناست که چند درصد از پاسخهای کششده از نظر معنایی درست بودهاند — نه اینکه چند درصد از درخواستها به کش اصابت کردهاند. نرخهای اصابت در محیط عملیاتی:
- چتهای آزاد: 10 تا 15 درصد.
- پرسشوپاسخ ساختاریافته / پشتیبانی: 40 تا 70 درصد.
- پرسشهای حوزهی کدنویسی: 20 تا 30 درصد (تغییرات جزئی مانع اصابت به کش میشوند).
- ایجنتهای صوتی با پرامپتهای تکراری: 50 تا 80 درصد (به دلیل نرمالسازی گفتار روی یک مجموعهی ثابت).
الگوی نامناسب موازیسازی
ایجنت شما 10 فراخوانی ابزار را به شکل موازی اجرا میکند. هر 10 درخواست پرامپت سیستم 4K توکنی یکسانی دارند. در Anthropic، نوشتن در کش به ازای هر درخواست انجام میشود؛ اولین عملیات نوشتن حدود 300 میلیثانیه پس از دریافت پرامپت توسط ارائهدهنده کامل خواهد شد. درخواستهای 2 تا 10 در همان بازهی چند میلیثانیهای میرسند و همگی با عدم اصابت به کش روبهرو میشوند. نتیجه این است که هزینهی اضافی نوشتن را 10 بار پرداخت میکنید، بدون اینکه حتی یک بار از تخفیف خواندن بهرهمند شوید.
راهکار: دستهبندی با اولویتِ درخواست اول — ابتدا درخواست 1 را بهتنهایی بفرستید، سپس به محض پر شدن کش حاصل از درخواست 1، درخواستهای 2 تا 10 را ارسال کنید. این کار 300 میلیثانیه به اولین فراخوانی ابزار اضافه میکند، ولی جلوی هزینهی 5 تا 10 برابری صورتحساب را میگیرد.
الگوی نامناسب محتوای پویا
فرض کنید پرامپت سیستم شما چنین ساختاری دارد:
You are a helpful assistant. The current time is 14:32:17.
User ID: abc123. Today is Tuesday...
هر درخواست کاملاً یکتا میشود. هر درخواست عمل نوشتن را اجرا میکند؛ نرخ اصابت: صفر.
راهکار: هر بخش کاملاً ایستا را به پیشوندِ قابل کش منتقل کنید؛ محتوای پویا را بعد از مرز کش قرار دهید:
[cacheable]
You are a helpful assistant. [rules, examples, instructions]
[/cacheable]
[dynamic, not cached]
Current time: 14:32:17. User: abc123.
تیم ProjectDiscovery با همین شیوه نرخ اصابت کش را از 7% به 74% رساند و جزئیات فنی آن را منتشر کرد.
ترکیب Batch و کش برای پردازشهای شبانه
سرویسهای Batch API (فاز 17 · درس 15) در ازای پاسخدهی 24 ساعته، 50% تخفیف ارائه میدهند. اگر ورودی کششده را هم به آن اضافه کنید، حدود 10 برابر دیگر هزینه کم میشود. پردازشهای شبانهی دستهبندی، برچسبگذاری و تولید گزارش میتوانند با این ترکیب، هزینهها را به حدود 10% حالت همگام و کشنشده برسانند.
اعدادی که باید به خاطر بسپارید
قیمتها در تاریخ 04-2026 از مستندات لینکشدهی شرکتها ثبت شدهاند و معمولاً هر چند ماه یک بار تغییر میکنند — پیش از تکیه بر آنها، دوباره نرخها را بررسی کنید.
- هزینهی خواندن کش در Anthropic: معادل 0.30 دلار به ازای هر میلیون توکن در Claude 3.5 Sonnet، تقریباً 10 برابر ارزانتر از ورودی تازه (docs.anthropic.com).
- هزینهی اضافی نوشتن در کش Anthropic: معادل 1.25 برابر (TTL پنجدقیقهای) یا 2 برابر (TTL یکساعته).
- کش خودکار OpenAI: برای پرامپتهای 1024 توکن یا بیشتر؛ قیمت ورودی کششده طبق تعرفههای فعلی حدود 10% ورودی تازه است (platform.openai.com).
- نرخ اصابت کش معنایی (طبق گزارشهای جامعهی کاربری): حدود 10% در چت آزاد؛ تا حدود 70% در پرسشوپاسخ ساختاریافته؛ 50 تا 80 درصد در ایجنتهای صوتی با مجموعهپرامپت ثابت. این ارقام خط مبنای مستندشده از سوی ارائهدهندگان نیستند.
- گزارش ProjectDiscovery: جهش از 7% به 74% نرخ اصابت با خارج کردن بخش پویا از پیشوند (وبلاگ پروژه، 11-2025).
- الگوی نامناسب موازیسازی: گزارشهای معمول حاکی از افزایش 5 تا 10 برابری صورتحساب در شرایطی است که N درخواست موازی پیش از ثبت اولین کش ارسال شوند.
استفاده در عمل
فایل code/main.py عملکرد کش لایههای L1 و L2 را روی حجمهای کاری ترکیبی شبیهسازی میکند. این اسکریپت نرخهای اصابت، هزینهی کل و اثر منفی موازیسازی نادرست را نشان میدهد.
تحویل به پروداکشن
خروجی این درس سند outputs/skill-cache-auditor.md است. این ابزار با دریافت قالب پرامپت و ترافیک ورودی، میزان کشپذیری را ارزیابی کرده و ساختار بازنویسیشدهی پیشنهادی را ارائه میدهد.
تمرینها
- اسکریپت
code/main.pyرا اجرا کنید. فلگ موازیسازی را تغییر دهید. هزینهی پرداختی چقدر عوض میشود؟ - پرامپت سیستم شما حاوی تاریخ است. آن را خارج کنید. محاسبات نرخ اصابت را قبل و بعد از این کار نشان دهید.
- با توجه به نرخ ورود درخواستها در سیستم خود، نقطهی سربهسر میان TTL یکساعته (هزینهی نوشتن 2 برابر) و TTL پنجدقیقهای (هزینهی نوشتن 1.25 برابر) را محاسبه کنید.
- کش معنایی با آستانهی 0.95 نرخ اصابت 20% دارد. با آستانهی 0.85 این رقم به 50% میرسد اما پاسخهای نامربوط کششده مشاهده میکنید. آستانهی مناسب را انتخاب و دلیل آن را مستند کنید.
- به ازای هر سوال کاربر، 10 زیرپرسوجوی موازی میفرستید. این بخش را طوری بازنویسی کنید که با کش سازگار شود بدون آنکه تاخیر سرتاسری اضافه شود.
اصطلاحات کلیدی
| اصطلاح | در گفتگوها چه میگویند | معنای دقیق فنی |
|---|---|---|
| کش پرامپت L2 | «کش پیشوند» | ذخیرهی مقادیر KV توسط ارائهدهنده برای پیشوندهای تکراری |
cache_control |
«مارکر کش Anthropic» | ویژگی صریح برای مشخص کردن بلوکهای قابل کش |
| هزینهی اضافی نوشتن در کش | «مالیات نوشتن» | هزینهی اضافهی اولین ثبت داده در کش پس از عدم اصابت (1.25 یا 2 برابر) |
| کش معنایی L1 | «کش امبدینگی» | هش و امبد کردن درخواست در سطح برنامه پیش از فراخوانی LLM |
| GPTCache | «کتابخانهی کش LLM» | کتابخانهی متنباز محبوب برای کش معنایی لایهی L1 |
| نرخ اصابت کش | «تعداد اصابت / کل» | نسبت درخواستهایی که مستقیماً از طریق کش پاسخ داده شدهاند |
| الگوی نامناسب موازیسازی | «تلهی N بار نوشتن» | حالتی که در آن N درخواست موازی، N بار به عدم اصابت به کش میخورند |
| تلهی محتوای پویا | «تلهی تاریخ در پرامپت» | بایتهای متغیر درون پیشوند که نرخ اصابت را بهکلی از بین میبرند |
| RadixAttention | «کش دروننمونهای» | پیادهسازی کش پیشوند در کتابخانهی SGLang |
برای مطالعهی بیشتر
- Anthropic Prompt Caching — مستندات رسمی دربارهی رفتار
cache_controlو بازههای TTL. - OpenAI Prompt Caching — رفتار کش خودکار و شرایط واجد شرایط بودن پرامپتها.
- TianPan — Semantic Caching for LLMs Production
- ProjectDiscovery — Cut LLM Costs 59% With Prompt Caching
- DigitalOcean / Anthropic — Prompt Caching
