למה לשלם מחיר מלא כשאפשר חצי?
יש קטגוריה שלמה של עבודות AI שרוב המפתחים עושים בצורה יקרה מדי: ניתוח של אלפי מסמכים, סיווג תוכן בקנה מידה, הרצת evaluations, יצירת תוכן בכמות. הם שולחים 10,000 בקשות אחת אחרי השנייה, ומשלמים מחיר מלא על כל אחת.
ה-Message Batches API של Anthropic פותר בדיוק את זה: שלח עד 10,000 בקשות בפעולה אחת, קבל תוצאות בתוך שעה בדרך כלל (מקסימום 24 שעות), ושלם 50% פחות. כלום לא משתנה בלוגיקה, רק הדרך בה שולחים.
Batch vs Sync, הטבלה שמחליטה מתי לא להשתמש בbatch
| קריטריון | Batch API | Sync API |
|---|---|---|
| עלות | 50% הנחה על כל מודל | מחיר מלא |
| זמן תשובה | דקות-שעות (עד 24 שעות) | שניות |
| מקסימום בקשות | 10,000 per batch | rate limit רגיל |
| Streaming | לא נתמך | נתמך |
| שמירת תוצאות | 29 יום אוטומטית | בידי המפתח |
| מתאים ל | ניתוח, evals, סיווג, תוכן בכמות | chatbot, API ראשוני, streaming UX |
חשוב להבין: batch אינו פתרון קסם לכל מצב. כפי שאמר מפתח ב-Hacker News שניסה לחסוך בעלויות: "my Anthropic API bills were getting out of hand, spoiler: they remain high even with this, batch is not a magic bullet." Batch חוסך 50%, לא 100%.
Python, Batch מלא מהתחלה עד הסוף
שלושה שלבים: יצירה, המתנה (polling), ושליפת תוצאות. כל שלב הוא קריאה נפרדת לAPI.
import anthropic, time
client = anthropic.Anthropic()
# שלב 1: יצירת batch
def create_batch(texts: list[str]) -> str:
requests = [
{
"custom_id": f"item-{i}",
"params": {
"model": "claude-haiku-4-5", # זול 6x מSonnet
"max_tokens": 100,
"messages": [{"role": "user",
"content": f"סווג כ-positive/negative/neutral:\n{text}"}]
}
}
for i, text in enumerate(texts)
]
batch = client.messages.batches.create(requests=requests)
print(f"Batch ID: {batch.id}")
return batch.id
# שלב 2: polling עד סיום
def wait_for_batch(batch_id: str) -> None:
while True:
status = client.messages.batches.retrieve(batch_id)
c = status.request_counts
print(f"succeeded={c.succeeded} errored={c.errored} processing={c.processing}")
if status.processing_status == "ended":
break
time.sleep(30) # לא פחות, polling צפוף לא מזרז
# שלב 3: שליפת תוצאות
def get_results(batch_id: str) -> dict:
out = {}
for result in client.messages.batches.results(batch_id):
if result.result.type == "succeeded":
out[result.custom_id] = result.result.message.content[0].text
else:
out[result.custom_id] = None
return out
# שימוש:
texts = ["המוצר מצוין!", "שירות איטי ומאכזב", "בסדר, לא רע"]
batch_id = create_batch(texts)
wait_for_batch(batch_id)
results = get_results(batch_id)
print(results)
דוגמה ישראלית: סטארטאפ מנתח 5,000 ביקורות
חברת fintech בתל אביב אוספת ביקורות על אפליקציה פיננסית מכל הצ'אנלים (App Store, Play Store, פורומים ישראלים). בכל שבוע מצטברות כ-5,000 ביקורות חדשות שצריך לסווג לקטגוריות: UX, ביצועים, אמון, תכונות חסרות.
חישוב עלות שבועית עם Haiku 4.5 (ממוצע 150 tokens קלט + 30 tokens פלט לביקורת):
reviews = 5_000
input_tokens = reviews * 150 # 750,000
output_tokens = reviews * 30 # 150,000
# Haiku sync:
sync = (input_tokens * 1.00 + output_tokens * 5.00) / 1_000_000 # ~$1.50/week
# Haiku batch (50% off):
batch = sync * 0.5 # ~$0.75/week
# שנתי:
print(f"Sync: ${sync*52:.0f}/year") # ~$78
print(f"Batch: ${batch*52:.0f}/year") # ~$39
print(f"Savings: ${(sync-batch)*52:.0f}/year") # ~$39
בדוגמה זו החיסכון קטן, אבל הסטארטאפ גם מפעיל Sonnet לניתוח עסקי מעמיק, שם ההנחה שווה פי 15 יותר. טיפ מעשי: עבדו עם Haiku לסיווג ראשוני, ורק מסמכים שדורשים ניתוח מעמיק עוברים לSonnet.
טעויות נפוצות שעולות כסף
- לא שומרים batch_id, אם הסקריפט קורס אחרי `create` ולפני `results`, מאבדים את ה-ID ולא ניתן לשלוף תוצאות שכבר עובדו. תמיד שמרו את ה-ID לקובץ לפני polling.
- polling כל שנייה, מבזבז קריאות API ולא מזרז את הבatch. 30 שניות הוא המינימום ההגיוני; בbatch גדול, דקות.
- שימוש בSonnet כשHaiku מספיק, לסיווג סנטימנט, תיוג קטגוריות, חילוץ ישויות פשוטות, Haiku 4.5 מספיק ועולה פי 3 פחות (גם בbatch). אל תשלמו Sonnet על Haiku-task.
עדכון 2026: 300K output tokens ו-Claude 4
מ-2026, Sonnet 4.6 ו-Opus 4.6 תומכים ב-300,000 output tokens לבקשה בbatch דרך beta header `output-300k-2026-03-24`. זה שימושי לגנרציה ארוכה כמו כתיבת דוחות מלאים, עיבוד ספרים, או יצירת קוד ארוך. בלי ה-header, המגבלה הרגילה עומדת על 8,192 tokens.
batch = client.messages.batches.create(
requests=requests,
betas=["output-300k-2026-03-24"] # beta header לפלט ארוך
)
