[{"data":1,"prerenderedAt":781},["ShallowReactive",2],{"blog-llm-batch-api-offline-workloads-de":3},{"slug":4,"published":5,"minutes":6,"category":7,"tags":8,"keywords":14,"about":25,"sources":35,"cover":60,"og":61,"expertise":62,"locales":63,"lang":65,"title":67,"description":68,"coverAlt":69,"metaTitle":70,"takeaways":71,"faq":77,"toc":93,"blocks":124,"others":546},"llm-batch-api-offline-workloads","2026-10-17",9,"llmops",[9,10,11,12,13],"Batch API","Cost","LLMOps","Prompt caching","Data pipelines",[15,16,17,18,19,20,21,22,23,24],"llm batch api","anthropic message batches api","openai batch api","gemini batch mode","batch inference llm cost","batch api 50 percent discount","openai flex processing","bedrock batch inference","llm offline processing","batch api prompt caching",[26,29,32],{"name":27,"url":28},"Batch processing","https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FBatch_processing",{"name":30,"url":31},"JSON Lines","https:\u002F\u002Fjsonlines.org\u002F",{"name":33,"url":34},"Large language model","https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FLarge_language_model",[36,39,42,45,48,51,54,57],{"title":37,"url":38},"Claude Platform Docs: Batch processing","https:\u002F\u002Fplatform.claude.com\u002Fdocs\u002Fen\u002Fbuild-with-claude\u002Fbatch-processing",{"title":40,"url":41},"Claude Platform Docs: Rate limits (Message Batches API)","https:\u002F\u002Fplatform.claude.com\u002Fdocs\u002Fen\u002Fapi\u002Frate-limits",{"title":43,"url":44},"Claude Platform Docs: Prompt caching","https:\u002F\u002Fplatform.claude.com\u002Fdocs\u002Fen\u002Fbuild-with-claude\u002Fprompt-caching",{"title":46,"url":47},"OpenAI API Docs: Batch API","https:\u002F\u002Fdevelopers.openai.com\u002Fapi\u002Fdocs\u002Fguides\u002Fbatch",{"title":49,"url":50},"OpenAI API Docs: Flex processing","https:\u002F\u002Fdevelopers.openai.com\u002Fapi\u002Fdocs\u002Fguides\u002Fflex-processing",{"title":52,"url":53},"OpenAI API Docs: Rate limits (batch queue limits)","https:\u002F\u002Fdevelopers.openai.com\u002Fapi\u002Fdocs\u002Fguides\u002Frate-limits",{"title":55,"url":56},"Google AI for Developers: Gemini Batch API","https:\u002F\u002Fai.google.dev\u002Fgemini-api\u002Fdocs\u002Fbatch-api",{"title":58,"url":59},"Amazon Bedrock User Guide: Batch inference","https:\u002F\u002Fdocs.aws.amazon.com\u002Fbedrock\u002Flatest\u002Fuserguide\u002Fbatch-inference.html","\u002Fimages\u002Fblog\u002Fllm-batch-api-offline-workloads\u002Fcover.webp","\u002Fimages\u002Fblog\u002Fllm-batch-api-offline-workloads\u002Fog.jpg","ai-engineer",[64,65,66],"en","de","hu","LLM-Batch-APIs: Inferenz zum halben Preis für Arbeit, die warten kann","Wann sich die Batch-APIs von Anthropic, OpenAI und Gemini lohnen, wie Limits, Zuordnung und Fehler funktionieren und wie sich Rabatte mit Caching addieren.","Eine breite Kiste mit acht kleinen Quadraten, Zulauf von links, ein langer Pfeil kehrt zurück.","LLM-Batch-APIs: Offline zum halben Preis · Balázs Csorba",[72,73,74,75,76],"Anthropic, OpenAI und Gemini berechnen für Batch-Anfragen 50 % der Standardpreise, im Gegenzug kommen die Ergebnisse asynchron innerhalb eines 24-Stunden-Fensters.","Ergebnisse kommen in beliebiger Reihenfolge zurück: immer über custom_id oder key den Quelldatensätzen zuordnen, nie über die Position.","Batch-Limits sind ein eigener Topf neben den synchronen Limits, die Verlagerung von Backfills und Evals in Batches schützt also auch den interaktiven Verkehr.","Batch- und Prompt-Caching-Rabatte addieren sich, aber Cache-Treffer im Batch sind Best Effort; identische cache_control-Blöcke verwenden und den 1-Stunden-Cache erwägen.","Batch-Daten liegen wochenlang beim Anbieter: Anthropic hält Ergebnisse 29 Tage, OpenAI löscht Output-Dateien nach 30 Tagen, Gemini nach 6 Wochen.",[78,81,84,87,90],{"q":79,"a":80},"Wie viel günstiger ist eine Batch-API?","Anthropic, OpenAI und Google Gemini berechnen für Batch-Anfragen 50 % der Standardpreise. Bei der Claude API gilt das für Input-, Output- und Sondertokens, Claude Opus 5.5 kostet im Batch also 2 Dollar pro Million Input-Tokens und 10 Dollar pro Million Output-Tokens. Rabatte durch Prompt-Caching kommen hinzu.",{"q":82,"a":83},"Wie lange dauert ein Batch?","Alle drei Anbieter arbeiten mit einem 24-Stunden-Fenster. Laut Anthropic sind die meisten Batches in weniger als einer Stunde fertig, aber Anfragen, die nicht innerhalb von 24 Stunden verarbeitet werden, verfallen. Pipelines für den ungünstigsten Fall von 24 Stunden planen, nicht für den typischen.",{"q":85,"a":86},"Kann ich Tools und strukturierte Ausgabe in Batch-Anfragen nutzen?","Bei der Claude API lässt sich fast jede Messages-Anfrage batchen, auch mit Tool-Nutzung, Server-Tools, Bildern, System-Prompts und mehrteiligen Gesprächen; stream, speed und max_tokens 0 werden nicht unterstützt. Client-Tools brauchen weiterhin einen Rundweg, jeder Tool-Aufruf bedeutet also eine neue Anfrage. Bei Bedrock braucht Tool-Calling das InvokeModel-Format statt Converse.",{"q":88,"a":89},"Was passiert mit fehlgeschlagenen Anfragen in einem Batch?","Jede Anfrage bekommt ein eigenes Ergebnis. Bei der Claude API werden errored, canceled und expired nicht berechnet. Bei OpenAI landen Fehler in einer eigenen Fehlerdatei, und verfällt ein Batch, bezahlt man die Anfragen, die fertig wurden. Die Fehlschläge sammeln und in einem neuen Batch erneut einreichen.",{"q":91,"a":92},"Batch-API oder OpenAI Flex Processing?","Flex ist eine synchrone Anfrage mit service_tier flex, zu Batch-Preisen, aber langsamer und manchmal nicht verfügbar; dann kommt ein 429, der nicht berechnet wird. Es passt zu Jobs, die einfachen Request-Response-Code wollen. Ein Batch passt zu großen Mengen, bei denen man auf eine Ergebnisdatei warten kann.",[94,97,100,103,106,109,112,115,118,121],{"id":95,"title":96},"when-batch-fits","Welche Workloads in einen Batch gehören",{"id":98,"title":99},"provider-comparison","Anthropic, OpenAI, Gemini und Bedrock im Vergleich",{"id":101,"title":102},"batch-lifecycle","Der Lebenszyklus eines Batches",{"id":104,"title":105},"building-requests","Anfragen bauen, die man zuordnen und wiederholen kann",{"id":107,"title":108},"results-and-failures","Teilausfälle und was man bezahlt",{"id":110,"title":111},"caching-with-batches","Batch- und Prompt-Caching-Rabatte kombinieren",{"id":113,"title":114},"limits-throughput","Limits, Durchsatz und Ausgaben",{"id":116,"title":117},"flex-alternative","Wann Flex Processing die einfachere Wahl ist",{"id":119,"title":120},"data-retention","Datenaufbewahrung und DSGVO",{"id":122,"title":123},"sources","Quellen",[125,129,132,135,138,181,184,185,271,285,286,295,340,341,351,353,360,361,380,410,411,418,425,426,429,436,446,447,462,496,497,504,517,518],{"type":126,"content":127},"paragraph",[128],"Ein überraschend großer Teil der LLM-Ausgaben berührt nie einen Nutzer. Ein Support-Archiv nach einer Taxonomieänderung neu klassifizieren, Produkttexte für einen Katalogimport schreiben, eine nächtliche Eval-Suite laufen lassen, Dokumente nach einem Modellwechsel neu embedden: nichts davon braucht eine Antwort in zwei Sekunden, trotzdem schicken viele Teams es über denselben synchronen Endpunkt wie ihr Chat-Feature, zum vollen Preis und im Wettbewerb um dieselben Rate-Limits.",{"type":126,"content":130},[131],"Genau für diese Arbeit gibt es Batch-APIs. Man reicht viele Anfragen auf einmal ein, der Anbieter verarbeitet sie, wenn er Kapazität hat, und man holt innerhalb von 24 Stunden eine Ergebnisdatei zum halben Preis ab. Dieser Leitfaden vergleicht die Angebote von Anthropic, OpenAI, Gemini und Bedrock und zeigt dann, was sich im Code ändert: Zuordnung der Ergebnisse, Teilausfälle, Caching, Limits, Datenaufbewahrung und wann OpenAIs Flex-Tier die einfachere Option ist.",{"type":133,"level":134,"id":95,"text":96},"heading",2,{"type":126,"content":136},[137],"Der Test ist einfach: würde es jemand merken, wenn das Ergebnis morgen früh statt jetzt käme? Anthropics eigene Liste der Einsatzfälle umfasst großangelegte Evaluationen, Content-Moderation, Datenanalyse und Massenerzeugung von Inhalten wie Produktbeschreibungen. Typische Kandidaten in meinen Projekten:",{"type":139,"items":140},"list",[141,153,162,167],[142,146,147,152],{"tag":143,"children":144},"strong",[145],"Katalogpflege."," Beschreibungen, Attributextraktion und Übersetzungen für Tausende SKUs nach einem PIM-Import, siehe ",{"tag":148,"to":149,"children":150},"link","\u002Fblog\u002Fpimcore-erp-delta-sync",[151],"Pimcore-ERP-Delta-Sync",".",[154,157,158,152],{"tag":143,"children":155},[156],"Eval-Läufe."," Regressionssuiten mit Hunderten Fällen pro Prompt-Version, bei denen ein Ergebnis in einer Stunde reicht; siehe ",{"tag":148,"to":159,"children":160},"\u002Fblog\u002Fllm-evals-for-product-features",[161],"LLM-Evals für Produktfeatures",[163,166],{"tag":143,"children":164},[165],"Backfills."," Historische Tickets, Bestellungen oder Dokumente nach einer Schema- oder Taxonomieänderung klassifizieren oder zusammenfassen.",[168,171,172,176,177,180],{"tag":143,"children":169},[170],"Embeddings und Moderation."," OpenAI-Batches decken ",{"tag":173,"children":174},"code",[175],"\u002Fv1\u002Fembeddings"," und ",{"tag":173,"children":178},[179],"\u002Fv1\u002Fmoderations"," ab; Gemini hat einen eigenen Batch-Aufruf für Embeddings.",{"type":126,"content":182},[183],"Was nicht passt: alles, worauf ein Nutzer wartet, und Agentenschleifen, deren Tools im eigenen Code laufen. Jede Batch-Anfrage ist ein Modellzug, ein Agent, der ein Client-Tool aufruft, braucht also für jeden Schritt eine neue Anfrage. Serverseitige Tools sind anders: bei der Claude API laufen Websuche, Web-Fetch und Code-Ausführung im Batch-Worker, der pro Zug mehr Schleifendurchläufe macht als ein synchroner Aufruf, bevor er pausiert.",{"type":133,"level":134,"id":98,"text":99},{"type":186,"head":187,"rows":198},"table",[188,190,192,194,196],[189],"Aspekt",[191],"Anthropic",[193],"OpenAI",[195],"Gemini",[197],"Bedrock",[199,209,220,231,242,260],[200,202,204,206,207],[201],"Preis",[203],"50 % des Standards",[205],"50 % weniger",[203],[208],"Siehe Bedrock-Preise",[210,212,214,216,218],[211],"Pro Batch",[213],"100.000 Anfragen oder 256 MB",[215],"50.000 Anfragen, 200-MB-Datei",[217],"20 MB inline, 2-GB-Datei",[219],"Kontingente pro Konto",[221,223,225,227,229],[222],"Fenster",[224],"24 h, meist unter 1 h",[226],"24 h, fest",[228],"24 h Ziel",[230],"Asynchroner Job",[232,234,236,238,240],[233],"Eingabe",[235],"JSON-Anfrageliste",[237],"Hochgeladene JSONL-Datei",[239],"Inline oder JSONL-Datei",[241],"JSONL in S3",[243,245,249,252,256],[244],"Zuordnungsschlüssel",[246],{"tag":173,"children":247},[248],"custom_id",[250],{"tag":173,"children":251},[248],[253],{"tag":173,"children":254},[255],"key",[257],{"tag":173,"children":258},[259],"recordId",[261,263,265,267,269],[262],"Ergebnisse verfügbar",[264],"29 Tage",[266],"Output nach 30 Tagen gelöscht",[268],"6 Wochen",[270],"Eigener S3-Bucket",{"type":126,"content":272},[273,274,277,278,176,281,284],"Einige Einschränkungen übersieht man leicht. Eine OpenAI-Eingabedatei kann nur ein Modell ansprechen. Bedrock-Batch-Jobs im Converse-Format können kein Tool-Calling nutzen; dafür braucht man das InvokeModel-Format mit dem nativen Request-Body des jeweiligen Modells. Und bei der Claude API werden ",{"tag":173,"children":275},[276],"stream",", der Fast-Mode-Parameter ",{"tag":173,"children":279},[280],"speed",{"tag":173,"children":282},[283],"max_tokens: 0"," im Batch abgelehnt; fast alles andere, auch Bilder, Tool-Nutzung und die meisten Beta-Features, funktioniert.",{"type":133,"level":134,"id":101,"text":102},{"type":287,"attrs":288,"inner":292,"caption":293},"diagram",{"viewBox":289,"role":290,"aria-labelledby":291},"0 0 720 170","img","lba1-t lba1-d","\u003Ctitle id=\"lba1-t\">Batch-Lebenszyklus von Quelldaten bis zu gespeicherten Ergebnissen\u003C\u002Ftitle>\u003Cdesc id=\"lba1-d\">Quelldatensätze werden zu Anfragen mit deterministischen IDs, der Batch wird eingereicht und abgefragt, bis er endet, Ergebnisse werden über die ID zugeordnet und Fehlschläge kommen in einen neuen Batch.\u003C\u002Fdesc>\u003Cdefs>\u003Cmarker id=\"lba1-ah\" viewBox=\"0 0 10 10\" refX=\"9\" refY=\"5\" markerWidth=\"7\" markerHeight=\"7\" orient=\"auto-start-reverse\">\u003Cpath d=\"M0 0L10 5L0 10z\" class=\"d-head\" \u002F>\u003C\u002Fmarker>\u003C\u002Fdefs>\u003Crect x=\"20\" y=\"47\" width=\"118\" height=\"76\" rx=\"10\" class=\"d-box\" \u002F>\u003Ctext x=\"79\" y=\"81\" text-anchor=\"middle\" class=\"d-text\">Bauen\u003C\u002Ftext>\u003Ctext x=\"79\" y=\"103\" text-anchor=\"middle\" class=\"d-small\">ID pro Datensatz\u003C\u002Ftext>\u003Cpath d=\"M138 85H158\" class=\"d-line\" marker-end=\"url(#lba1-ah)\" \u002F>\u003Crect x=\"160\" y=\"47\" width=\"118\" height=\"76\" rx=\"10\" class=\"d-sky\" \u002F>\u003Ctext x=\"220\" y=\"81\" text-anchor=\"middle\" class=\"d-text\">Einreichen\u003C\u002Ftext>\u003Ctext x=\"220\" y=\"103\" text-anchor=\"middle\" class=\"d-small\">ein Modell\u003C\u002Ftext>\u003Cpath d=\"M279 85H299\" class=\"d-line\" marker-end=\"url(#lba1-ah)\" \u002F>\u003Crect x=\"301\" y=\"47\" width=\"118\" height=\"76\" rx=\"10\" class=\"d-gold\" \u002F>\u003Ctext x=\"360\" y=\"81\" text-anchor=\"middle\" class=\"d-text\">Abfragen\u003C\u002Ftext>\u003Ctext x=\"360\" y=\"103\" text-anchor=\"middle\" class=\"d-small\">bis beendet\u003C\u002Ftext>\u003Cpath d=\"M419 85H439\" class=\"d-line\" marker-end=\"url(#lba1-ah)\" \u002F>\u003Crect x=\"441\" y=\"47\" width=\"118\" height=\"76\" rx=\"10\" class=\"d-mint\" \u002F>\u003Ctext x=\"500\" y=\"81\" text-anchor=\"middle\" class=\"d-text\">Zuordnen\u003C\u002Ftext>\u003Ctext x=\"500\" y=\"103\" text-anchor=\"middle\" class=\"d-small\">über custom_id\u003C\u002Ftext>\u003Cpath d=\"M560 85H580\" class=\"d-line\" marker-end=\"url(#lba1-ah)\" \u002F>\u003Crect x=\"582\" y=\"47\" width=\"118\" height=\"76\" rx=\"10\" class=\"d-box\" \u002F>\u003Ctext x=\"641\" y=\"81\" text-anchor=\"middle\" class=\"d-text\">Erneut\u003C\u002Ftext>\u003Ctext x=\"641\" y=\"103\" text-anchor=\"middle\" class=\"d-small\">nur Fehler\u003C\u002Ftext>",[294],"Die Schleife schließt sich über die Fehler: errored und expired kommen in den nächsten Batch, nicht zurück in die synchrone API.",{"type":126,"content":296},[297,298,301,302,305,306,309,310,313,314,317,318,313,320,313,323,313,326,313,329,176,332,335,336,339],"Bei der Claude API startet ein neuer Batch mit ",{"tag":173,"children":299},[300],"processing_status"," gleich ",{"tag":173,"children":303},[304],"in_progress"," und wechselt auf ",{"tag":173,"children":307},[308],"ended",", wenn jede Anfrage fertig ist; Ergebnisse lassen sich herunterladen, sobald alle Nachrichten fertig sind oder nach 24 Stunden, je nachdem, was zuerst eintritt. OpenAI hat mehr Zustände: ",{"tag":173,"children":311},[312],"validating",", ",{"tag":173,"children":315},[316],"failed"," bei ungültiger Eingabedatei, ",{"tag":173,"children":319},[304],{"tag":173,"children":321},[322],"finalizing",{"tag":173,"children":324},[325],"completed",{"tag":173,"children":327},[328],"expired",{"tag":173,"children":330},[331],"cancelling",{"tag":173,"children":333},[334],"cancelled",". Gemini verwendet ",{"tag":173,"children":337},[338],"JOB_STATE_*","-Werte von pending bis expired. Bedrock kann statt Polling über EventBridge benachrichtigen.",{"type":133,"level":134,"id":104,"text":105},{"type":126,"content":342},[343,344,346,347,350],"Anthropic und OpenAI weisen beide darauf hin, dass Ergebnisse nicht in Eingabereihenfolge zurückkommen müssen, und raten, über ",{"tag":173,"children":345},[248]," zuzuordnen. Diese ID deterministisch machen: aus Quelldatensatz und Prompt-Version ableiten, damit ein erneuter Lauf dieselbe ID erzeugt und der Schreibprozess upserten kann statt zu duplizieren. Bei der Claude API muss sie ",{"tag":173,"children":348},[349],"^[a-zA-Z0-9_-]{1,64}$"," entsprechen, rohe SKUs mit Schrägstrichen oder Punkten scheiden also aus.",{"type":173,"code":352},"import hashlib, time, anthropic\n\nclient = anthropic.Anthropic()\nPROMPT_VERSION = \"desc-v7\"\n\ndef cid(sku: str) -> str:   # deterministic, safe characters, \u003C= 64 chars\n    return f\"{PROMPT_VERSION}-{hashlib.sha1(sku.encode()).hexdigest()[:20]}\"\n\nrequests = [{\n    \"custom_id\": cid(p[\"sku\"]),\n    \"params\": {\n        \"model\": \"claude-sonnet-5-5\",\n        \"max_tokens\": 800,\n        \"system\": [{\"type\": \"text\", \"text\": STYLE_GUIDE,             # identical in every request\n                    \"cache_control\": {\"type\": \"ephemeral\", \"ttl\": \"1h\"}}],\n        \"messages\": [{\"role\": \"user\", \"content\": render_product(p)}],\n    },\n} for p in products]\n\nbatch = client.messages.batches.create(requests=requests)\nwhile client.messages.batches.retrieve(batch.id).processing_status != \"ended\":\n    time.sleep(60)\n\nretry = []\nfor r in client.messages.batches.results(batch.id):\n    if r.result.type == \"succeeded\":\n        upsert_description(r.custom_id, r.result.message)   # idempotent write\n    else:                                                    # errored, canceled, expired\n        retry.append(r.custom_id)",{"type":126,"content":354},[355,356,359],"Die Validierung der ",{"tag":173,"children":357},[358],"params"," jeder Anfrage erfolgt bei der Claude API asynchron, ein Tippfehler in einem Feld zeigt sich also erst, wenn der ganze Batch beendet ist. Anthropic rät, eine Anfrageform vorher gegen die synchrone Messages API zu testen. Ich mache das im selben Skript: die erste Anfrage synchron senden, die Antwort gegen das Schema prüfen, dann den Rest einreichen.",{"type":133,"level":134,"id":107,"text":108},{"type":126,"content":362},[363,364,313,367,313,370,373,374,376,377,152],"Ein Batch gelingt oder scheitert nie einfach so. Bei der Claude API endet jede Anfrage als ",{"tag":173,"children":365},[366],"succeeded",{"tag":173,"children":368},[369],"errored",{"tag":173,"children":371},[372],"canceled"," oder ",{"tag":173,"children":375},[328],", und nur die erste Art wird berechnet. Verfall ist nicht hypothetisch: Anthropic weist darauf hin, dass sich die Verarbeitung je nach Nachfrage und eigenem Anfragevolumen verlangsamen kann, dann verfallen mehr Anfragen nach 24 Stunden. OpenAI schreibt Erfolge in eine Output-Datei und Fehler in eine Fehlerdatei; verfällt ein Batch, bleiben fertige Anfragen verfügbar und werden berechnet, der Rest erscheint mit dem Code ",{"tag":173,"children":378},[379],"batch_expired",{"type":139,"items":381},[382,387,392,405],[383,386],{"tag":143,"children":384},[385],"Fehlerklassen trennen."," Validierungsfehler brauchen einen Code-Fix; Serverfehler und Verfall kommen unverändert in den nächsten Batch.",[388,391],{"tag":143,"children":389},[390],"Retry-Runden begrenzen."," Zwei oder drei Neueinreichungen, dann die Datensätze für einen menschlichen Blick parken.",[393,396,397,400,401,152],{"tag":143,"children":394},[395],"Inhalt prüfen, nicht nur Status."," Auch eine erfolgreiche Anfrage kann an ",{"tag":173,"children":398},[399],"max_tokens"," stoßen oder JSON liefern, das am Schema scheitert, siehe ",{"tag":148,"to":402,"children":403},"\u002Fblog\u002Fstructured-outputs-json-schema-llm",[404],"strukturierte Ausgaben",[406,409],{"tag":143,"children":407},[408],"Sehr große Jobs aufteilen."," Anthropic empfiehlt, große Datensätze auf mehrere Batches zu verteilen; das macht auch Fortschritt und Kosten pro Teil sichtbar.",{"type":133,"level":134,"id":110,"text":111},{"type":126,"content":412},[413,414,417],"Batch-Jobs sind meist dieselben langen Anweisungen, angewendet auf viele Datensätze, die ideale Form für Prompt-Caching. Anthropic hält fest, dass sich Caching- und Batch-Rabatte addieren. Der Haken: Batch-Anfragen laufen parallel und in beliebiger Reihenfolge, Cache-Treffer sind also Best Effort; Anthropic nennt typische Trefferquoten zwischen 30 % und 98 %, je nach Verkehrsmuster. Die Empfehlung lautet, in jede Anfrage identische ",{"tag":173,"children":415},[416],"cache_control","-Blöcke zu setzen und, weil ein Batch länger laufen kann als die fünfminütige Cache-Lebensdauer, den Ein-Stunden-Cache zu erwägen. Auch Gemini unterstützt Context Caching für Batch-Anfragen zu den normalen Caching-Preisen.",{"type":126,"content":419},[420,421,152],"Vorher nachrechnen. Der Write in den Ein-Stunden-Cache kostet das Doppelte des Input-Basispreises statt des 1,25-Fachen, er lohnt sich also nur, wenn das gemeinsame Präfix lang ist und der Batch groß genug, um es oft zu lesen. Zur Caching-Mechanik selbst siehe ",{"tag":148,"to":422,"children":423},"\u002Fblog\u002Fllm-cost-latency-prompt-caching-routing",[424],"Prompt-Caching und Modell-Routing",{"type":133,"level":134,"id":113,"text":114},{"type":126,"content":427},[428],"Batch-Verkehr hat auf beiden Plattformen eigene Limits, und das ist der halbe Sinn. Laut Anthropic beeinflusst die Nutzung der Batches API die Rate-Limits der Messages API nicht; stattdessen werden HTTP-Anfragen an die Batch-Endpunkte und die Zahl der in der Verarbeitungswarteschlange wartenden Batch-Anfragen begrenzt, modellübergreifend: 200.000 wartende Anfragen im Start-Tier, 300.000 im Build-Tier und 500.000 im Scale-Tier, höchstens 100.000 pro Batch. Die Batch-Limits von OpenAI sind ein eigener Topf, berechnet aus den wartenden Input-Tokens pro Modell, und man kann bis zu 2.000 Batches pro Stunde anlegen.",{"type":430,"variant":431,"title":432,"body":433},"callout","warn","Batches können ein Ausgabenlimit überschreiten",[434],[435],"Anthropic weist darauf hin, dass Batches wegen hohen Durchsatzes und paralleler Verarbeitung das konfigurierte Ausgabenlimit eines Workspaces leicht überschreiten können. Ist ein Workspace-Limit der einzige Schutz gegen einen außer Kontrolle geratenen Backfill, eine eigene Prüfung ergänzen: Tokens pro Anfrage schätzen, mit der Batch-Größe multiplizieren und oberhalb eines Budgets nicht einreichen.",{"type":126,"content":437},[438,439,442,443,445],"Für lange Ausgaben gibt es bei der Claude API eine reine Batch-Funktion: der Beta-Header ",{"tag":173,"children":440},[441],"output-300k-2026-03-24"," hebt ",{"tag":173,"children":444},[399]," bei der aktuellen Generation Opus, Sonnet und Haiku 5.5 und mehreren älteren Modellen auf 300.000, für Entwürfe in Buchlänge oder erschöpfende Extraktion. Eine einzelne Generierung dieser Größe kann über eine Stunde dauern und frisst damit am 24-Stunden-Fenster.",{"type":133,"level":134,"id":116,"text":117},{"type":126,"content":448},[449,450,453,454,457,458,461],"OpenAI bietet einen Mittelweg. Wer bei einem Responses- oder Chat-Completions-Aufruf ",{"tag":173,"children":451},[452],"service_tier"," auf ",{"tag":173,"children":455},[456],"flex"," setzt, bekommt Batch-Preise für eine normale synchrone Anfrage, im Tausch gegen langsamere Antworten und gelegentliche Nichtverfügbarkeit. Fehlt Kapazität, kommt ein 429, der nicht berechnet wird, und man wartet und wiederholt oder sendet mit ",{"tag":173,"children":459},[460],"service_tier: auto"," zum Standardpreis erneut. Das Standard-Timeout des SDK beträgt zehn Minuten, OpenAIs Beispiele erhöhen es auf fünfzehn.",{"type":186,"head":463,"rows":469},[464,466,467],[465],"Frage",[9],[468],"Flex Processing",[470,477,482,489],[471,473,475],[472],"Codeform",[474],"Datei einreichen, abfragen, Ergebnisse parsen",[476],"Normale Anfrage und Antwort",[478,479,481],[201],[480],"Batch-Preise",[480],[483,485,487],[484],"Fehlerbild",[486],"Verfallene oder fehlerhafte Zeilen im Ergebnis",[488],"429 Resource Unavailable, nicht berechnet",[490,492,494],[491],"Am besten für",[493],"Zehntausende unabhängige Anfragen",[495],"Niedrig priorisierte Arbeit in bestehenden Codepfaden",{"type":133,"level":134,"id":119,"text":120},{"type":126,"content":498},[499,500,503],"Asynchrone Verarbeitung heißt, dass der Anbieter Eingaben und Ausgaben speichert, bis man sie abholt. Anthropic hält Batch-Anfrage- und Antwortdaten bis zu 29 Tage nach Erstellung vor, erlaubt das Löschen eines fertigen Batches über ",{"tag":173,"children":501},[502],"DELETE \u002Fv1\u002Fmessages\u002Fbatches\u002F{batch_id}",", isoliert Batches pro Workspace und lässt den Ergebnis-Download in der Console abschalten; ob Zero Data Retention gilt, steht pro Feature auf der Seite zur Datenaufbewahrung. OpenAI löscht Output-Dateien 30 Tage nach Abschluss des Batches, Gemini hält Ergebnisse 6 Wochen vor, und Bedrock schreibt sie in einen S3-Bucket unter eigener Kontrolle.",{"type":126,"content":505},[506,507,511,512,516],"Für personenbezogene Daten heißt das dreierlei: Batches löschen, sobald die Ergebnisse gespeichert sind, Anbieter und Region im Verzeichnis der Verarbeitungstätigkeiten führen und prüfen, ob die Aufbewahrungszusagen im Vertrag Batch-Speicher überhaupt abdecken. Das größere Bild steht in ",{"tag":148,"to":508,"children":509},"\u002Fblog\u002Fgdpr-llm-api-eu-data-residency",[510],"DSGVO-Datenresidenz für LLM-APIs","; berührt ein Backfill Kundendaten, ihn vorher durch eine ",{"tag":148,"to":513,"children":514},"\u002Fblog\u002Fpii-redaction-llm-pipelines",[515],"PII-Redaktion"," schicken.",{"type":133,"level":134,"id":122,"text":123},{"type":139,"ordered":519,"items":520},true,[521,525,528,531,534,537,540,543],[522],{"tag":523,"href":38,"children":524},"a",[37],[526],{"tag":523,"href":41,"children":527},[40],[529],{"tag":523,"href":44,"children":530},[43],[532],{"tag":523,"href":47,"children":533},[46],[535],{"tag":523,"href":50,"children":536},[49],[538],{"tag":523,"href":53,"children":539},[52],[541],{"tag":523,"href":56,"children":542},[55],[544],{"tag":523,"href":59,"children":545},[58],[547,613,671,724],{"slug":548,"published":5,"minutes":549,"category":7,"tags":550,"keywords":556,"about":568,"sources":578,"cover":607,"og":608,"expertise":62,"locales":609,"lang":65,"title":610,"description":611,"coverAlt":612},"llm-rate-limits-retries-provider-fallback",10,[551,552,553,554,555],"Rate limits","Retries","Fallback","Reliability","LLM gateway",[557,558,559,560,561,562,563,564,565,566,567],"llm rate limit handling","429 too many requests llm api","exponential backoff with jitter","anthropic 529 overloaded error","openai rate limit retry","llm provider fallback","litellm fallbacks","retry-after header","llm circuit breaker","multi provider llm failover","claude api rate limits",[569,572,575],{"name":570,"url":571},"Token bucket","https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FToken_bucket",{"name":573,"url":574},"Exponential backoff","https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FExponential_backoff",{"name":576,"url":577},"Circuit breaker design pattern","https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FCircuit_breaker_design_pattern",[579,581,584,586,589,592,595,598,601,604],{"title":580,"url":41},"Claude Platform Docs: Rate limits",{"title":582,"url":583},"Claude Platform Docs: API errors","https:\u002F\u002Fplatform.claude.com\u002Fdocs\u002Fen\u002Fapi\u002Ferrors",{"title":585,"url":53},"OpenAI API Docs: Rate limits",{"title":587,"url":588},"AWS Builders Library: Timeouts, retries and backoff with jitter","https:\u002F\u002Fbuilder.aws.com\u002Fcontent\u002F3EumjoZascWd1oZiEgL8ORlv3qE\u002Ftimeouts-retries-and-backoff-with-jitter",{"title":590,"url":591},"MDN: Retry-After header","https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FWeb\u002FHTTP\u002FReference\u002FHeaders\u002FRetry-After",{"title":593,"url":594},"Martin Fowler: Circuit Breaker (2014)","https:\u002F\u002Fmartinfowler.com\u002Fbliki\u002FCircuitBreaker.html",{"title":596,"url":597},"LiteLLM Docs: Router, retries and cooldowns","https:\u002F\u002Fdocs.litellm.ai\u002Fdocs\u002Frouting",{"title":599,"url":600},"LiteLLM Docs: Proxy fallbacks and reliability","https:\u002F\u002Fdocs.litellm.ai\u002Fdocs\u002Fproxy\u002Freliability",{"title":602,"url":603},"OpenRouter Docs: Model fallbacks","https:\u002F\u002Fopenrouter.ai\u002Fdocs\u002Fguides\u002Frouting\u002Fmodel-fallbacks",{"title":605,"url":606},"AI SDK Docs: Settings (maxRetries, timeout)","https:\u002F\u002Fai-sdk.dev\u002Fdocs\u002Fai-sdk-core\u002Fsettings","\u002Fimages\u002Fblog\u002Fllm-rate-limits-retries-provider-fallback\u002Fcover.webp","\u002Fimages\u002Fblog\u002Fllm-rate-limits-retries-provider-fallback\u002Fog.jpg",[64,65,66],"LLM-Rate-Limits in Produktion: Retries, Backoff und Provider-Fallback","Wie LLM-Rate-Limits funktionieren, welche Fehler man wiederholt, Backoff mit Jitter, Retries in nur einer Schicht und Fallback-Ketten ohne kaputte Ausgaben.","Kleine Quadrate steigen drei Stufen zu einem breiten Rechteck, dahinter zwei weitere in einer Reihe.",{"slug":614,"published":5,"minutes":615,"category":7,"tags":616,"keywords":621,"about":632,"sources":642,"cover":665,"og":666,"expertise":62,"locales":667,"lang":65,"title":668,"description":669,"coverAlt":670},"prompt-versioning-management",8,[617,618,11,619,620],"Prompt management","Versioning","Evals","Langfuse",[622,623,624,625,626,627,628,629,630,631],"prompt versioning","prompt management","prompt registry","version control for prompts","langfuse prompt management","mlflow prompt registry","prompts in git","openai prompt object deprecation","prompt rollback production","prompt ci evaluation",[633,636,639],{"name":634,"url":635},"Prompt engineering","https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FPrompt_engineering",{"name":637,"url":638},"Version control","https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FVersion_control",{"name":640,"url":641},"Continuous integration","https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FContinuous_integration",[643,646,649,652,655,658,661,664],{"title":644,"url":645},"OpenAI API Docs: Migrate from prompt objects","https:\u002F\u002Fdevelopers.openai.com\u002Fapi\u002Fdocs\u002Fguides\u002Fprompting\u002Fmigrate-from-prompt-object",{"title":647,"url":648},"OpenAI API Docs: Prompt engineering (reusable prompts deprecation note)","https:\u002F\u002Fdevelopers.openai.com\u002Fapi\u002Fdocs\u002Fguides\u002Fprompt-engineering",{"title":650,"url":651},"Langfuse Docs: Prompt version control","https:\u002F\u002Flangfuse.com\u002Fdocs\u002Fprompt-management\u002Ffeatures\u002Fprompt-version-control",{"title":653,"url":654},"Langfuse Docs: Prompt caching in the SDKs","https:\u002F\u002Flangfuse.com\u002Fdocs\u002Fprompt-management\u002Ffeatures\u002Fcaching",{"title":656,"url":657},"Langfuse Docs: Link prompts to traces","https:\u002F\u002Flangfuse.com\u002Fdocs\u002Fprompt-management\u002Ffeatures\u002Flink-to-traces",{"title":659,"url":660},"MLflow Docs: Prompt Registry","https:\u002F\u002Fmlflow.org\u002Fdocs\u002Flatest\u002Fgenai\u002Fprompt-registry\u002F",{"title":662,"url":663},"Promptfoo Docs: GitHub Action","https:\u002F\u002Fwww.promptfoo.dev\u002Fdocs\u002Fintegrations\u002Fgithub-action\u002F",{"title":43,"url":44},"\u002Fimages\u002Fblog\u002Fprompt-versioning-management\u002Fcover.webp","\u002Fimages\u002Fblog\u002Fprompt-versioning-management\u002Fog.jpg",[64,65,66],"Prompt-Versionierung in Produktion: Git, Registries, Labels und Rollbacks","Prompts in Produktion versionieren: was zu einer Version gehört, Git oder Prompt-Registry, Labels und Rollbacks, Eval-Gates in CI und Folgen für Caches.","Fünf aufrechte Karten in einer Reihe, die dritte schwenkt an einem Bogenpfeil zurück, ein Tor vor der letzten.",{"slug":672,"published":673,"minutes":6,"category":7,"tags":674,"keywords":680,"about":692,"sources":699,"cover":718,"og":719,"expertise":62,"locales":720,"lang":65,"title":721,"description":722,"coverAlt":723},"structured-outputs-json-schema-llm","2026-10-16",[675,676,677,678,679],"Structured outputs","JSON Schema","Constrained decoding","LLM APIs","Validation",[681,682,683,684,685,686,687,688,689,690,691],"structured outputs LLM","JSON schema LLM output","OpenAI structured outputs strict mode","Claude structured outputs","Gemini structured output","constrained decoding","JSON mode vs structured outputs","validate LLM JSON output","Zod structured output","Pydantic LLM output","vLLM structured outputs",[693,696,698],{"name":694,"url":695},"JSON","https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FJSON",{"name":676,"url":697},"https:\u002F\u002Fjson-schema.org\u002F",{"name":33,"url":34},[700,703,706,709,712,715],{"title":701,"url":702},"OpenAI API docs: Structured model outputs","https:\u002F\u002Fplatform.openai.com\u002Fdocs\u002Fguides\u002Fstructured-outputs",{"title":704,"url":705},"Claude API docs: Structured outputs","https:\u002F\u002Fplatform.claude.com\u002Fdocs\u002Fen\u002Fbuild-with-claude\u002Fstructured-outputs",{"title":707,"url":708},"Gemini API docs: Structured outputs","https:\u002F\u002Fai.google.dev\u002Fgemini-api\u002Fdocs\u002Fstructured-output",{"title":710,"url":711},"vLLM docs: Structured Outputs","https:\u002F\u002Fdocs.vllm.ai\u002Fen\u002Flatest\u002Ffeatures\u002Fstructured_outputs.html",{"title":713,"url":714},"Tam et al.: Let Me Speak Freely? A Study on the Impact of Format Restrictions on Performance of LLMs (2024)","https:\u002F\u002Farxiv.org\u002Fabs\u002F2408.02442",{"title":716,"url":717},"Geng et al.: JSONSchemaBench: A Rigorous Benchmark of Structured Outputs for Language Models (2025)","https:\u002F\u002Farxiv.org\u002Fabs\u002F2501.10868","\u002Fimages\u002Fblog\u002Fstructured-outputs-json-schema-llm\u002Fcover.webp","\u002Fimages\u002Fblog\u002Fstructured-outputs-json-schema-llm\u002Fog.jpg",[64,65,66],"Structured Outputs mit JSON Schema: was die Garantie abdeckt und was nicht","Wie Structured Outputs und Constrained Decoding bei OpenAI, Claude, Gemini und vLLM funktionieren, welche Schemaregeln zählen und was du validierst.","Ein festes Raster aus vier Fächern, drei Blöcke sitzen darin, einer zu breit schwebt darüber.",{"slug":725,"published":673,"minutes":6,"category":7,"tags":726,"keywords":732,"about":745,"sources":753,"cover":775,"og":776,"expertise":62,"locales":777,"lang":65,"title":778,"description":779,"coverAlt":780},"evaluating-ai-agents-trajectories",[727,728,729,730,731],"Agent evals","Trajectories","Tool calling","pass^k","LLM-as-judge",[733,734,735,736,737,738,739,740,741,742,743,744],"evaluating AI agents","agent trajectory evaluation","agent evals","tool call accuracy","trajectory match evaluator","pass^k metric","tau-bench","LLM as a judge for agents","agent regression testing","outcome vs trajectory evaluation","agentevals","tool correctness metric",[746,749,752],{"name":747,"url":748},"Intelligent agent","https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FIntelligent_agent",{"name":750,"url":751},"Software testing","https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FSoftware_testing",{"name":33,"url":34},[754,757,760,763,766,769,772],{"title":755,"url":756},"Anthropic: Demystifying evals for AI agents (Jan 2026)","https:\u002F\u002Fwww.anthropic.com\u002Fengineering\u002Fdemystifying-evals-for-ai-agents",{"title":758,"url":759},"Yao et al.: τ-bench: A Benchmark for Tool-Agent-User Interaction in Real-World Domains (2024)","https:\u002F\u002Farxiv.org\u002Fabs\u002F2406.12045",{"title":761,"url":762},"Barres et al.: τ²-Bench: Evaluating Conversational Agents in a Dual-Control Environment (2025)","https:\u002F\u002Farxiv.org\u002Fabs\u002F2506.07982",{"title":764,"url":765},"LangChain: agentevals (GitHub)","https:\u002F\u002Fgithub.com\u002Flangchain-ai\u002Fagentevals",{"title":767,"url":768},"DeepEval docs: Tool Correctness","https:\u002F\u002Fdeepeval.com\u002Fdocs\u002Fmetrics-tool-correctness",{"title":770,"url":771},"Ragas docs: Agentic or tool use metrics","https:\u002F\u002Fdocs.ragas.io\u002Fen\u002Fstable\u002Fconcepts\u002Fmetrics\u002Favailable_metrics\u002Fagents\u002F",{"title":773,"url":774},"OpenAI API docs: Trace grading","https:\u002F\u002Fplatform.openai.com\u002Fdocs\u002Fguides\u002Ftrace-grading","\u002Fimages\u002Fblog\u002Fevaluating-ai-agents-trajectories\u002Fcover.webp","\u002Fimages\u002Fblog\u002Fevaluating-ai-agents-trajectories\u002Fog.jpg",[64,65,66],"KI-Agenten evaluieren: Trajektorien, Ergebnisse und Zuverlässigkeit bewerten","KI-Agenten evaluieren: Ergebnis- und Trajektorie-Grader, Match-Modi, pass^k, isolierte Umgebungen und LLM-Judges, die belastbar sind.","Zwei gepunktete Wege aus Kreisen zwischen zwei Quadraten, eine Klammer umrahmt den gebogenen Weg.",1792222777407]