Der Agent ruft Ihren Video-Transkodierungs-Endpunkt auf. Der Endpunkt gibt 202 Accepted und eine Auftrags-ID zurück. Der Agent, der keine Ahnung hat, was 202 in Ihrem System bedeutet, meldet, dass die Transkodierung abgeschlossen ist, und geht zum nächsten Schritt über, der eine Datei liest, die noch nicht existiert.
Langlaufende Operationen stören Agenten auf eine bestimmte Weise. Ein synchroner Aufruf hat einen offensichtlichen Vertrag: Sie senden, Sie warten, Sie erhalten eine Antwort. Ein asynchroner Aufruf teilt dies in einen Start und ein Ende auf, und die Lücke dazwischen ist der Punkt, an dem Agenten verwirrt werden. Sie melden den Erfolg zu früh, sie fragen tausendmal in einer engen Schleife ab, oder sie sitzen sechs Minuten lang blockiert und halten einen Gesprächszug offen.
Dieser Leitfaden behandelt, wie man den asynchronen Vertrag so gestaltet, dass ein Agent ihm folgen kann, wann man abfragen und wann man übergeben sollte, wie man die Tools schreibt, damit sich das Modell richtig verhält, und wie man den gesamten Pfad einschließlich der langsamen und fehlgeschlagenen Fälle testet. Unser Beitrag zur Fehlerbehebung für KI-Agenten behandelt die Fehlerseite von API-Aufrufen; dieser hier behandelt diejenigen, die langsam erfolgreich sind.
Apidog passt genau dann, wenn Sie beweisen müssen, dass der Agent eine Aufgabe bewältigt, die vier Minuten dauert und dann fehlschlägt, was Sie in der Produktion nicht entdecken möchten.
Warum Agenten asynchrone Vorgänge falsch handhaben
Drei Gewohnheiten verursachen die meisten Probleme.
Modelle behandeln ein 2xx als erledigt. Ein 202 besagt, dass die Anfrage zur Verarbeitung angenommen wurde, und die HTTP-Semantik-Spezifikation legt explizit fest, dass die Verarbeitung möglicherweise noch nicht abgeschlossen ist. Modelle, die auf gewöhnlichem Anfrage-/Antwort-Verkehr trainiert wurden, neigen dazu, jedes 2xx als Abschluss zu interpretieren, es sei denn, die Antwort besagt ausdrücklich etwas anderes.
Schleifen sind teuer. Wenn ein Agent innerhalb seiner Denk-Schleife abfragt, kostet jede Prüfung einen Modell-Turn plus die Tokens des vorherigen Gesprächs. Alle zwei Sekunden eine Abfrage für einen vierminütigen Job bedeutet 120 Turns, und der Durchlauf erschöpft entweder den Kontext oder das Budget. Unser Beitrag zum Heraushalten von Tool-Antworten aus dem Kontextfenster erklärt, warum sich das schneller summiert, als man erwartet.
Agenten verlieren die Übersicht über Aufträge. Ein Tool, das eine Arbeit beginnt und eine Auftrags-ID zurückgibt, hat einen Zustand erzeugt, den der Agent weiterführen muss. Wenn die ID mitten in einem langen Gespräch landet, kann sie komprimiert werden, und der Agent vergisst, dass er einen laufenden Auftrag hat.
Gestalten Sie die Antwort so, dass das Modell sie nicht falsch interpretieren kann
Die effektivste Lösung ist die Formulierung, nicht die Architektur. Unabhängig von Ihrem Statuscode sollte der Body klar sagen, was passiert ist und was als Nächstes zu tun ist.
{
"status": "processing",
"job_id": "job_7f21c",
"message": "The transcode has STARTED and is NOT complete. Do not report success. Check status with getJobStatus(job_id) after at least 30 seconds.",
"poll_after_seconds": 30,
"estimated_duration_seconds": 240,
"status_url": "/v1/jobs/job_7f21c"
}
Das klingt für einen menschlichen API-Konsumenten übertrieben. Es richtet sich an ein Modell, und Modelle folgen expliziten Anweisungen in einem Antwort-Body weitaus zuverlässiger, als sie die Bedeutung aus einem Statuscode ableiten. Drei Details leisten die Arbeit: das Wort „nicht abgeschlossen“, das benannte nächste Tool und eine Mindestwartezeit.
Googles AIP-151 zu langlaufenden Operationen beschreibt eine saubere Ressourcenform dafür, mit einem einzigen Operation-Objekt, das die Felder done, error und response enthält. Das Kopieren dieser Struktur bietet Ihnen eine konsistente Oberfläche über jeden langsamen Endpunkt hinweg, was wichtig ist, da ein Agent, der ein Abfragemuster lernt, dann alle davon verarbeiten kann.
Halten Sie die Statusantwort ebenso direkt:
{
"job_id": "job_7f21c",
"status": "processing",
"done": false,
"progress_percent": 45,
"elapsed_seconds": 108,
"poll_after_seconds": 45,
"message": "Still processing. Do not proceed to the next step."
}
Und bei Abschluss geben Sie das Ergebnis inline zurück, wenn es klein ist, damit der Agent keinen dritten Aufruf benötigt:
{
"job_id": "job_7f21c",
"status": "succeeded",
"done": true,
"result": { "output_url": "https://cdn.example.com/out/7f21c.mp4", "duration_seconds": 372 }
}
Abfragen außerhalb des Modells, nicht innerhalb
Die wichtigste Implementierungsentscheidung: Platzieren Sie das Warten in Ihrem Tool-Wrapper, nicht in der Denk-Schleife des Agenten.
import time
def start_and_await_transcode(client, source_url, max_wait=600):
job = client.post("/v1/transcode", json={"source_url": source_url}).json()
job_id = job["job_id"]
delay = job.get("poll_after_seconds", 5)
waited = 0
while waited < max_wait:
time.sleep(delay)
waited += delay
status = client.get(f"/v1/jobs/{job_id}").json()
if status.get("done"):
if status["status"] == "succeeded":
return {"status": "succeeded", "result": status["result"]}
return {"status": "failed", "error": status.get("error")}
delay = min(int(delay * 1.5), 60)
return {
"status": "timed_out",
"job_id": job_id,
"message": f"Still running after {max_wait}s. Job {job_id} continues in the background.",
}
Aus Sicht des Modells ist dies ein Tool-Aufruf, der eine Weile dauert und eine endgültige Antwort zurückgibt. Keine Abfrageschleife im Kontext, keine vergessenen Auftrags-IDs, keine 120 Züge. Der Backoff hält die Anzahl der Anfragen vernünftig, und die Obergrenze verhindert, dass ein festgefahrener Job den Durchlauf ewig blockiert. Amazons Artikel über Timeouts, Wiederholungsversuche und Backoff mit Jitter ist die Referenz, die man lesen sollte, bevor man diese Zahlen anpasst.
Zwei Regeln machen dies sicher. Begrenzen Sie die Wartezeit immer, und geben Sie bei einem Timeout immer die Auftrags-ID zurück, damit der Agent oder ein Mensch später nachsehen kann. Geben Sie niemals ein mehrdeutiges Ergebnis zurück: succeeded, failed und timed_out sind drei verschiedene Ergebnisse, und das Modell sollte drei verschiedene Wörter sehen.
Für Jobs, die in Stunden statt in Minuten gemessen werden, macht das In-Wrapper-Polling keinen Sinn mehr. Dann ist die richtige Form zwei Tools, eines zum Starten und eines zum Überprüfen, plus eine dauerhafte Aufzeichnung der laufenden Jobs außerhalb des Gesprächs, damit nichts durch Komprimierung verloren geht. Speichern Sie job_id, die Aufgabe, zu der sie gehört, und die Startzeit, und lassen Sie den Agenten diese Liste am Anfang jedes Durchlaufs lesen.
Wann Webhooks die bessere Antwort sind
Polling ist einfach und funktioniert überall. Callbacks sind effizienter und mit mehr Aufwand verbunden. Der Kompromiss wird in unserem Vergleich Webhooks vs. Polling gut behandelt, und die agentspezifische Version ist enger gefasst.
Nutzen Sie Polling, wenn der Job Sekunden bis Minuten dauert, wenn der Agent auf das Ergebnis wartet, um fortzufahren, oder wenn Sie keinen öffentlichen Endpunkt hosten können. Die meisten Agenten-Workloads fallen hierher.
Verwenden Sie Webhooks, wenn Jobs Stunden dauern, wenn der Agent Arbeit auslöst und weitermacht, oder wenn viele Jobs gleichzeitig laufen und das Abfragen jedes einzelnen verschwenderisch ist. Die Kosten sind real: Sie benötigen einen öffentlichen Empfänger, eine Signaturprüfung, eine Fehlerbehandlung bei Wiederholungsversuchen und eine Möglichkeit, den Agenten zu wecken, wenn der Callback eintrifft. Unsere Leitfäden zum Entwerfen zuverlässiger Webhooks und zur Webhook-Signaturprüfung decken diese Grundlagen ab.
Eine mittlere Option ist wissenswert. Das Streaming des Jobfortschritts über Server-Sent Events bietet Ihnen Push-Semantik ohne einen öffentlichen Endpunkt, da der Client die Verbindung hält. Es eignet sich für interaktive Agenten, bei denen ein Mensch zuschaut, und unser Leitfaden zum Streaming von API-Antworten mit SSE behandelt die Implementierung.
Für welche Option Sie sich auch entscheiden, der Abschluss-Pfad muss idempotent sein. Webhooks versuchen es erneut, Abfragen überschneiden sich, und ein Agent, der zweimal „erfolgreich“ sieht, sollte den nachgelagerten Schritt nicht zweimal starten. Unser Beitrag zu Idempotenz für KI-Agenten behandelt die Schlüssel, die dies sicherstellen.
Testen Sie den langsamen Pfad, nicht nur den schnellen
Asynchrone Fehler verstecken sich, weil Testumgebungen schnell sind. Ein Job, der in der Produktion vier Minuten dauert, ist gegen einen lokalen Stub in 200 Millisekunden abgeschlossen, sodass der Agent nie den Zustand erlebt, dem er tatsächlich begegnen wird.
Vier Szenarien sollten bewusst aufgebaut werden.
- Der wirklich langsame Job. Mocken Sie den Status-Endpunkt so, dass er bei den ersten mehreren Aufrufen
processingund danachsucceededzurückgibt. Dies beweist, dass der Wrapper abfragt, zurückweicht und schließlich zurückkehrt. In Apidog können Sie dies mit einem Mock steuern, der sich nach der Anzahl der Anfragen oder nach einem Steuerungsparameter richtet, sodass derselbe Test jedes Mal auf dieselbe Weise ausgeführt wird.

