Zum Inhalt springen
Blog

AI

Warum Ihr KI-Agent diese Nachricht doppelt geschickt hat, und was Sie vor dem Launch verlangen sollten

KI-Agenten versenden Nachrichten, E-Mails und Bestellungen doppelt, weil die darunterliegende Infrastruktur standardmäßig erneut zustellt. Das sollten Gründer verlangen, bevor ein Agent echte Kunden erreicht.

Von Pykero Agency · Engineering team23. Okt. 20267 Min. Lesezeit

TL;DR

Doppelte Nachrichten sind kein LLM-Fehler, sondern ein Retry-Fehler: Webhooks, Queues und Modellaufrufe liefern alle mindestens einmal zu, daher braucht jede externe Aktion eines Agenten einen Idempotenzschlüssel, einen Reservierungsschritt und eine Dedupe-Tabelle. Verlangen Sie das, bevor ein Agent an echte Kunden sendet.

doppelte Chat-Benachrichtigungen auf dem Smartphone, Warum Ihr KI-Agent diese Nachricht doppelt geschickt hat, und was Sie vor dem Launch verlangen sollten

Ihr KI-Agent hat die Nachricht zweimal gesendet, weil etwas darunter erneut zugestellt hat, nicht weil das Modell sich "entschieden" hat. Webhooks, Queues, Worker und LLM-API-Clients liefern standardmäßig mindestens einmal zu, und ein Agent, der die Außenwelt ohne Idempotenzschlüssel aufruft, wird irgendwann doppelt senden, doppelt buchen oder doppelt abrechnen. Die Lösung ist architektonisch und im Vergleich zum Schaden günstig, sie gehört also in die Anforderungen, nicht in einen Patch nach dem Launch.

Retries sind der Standardfall, nicht die Ausnahme

Gründer stellen sich einen Agenten gerne als einzelnes Gespräch vor: Ein Kunde schreibt, das Modell denkt, eine Antwort geht raus. In der Produktion ist das eine Kette von Hops, und fast jeder Hop wiederholt sich unter Last.

  • Der eingehende Webhook. Messaging-Plattformen senden eine Benachrichtigung erneut, wenn Ihr Endpoint langsam antwortet oder einen Fehler zurückgibt. Wenn Ihr Handler bereits vor dem Timeout mit der Arbeit begonnen hat, haben Sie nun zwei Kopien desselben Events im Umlauf.
  • Die Queue. Standard-Queues wie Amazon SQS sind ausdrücklich als "at-least-once" dokumentiert: Eine Nachricht kann mehr als einmal zugestellt werden, und Ihr Consumer muss damit umgehen können (AWS-Dokumentation). Die meisten Managed-Agent-Runtimes bauen auf etwas Gleichwertigem auf.
  • Der Worker. Ein Crash, ein Deploy oder ein Out-of-Memory-Kill mitten in einer Aufgabe bedeutet, dass der Job von vorn läuft. Alles, was er schon erledigt hat, macht er noch einmal.
  • Der Modellaufruf. Jedes ernstzunehmende LLM-SDK führt bei Rate Limits und transienten Fehlern Retries durch. Wenn der erste Versuch serverseitig tatsächlich erfolgreich war, die Antwort aber verloren ging, zahlen Sie doppelt, und schlimmer noch, Ihr Code reagiert womöglich auf beide.
  • Der Tool-Call. Der Agent ruft Ihre Funktion zum Senden einer Nachricht oder Anlegen einer Bestellung auf. Diese Funktion spricht mit einer Drittanbieter-API mit eigenen Timeouts. Ein Timeout ist kein Fehlschlag, er ist ein Unbekanntes.

Nichts davon ist exotisch. Das ist das normale Verhalten normaler Infrastruktur. Ein Agent, der in einer Demo "zu 99 % zuverlässig" ist, wird bei einer Last getestet, bei der nichts davon auslöst. Im zweiten Monat, mit ein paar Tausend Konversationen pro Tag, löst alles davon aus.

Warum das LLM das schwieriger macht als ein klassischer Job

Ein konventioneller Worker, der erneut zustellt, verhält sich beim zweiten Mal zumindest gleich. Ein Agent nicht. Wenn ein Worker einen Planungsschritt erneut ausführt, wählt das Modell möglicherweise eine etwas andere Aktion: Der erste Versuch sendet "Ihre Bestellung wird Dienstag versendet", der Retry sendet "Ihre Bestellung wird morgen versendet", weil das Kontextfenster jetzt einen halb geschriebenen Zustand enthält. Der Kunde sieht zwei selbstbewusste, widersprüchliche Nachrichten vom selben Unternehmen.

