Asynchrone API-Jobs: Nachvollziehbare Agenten-Workflows
Asynchrone API-Jobs brauchen dauerhaften Status, Idempotenz, Abfragen, bestätigte Abbrüche, Ergebnisprüfungen und Audit-Datensätze für KI-Agenten.

Ein Agent, der eine lang laufende API-Anfrage übermittelt, braucht einen Workflow und keine Schleife, die Endpunkte so lange aufruft, bis etwas fertig aussieht. Erstellung, Beobachtung, Abbruch und Abruf des Ergebnisses haben jeweils eigene Fehlerbilder. Wenn du sie in einem Prompt und einigen Wiederholungen zusammenfasst, wirst du irgendwann eine Aufgabe doppelt starten, ein fertiges Ergebnis verlieren oder einen Abbruch melden, der nie wirksam war.
Die Schwierigkeit liegt nicht darin, eine HTTP-Anfrage zu senden. Entscheidend ist, die Absicht über einen Neustart des Agenten, eine Netzwerk-Zeitüberschreitung, einen Ausfall des Anbieters und einen Menschen hinweg zu bewahren, der «Stopp» sagt, nachdem der Remote-Dienst bereits mit der Arbeit begonnen hat. Baue den Ablauf um einen dauerhaften lokalen Job-Datensatz auf. Jeder externe Aufruf muss später nachvollziehbar sein: Was haben wir angefordert, welcher Remote-Job gehört dazu, welchen Status haben wir beobachtet und was haben wir anschließend getan?
Eine Erstellungsanfrage muss die Zuständigkeit festlegen
Ein Erstellungs-Endpunkt startet eine asynchrone Operation und antwortet, bevor sie einen endgültigen Status erreicht. Die erste Antwort muss dem Agenten genügend Informationen geben, damit er fortfahren kann, ohne die Anfrage zu wiederholen. Bei einer gut entworfenen API sind das eine Job-ID, ein Anfangsstatus und entweder eine Status-URL oder eine Konvention zum Abruf des Jobs.
Schließe nicht daraus, dass eine Anfrage angenommen wurde, nur weil eine Socket-Verbindung zustande kam oder der Client nach dem Senden von Bytes eine Zeitüberschreitung meldete. Der einzige brauchbare Beleg ist eine Serverantwort oder eine spätere Abfrage, die die ursprüngliche logische Anfrage an einen Job bindet. Gerade in dem Moment, in dem ein Client eine einfache Antwort braucht, ist die Zustellung über das Netzwerk unsicher.
Gib jeder logischen Operation eine lokale Operations-ID, bevor der Agent die Anfrage sendet. Das ist deine Kennung, nicht die des Anbieters. Speichere sie zusammen mit dem Anfragetext oder einem normalisierten Fingerabdruck dieses Textes, dem vorgesehenen Ziel, dem Idempotenz-Token, Zeitstempeln und dem Aufrufer, der die Arbeit genehmigt hat. Schreibe diesen Datensatz dauerhaft, bevor du die Anfrage sendest.
Ein minimaler Datensatz kann so aussehen:
{
"operation_id": "op_01J7Q5X4D4PA3D",
"request_fingerprint": "sha256:4f8b...",
"idempotency_token": "idem_5b5c76c7",
"remote_job_id": null,
"state": "create_pending",
"created_at": "2025-03-08T14:22:11Z",
"create_deadline": "2025-03-08T14:24:11Z",
"result_deadline": "2025-03-08T15:22:11Z"
}
Der Fingerabdruck fängt einen subtilen, aber häufigen Fehler ab: Ein Agent wiederholt einen Erstellungsaufruf, nachdem er einen Parameter geändert hat. Das ist eine neue Operation, auch wenn ein Mensch sie als «dieselbe Aufgabe» beschreiben würde. Ein Token, das an eine bestimmte Anfrageform gebunden ist, darf nicht stillschweigend eine andere Anfrage autorisieren.
Eine Antwort auf die Erstellung könnte so aussehen:
HTTP/1.1 202 Accepted
Location: /v1/jobs/job_7ad2
Content-Type: application/json
{
"job_id": "job_7ad2",
"state": "queued",
"status_url": "/v1/jobs/job_7ad2"
}
Sobald die Antwort eintrifft, aktualisiere den dauerhaften Datensatz mit remote_job_id, dem beobachteten Status und den Metadaten der Antwort. Erst danach kann der Agent zur Beobachtung übergehen. Gibt die API stattdessen einen synchronen Erfolg zurück, speichere dieses Ergebnis unter derselben Operation. Der Workflow sollte beide Wege unterstützen, ohne so zu tun, als bedeuteten sie dasselbe.
Idempotenz ist für unsichere Zustellung gedacht, nicht für beliebige Wiederholungen
Ein Idempotenz-Token teilt dem Server mit, dass eine wiederholte Zustellung derselben logischen Erstellungsanfrage nicht zu wiederholter Arbeit führen darf. Es macht nicht jede Anfrage sicher und repariert auch keine API, die Idempotenz an ihrem Erstellungs-Endpunkt nie implementiert hat.
Das Token gehört gemäß dem Vertrag des Anbieters in die Erstellungsanfrage. Manche APIs akzeptieren einen Idempotency-Key-Header, andere ein Anfragefeld. Verwende die dokumentierte Form und erzeuge ein Token mit genügend Entropie, damit unabhängige Operationen nicht kollidieren können. Bewahre dasselbe Token auf, bis du die ursprüngliche Operation geklärt hast.
POST /v1/reports HTTP/1.1
Content-Type: application/json
Idempotency-Key: idem_5b5c76c7
X-Trace-ID: tr_0830d3
{
"account": "acct_218",
"range": {"start": "2025-02-01", "end": "2025-02-28"},
"format": "csv"
}
Die sichere Reihenfolge für Wiederholungen ist eng begrenzt:
- Erzeuge das Token und speichere den Operationsdatensatz.
- Sende die Erstellungsanfrage mit diesem Token.
- Wenn die Antwort verloren geht oder der Client eine Zeitüberschreitung meldet, wiederhole dieselbe Anfrage mit demselben Token.
- Wenn der Server den ursprünglichen Job zurückgibt, speichere seine ID und fahre fort.
- Wenn du andere Eingaben brauchst, schließe oder beende die alte Operation, sofern möglich. Lege danach einen neuen Datensatz und ein neues Token an.
Diese Unterscheidung ist wichtig, weil Agenten Anfragen während ihrer Überlegungen ganz selbstverständlich umformulieren. Ein geänderter Zeitraum, ein anderes Ziel, Konto oder Ausgabeformat verändert die Wirkung. Wird ein Token danach wiederverwendet, entsteht ein Konflikt zwischen Client und Server: Ein sorgfältiger Server lehnt die Abweichung ab, ein weniger sorgfältiger gibt womöglich eine alte Antwort zurück, die nicht mehr zur Absicht des Agenten passt.
Der HTTP-Standard macht die relevante Unterscheidung deutlich. RFC 9110 definiert idempotente Methoden als Methoden, deren beabsichtigte Wirkung bei wiederholten identischen Anfragen dieselbe ist wie bei einer einzigen Anfrage. POST ist standardmäßig nicht idempotent. Ein Anbieter kann einem POST-Endpunkt Idempotenzverhalten hinzufügen, aber der Client muss dies als ausdrücklichen Vertrag der Anwendung behandeln, nicht als HTTP-Gesetz.
Eine verbreitete schlechte Empfehlung lautet: «POST nur einmal wiederholen.» Die Zahl der Wiederholungen ist nicht der entscheidende Punkt. Schon eine doppelte Übermittlung kann eine Zahlung senden, eine Umgebung bereitstellen oder einen teuren Batch starten. Wiederhole eine Erstellungsanfrage, wann immer Frist und Hinweise des Anbieters es erlauben, aber nur mit einem Token, anhand dessen der Server die ursprüngliche Operation erkennen kann.
Eine Zeitüberschreitung lässt den Job-Status offen
Eine Zeitüberschreitung bei der Erstellung bedeutet nicht, dass der Dienst die Anfrage abgelehnt hat. Sie bedeutet, dass der Agent innerhalb seiner eigenen Frist keine eindeutige Antwort erhalten hat. Der Server kann die Anfrage angenommen haben, sie noch verarbeiten oder sie nie erhalten haben.
Dieser Fehler legt schwache Agenten-Workflows offen. Ein Agent sendet eine Erstellungsanfrage, wartet dreißig Sekunden, erhält keine Antwort und sendet eine neue Anfrage mit einem neuen Token. Nun laufen zwei Berichte. Der zweite kann zuerst fertig werden, wodurch der Vorfall erst auffällt, wenn jemand Gebühren, Exporte oder nachgelagerte Änderungen vergleicht.
Führe einen ausdrücklichen Status create_pending. Wenn der Aufruf nicht eindeutig fehlschlägt, speichere Fehlerklasse, Zeitstempel und Anzahl der Versuche, aber verwerfe die Operation nicht. Nutze danach den Abgleichsweg der API. Anbieter stellen dafür unterschiedliche Möglichkeiten bereit:
- Eine Wiederholung mit demselben Idempotenz-Token kann die ursprüngliche Annahmeantwort zurückgeben.
- Ein Listen- oder Such-Endpunkt kann nach einer Referenz der Client-Anfrage filtern.
- Eine Statusabfrage kann eine vom Client gelieferte Operations-ID akzeptieren.
- Ein Anbieter kann eine dokumentierte Abfrage kürzlich erstellter Jobs anhand einer Anfragekennung anbieten.
Gibt es keinen solchen Weg, kann die API bei einer verlorenen Antwort keine zuverlässige Erstellungssemantik mit höchstens einer Ausführung garantieren. Sage das in deinem Design klar. Mit einer lokalen Outbox und zurückhaltenden Wiederholungen kannst du Duplikate reduzieren, aber du kannst nicht beweisen, dass eine Wiederholung keine zusätzliche Arbeit ausgelöst hat.
Behandle eine Antwort, die mit demselben Token eine unbekannte Job-ID enthält, als schwerwiegenden Vertragsverstoß. Überschreibe die alte ID nicht. Bewahre beide Antwortdatensätze auf, stoppe automatische Aktivitäten für diese Operation und verlange eine menschliche Entscheidung. Wer stillschweigend eine der beiden auswählt, macht aus dem Audit-Trail eine Fiktion.
Verwende Fristen, die Kommunikation und Arbeit unterscheiden. Die Erstellungsfrist bestimmt, wie lange der Agent versucht, eine Remote-Job-ID zu erhalten. Die Ergebnisfrist bestimmt, wie lange der Geschäftsprozess auf den Abschluss wartet. Ein Job kann eine kurze Zeitüberschreitung bei der Antwort überstehen und trotzdem noch Stunden bis zum Abschluss haben. Werden beide Fristen zu einem einzigen Timer zusammengelegt, geben Agenten wiederherstellbare Arbeit auf oder wiederholen sie zum falschen Zeitpunkt.
Abfragen brauchen Backoff, Zuständigkeit und einen Endzeitpunkt
Abfragen sind sicher, wenn ein dauerhafter Workflow für den Job zuständig ist und jede Abfrage eine Beobachtung speichert. Sie werden missbräuchlich, wenn mehrere Agent-Läufe denselben Job wiederfinden und ihn unabhängig voneinander abfragen.
Speichere die Remote-Job-ID in einem Datensatz und weise dem Prozess, der die Beobachtung gerade übernimmt, eine Lease zu. Das kann eine Datenbankzeile mit Ablaufzeit, eine Queue-Nachricht mit Sichtbarkeitsregeln oder eine andere dauerhafte Steuerung gleichzeitiger Zugriffe sein. Stürzt der Worker ab, kann ein späterer Worker nach Ablauf der Lease übernehmen. Ohne Zuständigkeit vervielfachen Wiederholungen und Neustarts die Zahl der Statusaufrufe.
Beachte Retry-After, wenn die API den Wert sendet. Gibt die API keine Empfehlung, verwende begrenztes exponentielles Backoff mit zufälliger Streuung. Die genaue Obergrenze hängt davon ab, wie schnell der Geschäftsprozess eine Antwort braucht und welche Ratenbegrenzungen der Anbieter setzt. Der Verlauf sollte jedoch gleichzeitige Lastspitzen vermeiden.
attempt 1: wait a randomized interval near 2 seconds
attempt 2: wait a randomized interval near 4 seconds
attempt 3: wait a randomized interval near 8 seconds
later attempts: keep increasing until the configured cap
Berechne die nächste Verzögerung nicht anhand einer Zusammenfassung in den Worten des Agenten. Speichere den Zeitpunkt der nächsten Abfrage im Job-Datensatz. So kann ein neu gestarteter Worker den Zeitplan fortsetzen, und ein Bediener kann nachvollziehen, warum der Agent wartet.
Eine Statusantwort sollte nur beobachtete Fakten aktualisieren. Zum Beispiel:
{
"job_id": "job_7ad2",
"state": "running",
"updated_at": "2025-03-08T14:26:40Z",
"progress": {"completed": 146, "total": 500}
}
Speichere state, den Zeitstempel des Anbieters, sofern vorhanden, den Abrufzeitpunkt, eine Referenz auf die Rohantwort und die nächste Aktion. Verwandle ein vages Fortschrittsfeld nicht in ein Versprechen, dass der Job fertig wird. Anbieter melden Fortschritt oft verspätet oder in Blöcken. Fortschritt hilft Bedienern, aber der endgültige Status steuert den Workflow.
Setze eine Ergebnisfrist und behandle ihren Ablauf als Status, nicht als Grund, den Job zu vergessen. result_timed_out bedeutet, dass der Agent die automatische Abfrage beendet hat, weil seine Vereinbarung abgelaufen ist. Es bedeutet nicht, dass der Remote-Job angehalten wurde. Bei Aktionen mit echten Kosten oder Nebenwirkungen musst du genügend Informationen für einen späteren Abgleich aufbewahren und entscheiden, ob ein Abbruch sinnvoll ist.
Webhooks können die Latenz verbessern, ersetzen aber nicht die Statusschleife. Anbieter können Callbacks wiederholen, in falscher Reihenfolge liefern oder gar nicht zustellen. Prüfe den Callback nach der Dokumentation des Anbieters, entferne Duplikate anhand einer Ereignis-ID, sofern vorhanden, aktualisiere denselben Job-Datensatz und führe vor der Erfolgsmeldung eine abschließende Statusabfrage durch.
Statusübergänge müssen Wunschdenken zurückweisen
Eine Zustandsmaschine schützt den Workflow vor einem Agenten, der Aussagen zu großzügig interpretiert. Definiere lokale Zustände und erlaubte Übergänge, bevor du Tools mit der API verbindest. Remote-Dienste verwenden unterschiedliche Namen, aber dein Datensatz sollte Unsicherheit sichtbar machen.
Ein praktisches lokales Modell ist:
create_pending -\u003e accepted -\u003e observing -\u003e result_collecting -\u003e succeeded
create_pending -\u003e create_unknown -\u003e reconciliation
accepted or observing -\u003e cancel_requested -\u003e cancelling -\u003e cancelled
accepted or observing -\u003e failed
observing -\u003e result_timed_out
Die Pfeile sind Regeln, keine Dokumentationsgrafik. Ein Worker muss einen Übergang ohne Beleg ablehnen. Er darf succeeded nicht setzen, nur weil er einen Fortschrittswert von 100 gesehen hat. Er darf cancelled nicht setzen, nur weil er DELETE /jobs/job_7ad2 gesendet hat. Von failed darf er nur dann zu observing wechseln, wenn die Remote-API ausdrücklich eine Wiederholung oder Fortsetzung unterstützt und die neue Aktion separat gespeichert wird.
Halte Remote-Status und lokalen Status getrennt. cancel_requested beschreibt einen lokalen Fakt: Der Agent hat eine Abbruchanfrage gesendet und wartet auf Bestätigung. cancelled beschreibt einen Remote-Fakt: Der Dienst hat einen endgültigen Abbruchstatus gemeldet. Diese kleine Unterscheidung verhindert während eines Vorfalls viel Verwirrung.
Verwende eine nur ergänzbare Historie für Übergänge. Jeder Eintrag braucht die Operations-ID, den Akteur, den Zeitpunkt, den vorherigen und den nächsten lokalen Status, die auslösende Anfrage oder Antwort und den Grund. Eine kompakte Historie reicht aus:
{
"at": "2025-03-08T14:29:02Z",
"actor": "worker-3",
"from": "observing",
"to": "cancel_requested",
"cause": "human_request:req_91af",
"remote_job_id": "job_7ad2"
}
Verlasse dich nicht auf ein einziges veränderliches Feld status. Es zeigt dir, was der Workflow jetzt glaubt, aber nicht, warum er vor fünf Minuten davon überzeugt war. Wenn eine Remote-API später einen überraschenden Status zurückgibt, zeigt die Historie, ob sich der Anbieter geändert hat, der Agent einen Aufruf wiederholt hat oder ein Bediener eingegriffen hat.
Ein Abbruch braucht Bestätigung und eine Schadensgrenze
Ein Abbruch ist eine Aufforderung, künftige Arbeit zu stoppen. Bereits vom Anbieter festgeschriebene Arbeit kann er nicht rückgängig machen. Manche Anbieter erlauben außerdem eine Überschneidung, bei der ein Job genau dann fertig wird, wenn die Abbruchanfrage eintrifft. Baue den Workflow um diese Realität herum.
Wenn ein Mensch oder eine Richtlinie entscheidet, einen Job zu stoppen, speichere zuerst die Abbruchabsicht. Halte fest, wer die Anfrage gestellt hat, warum und welche Wirkung erwartet wird. Rufe dann den dokumentierten Abbruch-Endpunkt mit der gespeicherten Remote-Job-ID auf. Speichere die Antwort auch dann, wenn sie nur besagt, dass der Server die Anfrage angenommen hat.
Setze die Abfragen nach dem Abbruch fort. Zu den akzeptablen endgültigen Ergebnissen gehören meist cancelled, succeeded und failed. Ein fertiges Ergebnis nach einer Abbruchanfrage ist nicht automatisch ein Fehler. Es kann das ehrliche Ergebnis eines Jobs sein, der Sekunden zuvor seinen Festschreibepunkt überschritten hat. Der Workflow muss diese Abfolge korrekt melden, statt die Historie an das gewünschte Ergebnis anzupassen.
Manche Operationen brauchen eine eigene Schadensgrenze neben dem Abbruch. Wenn ein Exportjob eine Datei schreibt, kann eine Abbruchanfrage eine unvollständige Datei hinterlassen. Wenn ein Bereitstellungsjob Ressourcen anlegt, können einige davon bereits erstellt worden sein. Der API-Vertrag sollte angeben, ob Bereinigung, Rollback oder Details zu Teilergebnissen möglich sind. Falls nicht, behandle den Abbruch als betriebliche Steuerung und nicht als Transaktion.
Sende nicht aus jedem Polling-Worker wiederholte Abbruchaufrufe. Speichere cancel_requested, mache die Abbruchoperation idempotent, sofern der Anbieter dies erlaubt, und überlasse die Nachverfolgung dem Besitzer der Lease. Eine harmlose Anfrage zu wiederholen, verschwendet Kapazität. Eine Abbruchanfrage mit Nebenwirkungen zu wiederholen, kann das Remote-Audit-Log verwirren.
Auch eine Abbruchfrist hilft. Nach einer angemessenen, dokumentierten Wartezeit wechselst du zu cancellation_unconfirmed, statt Erfolg zu behaupten. Eskaliere mit Remote-Job-ID, Trace-ID, Anfragehistorie und allen Anfrage-IDs des Anbieters. Damit können ein Mensch oder der Support des Anbieters die tatsächliche Abfolge nachvollziehen, ohne sie aus Chatnachrichten rekonstruieren zu müssen.
Die Ergebnissammlung ist eine eigene Aktion
Ein endgültiger Erfolgsstatus bedeutet, dass die Remote-Arbeit abgeschlossen ist. Er garantiert nicht, dass das Ergebnis abgerufen, geprüft, gespeichert oder an das nächste System übergeben wurde. Behandle die Sammlung als eigene gespeicherte Aktion.
Rufe zuerst das Ergebnis mit der Job-ID oder der von der API gelieferten Ergebnisreferenz ab. Prüfe erwarteten Inhaltstyp, Schema, Prüfsumme, Größe oder Datensatzanzahl, sofern der Anbieter solche Angaben liefert. Speichere Ergebnisreferenz und Prüfergebnis im Job-Datensatz. Bei großen Ergebnissen speicherst du besser einen dauerhaften Speicherort und Integritätsdaten, statt undurchsichtige Inhalte in ein Ereignisprotokoll zu kopieren.
Prüfe anschließend, ob auch die Sammlung selbst Idempotenz braucht. Viele Ergebnis-Endpunkte sind sichere Lesezugriffe. Andere erzeugen einen temporären Download, verbrauchen ein einmaliges Artefakt oder markieren einen Job als zugestellt. Lies den Vertrag. Ein Agent, der jeden GET-Aufruf als harmlos behandelt, kann trotzdem eine anbieterspezifische Statusänderung auslösen.
Verwende einen erfolgreichen HTTP-Status nicht als einzige Prüfung. Ein Berichts-Endpunkt kann eine gültige Datei mit einer Fehlerzeile zurückgeben. Ein Bild-Batch kann ein Manifest mit fehlgeschlagenen Elementen liefern. Ein Datenexport kann abgeschlossen sein und trotzdem Datensätze auslassen, auf die der Aufrufer laut API keinen Zugriff hat. Prüfe anhand der geschäftlichen Erwartung, wegen der der Job überhaupt angelegt wurde.
Bei Batch-Arbeit speicherst du Ergebnisse auf Elementebene, sofern der Anbieter dies unterstützt. Ein endgültiger Job kann 498 Erfolge und zwei Fehler enthalten. Ihn einfach als «erfolgreich» zu bezeichnen, zwingt den nächsten Agenten, den Teilfehler erst im Ergebnis selbst zu entdecken. Dein lokaler Endstatus kann erfolgreich bleiben, während die Ergebniszusammenfassung Mengen und eine Liste fehlgeschlagener Elementreferenzen enthält.
Schließe die Operation erst, wenn die Sammlung ihren Vertrag erfüllt. succeeded sollte bedeuten, dass das erwartete Ergebnis nach deinen Regeln verfügbar und geprüft ist. Wenn der Anbieter fertig ist, die Sammlung aber fehlschlägt, verwende einen eigenen lokalen Status wie result_unavailable oder result_validation_failed. Der Remote-Job kann abgeschlossen sein, während dein Workflow es noch nicht ist.
Trace-IDs verbinden Aktionen, Audit-Datensätze schaffen Fakten
Verwende für jede Operation eine Trace-ID und sende sie bei Erstellung, Statusabfragen, Abbruch und Sammlung mit, sofern die API benutzerdefinierte Header akzeptiert. Ergänze sie um die Remote-Job-ID, sobald diese bekannt ist. Die Trace-ID verbindet Ereignisse in deinen Systemen, die Job-ID ermöglicht dem Anbieter, sein eigenes Arbeitselement zu finden.
Überlade keine der beiden Kennungen. Eine Trace-ID darf nicht zum Idempotenz-Token werden, weil eine Operation mehrere Anfragen mit unterschiedlichen Wiederholungsregeln umfassen kann. Eine Job-ID darf nicht zu deinem Autorisierungsnachweis werden, weil der Anbieter sie erst erzeugt, nachdem du lokal die Entscheidung zum Handeln getroffen hast.
Dein Audit-Datensatz sollte Fragen beantworten, die Logs oft nicht beantworten können: Welcher Agent-Prozess hat die Operation gestartet, welche menschliche Genehmigung deckte sie ab, welche Aktion mit Zugangsdaten wurde ausgeführt und hat jemand die Historie nachträglich bearbeitet? Schreibe vor dem Erstellungsaufruf einen knappen Absichtsdatensatz und ergänze danach Beobachtungen. Bewahre Anfrage-IDs und bereinigte Antwortmetadaten auf. Speichere niemals Bearer-Tokens, Passwörter, private Schlüssel oder vollständige vertrauliche Nutzdaten in einem allgemeinen Log.
Sallyport kann HTTP-API-Aufrufe ausführen, ohne gespeicherte Zugangsdaten an den Agenten weiterzugeben. Seine Sessions und einzelnen Aufrufe erzeugen eine manipulationssichere Spur, die mit sp audit verify geprüft werden kann. Das schützt die Verwahrung von Zugangsdaten und die Belege für Aktionen. Dein Workflow braucht trotzdem einen eigenen Operationsdatensatz, denn nur er weiß, ob job_7ad2 zur angeforderten Geschäftsaufgabe gehört.
Eine Trace-ID ist an einem schlechten Tag nur dann nützlich, wenn jede Komponente sie einheitlich speichert. Lege sie in den lokalen Job-Datensatz, den Ausführungskontext des Agenten, Anfrage-Header, sofern erlaubt, Audit-Anmerkungen, sofern erlaubt, und Bediener-Tickets. Erzeuge nicht für jede Abfrage eine neue Trace-ID. Diese Abfragen sind untergeordnete Ereignisse derselben Operation.
Eine Referenzschleife behandelt die gewöhnlichen Fehler
Der folgende Workflow hält schwierige Entscheidungen ausdrücklich fest. Er setzt einen Anbieter mit idempotentem Erstellungsvertrag, einem Status-Endpunkt und einem Abbruch-Endpunkt voraus. Passe die Endpunktnamen an, aber entferne die dauerhaften Statusübergänge nicht.
load operation by local operation ID
if no operation exists:
create and persist record with fingerprint and idempotency token
if remote job ID is absent:
send create with the stored token
if response confirms job ID:
persist job ID and move to observing
if response is ambiguous:
move to create_unknown and reconcile using the stored token
if response rejects request definitively:
move to failed
while local state requires observation and result deadline has not passed:
acquire lease for the operation
read remote status
append the observation
if cancellation was requested and remote state is nonterminal:
send cancellation once and record the attempt
if remote state is terminal:
collect and validate result if appropriate
persist final local state
otherwise:
persist next poll time and release lease
if the deadline expires before a terminal observation:
move to result_timed_out and preserve the reconciliation record
Diese Schleife enthält keine magische Anzahl von Wiederholungen, weil die Grenzen vom Anbieter, den Kosten der Operation und der Frist des Aufrufers abhängen. Sie enthält aber eine wichtigere Regel: Jede Wiederholung bezieht sich auf eine gespeicherte Operation, und jede nach außen sichtbare Aktion verändert deren Historie.
Teste den Ablauf mit absichtlich erzeugten Fehlern, bevor du ihn autonomen Agenten übergibst. Verwirf die Erstellungsantwort, nachdem der Server sie angenommen hat. Beende den Worker, nachdem er die Job-ID gespeichert, aber bevor er die erste Abfrage geplant hat. Gib während eines Abbruchrennens ein endgültiges Ergebnis zurück. Liefere denselben Webhook zweimal. Starte mit einer abgelaufenen Lease neu. Wenn der Workflow keinen dieser Fälle erklären und beheben kann, ist er noch nicht bereit, teure oder folgenreiche Jobs zu starten.
Die erste Implementierungsaufgabe ist unspektakulär: Lege den dauerhaften Operationsdatensatz an und verweigere jeden Erstellungsaufruf, solange er fehlt. Diese eine Einschränkung zwingt den Agenten, seine Absicht zu bewahren, macht die Vermeidung von Duplikaten möglich und gibt allen Beteiligten einen sachlichen Datensatz, wenn sich das Remote-System nicht perfekt verhält.
FAQ
Was ist ein asynchroner API-Job?
Ein asynchroner API-Job startet eine Aufgabe und liefert eine Antwort, bevor sie abgeschlossen ist. Die Antwort auf die Erstellung sollte dem Aufrufer eine dauerhafte Job-ID und eine Möglichkeit geben, den aktuellen Status später abzufragen. Behandle diese ID als Bezugspunkt für den gesamten Ablauf, nicht als vergängliche Quittung.
Wie verhindere ich doppelte Einreichungen asynchroner Jobs?
Verwende ein Idempotenz-Token, das einmal für die logische Anfrage erzeugt wird, und nutze dasselbe Token erneut, wenn du dieselbe Erstellungsoperation wiederholst. Der Server muss das Token an die ursprünglich angenommene Anfrage binden und das frühere Ergebnis zurückgeben, statt einen zweiten Job anzulegen. Verwende das Token nicht für eine geänderte Anfrage.
Wie oft sollte ein Agent einen Job-Status-Endpunkt abfragen?
Ein allgemeingültiges Intervall gibt es nicht. Beginne mit dem Wert von Retry-After, wenn der Server ihn liefert. Andernfalls verwende exponentielles Backoff mit zufälliger Streuung und einer maximalen Wartezeit. Jede Sekunde von einer Gruppe von Agenten abzufragen, ist meist ein Zeichen für ein bequem entworfenes Client-Verhalten und keine sinnvolle Überwachung.
Was sollte ein Agent nach dem Erstellen eines Hintergrundjobs speichern?
Ein Agent braucht einen dauerhaften Datensatz mit Job-ID, Anfrage-Fingerprint, Idempotenz-Token, aktuellem Status, Anzahl der Wiederholungen und Fristen. Speichere ihn vor dem ersten Netzwerkaufruf, nicht erst nach einer erfolgreichen Antwort. Ohne diesen Datensatz wird ein Prozessneustart schnell zu doppelter Arbeit.
Kann ein Agent einen asynchronen Job sicher abbrechen?
Eine Abbruchanfrage bittet den Dienst, die Arbeit zu stoppen, kann aber bereits abgeschlossene Arbeit nicht rückgängig machen. Der Agent sollte den Abbruchwunsch speichern, so lange abfragen, bis der Dienst einen endgültigen Status meldet, und verfügbare Teilergebnisse oder Fehlerdetails abrufen. Behandle eine angenommene Abbruchanfrage niemals als Beweis dafür, dass nichts passiert ist.
Was gilt als endgültiger Status eines asynchronen Jobs?
Endgültige Zustände sind Zustände, in denen sich der Job nicht mehr ändern wird, etwa erfolgreich, fehlgeschlagen, abgebrochen oder abgelaufen. Ein endgültiger Status bedeutet nicht immer, dass ein verwendbares Ergebnis vorliegt. Lies den API-Vertrag, um zu erfahren, ob fehlgeschlagene und abgebrochene Jobs Diagnoseinformationen, Teilergebnisse oder gar nichts zurückgeben.
Was sollte ein Agent nach einer Zeitüberschreitung beim Erstellen eines Jobs tun?
Eine Zeitüberschreitung bedeutet nur, dass der Client nicht länger gewartet hat. Bevor der Agent die Anfrage erneut sendet, sollte er anhand der gespeicherten Job-ID suchen oder dasselbe Idempotenz-Token verwenden, sofern die API eine Wiederholung unterstützt. Eine neue Erstellungsanfrage zu senden, weil die erste Antwort zu spät kam, ist der typische Weg, auf dem doppelte Jobs in die Produktion gelangen.
Brauche ich sowohl eine Trace-ID als auch eine Job-ID?
Verwende für Erstellung, Statusabfragen, Abbruch und Ergebnissammlung dieselbe Trace-ID und speichere daneben die Job-ID der API. Die Trace-ID verbindet deine eigenen Logs, die Job-ID bezeichnet das Arbeitselement beim Anbieter. Beide werden gebraucht, wenn sich ein Vorfall über mehrere Prozesse und Dienste erstreckt.
Sind Webhooks für lang laufende Jobs besser als Abfragen?
Ein Callback kann die Zahl der Abfragen verringern, ersetzt aber keinen Status-Endpunkt. Callbacks können verspätet, mehrfach oder gar nicht eintreffen. Deshalb muss der Agent den endgültigen Status weiterhin abgleichen. Prüfe die Echtheit des Callbacks, bevor er einen lokalen Datensatz verändert.
Kann ein Aktions-Gateway den gesamten Job-Ablauf verwalten?
Die Aufbewahrung von Zugangsdaten und die Korrektheit des Ablaufs sind zwei getrennte Aufgaben. Sallyport kann API-Zugangsdaten aus dem Agenten heraushalten und die HTTP-Aufrufe ausführen. Der Agent braucht trotzdem Idempotenz, Statusspeicherung, Fristen und eine Abgleichlogik. Erwarte von einem Aktions-Gateway nicht, dass es die Job-Semantik der Remote-API erfindet.