Claude API Mastery, Streaming, Caching ו-Tool Use

📚 תת-סוכנים, Multi-Agent Systems ⏱️ 14 דק׳ 🎓 מתקדם ✓ חינם לגמרי
Claude API Mastery, Streaming, Caching ו-Tool Use

🛠️ שיעור למתקדמים, דורש ידע ב-Python ו-API. אם אתה מתחיל, דלג ועבור ל-lesson 30b לסיום הקורס.

💡 בשיעור הקודם, שיעור 29: בניית AI Agents אוטונומיים עם Claude, בנית agent שפועל בלולאה עצמאית, משתמש בכלים ומגיע לתוצאות בלי התערבות ידנית. עכשיו נשלים את התמונה: שלוש טכניקות ה-API שהופכות כל אותו קוד ל-product שמחזיק בפרודקשן.

מעבר ל-API הבסיסי, למה זה חשוב לך בתור מפתח

רוב המפתחים מתחילים עם Claude API בקריאה אחת: messages.create, מחכים לתשובה מלאה, מציגים אותה. זה עובד, אבל ב-production מרגיש כמו אפליקציה מגושמת. המשתמש מחכה 8 שניות לפני שרואה את המילה הראשונה. עלות ה-API מצטברת מהר. כל request חוזר ושולח את אותן 5,000 מילות system prompt.

שלוש הטכניקות בשיעור הזה, Streaming, Prompt Caching, Tool Use, הן ההבדל בין דמו ל-product. סטארטאפ ת"א שמפעיל chatbot תמיכה ל-50,000 משתמשים לא יוכל לשלם $18,000 בחודש על input tokens כשאפשר לשלם $1,800.

Streaming, כל מילה ברגע שנוצרת

Streaming מעביר את הטקסט של Claude למשתמש מילה-מילה דרך Server-Sent Events (SSE), בלי לחכות שהתשובה תסתיים. "A 2-second response that streams feels 3x faster than a 2-second response that appears all at once", כך מנסחים את זה במסמכי Anthropic.

שלושה כללים קריטיים ל-SSE שמפתחים מפספסים:

import anthropic

client = anthropic.Anthropic()

# Streaming בסיסי ב-Python
with client.messages.stream(
    model="claude-sonnet-4-20250514",
    max_tokens=1024,
    messages=[{"role": "user", "content": "הסבר מה זה RAG ב-4 משפטים"}]
) as stream:
    for text in stream.text_stream:
        print(text, end="", flush=True)

# TypeScript, SSE endpoint ב-Express
// res.setHeader('Content-Type', 'text/event-stream');
// res.setHeader('Cache-Control', 'no-cache');
// res.setHeader('X-Accel-Buffering', 'no');
// const stream = await client.messages.stream({ ... });
// for await (const event of stream) {
//   if (event.type === 'content_block_delta') {
//     res.write(`data: ${JSON.stringify({text: event.delta.text})}\n\n`);
//   }
// }
// res.end();

שאלה נפוצה: האם streaming עולה יותר? לא. כמות הטוקנים זהה, רק אופן המסירה שונה. Streaming לא חוסך כסף, אבל מספק חוויית משתמש טובה בהרבה.

Prompt Caching, 90% הנחה על input tokens

אם ה-system prompt שלך מכיל 4,000 טוקנים (כ-3,000 מילים), וכל request שולח אותו מחדש, אתה משלם פי 4,000 יותר ממה שצריך. Prompt Caching שומר את ה-prefix הקבוע בזיכרון של Anthropic וגובה 90% הנחה על כל קריאה שמשתמשת בו.

import anthropic

client = anthropic.Anthropic()

# System prompt ארוך שנשאר קבוע בין בקשות
long_system = """אתה נציג שירות לקוחות של חברת PropTech ישראלית.

קטלוג נכסים:
- פרויקט A: דירות בתל אביב, 3-5 חדרים, 2.8-4.5M ש"ח...
- פרויקט B: בתים בהרצליה, 5-7 חדרים, 3.5-6M ש"ח...
[... 3000 מילים נוספות של פרטי נכסים ומדיניות ...]
"""

# הפעלת caching, שים לב ל-cache_control
response = client.messages.create(
    model="claude-sonnet-4-20250514",
    max_tokens=1024,
    system=[
        {
            "type": "text",
            "text": long_system,
            "cache_control": {"type": "ephemeral"}  # <- מפעיל caching!
        }
    ],
    messages=[{"role": "user", "content": "יש לכם דירות בתל אביב מתחת ל-3M?"}]
)

# ניטור ביצועי cache
print(f"Cache creation: {response.usage.cache_creation_input_tokens}")  # בקשה ראשונה
print(f"Cache read:     {response.usage.cache_read_input_tokens}")       # בקשות הבאות

עדכון קריטי: ה-TTL ירד מ-60 דקות ל-5 דקות (מרץ 2026)

