Streamingtoken-accounting in een AI API-gateway: eindgebruik, annuleringen en gedeeltelijke reacties
Streaming verbetert de waargenomen latentie, maar kan AI-gebruiksanalyses en facturering verbreken als de gateway alleen proxybytes gebruikt. Hier is een praktisch state-machine-patroon voor het vastleggen van eindgebruik, afgebroken streams, providerfouten en gedeeltelijke reacties.
Streaming LLM-reacties zijn gemakkelijk te proxyen en moeilijk correct te factureren. Als een AI API-gateway door de server verzonden gebeurtenissen doorstuurt naar de client, maar de eerste chunks als gebruiksrecord behandelt, zullen de tenantanalyses afwijken. Deze afwijking komt meestal tot uiting in geschillen zoals: “de gebruiker zag slechts de helft van het antwoord”, “de provider heeft meer gefactureerd dan ons dashboard laat zien”, “quotum is te vroeg vrijgegeven” of “een time-out leverde tokens op, maar geen factuurregel.”
Het kernprobleem is dat gestreamde oproepen niet uit één gebeurtenis bestaan. Ze vormen een reeks: verzoek geaccepteerd, upstream-stream geopend, bytes geleverd, eindgebruik gerapporteerd, provider gestopt, client-verbinding verbroken, gateway-time-out en facturering afgehandeld. Een betrouwbare gateway zou deze toestanden expliciet moeten modelleren in plaats van aan te nemen dat een voltooid HTTP-antwoord het enige succesvolle pad is.
De faalmodus: streaming verbergt de boekhoudkundige grens
Niet-gestreamde voltooiingen retourneren doorgaans één antwoordobject met metagegevens over het gebruik. Een gateway kan dat gebruik normaliseren, een grootboekrij schrijven, quota bijwerken en analyses in één keer verzenden.
Streaming verandert de grens. De gebruikerservaring is incrementeel, maar de factureringswaarheid kan aan het einde komen, in een providerspecifieke eindgebeurtenis, in een cumulatieve delta, via een geaggregeerde SDK-reactie, of later via API's voor providerrapportage. Als de client de verbinding verbreekt vóór de uiteindelijke gebruiksgebeurtenis, heeft de gateway mogelijk slechts een deel van het antwoord geleverd, terwijl de provider nog steeds meer tokens heeft gegenereerd en gefactureerd.
Feit: OpenAI documenteert dat streaming-bellers die gebruiksgegevens willen, stream_options moeten instellen met include_usage. OpenAI biedt ook gebruiks- en kosteneindpunten op organisatieniveau, maar merkt op dat gebruik en kosten om financiële doeleinden niet altijd perfect op elkaar aansluiten.
Feit: antropische streaming maakt gebruik van door de server verzonden gebeurtenissen zoals message_start, content_block_delta, message_delta en message_stop. De gebruiksinformatie van message_delta is cumulatief, dus een gateway mag niet elke gebruiksdelta bij elkaar optellen.
Feit: streaming-API's in Gemini- en Vertex-stijl kunnen incrementele delen weergeven, terwijl SDK's ook een geaggregeerd antwoordobject kunnen bieden. Voor gateways kan dat samengevoegde pad een betere bron zijn voor voltooid gebruik dan alleen de zichtbare delen.
Gebruik een stream state machine, geen booleaanse succesvlag
Een gestreamd verzoek moet een duurzaam gebruiksrecord hebben voordat het upstream-gesprek begint. Dat record zou door expliciete staten moeten bewegen. Een praktisch minimum is:
geaccepteerd: de gateway heeft de sleutel geverifieerd, de tenant toegewezen en een open grootboekrij gemaakt.first_byte_sent: ten minste één uitvoergebeurtenis heeft de downstream-client bereikt.provider_completed: de upstreamprovider heeft een normaal stopsignaal of voltooid antwoordobject uitgezonden.client_aborted: de downstream-socket is gesloten voordat de normale gateway is voltooid.provider_error: de upstreamprovider heeft een fout geretourneerd nadat de stream begon of voordat het uiteindelijke gebruik arriveerde.gateway_timeout: de gateway heeft zijn latentiebudget afgedwongen en het verzoek beëindigd.afgewikkeld: de gateway heeft het gebruik omgezet in tenantkosten en quotumverbruik.afgestemd: latere providergebruiks- of kostengegevens hebben de rij bevestigd of aangepast.
Dit model voorkomt een veel voorkomende analysefout: elke stream die tekst produceerde, wordt gemarkeerd als 'succesvol en exact'. Een stream kan nuttig zijn voor de gebruiker, onvolledig zijn bij de provider, geschat worden voor facturering en tegelijkertijd in afwachting zijn van afstemming.
Aanbevolen grootboekvelden
Houd de rij met verzoektijd klein maar expliciet:
{
"request_id": "gw_req_...",
"tenant_id": "tenant_123",
"api_key_id": "key_456",
"provider": "openai|antropisch|gemini|...",
"provider_request_id": null,
"model": "provider-model-id",
"staat": "geaccepteerd",
"stream": waar,
"input_tokens": null,
"output_tokens_billed": null,
"output_tokens_delivered_schatting": 0,
"provider_usage_source": null,
"billing_status": "in afwachting van_afstemming",
"client_abort_at": null,
"provider_completed_at": null,
"settled_at": null,
"error_class": nul
De belangrijke scheiding is output_tokens_billed versus output_tokens_delivered_ estimate. Het maakt gebruikers uit wat hun applicatie bereikt. Financiën maakt uit wat de aanbieder in rekening brengt. Deze cijfers kunnen verschillen na verbroken verbindingen, tool-call-streams, verborgen redeneringstokens, in de cache opgeslagen tokens, veiligheidsstops of gateway-time-outs.
Providerspecifieke vastleggingsregels
Een provider-neutrale OpenAI-compatibele API is handig voor applicatie-ontwikkelaars, maar de gateway-adapter heeft nog steeds provider-specifieke boekhoudregels nodig.
OpenAI-compatibele streaming
Voor OpenAI-routes moet u een gateway-optie beschikbaar stellen die upstream-gebruiksrapportage mogelijk maakt, indien ondersteund. Een gebruikelijk patroon is het accepteren van een standaardinstelling op gatewayniveau, zoals:
{
"stream": waar,
"stream_opties": {
"include_usage": waar
}
Als de downstream-beller het weglaat, kan de gateway beslissen of het moet worden geïnjecteerd voor routes waar dit compatibel is. Documenteer dit gedrag omdat sommige clients exacte kabelcompatibiliteit verwachten en sommige modellen of upstreams het eindgebruik mogelijk niet op dezelfde manier ondersteunen.
Aanbeveling: verreken de huurderkosten niet op basis van vroege delen. Houd de grootboekrij open totdat de uiteindelijke gebruiksgebeurtenis is vastgelegd, de respons van de provider eindigt zonder gebruik, of de stream een fout- of annuleringspad binnengaat.
Antropische streaming
Het cumulatieve gebruik van Anthropic vereist een andere regel. Als een gateway drie message_delta-gebeurtenissen ziet met een uitvoertokenaantal van 10, 25 en 40, is het uitvoeraantal 40 en niet 75.
laat nieuwsteUsage = null;
voor wachten (const-gebeurtenis van anthropicStream) {
if (gebeurtenistype === "message_delta" && gebeurtenis.usage) {
if (laatsteGebruik && event.usage.output_tokens
Aanbeveling: registreer de laatste cumulatieve gebruikswaarde en verzend een waarneembaarheidsgebeurtenis als deze achteruitgaat. Een regressie kan wijzen op parserbugs, dubbele gebeurtenissen, wijzigingen in de provider of gemengde streams.
Streaming in Gemini- en Vertex-stijl
Gemini ondersteunt streaming-brokken om de waargenomen latentie te verminderen. In SDK's in Vertex-stijl kan streaming zowel een asynchrone stroom als een geaggregeerd antwoordobject blootleggen. Een gateway moet dat geaggregeerde pad behouden, indien beschikbaar.
const streamingResult = wachten op model.generateContentStream(request);
voor wachten (const deel van streamingResult.stream) {
forwardChunk(stuk);
countDeliveredBytesOrText(chunk);
}
const geaggregeerd = wacht op streamingResult.response;
nederzettingFromAggregatedUsage(geaggregeerd);
Aanbeveling: vermijd het opbouwen van alle boekhouding uit zichtbare delen als de SDK een voltooid antwoordrecord geeft. Chunks zijn voor latentie. Het uiteindelijke doel is vaak beter voor facturering en analyse.
Behandel verbroken verbindingen van klanten als eersteklas boekhoudkundige gebeurtenissen
Clientverbroken verbindingen zijn de reden dat veel gateways geld verliezen of klanten te veel in rekening brengen. Een browsertabblad wordt gesloten, een mobiel netwerk valt weg of een applicatie annuleert een verzoek. De gateway merkt dat de downstream-socket gesloten is, maar de upstream-provider genereert mogelijk nog steeds.
De gateway moet een expliciete beleidskeuze maken:
- Upstream onmiddellijk opzeggen: vermindert verspilling van opwekking en providerkosten, maar kan workflows verbreken waarbij de backend nog steeds het resultaat nodig heeft nadat de gebruikersinterface is verbroken.
- Upstream doorgaan op de achtergrond: kan werk behouden voor consumenten aan de serverzijde, maar de gebruiker ziet mogelijk niet alle gegenereerde en gefactureerde tokens.
- Routeafhankelijk gedrag: annuleer voor interactieve chat, ga door voor taakachtige workflows en maak de instelling zichtbaar voor huurders.
Een praktische standaard voor interactieve streaming is om upstream te annuleren wanneer de downstream-client de verbinding verbreekt, en vervolgens de grootboekrij te markeren als client_aborted. Als het definitieve gebruik tijdens de annulering binnenkomt, reken dan af met dat gezaghebbende gebruik. Als dit niet het geval is, markeert u de rij geschat of pending_reconciliation in plaats van te doen alsof deze exact is.
downstream.on("close", async () => {
if (!providerCompleted) {
ledger.markClientAborted(requestId);
wacht stroomopwaarts.abort().catch(() => {
ledger.emit("upstream_cancel_failed", requestId);
});
}
});
Aanbeveling: maak transparante factureringslabels zichtbaar, zoals definitief, provider_reconciled, geschat, vrijgesteld of pending_reconciliation. Dit is beter verdedigbaar dan het weergeven van elk gestreamd gesprek als onmiddellijk exact.
Quotahandhaving tijdens een stream
Nauwkeurige facturering is meestal afhankelijk van het uiteindelijke gebruik van de provider, maar het afdwingen van quota kan niet altijd tot het einde wachten. Een huurder met een vast budget mag niet voor onbepaalde tijd streamen, omdat het exacte gebruik halverwege de vlucht niet beschikbaar is.
Gebruik twee mechanismen samen:
- Preflight-reservering: reserveer een geschat maximum op basis van model, aangevraagde maximale tokens, tenantbeleid en huidig saldo.
- Streamingdrukcontroles: schat de geleverde output tijdens de stream en stop als het verzoek een geconfigureerde veiligheidsgrens overschrijdt.
Dit is een controlemechanisme, niet de eindafrekening. Providers kunnen tokens in het cachegeheugen, redeneringstokens, multimodale tokens of verborgen tokens anders tellen dan de schatter van een gateway.
Trade-off: realtime schattingen helpen bij het handhaven van budgetten, maar ze kunnen afwijken van door de provider gefactureerde tokens. Bij de eindafrekening moet gebruik worden gemaakt van gezaghebbend gebruik van de provider, indien beschikbaar, en bij afstemming moeten de schattingen later worden aangepast.
Waarneembaarheidsgebeurtenissen die boekhoudfouten opsporen
Fouten bij het streamen van facturering zijn gemakkelijker op te sporen wanneer de gateway gerichte gebeurtenissen uitzendt in plaats van alleen generieke verzoeklogboeken. Voeg evenementen toe zoals:
final_usage_missing: stream beëindigd zonder gezaghebbend gebruik.cumulative_usage_regressed: cumulatieve tokentelling achteruit verplaatst.stream_ended_without_stop_event: er is geen normale stopmarkering voor de provider waargenomen.aborted_after_provider_completion: de provider is voltooid, maar de downstream-client is gesloten voordat de gateway klaar was met doorsturen.settled_from_ estimate: huurdersgrootboek gebruikte een schatting omdat het uiteindelijke gebruik niet beschikbaar was.reconciliation_adjusted_usage: providerrapportage heeft de rij later gewijzigd.
Feit: de semantische conventies van OpenTelemetry GenAI raden aan om door de provider geretourneerde gebruiksinformatie te gebruiken voor het streamen van reacties indien beschikbaar, en waarschuwen voor het rapporteren van gebruiksstatistieken als het aantal tokens niet efficiënt of nauwkeurig kan worden verkregen.
Voor AI-gebruiksanalyses betekent dit dat dashboards de betrouwbaarheidsniveaus moeten ondersteunen. Een diagram waarin definitieve, geschatte en afgestemde waarden zonder labels worden gecombineerd, ziet er misschien netjes uit, maar kan financiële en ondersteuningsteams misleiden.
Conformiteitstests voor streaming accounting
Vertrouw niet op handmatig testen met een vrolijke chatprompt. Elke provideradapter moet conformiteitstests ondergaan voor de gevallen waarin grootboeken kapot gaan:
- Normale stroom: het uiteindelijke gebruik arriveert, de stopgebeurtenis wordt waargenomen, het grootboek wordt afgehandeld als
definitief. - Tool-call-stream: tool-call-delta's worden doorgestuurd, gebruik wordt vastgelegd, gestructureerde metagegevens verstoren het aantal tokens niet.
- Veiligheids- of weigeringsstop: aanbieder stopt vroegtijdig, gebruik wordt nog steeds correct afgehandeld.
- Geforceerd ontkoppelen van client: stroomafwaarts wordt gesloten na gedeeltelijke uitvoer; upstream wordt geannuleerd of voortgezet volgens het beleid.
- Upstream 5xx na gedeeltelijke uitvoer: gateway registreert gedeeltelijke levering en markeert het verzoek niet als volledig succes.
- Gatewaytime-out vóór definitief gebruik: rij wordt geschat of is in afwachting van afstemming.
- Ontbrekende laatste gebeurtenis: adapter zendt
final_usage_missinguit en vermijdt exacte factuurlabels.
Deze tests moeten statusovergangen, grootboekvelden, uitgezonden waarneembaarheidsgebeurtenissen en stroomafwaarts gedrag bevestigen. Byte-voor-byte stream-compatibiliteit is niet voldoende; de boekhoudkundige neveneffecten maken deel uit van het contract.
Praktische implementatiechecklist
- Maak de gebruiksgrootboekrij voordat u het upstream-verzoek verzendt.
- Sla huurder-, sleutel-, gebruiker-, model-, route-, provider- en verzoek-ID's op op het moment van de aanvraag.
- Schakel rapportage van het eindgebruik van de provider in waar dit wordt ondersteund, zoals OpenAI-compatibele
stream_options.include_usage. - Voor cumulatieve providers slaat u de laatste gebruikswaarde op in plaats van gebeurtenissen op te tellen.
- Bewaar de verzamelde antwoordobjecten wanneer SDK's deze leveren.
- Volg de geleverde output afzonderlijk van het door de provider gefactureerde gebruik.
- Bij het verbreken van de verbinding annuleert u upstream volgens het routebeleid en markeert u
client_aborted. - Gebruik transparante factureringsstatussen: definitief, geschat, afstemming in behandeling, afstemming met provider of kwijtschelding.
- Accountingspecifieke waarneembaarheidsgebeurtenissen uitzenden.
- Vergelijk later het gebruik van de provider of de kostenrapporten, indien beschikbaar, terwijl de toewijzing van de tenant op de aanvraagtijd behouden blijft.
Wat huurders moeten laten zien
Huurders hebben niet elk intern evenement nodig, maar wel eerlijke labels. Een nuttige gebruikstabel zou het volgende kunnen tonen:
- Status: definitief, geschat of afgestemd.
- Verzoekresultaat: voltooid, client afgebroken, providerfout of gateway-time-out.
- Geleverde uitvoer: geschatte tekst of bytes verzonden naar de client.
- Gefactureerde tokens: door de provider genormaliseerd gebruik gebruikt voor de kosten.
- Aanpassing: eventuele latere afstemmingsdelta.
Dit ontwerp vermindert de dubbelzinnigheid van de ondersteuning. Als een gebruiker slechts een deel van een reactie heeft gezien, kan het dashboard uitleggen of de provider al heeft voltooid, of de gateway upstream heeft geannuleerd en of de kosten definitief of geschat zijn.
Aanbevelingen versus voorspellingen
Aanbevelingen: behandel gestreamde verzoeken als statusmachines, wacht op gezaghebbend eindgebruik voordat de exacte afhandeling plaatsvindt, scheid geleverde uitvoer van gefactureerd gebruik en label geschatte rijen eerlijk. Provideradapters moeten providerspecifieke gebruikssemantiek coderen in plaats van elke stream af te vlakken in een generieke byteproxy.
Voorspelling: streaming-accounting zal belangrijker worden naarmate modellen meer verborgen werk blootleggen: redeneringstokens, kortingen op cache-tokens, multimodale verwerking, sporen van toolgebruik en veiligheidsstops. Gateways die het door de provider gefactureerde gebruik al scheiden van de voor de klant zichtbare uitvoer, zullen zich gemakkelijker aanpassen dan gateways die alleen gestreamde tekst tellen.
Bruikbare conclusie
Als uw gateway streaming ondersteunt, controleer dan vandaag nog één pad: forceer de verbinding van een client na de eerste paar chunks en inspecteer de grootboekrij. Als er ‘succes’ staat met exact uitziende tokenaantallen, liegen uw analyses waarschijnlijk.
De oplossing is om het streamen niet te staken. Behoud de snelle gebruikerservaring, maar maak de voltooiing van streams, annuleringen, providerfouten, ontbrekend eindgebruik en afstemming expliciete boekhoudkundige statussen. Dat geeft productteams responsieve output, financiële teams verdedigbare kosten en ondersteuningsteams voldoende bewijs om gedeeltelijke reacties te verklaren zonder te raden.