Deshalb scheitern Lösungen auf Prompt-Ebene. Dem Modell zu sagen "sende niemals eine Nachricht zweimal" setzt voraus, dass das Modell weiß, dass der erste Versuch stattgefunden hat. Oft weiß es das nicht, weil der Fehler aufgetreten ist, nachdem das Modell geantwortet hat und bevor Ihr Code das Ergebnis erfasst hat. Deduplizierung muss unterhalb des Modells stattfinden, an der Grenze, an der Ihr System die Welt berührt. Das ist dasselbe Prinzip, das hinter den deterministischen Leitplanken steht, die wir in Zuverlässigkeit bei KI-Funktionen behandeln: Das Modell schlägt vor, der Code entscheidet, ob diese Aktion noch zulässig ist.

Was Exactly-Once für einen Agenten tatsächlich bedeutet

Exactly-once-Zustellung aus dem Netzwerk bekommen Sie nicht. Exactly-once-Wirkung schon, indem Sie jede externe Aktion idempotent machen. Drei Bausteine erledigen das.

Ein Idempotenzschlüssel pro beabsichtigter Aktion

Bevor der Agent etwas sendet, leitet Ihr Code einen Schlüssel davon ab, was die Aktion ist, nicht vom Versuch. Für eine Antwort ist das typischerweise die ID der eingehenden Nachricht plus der Konversationsschritt. Für eine Bestellung die Warenkorb-ID plus der Kunde. Zwei Retries derselben Absicht erzeugen denselben Schlüssel; zwei tatsächlich unterschiedliche Aktionen nicht. Stripes API ist hier das Referenzdesign: Der Client liefert den Schlüssel, der Server speichert das erste Ergebnis und gibt es bei Wiederholungen zurück (Stripe-Dokumentation). Die Send-Funktion Ihres Agenten sollte sich genauso verhalten, egal ob die nachgelagerte API Schlüssel nativ unterstützt oder Sie das selbst erzwingen.

Erst reservieren, dann handeln, dann aufzeichnen

Der Fehler, der am härtesten zuschlägt, ist "gesendet, aber nicht aufgezeichnet". Der Agent ruft die Messaging-API auf, die API akzeptiert die Nachricht, Ihr Prozess stirbt vor dem Schreiben in die Datenbank, und der Retry sieht keinen Eintrag und sendet erneut. Die Lösung ist, zuerst zu reservieren: den Schlüssel mit Status pending in eine actions-Tabelle einzufügen, bevor Sie nach außen rufen. Ein Unique Constraint auf dem Schlüssel bedeutet, dass ein gleichzeitiger oder wiederholter Versuch beim Insert fehlschlägt und stoppt (PostgreSQL-Constraints). Nachdem der externe Aufruf erfolgreich war, aktualisieren Sie die Zeile auf sent mit der Nachrichten-ID des Anbieters. Wenn Sie eine pending-Zeile finden, die älter als Ihr Timeout ist, ist das ein Fall für Reconciliation, nicht für erneutes Senden: Fragen Sie den Anbieter über den Schlüssel ab oder warten Sie auf einen Menschen.

Eingehende Events am Rand deduplizieren

Webhook-Handler sollten schnell bestätigen und die Event-ID mit demselben Unique-Constraint-Trick in einer Dedupe-Tabelle speichern. Eine doppelte Zustellung läuft gegen den Constraint und wird verworfen, bevor überhaupt ein Modell aufgerufen wird. Das spart auch Geld: Jedes Duplikat, das Sie am Rand verwerfen, ist ein LLM-Aufruf, den Sie nie bezahlen, was bei den Volumina relevant ist, über die wir in was ein WhatsApp-Sales-Agent kostet sprechen.

Was wir bei unserer eigenen Outreach-Engine gelernt haben

Unser Cold-Outreach-System scrapt die Website jedes Prospects mit einem selbst gehosteten Crawler und einem lokalen Modell und verfasst dann eine maßgeschneiderte E-Mail pro Unternehmen. Anfangs dachten wir, das schwierige Problem sei die Schreibqualität, und das war es teilweise auch. Das Muster, das sowohl bei Kosten als auch bei Qualität gewann, war ein einzelner Modellaufruf, der Fakten extrahiert und die E-Mail gemeinsam verfasst, statt einer mehrstufigen Kette. Ein unterschätzter Vorteil zeigte sich später: Ein einzelner Aufruf hat nur eine Ausgabe, die idempotent gemacht werden muss, sodass das Versprechen "eine E-Mail pro Unternehmen" mit einer einzigen Reservierungszeile, die auf der Unternehmensdomain basiert, durchgesetzt werden konnte. Jeder zusätzliche Schritt in einer Kette ist eine weitere Stelle, an der ein Retry doppelt auslösen kann, daher hat die Vereinfachung der Kette die Zuverlässigkeitsgeschichte ebenso vereinfacht wie die Rechnung. Wir haben die Seite des Verfassens in Single Call vs. Agent Chains beschrieben.

