LLM Caching
אחת הדרכים הפשוטות לחסוך הרבה כסף ולהאיץ תגובה: לא לשלם פעמיים על אותו חישוב. שלושה סוגי caching ומתי כל אחד.
למה caching חשוב
כל קריאה ל-LLM עולה כסף (לפי טוקנים) וזמן. אבל חלק גדול מהקריאות חוזר על עצמו — אותו system prompt ארוך, אותו הקשר קבוע, או אפילו אותה שאלה שנשאלת שוב ושוב. Caching אומר: חשב פעם אחת, השתמש שוב. התוצאה — חיסכון בעלות (לעיתים עשרות אחוזים) ותגובה מהירה בהרבה.
3 סוגים: Prompt caching (החלק הקבוע בפרומפט), Semantic caching (שאלות דומות), ו-Exact-match (שאלות זהות). כל אחד לתרחיש אחר.
1. Prompt Caching (Context Caching)
ספקי ה-LLM המובילים מאפשרים לשמור במטמון את החלק הקבוע והארוך של הפרומפט — system prompt, הוראות, מסמך הקשר שחוזר בכל קריאה. בקריאות הבאות, החלק הזה לא מחושב מחדש ומחויב בשבריר מהמחיר.
מתי זה זהב: צ'אטבוט עם system prompt ארוך, RAG עם מסמך קבוע, או סוכן ששולח את אותן הוראות שוב ושוב. דוגמה עם Anthropic:
import anthropic
client = anthropic.Anthropic()
resp = client.messages.create(
model="claude-opus-4-8",
max_tokens=1024,
system=[{
"type": "text",
"text": LONG_SYSTEM_PROMPT, # הוראות + הקשר קבוע
"cache_control": {"type": "ephemeral"} # סמן לשמירה במטמון
}],
messages=[{"role": "user", "content": user_question}],
)
# הקריאה הראשונה בונה את המטמון; הבאות משתמשות בו וזולות משמעותית
- שים את החלק הקבוע בהתחלה (המטמון עובד על prefix משותף).
- המטמון בדרך כלל קצר-חיים (דקות) — יעיל לתעבורה רציפה.
- אצל OpenAI זה לרוב אוטומטי לפרומפטים ארוכים חוזרים.
2. Semantic Caching
כאן חוסכים את הקריאה כולה: אם שאלה דומה במשמעות כבר נענתה — מחזירים את התשובה השמורה בלי לקרוא ל-LLM בכלל. משתמשים ב-embeddings: מחשבים וקטור לשאלה, מחפשים במטמון שאלה עם cosine similarity גבוה מסף, ואם נמצא — מחזירים.
def semantic_cache_get(question, cache, threshold=0.92):
q_vec = embed(question)
for entry in cache: # בייצור: vector DB, לא לולאה
if cosine(q_vec, entry["vec"]) >= threshold:
return entry["answer"] # cache hit — בלי קריאה ל-LLM
return None
answer = semantic_cache_get(q, cache)
if answer is None:
answer = call_llm(q) # cache miss
cache.append({"vec": embed(q), "answer": answer, "q": q})
- מתי מעולה: FAQ, תמיכה, שאלות נפוצות שחוזרות בניסוחים שונים.
- סף (threshold) קריטי: גבוה מדי — פספוסים; נמוך מדי — תשובות לא מדויקות. כייל (~0.9+).
- זהירות בהתאמה אישית: אל תחזיר תשובה שמורה כשהתשובה תלויה במשתמש/הקשר ספציפי.
3. Exact-match Caching
הפשוט ביותר: מפתח מטמון = hash של הקלט המלא (פרומפט + פרמטרים). אם בדיוק אותו קלט חוזר — החזר את הפלט השמור. מהיר וזול, אבל תופס רק חזרות מדויקות. טוב למשימות דטרמיניסטיות (טמפרטורה 0) שחוזרות בדיוק.
import hashlib, json
def key(payload): return hashlib.sha256(json.dumps(payload, sort_keys=True).encode()).hexdigest()
k = key({"model":"gpt-5.6","temp":0,"prompt":prompt})
if k in store: return store[k]
out = call_llm(prompt); store[k] = out; return out
פסילת מטמון (Invalidation)
מטמון מיושן = תשובות שגויות. נהל אותו:
- TTL: תפוגה אוטומטית (שעות/ימים) לפי כמה המידע משתנה.
- גרסת תוכן: אם עדכנת את מאגר הידע/הפרומפט — פסול מטמון רלוונטי (למשל שלב גרסה במפתח).
- אל תשמור מידע רגיש/אישי במטמון משותף.
טעויות נפוצות
- Semantic cache עם סף נמוך מדי. מחזיר תשובה של שאלה "כמעט דומה" ופוגע בדיוק.
- לשמור תשובות תלויות-משתמש במטמון גלובלי — לקוח אחד יראה תשובה של אחר.
- מטמון בלי TTL. תשובות מתיישנות והופכות שגויות.
- לשים את החלק הדינמי בהתחלה. שובר prompt caching — הקבוע צריך להיות ה-prefix.
- לשכוח למדוד hit rate. בלי מדידה לא יודעים אם ה-cache בכלל עוזר.
הצעד הבא
Caching הוא חלק מבקרת עלות רחבה. שלב אותו עם ניתוב מודלים ותמחור חכם.