ב-6 במרץ 2026 Anthropic שינתה את ה-TTL של prompt cache מ-60 דקות ל-5 דקות, ללא הודעה, ללא changelog. עבור אפליקציות production, זה אומר שהפסקה של יותר מ-5 דקות בשיחה מאפסת את ה-cache וגורמת לתשלום מחיר ה-creation מחדש (25% יותר מה-base). ה-GitHub issue #46829 בפרויקט Claude Code תיעד עלייה של 20-32% בעלויות cache creation.

שלושה כללים שמפחיתים את ה-נזק:

השוואת עלויות, עם ובלי Caching

תרחיש בלי Cache עם Cache חיסכון
System prompt 4K tokens, 100 בקשות 400K input tokens 4K + 99x0.4K = ~44K ~89%
RAG context 8K tokens, 50 בקשות 400K input tokens 8K + 49x0.8K = ~47K ~88%
Multi-turn chat, system 2K tokens מצטבר בכל turn system + history cached 50-80%

Tool Use, Claude קורא לפונקציות שלך

Tool Use מאפשר ל-Claude לומר לך "אני צריך לקרוא ל-API חיצוני", ואתה מריץ את הקריאה ומחזיר את התוצאה. זה שונה ממיצוי JSON: כאן Claude מנהל לולאה של פעולות שמסתיימת כשהוא מרגיש שיש תשובה מלאה.

הלולאה תמיד זהה: שלח request עם tools → קבל tool_use block → הרץ את הפונקציה → שלח tool_result → Claude ממשיך.

import anthropic, json

client = anthropic.Anthropic()

# דוגמה: חיפוש דירות לסוכן נדל"ן ישראלי
tools = [{
    "name": "search_properties",
    "description": "חיפוש נכסים למכירה לפי עיר ותקציב",
    "input_schema": {
        "type": "object",
        "properties": {
            "city": {"type": "string", "description": "שם העיר בעברית"},
            "max_price_ils": {"type": "number", "description": "מחיר מקסימלי בשקלים"}
        },
        "required": ["city", "max_price_ils"]
    }
}]

response = client.messages.create(
    model="claude-sonnet-4-20250514",
    max_tokens=1024,
    tools=tools,
    messages=[{"role": "user", "content": "מחפש דירה בחיפה עד 2.5 מיליון"}]
)

for block in response.content:
    if block.type == "tool_use":
        print(f"Claude קורא ל: {block.name}")
        print(f"פרמטרים: {block.input}")
        # {"city": "חיפה", "max_price_ils": 2500000}

        results = search_properties_db(block.input["city"], block.input["max_price_ils"])

        # הלולאה: מחזירים תוצאה ל-Claude
        final = client.messages.create(
            model="claude-sonnet-4-20250514",
            max_tokens=1024,
            tools=tools,
            messages=[
                {"role": "user", "content": "מחפש דירה בחיפה עד 2.5 מיליון"},
                {"role": "assistant", "content": response.content},
                {"role": "user", "content": [{
                    "type": "tool_result",
                    "tool_use_id": block.id,
                    "content": json.dumps(results, ensure_ascii=False)
                }]}
            ]
        )
        print(final.content[0].text)

טעות נפוצה: מפתחים מניחים שהאינטראקציה נגמרת בקריאה אחת לכלי. לא, Claude עשוי לקרוא לכלים מספר פעמים עד שמצטייר לו תמונה מלאה. צריך ללפף את הלולאה עד ש-stop_reason == "end_turn".

Message Batches, עיבוד המוני ב-50% הנחה

כשצריך לעבד 1,000 תיאורי נכסים, 10,000 מיילי לקוחות, או להריץ evaluation על 500 תגובות, Batches API מאפשר שליחה של כל הבקשות בבת אחת, מחכה עד 24 שעות, ומחזיר תוצאות ב-50% מחיר. לא מתאים ל-real-time, מתאים מאוד לתהליכי background.

import anthropic

client = anthropic.Anthropic()

# לדוגמה: סיכום אוטומטי של 500 דוחות לקוחות מ-CRM
requests = [
    {
        "custom_id": f"report_{i}",
        "params": {
            "model": "claude-haiku-3-5-20241022",  # Haiku מספיק לסיכום
            "max_tokens": 256,
            "messages": [{"role": "user", "content": f"סכם בשלוש שורות:\n{report}"}]
        }
    }
    for i, report in enumerate(crm_reports)
]

batch = client.batches.create(requests=requests)
print(f"Batch ID: {batch.id}")

# בדיקת סטטוס אחרי שעה
result = client.batches.retrieve(batch.id)
print(f"הושלמו: {result.request_counts.succeeded}/{result.request_counts.total}")
24 שעות
60 דקות
5 דקות (שונה ממרץ 2026)
ללא הגבלה

🎉 סיימת את הקורס!

עברת את כל 30 שיעורי הקורס. עכשיו יש לך את הכלים לעבוד עם Claude ברמה מקצועית, API, Agents, Tool Use, ו-Streaming. הצעד הבא: בנה פרויקט אמיתי.

רוצה ללמוד עם מעקב התקדמות, קוויזים ותעודה?

כל 130 השיעורים פתוחים בחינם, כולל נגן אינטראקטיבי, שמירת התקדמות ותעודה דיגיטלית בסיום.