Ein KI-Feature kann technisch funktionieren und trotzdem falsch zugeschnitten sein: Die Antwort erscheint zu spät, oder ein vermeintlich einfacher Hintergrundjob braucht plötzlich Statusanzeigen, Wiederholungen und Support. Meine Position: Produktmanager sollten zuerst zwischen synchroner Antwort und asynchronem Auftrag entscheiden, erst danach über Hosting und Skalierung. Für den ersten Release gewinnt meist die kleinere Variante – sofern ihr Scheitern für Nutzer sichtbar und beherrschbar ist.
Eine synchrone Antwort gewinnt, solange Warten Teil der Aufgabe ist
Wer in einem Editor einen Absatz umformulieren lässt, erwartet die Antwort im selben Moment und an derselben Stelle. Eine synchrone Anfrage passt dazu, weil der Nutzer das Ergebnis unmittelbar prüfen, verwerfen oder ändern kann. Sie spart zunächst einen Auftragsstatus, Benachrichtigungen und eine Ergebnisablage. Das ist ein echter Vorteil für den Umfang des Releases, nicht bloß eine technische Vorliebe.
Ich halte Managed KI oder Self-Hosting – wann gewinnt was im Betrieb? für eine nachgelagerte Frage im ersten Backlog-Schnitt, weil beide Betriebsformen eine schlecht gewählte Interaktion nur schneller oder teurer ausführen. Ein selbst betriebenes Modell macht einen blockierenden Dialog nicht automatisch erträglich; eine gemanagte API erspart umgekehrt keine Entscheidung darüber, was bei einem Timeout mit dem Entwurf geschieht.
Für den synchronen Pfad würde ich als veränderbaren Produktgrenzwert zunächst zwei Sekunden bis zu einer brauchbaren ersten Rückmeldung ansetzen. Das ist kein allgemeiner Messwert für Modelle: Das Team muss prüfen, ob die konkrete Aufgabe und Oberfläche längeres Warten vertragen. „Erste Rückmeldung“ kann bei Server-Sent Events über HTTP bereits ein Textanfang sein; sie ist nicht mit einem fertigen, geprüften Ergebnis gleichzusetzen. Streaming lohnt sich nur, wenn Teiltext nutzbar ist, weil es andernfalls zusätzliche Zustände in der Oberfläche erzeugt, ohne die Aufgabe früher zu erledigen.
Der Zuschnitt für einen ersten Release kann deshalb eng sein: ein Eingabefeld, ein klar begrenzter Ausgabetext, Abbrechen und erneutes Versuchen. FastAPI kann den HTTP-Endpunkt bereitstellen; OpenTelemetry-Spans können die Zeit für Eingabeprüfung, Modellaufruf und Ausgabe trennen. Ein Prometheus-Histogramm wie ai_request_duration_seconds macht anschließend das 95. Perzentil sichtbar. Ohne diese Trennung könnte ein Team dem Modell eine Verzögerung zuschreiben, die tatsächlich aus einer langsamen Datenabfrage stammt.
Ich würde keinen synchronen Endpunkt für einen Auftrag bauen, der mehrere Dokumente durchsucht und einen Bericht erstellt, weil ein offener Browser-Tab dann zum unzuverlässigen Auftragsmanager wird. Auch ein höheres HTTP-Timeout löst das Problem nicht: Verbindungsausfälle, erneute Klicks und doppelte Berechnungen bleiben möglich. Synchron gewinnt nur, wenn ein Fehlschlag billig ist. Kann der Nutzer die Eingabe behalten und den Versuch ohne Folgeschaden wiederholen, ist der kleine synchrone Schnitt oft die ehrlichere Planung.
Ein asynchroner Auftrag gewinnt, wenn Verlässlichkeit wichtiger als Sofortigkeit ist
Ein Bericht über viele Dateien, eine umfangreiche Zusammenfassung oder die Verarbeitung einer Sammlung hat einen anderen Produktvertrag: Der Nutzer gibt Arbeit ab und kann später zurückkommen. Hier gewinnt ein asynchroner Auftrag, weil seine Bearbeitung einen Tabwechsel, einen kurzen Ausfall und einen erneuten Abruf des Ergebnisses überstehen kann. Er kostet aber mehr als eine Queue. Produktmanager müssen festlegen, wann ein Auftrag als angenommen gilt, wie lange sein Ergebnis abrufbar bleibt und wer einen fehlgeschlagenen Lauf bemerkt.
Ein brauchbarer API-Vertrag beginnt mit HTTP 202 Accepted und einer Auftragskennung. Ein GET-Endpunkt liefert einen der Zustände queued, running, succeeded oder failed; beim Erfolg verweist er auf das Ergebnis. Der Header Idempotency-Key hilft bei wiederholten POST-Anfragen, weil ein verlorenes Antwortpaket sonst denselben kostspieligen Auftrag zweimal auslösen kann. PostgreSQL 16 kann Auftragszustand und Ergebnisverweis speichern; Redis 7 mit Celery 5.x oder Amazon SQS kann die Arbeit verteilen. Welche Queue passt, ist weniger entscheidend als die dokumentierte Regel, ob und wann ein Worker erneut versucht.
Asynchron bedeutet nicht, dass jede Aufgabe beliebig oft ausgeführt werden darf. Ein Worker kann nach der Modellantwort abstürzen, bevor er „erfolgreich“ speichert; beim Neustart könnte er denselben Auftrag nochmals bearbeiten. Deshalb gehört zum Umfang eine eindeutige Auftragskennung am Schreibziel. Wer Ergebnisse in PostgreSQL ablegt, kann einen eindeutigen Schlüssel auf diese Kennung setzen, weil doppelte Ausführung dann nicht automatisch doppelte Ergebnisse erzeugt. Für Aktionen mit Außenwirkung reicht ein Datenbankeintrag allein möglicherweise nicht; deren Wiederholungsverhalten muss separat entschieden werden.
Auch die Oberfläche ist Teil des Preises. „In Bearbeitung“ braucht einen verständlichen Ausweg, falls ein Job festhängt; „fehlgeschlagen“ braucht eine Handlung statt einer technischen Fehlermeldung. Eine Benachrichtigung sollte erst in den ersten Release, wenn Nutzer tatsächlich später zurückkehren müssen, weil sie sonst Berechtigungen, Zustellung und neue Fehlermöglichkeiten mitbringt. Für viele Teams reicht zunächst ein abrufbarer Status mit einer klar genannten Aufbewahrungsdauer.
Ich würde KI-Infrastruktur fuer skalierbare Softwareentwicklung erst nach diesem Auftragsvertrag in konkrete Ausbau-Tickets übersetzen, weil zusätzliche Worker weder einen unklaren Status noch doppelte Aufträge reparieren. Der asynchrone Ansatz gewinnt nicht aufgrund einer abstrakten Aussicht auf Skalierung, sondern wenn der Nutzer auf das Ergebnis nicht warten muss und der Auftrag trotz Unterbrechungen zuverlässig fertig werden soll.
Die Lastkurve entscheidet über den Schnitt, nicht der Modellpreis allein
Für die Entscheidung reichen durchschnittliche Anfragen pro Tag nicht aus, weil ein kurzer Andrang einen synchronen Dienst blockieren und eine asynchrone Queue sichtbar füllen kann. Angenommen, eine rein illustrative Lastspitze bringt 80 Aufträge in zehn Sekunden. Vier gleichzeitig arbeitende Worker benötigen jeweils fünf Sekunden pro Auftrag. Unter diesen vereinfachten Bedingungen schaffen sie während der Spitze acht Aufträge; 72 bleiben zunächst liegen. Das folgende ausführbare Python-Beispiel berechnet genau diese grobe Untergrenze, keine Prognose für einen echten Dienst:
python3 - <<'PY'
arrivals = 80
window_s = 10
parallel = 4
service_s = 5
completed = parallel * window_s // service_s
backlog = max(0, arrivals - completed)
drain_s = backlog * service_s / parallel
print(f"{backlog} warten; mindestens {drain_s:.0f} s Abbauzeit")
PY
Das Ergebnis sind mindestens 90 Sekunden zum Abarbeiten des Rückstands, sofern danach nichts Neues eintrifft und jeder Auftrag gleich lang dauert. Gerade diese günstigen Annahmen machen die Rechnung als Planungswerkzeug brauchbar: Ist schon die Untergrenze für den Nutzer untragbar, braucht das Team entweder weniger Arbeit pro Auftrag, mehr Kapazität oder einen anderen Produktvertrag. Die Zahl der Worker ist dabei ein zu justierender Kapazitätsparameter, keine Empfehlung, sofort vier Maschinen zu reservieren.
Ergänzend muss die Kostenrechnung die tatsächlich ausgelösten Versuche zählen. In einer angenommenen Tagesmenge von 1.800 Aufträgen mit je 1.200 Eingabe- und 300 Ausgabetokens entstehen 2,7 Millionen Tokens, bevor Wiederholungen hinzukommen. Bei einem ausdrücklich fiktiven Rechenpreis von 0,004 Euro je 1.000 Tokens wären das 10,80 Euro pro Tag. Dieser Betrag ist kein Anbieterangebot. Er zeigt, warum ein Produktmanager Eingabelänge, Ausgabelimit und Wiederholungsquote spezifizieren muss: Eine scheinbar billige Anfrage kann durch große Kontexte oder unbemerkte Retries einen anderen Umfang bekommen.
Ein Lastversuch mit k6 sollte deshalb nicht nur HTTP-Erfolge zählen. Er sollte realistische Eingabelängen und einen kurzen Burst enthalten; Grafana kann dazu Queue-Länge, fehlgeschlagene Jobs und das 95. Perzentil der Antwortzeit nebeneinander zeigen. Die im eigenen Test zu erhebende Kennzahl ist insbesondere die Wartezeit bis zum fertigen Ergebnis, nicht allein die Modelllaufzeit. Bei asynchronen Aufträgen kann ein schneller Worker-Aufruf für Nutzer trotzdem langsam sein, wenn die Arbeit lange in der Queue liegt.
Die explizite Abwägung lautet damit: Synchroner API-Aufruf gewinnt bei kurzen, unterbrechbaren Aufgaben mit sofort nutzbarem Ergebnis und kostet vor allem Kapazität für niedrige Latenz sowie eine saubere Fehleranzeige. Asynchroner Auftrag gewinnt bei längerer oder stoßweise anfallender Arbeit mit späterem Abruf und kostet Statusmodell, dauerhafte Speicherung, Wiederholungsregeln und Support für hängende Aufträge. Beides gleichzeitig als vollständige Produktoberfläche einzuplanen wäre für einen ersten Release meist zu teuer, weil jede Variante eigene Fehlerzustände und Abnahmekriterien verlangt.
Ein kleiner Produkttest schlägt eine große Infrastrukturwette
Vor der Architekturentscheidung braucht der Produktmanager drei Beobachtungen aus der tatsächlichen Aufgabe: Wie lange Nutzer auf ein Ergebnis warten wollen, ob sie währenddessen weiterarbeiten können und was ein fehlgeschlagener Versuch sie kostet. Diese Fragen lassen sich an einem schmalen Prototyp prüfen. Ein einzelner Anwendungsfall mit echten, freigegebenen Beispieldaten ist aussagekräftiger als eine Demo mit kurzen Mustereingaben, weil Eingabelänge und erwartete Ergebnisqualität die Laufzeit verändern.
Für den synchronen Kandidaten würde ich eine Aufgabe auswählen, deren Ergebnis direkt am Eingabeort erscheint. Im Test sind Abbrüche, erneute Versuche und Korrekturen zu beobachten. Für den asynchronen Kandidaten würde ich denselben Nutzwert als abgebbaren Auftrag formulieren und prüfen, ob Menschen den Status später tatsächlich abrufen. Das sind konkurrierende Produktschnitte, nicht zwei Ansichten derselben technischen Implementierung: Beim ersten verkauft das Team eine unmittelbare Hilfe, beim zweiten einen verlässlich erledigten Auftrag.
Ein Entscheidungsticket sollte anschließend ausdrücklich festhalten: maximale Eingabe, gewünschte Ergebnisform, erlaubte Wartezeit, Verhalten bei Abbruch, Aufbewahrungsdauer und Kostenlimit pro erledigtem Auftrag. „Erledigt“ ist wichtig, weil Kosten pro API-Aufruf fehlgeschlagene und wiederholte Versuche ausblenden. Ein weiteres Feld nennt die Rückfalloption: Darf der Nutzer ohne KI weitermachen, lässt sich ein synchroner Ausfall kleiner halten; hängt ein zugesagter Bericht daran, braucht der asynchrone Pfad einen sichtbaren Eskalationsweg.
Erst wenn die Probe zeigt, dass ein einzelner Pfad den Nutzwert nicht trägt, würde ich den zweiten hinzufügen. Der häufige Kompromiss „Wir starten synchron und legen vorsichtshalber schon eine Queue darunter“ spart selten Arbeit, weil das Team dann sowohl sofortige Antworten als auch dauerhafte Aufträge testen und betreiben muss. Ein späterer Wechsel bleibt möglich, wenn Auftragskennung und Ergebnisformat bewusst entworfen werden; vorsorglich beide Betriebsarten auszuliefern ist dafür nicht nötig.
Die erste Entscheidung ist ein Auftragssatz, kein Architekturdiagramm
Schreibe als Erstes einen Satz für den geplanten Release: „Der Nutzer erhält das Ergebnis während seiner Eingabe“ oder „Der Nutzer gibt einen Auftrag ab und holt das Ergebnis später ab.“ Ergänze eine zulässige Wartezeit und den Umgang mit einem Fehlschlag. Wenn das Team diesen Satz nicht gemeinsam akzeptiert, sollte es noch keine Queue und keinen Streaming-Endpunkt beauftragen: Beide würden eine offene Produktentscheidung lediglich in Code verstecken.




