Leitfaden und Einblick

Streaming-Token-Buchhaltung in einem AI-API-Gateway: Endgültige Nutzung, Stornierungen und Teilantworten

Streaming verbessert die wahrgenommene Latenz, kann jedoch die Analyse und Abrechnung der KI-Nutzung beeinträchtigen, wenn das Gateway nur Bytes weiterleitet. Hier ist ein praktisches Zustandsmaschinenmuster zum Erfassen der endgültigen Nutzung, abgebrochener Streams, Anbieterfehler und Teilantworten.

Streaming-LLM-Antworten sind leicht zu vermitteln und schwer korrekt abzurechnen. Wenn ein AI-API-Gateway vom Server gesendete Ereignisse an den Client weiterleitet, die ersten Blöcke jedoch als Nutzungsdatensatz behandelt, weichen die Mandantenanalysen ab. Die Abweichung tritt normalerweise bei Streitigkeiten auf wie: „Der Benutzer hat nur die Hälfte der Antwort gesehen“, „Der Anbieter hat mehr in Rechnung gestellt, als unser Dashboard anzeigt“, „Kontingent wurde zu früh freigegeben“ oder „Eine Zeitüberschreitung hat Token erzeugt, aber keinen Rechnungsposten.“

Das Grundproblem besteht darin, dass gestreamte Anrufe kein einzelnes Ereignis sind. Es handelt sich um eine Abfolge: Anforderung angenommen, Upstream-Stream geöffnet, Bytes geliefert, endgültige Nutzung gemeldet, Anbieter gestoppt, Client-Verbindung getrennt, Gateway-Zeitüberschreitung und Abrechnung erledigt. Ein zuverlässiges Gateway sollte diese Zustände explizit modellieren, anstatt davon auszugehen, dass eine abgeschlossene HTTP-Antwort der einzige erfolgreiche Pfad ist.

Der Fehlermodus: Streaming verbirgt die Abrechnungsgrenze

Nicht gestreamte Vervollständigungen geben normalerweise ein Antwortobjekt mit Nutzungsmetadaten zurück. Ein Gateway kann diese Nutzung normalisieren, eine Ledger-Zeile schreiben, das Kontingent aktualisieren und Analysen in einem Durchgang ausgeben.

Streaming verändert die Grenzen. Das Benutzererlebnis ist inkrementell, aber die Abrechnungswahrheit kann am Ende, in einem anbieterspezifischen Endereignis, in einem kumulativen Delta, durch eine aggregierte SDK-Antwort oder später durch Provider-Reporting-APIs ankommen. Wenn der Client die Verbindung vor dem endgültigen Nutzungsereignis trennt, hat das Gateway möglicherweise nur einen Teil der Antwort geliefert, während der Anbieter noch weitere Token generiert und in Rechnung gestellt hat.

Fakt: OpenAI dokumentiert, dass Streaming-Anrufer, die Nutzungsdaten wünschen, stream_options mit include_usage festlegen sollten. OpenAI bietet auch Nutzungs- und Kostenendpunkte auf Organisationsebene, weist jedoch darauf hin, dass Nutzung und Kosten aus finanziellen Gründen möglicherweise nicht immer perfekt vereinbar sind.

Fakt: Anthropic Streaming verwendet vom Server gesendete Ereignisse wie message_start, content_block_delta, message_delta und message_stop. Seine message_delta-Nutzungsinformationen sind kumulativ, sodass ein Gateway nicht jedes Nutzungsdelta addieren darf.

Fakt: Streaming-APIs im Gemini- und Vertex-Stil können inkrementelle Blöcke verfügbar machen, während SDKs möglicherweise auch ein aggregiertes Antwortobjekt bereitstellen. Für Gateways kann dieser aggregierte Pfad eine bessere Quelle für die abgeschlossene Nutzung sein als die sichtbaren Blöcke allein.

Verwenden Sie eine Stream-Zustandsmaschine, kein boolesches Erfolgsflag

