Prompt Caching للمتوسط: نزّل فاتورة Claude API بـ 90% بسطر واحد
مستوى المقال: متوسط — يتطلّب معرفة سابقة بـ Claude API أو أي LLM API، ومفهوم الـ system prompt والـ tokens. لو لسه بتبدأ، اقرا مقال "البدء مع Claude API" الأول.
لو chatbot شركتك بيرجّع system prompt من 12 ألف توكن في كل طلب وفاتورة Claude API بقت $4,200 في الشهر، انت بتدفع 90% منهم زيادة. سطر cache_control واحد في الـ payload بينزّل الفاتورة لـ $487 على نفس workload، بدون ما تلمس حرف في الكود التاني.
المشكلة باختصار
في كل API call لـ Claude بترسل نفس الـ system prompt الطويل، ونفس تعريفات الـ tools، ونفس الـ few-shot examples. سيرفر Anthropic بيقرا كل توكن من الأول كل مرة، وانت بتدفع full input price على بيانات ابعتّها قبل 30 ثانية بالظبط. ركز في الجزئية دي: نفس الـ 12,000 توكن بتترسل 50 ألف مرة في اليوم. الفاتورة بتطلع زي ما هي 50 ألف ضعف لمحتوى ثابت تماماً.
المفهوم بمثال بسيط
تخيّل إنك مدرّس بتشرح نفس قواعد اللعبة لـ 200 طالب جديد كل يوم. أول طريقة (الطريقة الغلط): تقعد تشرح القواعد من الأول لكل طالب لوحده — هتموت. أفضل طريقة: تسجّل الشرح في فيديو واحد وتعرضه، وتركّز انت في إجابة أسئلة كل طالب الخاصة. الفيديو ده هو الـ cache. الـ "قواعد اللعبة" هي الـ system prompt الثابت. السؤال الخاص بكل طالب هو الـ user message المتغيّر.
Anthropic Prompt Caching بيشتغل بالظبط بنفس المنطق على مستوى الـ infrastructure. انت بتحط breakpoint في الطلب يقول "كل اللي قبل النقطة دي ثابت، خزّنه". أول طلب بيدفع 25% زيادة على الـ input price (cache write)، وكل طلب بعد كده في الـ 5 دقائق التالية بيدفع 10% فقط من سعر الـ input على الجزء المخزّن. توفير صافي يقترب من 90%.
الشرح العلمي الدقيق
وفقاً لـ Anthropic Prompt Caching Documentation الرسمية، الـ infrastructure بتولّد hash من الـ tokens قبل الـ cache breakpoint. الـ hash ده بيتربط بمكان فيه الـ KV cache (key-value tensors) للـ tokens دي محفوظة على GPU memory مشتركة. لمّا يجي طلب تاني بنفس الـ prefix بالحرف، الـ infrastructure بترجع للـ KV cache الجاهز بدل ما تعمل forward pass من الأول.
الـ TTL الافتراضي 5 دقائق، وبيمتد كل ما يحصل cache hit. في 2024 أضافت Anthropic extended cache بـ ساعة كاملة بسعر 2× على الـ cache write. الافتراض هنا إن الـ traffic بتاعك متتالي (sustained)؛ لو الـ traffic عشوائي ومتباعد، الـ cache بيموت قبل أي استفادة.
الكود التنفيذي
مثال عملي لـ chatbot ببرومبت 12K توكن. لاحظ السطر الوحيد المتغيّر:
from anthropic import Anthropic
client = Anthropic()
with open("system_prompt_12k.txt") as f:
SYSTEM_PROMPT = f.read() # حوالي 12,000 توكن
response = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=1024,
system=[
{
"type": "text",
"text": SYSTEM_PROMPT,
"cache_control": {"type": "ephemeral"} # <-- السطر السحري
}
],
messages=[
{"role": "user", "content": "سعر iPhone 17 بعد خصم العميل الذهبي؟"}
]
)
print(response.usage)
# المخرج المتوقع بعد أول طلب:
# cache_creation_input_tokens: 12,043
# cache_read_input_tokens: 0
# input_tokens: 18
#
# المخرج المتوقع في الطلب التاني (خلال 5 دقائق):
# cache_creation_input_tokens: 0
# cache_read_input_tokens: 12,043
# input_tokens: 18