ההבדל בין agent שעולה $100 ביום ל-agent שעולה $10 ביום הוא לעתים קרובות רק prompt caching.

- חוכמת שוק

מילון מונחים

לפני שנצלול לעומק, בואי נבין את המונחים הבסיסיים:

Prefix (קידומת)

Prefix זה החלק ההתחלתי של ה-prompt שלך - כל מה שבא לפני ההודעה האחרונה של המשתמש.

תחשבי על זה כמו כתובת: “ישראל, תל אביב, רחוב דיזנגוף” - כל רמה היא prefix של מה שאחריה.

ב-prompt, ה-prefix כולל: system prompt, הגדרות tools, היסטוריית שיחה - כל מה שקבוע ולא משתנה בין requests.

Hash (גיבוב)

Hash זו פונקציה מתמטית שלוקחת טקסט בכל אורך ומחזירה “טביעת אצבע” קצרה וייחודית.

"Hello World" → hash → "abc123"
"Hello World!" → hash → "xyz789" // סימן קריאה אחד שינה הכל!

ה-hash משמש כמפתח לזיהוי: אם שני prompts מייצרים את אותו hash, הם זהים לחלוטין.

Cache Write vs Cache Read

Cache Write קורה בפעם הראשונה ששולחים prompt מסוים - עולה 1.25x אבל זו השקעה חד-פעמית.

Cache Read קורה כששולחים prompt עם prefix זהה - עולה רק 0.1x, עשירית מהמחיר!

הבעיה

כל API call ל-Claude עושה את אותו הדבר: שולח tokens, מחכה לתשובה. אבל מה שקורה בפנים זה לא טריוויאלי.

User sends: "What's the weather in Tel Aviv?"

API receives:
┌─────────────────────────────────────────────┐
│ System: "You are a helpful assistant..."    │ 2,000 tokens
│ Tools: [get_weather, search, ...]           │ 5,000 tokens
│ History: [previous 10 turns]                │ 8,000 tokens
│ User: "What's the weather in Tel Aviv?"     │ 10 tokens
└─────────────────────────────────────────────┘
                                      Total: 15,010 tokens

המודל צריך לעבד את כל ה-15,010 tokens לפני שהוא יכול להתחיל לייצר תשובה.

בלי caching vs עם caching

בלי: שוב מעבדים 15,000+ tokens.

עם: מעבדים רק את ה-tokens החדשים!

בדיוק כמו שלא צריך להסביר מחדש מי את בכל פעם שמתקשרים לחברה טובה - גם ה-agent שלך לא צריך “לקרוא” מחדש את ה-system prompt וה-tools בכל request.

מה זה KV Cache?

כדי להבין prompt caching, צריך להבין מה קורה בתוך Transformer.

1

Prefill - העיבוד היקר

כשה-prompt נכנס, כל token עובר דרך כל שכבה של המודל. בכל שכבה, מחושבים שני וקטורים: Key ו-Value.

Key = “מה אני מייצג?”

Value = “מה התוכן שלי?”

זה החלק היקר. עבור prompt של 100K tokens ומודל עם 80 שכבות, מחשבים 16 מיליון וקטורים.

2

Generation - היצירה הזולה

אחרי ה-prefill, המודל מייצר token אחד בכל פעם. כל token חדש דורש רק חישוב KV אחד (שלו), ואז attention על כל ה-KVs הקיימים.

3

The Caching Insight

הרעיון המרכזי: ה-KV pairs של prefix קבוע לא משתנים בין calls.

Call 1:
[System + Tools] → compute KV pairs → STORE IN CACHE
[History + User] → compute KV pairs → generate response

Call 2:
[System + Tools] → LOAD FROM CACHE (skip computation!)
[New History + User] → compute KV pairs → generate response

Prompt caching = לשמור את ה-KV cache של prefix קבוע ולהשתמש בו שוב.

איך ה-Cache עובד

Prefix Hashing

ה-cache עובד על בסיס prefix matching. המפתח הוא hash של כל ה-tokens עד נקודת ה-cache:

"You are helpful" + "Tools: ..." → hash: abc123
"You are helpful" + "Tools: ..." + " extra" → hash: def456 (שונה!)

כל שינוי ב-prefix, גם תו אחד, יוצר hash אחר = cache miss.

סדר ה-Hierarchy

Claude מחייב סדר קבוע: tools → system → messages

כל שינוי ב-level גבוה יותר שובר את ה-cache של כל מה שאחריו:

שינויtools cachesystem cachemessages cache
הוספת toolנשברנשברנשבר
שינוי systemתקיןנשברנשבר
הודעה חדשהתקיןתקיןנשבר
במילים פשוטות

זה כמו בניין. אם משנים את היסודות (tools), כל הקומות שמעל קורסות. אם משנים רק את הקומה האחרונה (messages), היסודות והקומות הביניים נשארים שלמים.

השימוש ב-API