Was Sie verlangen sollten, bevor ein Agent einen echten Kunden berührt

Nehmen Sie Folgendes in das Leistungsverzeichnis oder den Vertrag mit dem Anbieter auf. Jeder Punkt ist eine Ja-oder-Nein-Frage mit einer nachweisbaren Antwort.

  • Jede ausgehende Aktion hat einen benannten Idempotenzschlüssel, und die Herleitung ist pro Aktionstyp dokumentiert.
  • Reservierung vor dem Senden. Zeigen Sie die Tabelle, den Unique Constraint und die Zustandsmaschine. Fragen Sie, was mit einer in pending hängenden Zeile passiert.
  • Eingehende Deduplizierung am Webhook, mit angegebenem Aufbewahrungsfenster. Plattformen können Stunden später erneut zustellen.
  • Retry-sichere Modellaufrufe. Die SDK-Retries sind in Ordnung, aber der umgebende Code darf "keine Antwort" nicht mit "nichts ist passiert" gleichsetzen.
  • Ein Chaos-Test bei der Abnahme. Beenden Sie den Worker mitten im Senden, spielen Sie denselben Webhook dreimal ab, erzwingen Sie einen Timeout bei der Messaging-API. Null Duplikate erreichen die Testnummer. Wenn die Agentur diesen Test nicht durchführen kann, hat sie nicht dafür gebaut.
  • Reconciliation statt erneutem Senden als Standard, wenn der Zustand unbekannt ist. Eine für Menschen sichtbare Warteschlange für Unbekannte schlägt immer einen automatischen Retry.
  • Beobachtbarkeit bei Duplikaten. Ein Zähler für Constraint-Treffer ist Ihr Frühwarnsystem, dass die Infrastruktur häufiger zustellt als erwartet, lange bevor sich ein Kunde beschwert. Kombinieren Sie das mit dem Alerting aus Monitoring verpasster Agent-Läufe.

Das Kostengespräch

Einen Agenten retry-sicher zu machen, ist kein großer Kostenpunkt. Für einen typischen Sales- oder Support-Agenten mit drei oder vier Aktionstypen rechnen Sie mit wenigen Tagen fokussiertem Engineering, größtenteils für das Design der Schlüssel und des Reservierungsflows, plus einem Tag für die Chaos-Tests. Die teure Variante ist die, bei der Sie es überspringen: erstattete Doppelbelastungen, eine wegen spam-ähnlichem Verhalten gesperrte Messaging-Nummer und die schleichende Erosion, die entsteht, wenn Kunden lernen, dass Ihr Agent nicht ganz vertrauenswürdig ist. Wenn ein Angebot für einen Agenten, der echte Nachrichten sendet, Idempotenz nirgendwo erwähnt, ist das die Frage, die Sie vor der Unterschrift stellen sollten.

Wenn Sie einen Agenten planen, der im Namen Ihres Unternehmens handelt, und die Zuverlässigkeitsanforderungen festhalten möchten, bevor der Build beginnt, sprechen wir.

ai agentsreliabilityidempotencywhatsapp

Häufig gestellte Fragen

Warum hat mein KI-Agent dieselbe WhatsApp-Nachricht zweimal geschickt?

Fast immer, weil ein Webhook, eine Queue oder ein Worker nach einem Timeout erneut zugestellt hat und der Agent keinen Idempotenzschlüssel für die beabsichtigte Aktion hatte. Das Modell hat seine Arbeit getan; die Infrastruktur hat sie zweimal ausgeführt.

Kann Prompt Engineering doppelte Aktionen verhindern?

Nein. Der Prompt läuft innerhalb des Retries. Deduplizierung muss an der Grenze stattfinden, an der der Agent die Außenwelt aufruft, im Code und in der Datenbank, nicht in Anweisungen an das Modell.

Wie viel kostet es zusätzlich, einen Agenten retry-sicher zu machen?

Meist wenige Tage Engineering pro Typ externer Aktion, vor allem für das Design des Schlüssels und des Reservierungsschritts. Das ist weit günstiger als die Rückerstattungen, gesperrten Nummern und der Vertrauensverlust durch Duplikate.

Betrifft dieses Problem auch Managed-Agent-Plattformen?

Ja. Managed Runtimes wiederholen fehlgeschlagene Schritte für Sie, was hilfreich ist, aber die Idempotenz Ihrer eigenen Aktionen bleibt Ihre Verantwortung. Fragen Sie den Anbieter genau, wo die Deduplizierung stattfindet.

So kann Pykero helfen

Leistungen passend zu diesem Artikel.

Sie planen etwas Ähnliches?

Pykero Agency entwirft und liefert produktionsreife Web-, Mobile-, SaaS- und KI-Produkte.

Sprechen Sie mit uns

Discussion

Be the first to comment.

Weiterlesen