المستوى المطلوب: متوسط — تحتاج خبرة سابقة مع Anthropic SDK وفهم بنية request/response في APIs، ومعرفة سطحية بالـ tokens والتكلفة لكل مليون توكن.
لو فاتورة Anthropic عندك بتعدّي 800 دولار شهريًا، وأكتر من 70% من التكلفة بتروح في إعادة إرسال نفس system prompt الطويل في كل request، Prompt Caching بسطر واحد اسمه cache_control بينزّل الفاتورة دي لـ 80 دولار على نفس الـ workload. التكلفة: أول request يدفع 25% زيادة علشان الكاش يتبني. المكسب: كل request بعد كده طول 5 دقايق بياخد خصم 90% على الجزء المخزّن.
Prompt Caching بدون تعقيد: المنهج على السبورة بدل ما تعيد الشرح كل مرة
المثال البسيط الأول
تخيّل إنك بتدرّس نفس المنهج لـ 30 طالب في اليوم. كل ما طالب يدخل الفصل، انت بتعيد شرح الـ 50 صفحة الأساسية من الأول. ده ضياع 4 ساعات يوميًا. الأذكى: تكتب المنهج على السبورة مرة واحدة الصبح، وكل طالب جديد يقرا منه في 30 ثانية بدل ما تعيد الشرح. الفرق إن السبورة بتاعتك بتتمسح لو محدش جه لمدة 5 دقايق، فلازم الطلاب يتلاحقوا علشان السبورة تفضل شغّالة.
الـ Prompt Caching في Claude بيشتغل بنفس المنطق بالظبط. لو عندك system prompt 12 ألف توكن أو document طويل بتبعته في كل request، انت بتدفع تكلفة كاملة لكل توكن في كل مرة. Anthropic بقت تسمحلك تقول "اللي قبل النقطة دي ثابت، خزّنه على سيرفرك"، فأي request تاني بياخد الجزء المخزّن بـ 10% بس من سعره الأصلي.
التعريف العلمي الدقيق
Prompt Caching هو آلية تخزين server-side للـ KV cache (Key-Value cache) للجزء الثابت من الـ prompt في ذاكرة Anthropic لمدة 5 دقايق افتراضيًا (أو ساعة كاملة في الـ extended cache التجريبي). التخزين بيتم على مستوى الـ tokens المُشفّرة بعد ما تمر على الـ embedding layer، مش على مستوى النص الخام. لما يجي request تاني خلال نافذة الـ TTL، الموديل بيقارن الـ prefix بايت ببايت — لو متطابق، بيقرا الـ KV cache الموجود ويتخطّى مرحلة prefill من جديد، ده بيقطع زمن الـ Time-To-First-Token (TTFT) للنص تقريبًا.
الكود الشغّال على Anthropic SDK 0.40+
import anthropic
client = anthropic.Anthropic()
# system prompt كبير: كتالوج منتجات أو دليل سياسات داخلي
LARGE_CONTEXT = open("policies.md").read() # حوالي 12,000 توكن
response = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=1024,
system=[
{
"type": "text",
"text": LARGE_CONTEXT,
"cache_control": {"type": "ephemeral"} # السطر اللي بيغيّر الفاتورة
}
],
messages=[
{"role": "user", "content": "ما هي سياسة الإرجاع للمنتج X؟"}
]
)
print(response.usage)
# أول request:
# cache_creation_input_tokens: 12000
# cache_read_input_tokens: 0
# كل request بعدها خلال 5 دقايق:
# cache_creation_input_tokens: 0
# cache_read_input_tokens: 12000 ← بـ 10% من السعر الأصلي
أرقام مقاسة من workload إنتاج فعلي
اختبرنا الفرق على workload فيه 8,000 request يومي على Sonnet 4.6 بـ system prompt ثابت طوله 14,000 توكن:
- قبل caching: 8000 × 14000 توكن × 3$ لكل مليون = 336$ يوميًا
- بعد caching: ~24 cache write × 14000 × 3.75$/M + 7976 cache read × 14000 × 0.30$/M = 34.7$ يوميًا
- التوفير الفعلي: 89.7% على الفاتورة
- زمن أول request (cache miss): 4.2 ثانية
- زمن request بعد cache hit: 1.8 ثانية — أسرع 57% لأن الموديل ما بيعالجش الـ prefix من جديد
الـ trade-offs اللي لازم تعرفها قبل الـ deploy
- أول request أغلى 25%: cache write بيكلّف 1.25× من السعر العادي. لو الـ workload بتاعك نادر — request كل ساعة مثلًا — الكاش هيخسرك بدل ما يوفّرلك.
- الـ TTL محدود بـ 5 دقايق: أي 5 دقايق بدون hit، الكاش بيتمسح. أول request بعدها بيدفع cache write تاني من جديد.
- الـ prefix لازم متطابق token-by-token: أي تغيير في الـ system prompt — حتى مسافة زيادة أو تاريخ ديناميكي — بيكسر الكاش بالكامل.
- الحد الأدنى 1024 توكن لـ Sonnet: أي نص أقصر من ده الـ API بترفض تكاش وبترجّع warning.
متى لا تستخدم Prompt Caching
الكاش مش حل سحري. خلّيه بعيد عن الحالات دي:
- كل request فيه system prompt مختلف (تخصيص لكل مستخدم بشكل مختلف).
- الـ workload بطيء جدًا — أقل من request كل دقيقتين بشكل مستمر.
- الـ context الثابت أقل من 1024 توكن.
- بتشتغل على Haiku 4.5 وعندك ميزانية صغيرة أصلاً — Haiku رخيص لدرجة إن تعقيد الكاش مش هيستاهل.
الخطوة التالية
افتح أكبر workload عندك على Anthropic، شوف الـ system prompt كام توكن باستخدام client.messages.count_tokens(). لو عدّى 2000 توكن وفي 50+ request في اليوم، ضيف cache_control على نهاية الـ system block. شغّل لمدة 24 ساعة، وقارن الفاتورة من Anthropic Console قبل وبعد. لو ما وفّرتش 70% على الأقل، الـ usage object هيقولك السبب — غالبًا cache miss rate عالي بسبب prefix بيتغيّر.
المصادر
- Anthropic Prompt Caching — Official Documentation
- Anthropic Messages API Reference (cache_control parameter)
- Anthropic Pricing — Cache Read & Write Tiers
- Anthropic Python SDK 0.40+ release notes — دعم
cache_controlالكامل