Nicht für Demo-Apps – für Produktionslasten, bei denen Echtzeit kein Kriterium ist
Die Claude Message Batches API wurde im Oktober 2024 veröffentlicht. Was damals nach einem reinen Pricing-Feature klang, ist heute ein unterschätzter Baustein für ernsthafte LLM-Produktionsarchitekturen.
Dieser Artikel ist kein Launch-Text. Er beantwortet die Frage, die danach zählt: Wann sollte man Batch statt synchroner API-Calls einsetzen – und wo endet der sinnvolle Einsatz?
Was die Batch API in einem Satz ist
Du schickst viele Claude-Anfragen gebündelt ab; das System verarbeitet sie asynchron und hält die Ergebnisse für bis zu 29 Tage bereit. Kosten: 50 Prozent weniger als bei synchronen Calls auf demselben Modell.
Der Unterschied zu einem normalen API-Call: Du bekommst keine sofortige Antwort. Du bekommst eine Batch-ID – und holst die Ergebnisse später ab.
Warum Asynchronität hier ein Vorteil ist
Das klingt zunächst wie eine Einschränkung, ist aber oft der entscheidende Vorteil.
Bei synchronen LLM-Calls zahlt man für Latenz. Jede Verbindung bleibt offen, bis das Modell fertig ist. Das ist richtig für interaktive Anwendungen – Chat, Assistenten, Live-Feedback. Für alles andere ist es Overhead.
Ein Batch-Job, der 10.000 Support-Tickets klassifiziert, braucht keine Echtzeit-Verbindung. Er braucht Durchsatz und Kosteneffizienz. Dafür ist die Batch API gebaut.
Dazu kommt ein oft übersehener Aspekt: Die Batch API hat separate Rate-Limits, die unabhängig von den Limits der normalen Messages API laufen. Wer an Throughput-Grenzen stößt, kann über Batch deutlich mehr Volumen pro Tag abwickeln als über synchrone Calls – nicht nur günstiger, sondern strukturell mehr.
Typische Praxisfälle
Dokumente klassifizieren und taggen. Rechnungen nach Kategorie sortieren, Verträge nach Typ labeln, Artikel nach Thema zuordnen. Alles Aufgaben, bei denen Geschwindigkeit pro Dokument egal ist, aber Gesamtdurchsatz und Kosten zählen.
Support-Tickets in Masse verarbeiten. Zusammenfassen, priorisieren, weiterleiten. Nicht in Echtzeit beim Eingang, sondern stündlich oder nächtlich als Batch-Job.
Produktdaten und Metadaten anreichern. Beschreibungen aus Rohdaten erzeugen, Attribute extrahieren, Kategorien ergänzen. Typisch für E-Commerce-Migrationen oder Katalogpflege.
Eval-Jobs und Prompt-Tests. Wer Prompts systematisch testet oder Red-Teaming betreibt, muss oft tausende Varianten gegeneinander testen. Batch macht das zu einem Hintergrundlauf statt zu einem Engpass.
Nächtliche Pipelines. Berichte generieren, Logs analysieren, Content pre-processing – alles, was bis zum nächsten Morgen fertig sein kann.
Technisch: Wie ein Batch-Workflow aussieht
Das grundlegende Muster in Python mit dem offiziellen Anthropic SDK:
import anthropic
import time
import json
client = anthropic.Anthropic()
# 1. Batch erstellen – jede Anfrage bekommt eine custom_id
requests = [
{
"custom_id": f"ticket_{i}",
"params": {
"model": "claude-haiku-4-5",
"max_tokens": 150,
"messages": [{
"role": "user",
"content": (
"Klassifiziere als JSON: {dringlichkeit: hoch|mittel|niedrig, "
"kategorie: Abrechnung|Technik|Allgemein}\n\n"
f"Ticket: {ticket_text}"
)
}]
}
}
for i, ticket_text in enumerate(tickets)
]
batch = client.messages.batches.create(requests=requests)
print(f"Batch {batch.id} gestartet – {len(requests)} Anfragen")
# 2. Polling bis Verarbeitung abgeschlossen
while True:
batch = client.messages.batches.retrieve(batch.id)
if batch.processing_status == "ended":
break
remaining = batch.request_counts.processing
print(f"Noch {remaining} offen – warte 60s")
time.sleep(60)
# 3. Ergebnisse verarbeiten – pro Request einzeln prüfen
results = {}
for result in client.messages.batches.results(batch.id):
if result.result.type == "succeeded":
try:
data = json.loads(result.result.message.content[0].text)
results[result.custom_id] = data
except json.JSONDecodeError:
results[result.custom_id] = {"error": "parse_failed"}
else:
results[result.custom_id] = {
"error": result.result.error.type
}
Drei Punkte, die im Code nicht sofort auffallen, aber in der Praxis entscheidend sind:
custom_id ist dein Anker. Anthropic gibt keine Garantie über die Reihenfolge der Ergebnisse. Die custom_id ist die einzige Möglichkeit, Ergebnis und ursprünglichen Request zuverlässig zuzuordnen. Immer verwenden.
Fehler passieren pro Request, nicht pro Batch. Ein Batch mit 10.000 Requests kann 9.997 erfolgreiche und 3 fehlgeschlagene Ergebnisse liefern. Der Batch selbst gilt als beendet. Wer nicht pro Request prüft, übersieht Fehler.
Ergebnisse sind 29 Tage abrufbar. Du musst sie nicht sofort verarbeiten. Das ermöglicht asynchrone Downstream-Verarbeitung und vereinfacht Retry-Logik erheblich.
Wo Batch besser ist als synchrone Calls
| Synchron | Batch | |
|---|---|---|
| Latenz pro Antwort | Sekunden | Minuten bis Stunden |
| Kosten | Basispreis | 50 % Rabatt |
| Rate Limits | Geteiltes Limit | Separates Limit |
| Geeignet für | Interaktion, Live-Feedback | Pipelines, Massenverarbeitung |
| Fehlerbehandlung | Pro Call | Pro Request im Batch |
| Ergebnisabruf | Sofort | Bis zu 29 Tage |
Grenzen, die man frühzeitig kennen sollte
Maximalgröße pro Batch: 100.000 Message Requests oder 256 MB – je nachdem, was zuerst erreicht wird. Für sehr große Datensätze braucht man mehrere Batches.
24-Stunden-Timeout: Ein Batch, der nach 24 Stunden nicht abgeschlossen ist, wird von Anthropic beendet. Teilergebnisse sind trotzdem abrufbar. Für zuverlässige Pipelines heißt das: immer mit partiellen Ergebnissen rechnen und entsprechende Retry-Logik bauen.
Kein Streaming: Batch-Ergebnisse kommen gesammelt, nicht als Stream. Für Token-by-Token-Verarbeitung ist Batch ungeeignet.
Kein Echtzeit-Feedback: Wer wissen will, ob ein einzelner Request schon fertig ist, muss den gesamten Batch-Status abfragen. Es gibt kein Webhook-Push beim Abschluss – Polling ist das Standardmuster.
Architekturhinweise für den produktiven Einsatz
Batches idempotent bauen. Wenn ein Batch-Job unterbrochen wird oder Teilergebnisse liefert, will man ihn für die fehlenden Items erneut starten können. Das funktioniert, wenn custom_id deterministisch aus dem Input abgeleitet wird (z. B. Hash der Dokument-ID) – dann sind Duplikate identifizierbar.
Ergebnisse separat speichern. Anthropics 29-Tage-Retention ist ein Puffer, kein Archiv. Ergebnisse sofort nach Abschluss in eine eigene Datenbank oder einen S3-Bucket schreiben – dann ist man unabhängig von der Retention-Policy.
Modellwahl bewusst treffen. Claude Haiku ist für klassifizierende und extrahierende Tasks oft ausreichend – und in Kombination mit dem Batch-Rabatt erheblich günstiger als Sonnet oder Opus im synchronen Betrieb. Den teureren Modellen Batch-Jobs geben, die komplexeres Reasoning erfordern.
Batches und Queues kombinieren. In einem stabilen Setup werden eingehende Jobs in eine Queue geschrieben (SQS, Redis, Cloudflare Queues), ein Scheduler sammelt sie in definierten Intervallen zu Batches, und ein Processor verarbeitet die Ergebnisse nach Abschluss. Kein Polling im Hot Path, keine offenen Verbindungen.
Ein konkretes Produktionsmuster
Für eine nächtliche Klassifikation von Support-Tickets sieht ein belastbares Setup so aus:
| Baustein | Aufgabe |
|---|---|
tickets Tabelle | Rohdaten, Status, Mandant, Priorität |
batch_jobs Tabelle | Batch-ID, Modell, Prompt-Version, Status, Startzeit, Abschlusszeit |
batch_items Tabelle | Ticket-ID, custom_id, Request-Hash, Ergebnis, Fehlerklasse |
| Scheduler | sammelt offene Tickets, baut Batches in definierter Größe |
| Worker | pollt Batch-Status, lädt Ergebnisse, schreibt sie idempotent zurück |
| Review-Queue | zeigt unsichere oder fehlgeschlagene Ergebnisse für menschliche Kontrolle |
Der Prompt bekommt eine Versionsnummer. Das klingt klein, ist aber entscheidend: Wenn sich die Klassifikationslogik ändert, müssen alte Ergebnisse nachvollziehbar bleiben. Ein Batch-Ergebnis ohne Prompt-Version ist später kaum interpretierbar.
Ein robustes Ergebnisformat sieht nicht nur die Zielklasse vor, sondern auch Unsicherheit:
{
"priority": "medium",
"category": "billing",
"confidence": 0.78,
"needs_human_review": false,
"reason": "Ticket mentions a duplicated invoice and payment date."
}
Alles unter einem definierten Confidence-Wert landet nicht direkt im CRM, sondern in der Review-Queue. Damit wird die Batch API nicht zum blinden Automatisierer, sondern zu einem Vorsortierer mit klarer Eskalation.
Retry-Logik ohne doppelte Verarbeitung
Batch-Verarbeitung scheitert selten vollständig. Häufiger sind einzelne Requests ungültig, Ergebnisse nicht parsebar oder ein Teil des Batches läuft in ein Timeout. Die Retry-Strategie sollte deshalb auf Item-Ebene arbeiten:
- Ergebnisse für alle erfolgreichen
custom_ids speichern. - Fehlgeschlagene Items mit Fehlerklasse markieren.
- Nur fehlende oder reparierbare Items in einen neuen Batch geben.
- Alte
custom_ids beibehalten oder deterministisch aus Dokument-ID und Prompt-Version ableiten.
Nicht sinnvoll ist ein pauschaler Retry des gesamten Batches. Das erhöht Kosten, erzeugt Duplikate und macht die Auswertung schwerer. Besser ist ein kleines Statusmodell:
| Status | Bedeutung |
|---|---|
queued | Item wartet auf Batch-Zuordnung |
submitted | Item wurde an Anthropic übergeben |
succeeded | Ergebnis gespeichert und validiert |
parse_failed | Modellantwort passt nicht zum Schema |
api_failed | Request wurde von der API abgelehnt oder ist abgebrochen |
review_required | Ergebnis vorhanden, aber nicht automatisch vertrauenswürdig |
Mit diesem Modell kann ein Worker jederzeit neu starten, ohne den Stand zu verlieren.
Kostenrechnung: Wann sich der Aufwand lohnt
Der Batch-Rabatt klingt attraktiv, aber er rechtfertigt nicht automatisch zusätzliche Infrastruktur. Eine einfache Daumenregel:
| Volumen | Empfehlung |
|---|---|
| wenige hundert Requests pro Monat | synchron bleiben, Batch lohnt organisatorisch kaum |
| mehrere tausend gleichartige Requests | Batch prüfen, besonders bei wiederkehrenden Jobs |
| zehntausende Requests pro Woche | Batch als Standard für nicht-interaktive Verarbeitung einplanen |
| interaktive Nutzerantworten | keine Batch API, auch wenn sie günstiger wäre |
Der größte wirtschaftliche Hebel entsteht, wenn mehrere Dinge zusammenkommen: hohes Volumen, keine Echtzeit-Anforderung, kleines Modell ausreichend, gutes Schema für automatische Validierung.
Wann Batch die falsche Wahl ist
Batch ist kein Allheilmittel. Es lohnt sich nicht, wenn:
- Nutzer direkt auf eine Antwort warten
- Latenz unter einer Sekunde erforderlich ist
- Der Use Case wenige, sporadische Einzelanfragen hat (Overhead überwiegt)
- Streaming-Output Teil der UX ist
Für all das bleibt die Messages API das richtige Werkzeug.
Einordnung
Die Batch API ist kein Komfort-Feature für experimentelle Setups. Sie ist ein Produktionsprimitive für LLM-Workflows, bei denen Echtzeit kein Kriterium ist.
Wer anfängt, LLM-Verarbeitung in größerem Maßstab aufzubauen – Klassifikation, Anreicherung, Auswertung, Eval – und synchrone Calls als Standard übernimmt, zahlt doppelt: mehr Kosten und schlechtere Skalierbarkeit. Batch zu kennen und gezielt einzusetzen, ist in diesem Kontext genauso grundlegend wie zu wissen, wann man eine Queue statt eines direkten API-Calls braucht.