Eine gestreamte Anfrage sollte über einen dauerhaften Nutzungsdatensatz verfügen, bevor der Upstream-Aufruf beginnt. Dieser Datensatz sollte explizite Zustände durchlaufen. Ein praktisches Minimum ist:

  • akzeptiert: Das Gateway hat den Schlüssel authentifiziert, den Mandanten zugeordnet und eine offene Hauptbuchzeile erstellt.
  • first_byte_sent: Mindestens ein Ausgabeereignis hat den Downstream-Client erreicht.
  • provider_completed: Der Upstream-Anbieter hat ein normales Stoppsignal oder ein abgeschlossenes Antwortobjekt ausgegeben.
  • client_aborted: Der Downstream-Socket wurde vor dem normalen Gateway-Abschluss geschlossen.
  • provider_error: Der Upstream-Anbieter hat einen Fehler zurückgegeben, nachdem der Stream begann oder bevor die endgültige Verwendung eintraf.
  • gateway_timeout: Das Gateway hat sein Latenzbudget erzwungen und die Anfrage beendet.
  • abgerechnet: Das Gateway hat die Nutzung in Mieterkosten und Kontingentverbrauch umgewandelt.
  • abgeglichen: Spätere Anbieternutzungs- oder Kostendaten bestätigten oder passten die Zeile an.

Dieses Modell verhindert einen häufigen Analysefehler: Es markiert jeden Stream, der Text produziert hat, als „erfolgreich und genau“. Ein Stream kann für den Benutzer nützlich sein, vom Anbieter unvollständig sein, für die Abrechnung geschätzt werden und gleichzeitig auf einen Abgleich warten.

Empfohlene Ledger-Felder

Halten Sie die Anforderungszeitzeile klein, aber explizit:

{
  „request_id“: „gw_req_…“,
  „tenant_id“: „tenant_123“,
  „api_key_id“: „key_456“,
  „provider“: „openai|anthropic|gemini|…“,
  „provider_request_id“: null,
  „model“: „provider-model-id“,
  „state“: „akzeptiert“,
  „stream“: wahr,
  „input_tokens“: null,
  „output_tokens_billed“: null,
  „output_tokens_delivered_estimate“: 0,
  „provider_usage_source“: null,
  „billing_status“: „pending_reconciliation“,
  „client_abort_at“: null,
  „provider_completed_at“: null,
  „settled_at“: null,
  „error_class“: null

Die wichtige Trennung ist output_tokens_billed versus output_tokens_delivered_estimate. Den Benutzern ist es wichtig, was ihre Bewerbung erreicht hat. Der Finanzabteilung ist es wichtig, was der Anbieter in Rechnung gestellt hat. Diese Zahlen können nach Verbindungsabbrüchen, Tool-Call-Streams, versteckten Argumentationstokens, zwischengespeicherten Tokens, Sicherheitsstopps oder Gateway-Timeouts unterschiedlich sein.

Anbieterspezifische Erfassungsregeln

Eine anbieterneutrale OpenAI-kompatible API ist für Anwendungsentwickler nützlich, der Gateway-Adapter benötigt jedoch weiterhin anbieterspezifische Abrechnungsregeln.

OpenAI-kompatibles Streaming

Stellen Sie für OpenAI-Routen eine Gateway-Option bereit, die Upstream-Nutzungsberichte ermöglicht, sofern unterstützt. Ein gängiges Muster besteht darin, einen Standardwert auf Gateway-Ebene zu akzeptieren, z. B.:

{
  „stream“: wahr,
  "stream_options": {
    „include_usage“: wahr
  }

Wenn der Downstream-Aufrufer es weglässt, kann das Gateway entscheiden, ob es es für Routen einfügt, bei denen dies kompatibel ist. Dokumentieren Sie dieses Verhalten, da einige Kunden eine genaue Kabelkompatibilität erwarten und einige Modelle oder Upstreams die endgültige Verwendung möglicherweise nicht auf die gleiche Weise unterstützen.

Empfehlung: Begleichen Sie die Mieterkosten nicht aus frühen Teilen. Halten Sie die Hauptbuchzeile geöffnet, bis das endgültige Nutzungsereignis erfasst wird, die Anbieterantwort ohne Nutzung endet oder der Stream in einen Fehler- oder Abbruchpfad eintritt.

Anthropisches Streaming

Die kumulative Nutzung von Anthropic erfordert eine andere Regel. Wenn ein Gateway drei message_delta-Ereignisse mit Ausgabe-Token-Zählungen von 10, 25 und 40 erkennt, beträgt die Ausgabe-Zählung 40 und nicht 75.

let LatestUsage = null;
for wait (const event of anthropicStream) {
  if (event.type === "message_delta" && event.usage) {
    if (latestUsage && event.usage.output_tokens < LatestUsage.output_tokens) {
      emit("cumulative_usage_regressed", requestId);
    }
    LatestUsage = event.usage;
  }
  forwardToClient(event);
}
settleFromLatestCumulativeUsage(latestUsage);

Empfehlung: Erfassen Sie den neuesten kumulativen Nutzungswert und geben Sie ein Beobachtbarkeitsereignis aus, wenn er zurückgeht. Eine Regression kann auf Parserfehler, doppelte Ereignisse, Anbieteränderungen oder gemischte Streams hinweisen.

Streaming im Gemini- und Vertex-Stil

Gemini unterstützt Streaming-Chunks, um die wahrgenommene Latenz zu reduzieren. In SDKs im Vertex-Stil kann Streaming sowohl einen asynchronen Stream als auch ein aggregiertes Antwortobjekt verfügbar machen. Ein Gateway sollte diesen aggregierten Pfad beibehalten, sofern verfügbar.

const streamingResult = waiting model.generateContentStream(request);
forwait (const chunk of streamingResult.stream) {
  vorwärtsChunk(chunk);
  countDeliveredBytesOrText(chunk);
}
const aggregiert = warte auf StreamingResult.response;
settleFromAggregatedUsage(aggregiert);

Empfehlung: Vermeiden Sie den Aufbau der gesamten Buchhaltung aus sichtbaren Blöcken, wenn das SDK einen vollständigen Antwortdatensatz liefert. Chunks dienen der Latenz. Das Endobjekt eignet sich oft besser für Abrechnung und Analyse.

Behandeln Sie Verbindungsabbrüche von Clients als erstklassige Abrechnungsereignisse

Bei Verbindungsabbrüchen von Kunden verlieren viele Gateways Geld oder überfordern Kunden. Ein Browser-Tab wird geschlossen, ein Mobilfunknetz wird unterbrochen oder eine Anwendung bricht eine Anfrage ab. Das Gateway stellt fest, dass der Downstream-Socket geschlossen ist, aber der Upstream-Anbieter generiert möglicherweise noch.

Das Gateway sollte eine explizite Richtlinienauswahl treffen:

  • Upstream sofort abbrechen: reduziert verschwendete Generierung und Anbieterkosten, kann jedoch Arbeitsabläufe unterbrechen, bei denen das Backend das Ergebnis nach der Trennung der Benutzeroberfläche noch benötigt.
  • Upstream im Hintergrund fortfahren: kann die Arbeit für serverseitige Verbraucher bewahren, aber der Benutzer sieht möglicherweise nicht alle generierten und abgerechneten Token.
  • Routenabhängiges Verhalten: Für interaktiven Chat abbrechen, für auftragsähnliche Arbeitsabläufe fortfahren und die Einstellung für Mieter sichtbar machen.

Eine praktische Standardeinstellung für interaktives Streaming besteht darin, den Upstream abzubrechen, wenn der Downstream-Client die Verbindung trennt, und dann die Ledger-Zeile als client_aborted zu markieren. Wenn die endgültige Nutzung während der Stornierung erfolgt, rechnen Sie mit dieser maßgeblichen Nutzung ab. Wenn nicht, markieren Sie die Zeile als geschätzt oder pending_reconciliation, anstatt so zu tun, als sei sie exakt.

downstream.on("close", async () => {
  if (!providerCompleted) {
    ledger.markClientAborted(requestId);
    warte upstream.abort().catch(() => {
      ledger.emit("upstream_cancel_failed", requestId);
    });
  }
});

Empfehlung: Stellen Sie transparente Abrechnungsbezeichnungen wie final, provider_reconciled, estimated, waived oder pending_reconciliation bereit. Dies ist vertretbarer, als jeden gestreamten Anruf sofort als genau anzuzeigen.

Kontingentdurchsetzung während eines Streams

Eine genaue Abrechnung hängt in der Regel von der endgültigen Anbieternutzung ab, die Kontingentdurchsetzung kann jedoch nicht immer bis zum Ende warten. Einem Mieter mit knappem Budget sollte es nicht gestattet sein, unbegrenzt zu streamen, da die genaue Nutzung während der Laufzeit nicht verfügbar ist.

Verwenden Sie zwei Mechanismen zusammen:

  1. Preflight-Reservierung: Reservieren Sie einen geschätzten Höchstbetrag basierend auf dem Modell, den angeforderten maximalen Token, den Mieterrichtlinien und dem aktuellen Kontostand.
  2. Streaming-Druckprüfungen: Schätzen Sie die gelieferte Ausgabe während des Streams und stoppen Sie, wenn die Anfrage eine konfigurierte Sicherheitsgrenze überschreitet.

Dies ist ein Kontrollmechanismus, nicht die endgültige Rechnung. Anbieter können zwischengespeicherte Token, Reasoning-Token, multimodale Token oder versteckte Token anders zählen als der Schätzer eines Gateways.

Kompromiss: Echtzeitschätzungen helfen bei der Durchsetzung von Budgets, sie können jedoch von den vom Anbieter in Rechnung gestellten Token abweichen. Bei der endgültigen Abrechnung sollte, sofern verfügbar, die Verwendung eines maßgeblichen Anbieters verwendet werden, und bei der Abstimmung sollten die Schätzungen später angepasst werden.

Beobachtbarkeitsereignisse, die Buchhaltungsfehler aufdecken

Streaming-Abrechnungsfehler lassen sich einfacher beheben, wenn das Gateway gezielte Ereignisse ausgibt und nicht nur generische Anforderungsprotokolle. Fügen Sie Ereignisse hinzu wie:

  • final_usage_missing: Stream ohne autorisierende Verwendung beendet.
  • cumulative_usage_regressed: Die kumulative Token-Anzahl wurde nach hinten verschoben.
  • stream_ended_without_stop_event: Es wurde keine normale Provider-Stoppmarkierung beobachtet.
  • aborted_after_provider_completion: Der Anbieter wurde abgeschlossen, aber der Downstream-Client wurde geschlossen, bevor das Gateway die Weiterleitung beendete.
  • settled_from_estimate: Das Mieterbuch hat eine Schätzung verwendet, da die endgültige Nutzung nicht verfügbar war.
  • reconciliation_adjusted_usage: Die Anbieterberichterstattung hat die Zeile später geändert.

Fakt: Die semantischen Konventionen von OpenTelemetry GenAI empfehlen die Verwendung von vom Anbieter zurückgegebenen Nutzungsinformationen für Streaming-Antworten, sofern verfügbar, und warnen davor, Nutzungsmetriken zu melden, wenn die Token-Anzahl nicht effizient oder genau ermittelt werden kann.

Für KI-Nutzungsanalysen bedeutet dies, dass Dashboards Konfidenzniveaus unterstützen sollten. Ein Diagramm, das endgültige, geschätzte und abgeglichene Werte ohne Beschriftungen mischt, sieht vielleicht sauber aus, führt aber Finanz- und Supportteams in die Irre.

Konformitätstests für Streaming Accounting

Verlassen Sie sich nicht auf manuelle Tests mit einer Happy-Path-Chat-Eingabeaufforderung. Jeder Anbieteradapter sollte Konformitätstests für die Fälle haben, die Ledger beschädigen:

  • Normaler Stream: Endgültige Nutzung kommt, Stopp-Ereignis beobachtet, Hauptbuch wird als endgültig abgerechnet.
  • Tool-Call-Stream: Tool-Call-Deltas werden weitergeleitet, die Nutzung wird erfasst, strukturierte Metadaten beeinträchtigen die Token-Zählung nicht.
  • Sicherheits- oder Verweigerungsstopp: Anbieter stoppt vorzeitig, Nutzung rechnet trotzdem korrekt ab.
  • Erzwungene Client-Trennung: Downstream wird nach teilweiser Ausgabe geschlossen; Upstream wird gemäß den Richtlinien abgebrochen oder fortgesetzt.
  • Upstream 5xx nach Teilausgabe: Gateway zeichnet Teillieferung auf und markiert die Anfrage nicht als sauberen Erfolg.
  • Gateway-Zeitüberschreitung vor endgültiger Nutzung: Zeile wird geschätzt oder wartet auf den Abgleich.
  • Fehlendes letztes Ereignis: Der Adapter gibt final_usage_missing aus und vermeidet genaue Abrechnungsbezeichnungen.

Diese Tests sollten Zustandsübergänge, Ledger-Felder, ausgegebene Beobachtbarkeitsereignisse und Downstream-Verhalten bestätigen. Die Byte-für-Byte-Stream-Kompatibilität reicht nicht aus; Die buchhalterischen Nebeneffekte sind Vertragsbestandteil.

Checkliste für die praktische Umsetzung

  • Erstellen Sie die Nutzungsbuchzeile, bevor Sie die Upstream-Anfrage versenden.
  • Speichern Sie Mandanten-, Schlüssel-, Benutzer-, Modell-, Route-, Anbieter- und Anforderungskennungen zum Zeitpunkt der Anforderung.
  • Aktivieren Sie die endgültige Nutzungsberichterstattung des Anbieters, sofern dies unterstützt wird, z. B. OpenAI-kompatibles stream_options.include_usage.
  • Speichern Sie bei kumulativen Anbietern den neuesten Nutzungswert, anstatt Ereignisse zu summieren.
  • Aggregierte Antwortobjekte beibehalten, wenn SDKs sie bereitstellen.
  • Verfolgen Sie die gelieferte Ausgabe getrennt von der vom Anbieter in Rechnung gestellten Nutzung.
  • Bei Trennung stromaufwärts gemäß Routenrichtlinie abbrechen und client_aborted markieren.
  • Verwenden Sie transparente Abrechnungsstatus: endgültig, geschätzt, ausstehender Abgleich, Anbieter abgeglichen oder verzichtet.
  • Abrechnungsspezifische Observability-Ereignisse ausgeben.
  • Später Abgleich mit Anbieternutzungs- oder Kostenberichten, sofern verfügbar, unter Beibehaltung der Mieterzuordnung zum Zeitpunkt der Anfrage.

Was Mietern zu zeigen ist

Mieter brauchen nicht jedes interne Ereignis, aber sie brauchen ehrliche Etiketten. Eine nützliche Nutzungstabelle könnte Folgendes anzeigen:

  • Status: endgültig, geschätzt oder abgeglichen.
  • Anforderungsergebnis: abgeschlossen, Client abgebrochen, Anbieterfehler oder Gateway-Zeitüberschreitung.
  • Gelieferte Ausgabe: ungefährer Text oder Bytes, die an den Client gesendet werden.
  • In Rechnung gestellte Token: vom Anbieter normalisierte Nutzung, die für Kosten verwendet wird.
  • Anpassung: jedes spätere Abgleichsdelta.

Dieses Design reduziert die Mehrdeutigkeit der Unterstützung. Wenn ein Benutzer nur einen Teil einer Antwort gesehen hat, kann das Dashboard erklären, ob der Anbieter bereits abgeschlossen hat, ob das Gateway im Vorfeld gekündigt hat und ob die Gebühr endgültig oder geschätzt ist.

Empfehlungen versus Vorhersagen

Empfehlungen: Behandeln Sie gestreamte Anfragen als Zustandsmaschinen, warten Sie vor der genauen Abrechnung auf die maßgebliche endgültige Nutzung, trennen Sie die gelieferte Ausgabe von der in Rechnung gestellten Nutzung und beschriften Sie geschätzte Zeilen ehrlich. Anbieteradapter sollten eine anbieterspezifische Nutzungssemantik kodieren, anstatt jeden Stream in einen generischen Byte-Proxy zu reduzieren.

Vorhersage: Streaming-Accounting wird immer wichtiger, da Modelle mehr versteckte Arbeit aufdecken: Argumentations-Tokens, zwischengespeicherte Token-Rabatte, multimodale Verarbeitung, Werkzeugnutzungsspuren und Sicherheitsstopps. Gateways, die bereits die vom Anbieter abgerechnete Nutzung von der für den Client sichtbaren Ausgabe trennen, lassen sich leichter anpassen als Gateways, die nur gestreamten Text zählen.

Umsetzbare Schlussfolgerung

Wenn Ihr Gateway Streaming unterstützt, prüfen Sie noch heute einen Pfad: Erzwingen Sie die Trennung eines Clients nach den ersten paar Blöcken und überprüfen Sie die Ledger-Zeile. Wenn dort „Erfolg“ mit exakt aussehenden Token-Zählungen steht, lügen Ihre Analysen wahrscheinlich.

Die Lösung besteht nicht darin, das Streaming aufzugeben. Behalten Sie die schnelle Benutzererfahrung bei, aber machen Sie Stream-Abschluss, Abbruch, Anbieterfehler, fehlende endgültige Nutzung und Abgleich explizite Abrechnungsstatus. Das gibt Produktteams reaktionsfähige Ergebnisse, Finanzteams vertretbare Kosten und Supportteams genügend Beweise, um Teilantworten ohne Vermutungen zu erklären.

Verwandte Lektüre

FAQ

Häufig gestellte Fragen

Sollte ein Gateway gestreamte Antworten anhand der geschätzten Token-Anzahl abrechnen?
Nutzen Sie bei Bedarf Schätzungen für den Kontingentschutz in Echtzeit, aber berechnen Sie die genauen Mandantenkosten anhand der vom Anbieter zurückgegebenen Nutzung, sofern verfügbar. Wenn die endgültige Nutzung fehlt, kennzeichnen Sie die Zeile als „geschätzt“ oder „Ausstehender Abgleich“.
Warum können gelieferte Ausgabetokens von abgerechneten Tokens abweichen?
Der Client kann die Verbindung trennen, das Gateway kann eine Zeitüberschreitung haben, der Anbieter kann versteckte Begründungen oder multimodale Token zählen oder ein Anbieter kann die Generierung beenden, nachdem der Benutzer keine Bytes mehr empfängt. Verfolgen Sie die gelieferte Leistung getrennt von der vom Anbieter in Rechnung gestellten Nutzung.
Was ist der häufigste Buchhaltungsfehler bei Anthropic-Streaming?
Summieren kumulativer Nutzungsereignisse. Anthropic message_delta-Nutzungszahlen sind kumulativ, daher sollte das Gateway den neuesten Wert speichern, anstatt jedes Ereignis hinzuzufügen.
Was soll passieren, wenn ein Browser während eines Streams die Verbindung trennt?
Bei interaktiven Routen besteht eine praktische Standardeinstellung darin, die Upstream-Anforderung abzubrechen, die Ledger-Zeile als „client_aborted“ zu markieren und bei Eintreffen nur über die Verwendung des autorisierenden Anbieters abzurechnen. Andernfalls markieren Sie die Zeile als „geschätzt“ oder „Ausstehende Abstimmung“.