- Der Job, der spät fehlschlägt. Geben Sie dreimal
processingzurück, dannfailedmit einem Fehler-Body. Der Agent muss den Fehler melden, anstatt eine abgeschlossene Abfrage als abgeschlossenen Job zu behandeln. Dies ist der Fall, der bei falscher Handhabung zu stillem Datenverlust führt. - Der Timeout. Lassen Sie den Mock über die Obergrenze des Wrappers hinaus
processingzurückgeben und stellen Sie sicher, dass das Tooltimed_outmit der intakten Job-ID zurückgibt, nicht eine Ausnahme und keinen falschen Erfolg. - Die doppelte Fertigstellung. Liefern Sie den Erfolg zweimal, durch einen Webhook-Wiederholungsversuch oder durch eine sich überschneidende Abfrage, und stellen Sie sicher, dass der nachgelagerte Schritt nur einmal ausgeführt wird.
Speichern Sie alle vier als Szenarien, damit sie in CI ausgeführt werden. Sie kosten nichts bei der erneuten Ausführung und fangen Regressionen ab, bei denen jemand ein Timeout verkürzt oder einen Fehler verschluckt. Der umfassendere Ansatz findet sich in unserem Leitfaden zum API-Vertragstesting.
Drei Jobs, die das Problem aufzeigen
- Berichtserstellung. Ein Finanz-Agent fordert einen vierteljährlichen Export an. Dies dauert 90 Sekunden. Mit einem naiven Tool erhält der Agent eine Job-ID, verkündet, dass der Bericht fertig ist, und übergibt dem Benutzer dann einen defekten Download-Link. Mit einem blockierenden Wrapper wartet er 90 Sekunden und gibt die echte URL zurück. Dieselbe API, gegensätzliche Ergebnisse, und der einzige Unterschied ist, wo das Warten stattfindet.
- Massenimporte. Ein Ops-Agent lädt 20.000 Datensätze hoch. Der Import läuft acht Minuten lang und schlägt teilweise bei Zeile 14.000 fehl. Dies ist der Fall, der eine naive Erfolgskontrolle bestraft: Der Job ist abgeschlossen, daher ist ein Status von
donewahr, aber das Ergebnis enthält eine Liste abgelehnter Zeilen. Geben Sie Teilergebnisse explizit mit Zählungen zurück und lassen Sie den Agenten diese lesen, bevor er weitermacht. - Modell- und Build-Pipelines. Ein Agent löst einen Trainingslauf oder einen CI-Build aus, der 40 Minuten dauert. In-Wrapper-Polling ist hier die falsche Form; der Lauf würde einen Turn viel zu lange offen halten. Starten Sie den Job, speichern Sie die ID in einem dauerhaften Speicher, beenden Sie den Turn und lassen Sie eine geplante Überprüfung oder einen Callback die Nachverfolgung auslösen. Unser Beitrag zur Übergabe und Kontextweitergabe bei Multi-Agenten behandelt das Verschieben dieses Zustands zwischen Läufen ohne Verlust.
Teilergebnissen eine Form geben
Lange Jobs enden oft irgendwo zwischen Erfolg und Misserfolg, und ein Zwei-Zustands-Modell zwingt Sie, darüber zu lügen. Machen Sie den dritten Zustand explizit:
{
"job_id": "job_a11f",
"status": "completed_with_errors",
"done": true,
"summary": { "processed": 20000, "succeeded": 19860, "failed": 140 },
"errors_url": "/v1/jobs/job_a11f/errors?limit=50",
"message": "Import finished. 140 rows failed and were not written. Review errors before reporting success."
}
Zwei Dinge sind in dieser Payload wichtig. Die Zählungen sind inline, sodass der Agent ohne einen weiteren Aufruf entscheiden kann. Die fehlerhaften Zeilen sind hinter einer URL mit einem Limit, sodass 140 Fehlerobjekte nicht unaufgefordert im Kontext landen.
Jemand muss den Job sehen, der ins Stocken geraten ist
Der Timeout-Pfad endet mit einer Job-ID und einer Meldung, dass die Arbeit noch läuft. Das ist der korrekte Rückgabewert, und er ist nur nützlich, wenn er eine Person erreicht.
Wenn der Agent Ihr eigener Dienst ist, leiten Sie ihn in die Warteschlange, die Ihr Team bereits überwacht. Wenn der Agent eine Code-Laufzeitumgebung ist, die zugewiesene Aufgaben abarbeitet, hat die Plattform, auf der er läuft, normalerweise einen Ort, an dem dies landen kann. In Sharkly bleibt ein blockiert endender Lauf mit seinem Ausführungszustand und Ergebnis an seiner Aufgabe, und der Posteingang trennt Elemente, die eine menschliche Antwort oder Überprüfung benötigen, von normalen Updates. Es geht nicht um das spezifische Tool. Es geht darum, dass „noch läuft, später prüfen“ einen Verantwortlichen braucht, sonst wird es zu „niemand hat nachgesehen“.