response = client.messages.create(
    model="claude-sonnet-4-5",
    system=[
        {
            "type": "text",
            "text": "You are Beauty Intel - a trend scout...",
            "cache_control": {"type": "ephemeral"}  # ← נקודת cache
        }
    ],
    tools=[
        {
            "name": "search_trends",
            "description": "...",
            "input_schema": {...},
            "cache_control": {"type": "ephemeral"}  # ← cache כל ה-tools
        }
    ],
    messages=[...]
)

cache_control: {"type": "ephemeral"} אומר: “שמור את כל מה שעד לכאן ב-cache”.

מה חוזר ב-Response

# Call ראשון (cache write):
# cache_creation_input_tokens: 7000  ← נכתב ל-cache
# cache_read_input_tokens: 0

# Call שני (cache hit):
# cache_creation_input_tokens: 0
# cache_read_input_tokens: 7000  ← נקרא מ-cache!

TTL: ברירת מחדל 5 דקות. כל cache hit מרענן את הזמן.

דפוסים בעולם האמיתי

Claude Code Incremental Conversation Caching

┌─────────────────────────────────────┐
│ System prompt (~3K tokens)          │ ← cached
│ CLAUDE.md contents                  │ ← cached
│ Tool definitions (50+ tools)        │ ← cached
├─────────────────────────────────────┤
│ Conversation history                │ ← incrementally cached
│ Current user message                │ ← not cached
└─────────────────────────────────────┘

כל turn מוסיף cache breakpoint בסוף ה-history, כך שה-turn הבא יכול לקרוא את כל מה שלפניו.

למה זה עובד

בשיחה עם Claude Code, רוב ה-context נשאר קבוע. רק ההודעה האחרונה היא חדשה. במקום לעבד 50K+ tokens בכל turn, מעבדים רק את ההודעה החדשה.

Cursor File Content Caching

Cursor caches את תוכן הקבצים לצורך autocomplete:

Request 1: Complete code in file.py
  - Cache: file.py content (2000 tokens)

Request 2: Complete code in file.py (user typed more)
  - Cache HIT on file.py content
  - Only process: new cursor position + recent edits

זה מה שנותן להם autocomplete מהיר מאוד.

למה זה עובד

כשאת כותבת קוד, הקובץ לא משתנה דרמטית בין הקשות. Cursor שומר את תוכן הקובץ ב-cache, וכל הקשה מעבדת רק את השינוי הקטן.

RAG Long Document Caching

הסיטואציה: יש לך מסמך ארוך (חוזה, מדריך, ספר) ואת רוצה לשאול עליו שאלות.

system = [
    {"type": "text", "text": "You analyze legal documents..."},
    {
        "type": "text",
        "text": entire_contract,  # 100K tokens
        "cache_control": {"type": "ephemeral", "ttl": "1h"}
    }
]

# שאלה 1: "What are the termination clauses?"
# שאלה 2: "What about liability limits?"
# שאלה 3: "Summarize payment terms"

# כל שאלה משלמת 0.1x על 100K ה-tokens של החוזה
למה זה עובד

במקום לשלוח את כל המסמך בכל שאלה, שולחים אותו פעם אחת עם TTL של שעה. כל שאלה אחר כך משלמת רק 10% על המסמך. 10 שאלות = חיסכון של 90%.

כלכלת Tokens

פעולהעלות
Cache write (5min TTL)1.25x base
Cache write (1hr TTL)2.00x base
Cache read0.10x base
Regular input1.00x base

Break-Even Analysis

נניח 10K tokens cached, Sonnet 4.5 ($3/MTok):

ללא caching:
  Call 1: 10K × $3/MTok = $0.030
  Call 2: 10K × $3/MTok = $0.030
  Call 3: 10K × $3/MTok = $0.030
  Total: $0.090

עם caching:
  Call 1: 10K × $3.75/MTok = $0.0375 (cache write)
  Call 2: 10K × $0.30/MTok = $0.003  (cache read)
  Call 3: 10K × $0.30/MTok = $0.003  (cache read)
  Total: $0.0435

חיסכון: 52%

Break-even: 2 calls. מהשלישי ואילך את ברווח.

Latency Savings

ה-prefill phase הוא O(n²) על מספר ה-tokens. עבור 100K tokens:

ללא caching: 5-15 שניות TTFT (time to first token)

עם caching: פחות משנייה TTFT

זה לפעמים חשוב יותר מהכסף - UX של agent שמגיב מיד vs. אחד שמחכה 10 שניות.

טעויות נפוצות

מתחת לסף המינימום

Caching דורש 1024-4096 tokens מינימום לפי המודל. פחות מזה = לא נשמר.

שינויים שוברים cache

שינוי tool definitions, הוספת תמונות, שינוי extended thinking - כל אלה שוברים.

Concurrent requests

Cache זמין רק אחרי response ראשון. 10 requests במקביל = 10 cache writes.

JSON key ordering

בשפות כמו Go/Swift סדר keys אקראי. זה משנה את ה-hash = cache miss.


מקורות: