🛠️ שיעור למתקדמים, דורש ידע ב-Python ו-API. אם אתה מתחיל, דלג ועבור ל-lesson 30b לסיום הקורס.
מעבר ל-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 שמפתחים מפספסים:
- header:
Content-Type: text/event-stream, בלי זה הדפדפן מחכה לתשובה מלאה - header:
Cache-Control: no-cache, מונע buffer של proxy - header:
X-Accel-Buffering: no, חובה אם Nginx עומד מול ה-server שלך, אחרת 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.
שלושה כללים שמפחיתים את ה-נזק:
- הוצא תוכן דינמי מחוץ ל-prefix הממוכן, timestamps, שם המשתמש, תאריך, שים אותם ב-user message, לא ב-system prompt
- נטר את היחס
cache_read / cache_creationבכל request, יחס מתחת ל-5 אומר שה-cache לא עובד - Workspace isolation, מ-5 בפברואר 2026 caches מבודדים לפי workspace, לא לפי organization
השוואת עלויות, עם ובלי 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}")
🎉 סיימת את הקורס!
עברת את כל 30 שיעורי הקורס. עכשיו יש לך את הכלים לעבוד עם Claude ברמה מקצועית, API, Agents, Tool Use, ו-Streaming. הצעד הבא: בנה פרויקט אמיתי.