Eine kurze Checkliste
- Jeder langsame Endpunkt gibt eine Auftrags-ID, eine Status-URL und eine Nachricht in einfacher Sprache zurück, die besagt, dass die Arbeit noch nicht abgeschlossen ist.
- Statusantworten enthalten ein boolesches
done-Feld, nicht nur einen String, den das Modell interpretieren muss. - Das Polling befindet sich im Tool-Wrapper mit exponentiellem Backoff und einer festen Obergrenze.
- Timeouts geben die Auftrags-ID zurück, damit die Arbeit fortgesetzt und nicht verloren gehen kann.
- Erfolg, Fehler und Timeout sind drei verschiedene Rückgabewerte.
- Laufende Jobs werden außerhalb des Gesprächs für alles, was länger als ein paar Minuten dauert, aufgezeichnet.
- Die Abschlussbehandlung ist idempotent, egal ob das Signal durch Polling oder durch einen Callback empfangen wird.
- Langsame, spät fehlschlagende, abgelaufene und duplizierte Abschlüsse haben alle gespeicherte Tests.
Wenn die Antwortformulierung und der Wrapper stimmen, hören langlaufende Operationen auf, ein Sonderfall für den Agenten zu sein. Er ruft ein Tool auf, wartet und erhält eine Antwort, was der Vertrag ist, den er am besten handhabt. Laden Sie Apidog herunter, um die Mocks für langsame Jobs zusammen mit den Tests zu erstellen.
Häufig gestellte Fragen
- Sollte die API für einen asynchronen Start 202 oder 200 zurückgeben?
202 Acceptedist der ehrliche Code und signalisiert Standard-Clients, dass die Verarbeitung noch nicht abgeschlossen ist. Verlassen Sie sich bei Agenten nicht allein darauf, da der Body das ist, was das Modell am zuverlässigsten liest. Verwenden Sie beides. - Wie lange sollte der Tool-Wrapper warten, bevor er aufgibt? Setzen Sie die Obergrenze leicht über dem realistischen Worst Case des Endpunkts, üblicherweise zwei bis zehn Minuten. Darüber hinaus blockiert der Wrapper einen Gesprächszug zu lange, und ein „später überprüfen“-Tool ist eine bessere Form.
- Welches Polling-Intervall sollte ich verwenden? Beginnen Sie mit dem eigenen
poll_after_seconds-Hinweis des Servers, falls vorhanden, und erhöhen Sie dann schrittweise um einen Faktor von etwa 1,5 mit einer Obergrenze von etwa 60 Sekunden. Festes Ein-Sekunden-Polling verschwendet Anfragen und kann Ratenbegrenzungen auslösen, wie in unserem Leitfaden zur Überschreitung von Ratenbegrenzungen beschrieben. - Kann der Agent während des Wartens etwas Nützliches tun? Nur wenn Ihr Orchestrator gleichzeitige Tool-Aufrufe unterstützt. Wo dies der Fall ist, starten Sie den Job, erledigen Sie die unabhängige Arbeit und überprüfen Sie dann den Status. Wo dies nicht der Fall ist, ist der blockierende Wrapper einfacher und weniger fehleranfällig als ein selbstgeschriebener Scheduler.
- Wie verhindere ich, dass der Agent den Erfolg zu früh meldet? Sagen Sie es in Worten im Antwort-Body, stellen Sie ein boolesches
done-Feld bereit und machen Sie das Abschluss-Tool zum einzigen Ort, an dem ein Ergebnis erscheint. Wenn die Startantwort kein Ergebnis enthält, gibt es für das Modell nichts als Ergebnis zu melden. - Funktionieren Webhooks für Agenten, die auf einem Laptop laufen? Nicht direkt, da es keinen öffentlichen Endpunkt gibt. Verwenden Sie für die Entwicklung einen Tunnel, wie in unserem Leitfaden zum Testen von localhost-APIs mit Webhook-Diensten beschrieben, oder bleiben Sie beim Polling, bis der Agent an einem adressierbaren Ort läuft.
