Streaming av tokenregnskap i en AI API-gateway: endelig bruk, kanselleringer og delvise svar
Streaming forbedrer den oppfattede ventetiden, men det kan bryte AI-bruksanalyse og fakturering hvis gatewayen bare gir proxy-byte. Her er et praktisk tilstandsmaskinmønster for å fange opp endelig bruk, avbrutt strømmer, leverandørfeil og delvise svar.
Streaming av LLM-svar er enkle å fullføre og vanskelige å fakturere riktig. Hvis en AI API-gateway videresender serversendte hendelser til klienten, men behandler de første delene som bruksposten, vil leietakeranalysen drifte. Avviket vises vanligvis i tvister som: «brukeren så bare halve svaret», «leverandøren fakturerte mer enn dashbordet vårt viser», «kvoten ble frigitt for tidlig» eller «en tidsavbrudd ga tokens, men ingen fakturalinje».
Rotproblemet er at strømmede anrop ikke er én hendelse. De er en sekvens: forespørsel akseptert, oppstrømsstrøm åpnet, byte levert, endelig bruk rapportert, leverandør stoppet, klient koblet fra, gateway ble tidsavbrutt og fakturering avgjort. En pålitelig gateway bør modellere disse tilstandene eksplisitt i stedet for å anta at et fullført HTTP-svar er den eneste vellykkede banen.
Feilmodus: streaming skjuler regnskapsgrensen
Ikke-streamede fullføringer returnerer vanligvis ett svarobjekt med bruksmetadata. En gateway kan normalisere denne bruken, skrive en hovedbokrad, oppdatere kvote og sende ut analyser i én omgang.
Strøming endrer grensen. Brukeropplevelsen er inkrementell, men faktureringssannheten kan komme på slutten, i en leverandørspesifikk slutthendelse, i et kumulativt delta, gjennom et aggregert SDK-svar, eller senere gjennom leverandørrapporterings-APIer. Hvis klienten kobler fra før den endelige brukshendelsen, kan gatewayen ha levert bare deler av svaret mens leverandøren fortsatt genererte og fakturerte flere tokens.
Fakta: OpenAI dokumenterer at streaming-anropere som ønsker bruksdata bør angi stream_options med include_usage. OpenAI tilbyr også bruks- og kostnadsendepunkter på organisasjonsnivå, samtidig som det bemerkes at bruk og kostnader kanskje ikke alltid passer perfekt sammen for økonomiske formål.
Fakta: Antropisk strømming bruker serversendte hendelser som message_start, content_block_delta, message_delta og message_stop. Dens message_delta-bruksinformasjon er kumulativ, så en gateway må ikke legge sammen hvert bruksdelta.
Fakta: Streaming-API-er i Gemini- og Vertex-stil kan avdekke inkrementelle deler, mens SDK-er også kan gi et aggregert svarobjekt. For gatewayer kan den aggregerte banen være en bedre kilde for fullført bruk enn de synlige delene alene.
Bruk en strømstatusmaskin, ikke et boolsk suksessflagg
En strømmet forespørsel bør ha en varig brukspost før oppstrømsamtalen starter. Den posten bør gå gjennom eksplisitte tilstander. Et praktisk minimum er:
godkjent: gatewayen autentiserte nøkkelen, tilskrev leietakeren og opprettet en åpen hovedbokrad.first_byte_sent: minst én utdatahendelse nådde nedstrømsklienten.provider_completed: oppstrømsleverandøren sendte ut et normalt stoppsignal eller fullført responsobjekt.client_aborted: nedstrømskontakten lukket før normal gateway-fullføring.provider_error: oppstrømsleverandøren returnerte en feil etter at strømmen startet eller før endelig bruk ankom.gateway_timeout: gatewayen håndhevet ventebudsjettet og avsluttet forespørselen.oppgjort: gatewayen konverterte bruk til leietakerkostnad og kvoteforbruk.avstemt: senere leverandørbruk eller kostnadsdata bekreftet eller justert raden.
Denne modellen forhindrer en vanlig analysefeil: merking av hver strøm som produserte tekst som «vellykket og nøyaktig». En strøm kan være nyttig for brukeren, ufullstendig fra leverandøren, beregnet for fakturering og avventende avstemming på samme tid.
Anbefalte reskontrofelt
Hold raden for forespørselstid liten, men eksplisitt:
{
"request_id": "gw_req_...",
"tenant_id": "tenant_123",
"api_key_id": "key_456",
"provider": "openai|antropisk|tvilling|...",
"provider_request_id": null,
"model": "leverandør-modell-id",
"state": "akseptert",
"stream": sant,
"input_tokens": null,
"output_tokens_billed": null,
"output_tokens_delivered_estimate": 0,
"provider_usage_source": null,
"billing_status": "venting_reconciliation",
"client_abort_at": null,
"provider_completed_at": null,
"settled_at": null,
"error_class": null
}
Den viktige separasjonen er output_tokens_billed versus output_tokens_delivered_estimate. Brukerne bryr seg om hva som nådde søknaden deres. Finans bryr seg om hva leverandøren fakturerte. Disse tallene kan variere etter frakoblinger, verktøy-anropsstrømmer, skjulte resonnement-tokens, bufrede tokens, sikkerhetsstopp eller gateway-tidsavbrudd.
Leverandørspesifikke innsamlingsregler
Et leverandørnøytralt OpenAI-kompatibelt API er nyttig for applikasjonsutviklere, men gatewayadapteren trenger fortsatt leverandørspesifikke regnskapsregler.
OpenAI-kompatibel strømming
For OpenAI-ruter, vis et gatewayalternativ som muliggjør oppstrømsbruksrapportering der det støttes. Et vanlig mønster er å godta en standard på gateway-nivå som:
{
"stream": sant,
"stream_options": {
"inkluder_bruk": sant
}
}
Hvis nedstrømsoppringeren utelater den, kan gatewayen bestemme om den skal injiseres for ruter der det er kompatibelt. Dokumenter denne oppførselen fordi noen klienter forventer nøyaktig ledningskompatibilitet, og noen modeller eller oppstrøms støtter kanskje ikke sluttbruk på samme måte.
Anbefaling: Ikke avregn leietakerkostnader fra tidlige deler. Hold hovedbokraden åpen til den endelige brukshendelsen er registrert, leverandørens svar avsluttes uten bruk, eller strømmen går inn i en feil- eller kanselleringsbane.
Antropisk strømming
Anthropics kumulative bruk krever en annen regel. Hvis en gateway ser tre message_delta-hendelser med utdata-tokentellinger på 10, 25 og 40, er uttellingen 40, ikke 75.
let latestUsage = null;
for await (const event of anthropicStream) {
if (event.type === "message_delta" && event.usage) {
if (latestUsage && event.usage.output_tokens < latestUsage.output_tokens) {
emit("kumulativ_bruk_regressert", requestId);
}
latestUsage = hendelse.bruk;
}
forwardToClient(hendelse);
}
settleFromLatestCumulativeUsage(latestUsage);
Anbefaling: Registrer den siste kumulative bruksverdien og send ut en observerbarhetshendelse hvis den regresserer. En regresjon kan indikere parserfeil, dupliserte hendelser, leverandørendringer eller blandede strømmer.
Strøming i Gemini og Vertex-stil
Gemini støtter strømmebiter for å redusere opplevd ventetid. I Vertex-stil SDK-er kan strømming avsløre både en asynkron strøm og et aggregert svarobjekt. En gateway bør bevare den aggregerte banen når den er tilgjengelig.
const streamingResult = await model.generateContentStream(request);
for await (const chunk of streamingResult.stream) {
forwardChunk(klump);
countDeliveredBytesOrText(chunk);
}
const aggregert = avventer streamingResult.response;
settleFromAggregatedUsage(aggregated);
Anbefaling: unngå å bygge all regnskap fra synlige deler hvis SDK-en gir en fullført svarpost. Biter er for ventetid. Det endelige objektet er ofte bedre for fakturering og analyser.
Behandle klientfrakoblinger som førsteklasses regnskapshendelser
Klientfrakoblinger er hvor mange gatewayer taper penger eller overbelaste kunder. En nettleserfane lukkes, et mobilnettverk faller, eller en applikasjon kansellerer en forespørsel. Gatewayen merker at nedstrømskontakten er lukket, men oppstrømsleverandøren kan fortsatt generere.
Gatewayen bør gjøre et eksplisitt policyvalg:
- Avbryt oppstrøms umiddelbart: reduserer bortkastet generasjon og leverandørkostnader, men kan bryte arbeidsflyter der backend fortsatt trenger resultatet etter at brukergrensesnittet kobles fra.
- Fortsett oppstrøms i bakgrunnen: kan bevare arbeidet for forbrukere på serversiden, men det kan hende at brukeren ikke ser alle tokens generert og fakturert.
- Ruteavhengig atferd: avbryt for interaktiv chat, fortsett for jobblignende arbeidsflyter og gjør innstillingen synlig for leietakere.
En praktisk standard for interaktiv strømming er å avbryte oppstrøms når nedstrømsklienten kobler fra, og deretter merke hovedbokraden som client_aborted. Hvis endelig bruk kommer under kanselleringen, må du betale for den autoritative bruken. Hvis ikke, merk raden estimert eller pending_reconciliation i stedet for å late som om den er nøyaktig.
downstream.on("close", async () => {
if (!providerCompleted) {
ledger.markClientAborted(requestId);
vent upstream.abort().catch(() => {
ledger.emit("upstream_cancel_failed", requestId);
});
}
});
Anbefaling: vis gjennomsiktige faktureringsetiketter som final, provider_reconciled, estimert, waived eller pending_reconciliation. Dette er mer forsvarlig enn å vise hver streamet samtale som umiddelbart nøyaktig.
Kvotehåndhevelse under en strømming
Nøyaktig fakturering avhenger vanligvis av endelig leverandørbruk, men kvotehåndhevelse kan ikke alltid vente til slutten. En leietaker med et hardt budsjett bør ikke få lov til å strømme på ubestemt tid fordi eksakt bruk er utilgjengelig underveis.
Bruk to mekanismer sammen:
- Forhåndsreservasjon: reserver et estimert maksimum basert på modell, forespurte maks tokens, leietakerpolicy og gjeldende saldo.
- Strømtrykksjekker: estimer levert utgang under strømmen og stopp hvis forespørselen krysser en konfigurert sikkerhetsgrense.
Dette er en kontrollmekanisme, ikke den endelige regningen. Leverandører kan telle bufrede tokens, resonnement-tokens, multimodale tokens eller skjulte tokens annerledes enn en gateways estimator.
Avveining: sanntidsanslag bidrar til å håndheve budsjetter, men de kan avvike fra leverandørfakturerte tokens. Sluttoppgjør bør bruke autoritativ leverandørbruk når tilgjengelig, og avstemming bør justere estimater senere.
Observasjonshendelser som fanger opp regnskapsfeil
Streaming faktureringsfeil er lettere å feilsøke når gatewayen sender ut målrettede hendelser i stedet for bare generiske forespørselslogger. Legg til hendelser som:
final_usage_missing: strømmen ble avsluttet uten autoritativ bruk.cumulative_usage_regressed: kumulativ tokenantall flyttet bakover.stream_ended_without_stop_event: ingen normal leverandørstoppmarkør ble observert.aborted_after_provider_completion: leverandøren fullførte, men nedstrømsklienten stengte før gatewayen fullførte videresendingen.settled_from_estimate: leietakerreskontro brukte et estimat fordi endelig bruk ikke var tilgjengelig.reconciliation_adjusted_usage: leverandørrapportering endret raden senere.
Fakta: OpenTelemetry GenAI semantiske konvensjoner anbefaler å bruke leverandørreturnert bruksinformasjon for strømmesvar når det er tilgjengelig, og advarer mot å rapportere bruksberegninger hvis tokenantall ikke kan oppnås effektivt eller nøyaktig.
For AI-bruksanalyse betyr dette at dashbord bør støtte konfidensnivåer. Et diagram som blander endelige, estimerte og avstemte verdier uten etiketter kan se rent ut, men villede finans- og støtteteam.
Konformitetstester for strømmeregnskap
Ikke stol på manuell testing med en chat-melding. Hver leverandøradapter bør ha samsvarstester for tilfeller som bryter hovedbok:
- Vanlig strøm: endelig bruk ankommer, stopphendelse observert, hovedbok blir
endelig. - Verktøyanropsstrøm: verktøyanropsdeltaer videresendes, bruk registreres, strukturerte metadata ødelegger ikke tokentelling.
- Sikkerhet eller avslag stopp: leverandøren stopper tidlig, bruken avgjøres fortsatt riktig.
- Tvungen klientfrakobling: nedstrøms lukkes etter delvis utgang; oppstrøms kanselleres eller fortsettes i henhold til retningslinjene.
- Oppstrøm 5xx etter delvis utgang: gateway registrerer delvis levering og merker ikke forespørselen som en ren suksess.
- Gateway-tidsavbrudd før endelig bruk: rad blir estimert eller venter på avstemming.
- Manglende siste hendelse: adapter sender ut
final_usage_missingog unngår eksakte faktureringsetiketter.
Disse testene skal bekrefte tilstandsoverganger, hovedbokfelt, utsendte observerbarhetshendelser og nedstrømsatferd. Byte-for-byte-strømkompatibilitet er ikke nok; de regnskapsmessige bivirkningene er en del av kontrakten.
Sjekkliste for praktisk implementering
- Opprett bruksreskontro-raden før du sender oppstrømsforespørselen.
- Lagre leietaker-, nøkkel-, bruker-, modell-, rute-, leverandør- og forespørselsidentifikatorer på forespørselstidspunktet.
- Aktiver leverandørens endelige bruksrapportering der dette støttes, for eksempel OpenAI-kompatibel
stream_options.include_usage. - For kumulative leverandører, lagre den siste bruksverdien i stedet for å summere hendelser.
- Bevar aggregerte svarobjekter når SDK-er gir dem.
- Spor levert utdata separat fra leverandørfakturert bruk.
- Ved frakobling, avbryt oppstrøms i henhold til rutepolicy og merk
client_aborted. - Bruk transparente faktureringsstatuser: endelig, estimert, ventende avstemming, leverandør avstemt eller frafalt.
- Skriv ut regnskapsspesifikke observerbarhetshendelser.
- Avstem senere mot leverandørbruk eller kostnadsrapporter når tilgjengelige, samtidig som leietaker-attribusjon for forespørselstid bevares.
Hva du skal vise leietakere
Leietakere trenger ikke alle interne arrangementer, men de trenger ærlige etiketter. En nyttig brukstabell kan vise:
- Status: endelig, estimert eller avstemt.
- Forespørselsutfall: fullført, klient avbrutt, leverandørfeil eller gateway-tidsavbrudd.
- Leveret utdata: omtrentlig tekst eller byte sendt til klienten.
- Fakturerte tokens: leverandørnormalisert bruk brukt for kostnad.
- Justering: eventuelle senere avstemmingsdelta.
Denne designen reduserer støttetvetydighet. Hvis en bruker bare så en del av et svar, kan dashbordet forklare om leverandøren allerede hadde fullført, om gatewayen ble kansellert oppstrøms, og om belastningen er endelig eller estimert.
Anbefalinger kontra spådommer
Anbefalinger: behandle strømmede forespørsler som statsmaskiner, vent på autoritativ endelig bruk før eksakt oppgjør, separer levert utdata fra fakturert bruk, og merk estimerte rader ærlig. Leverandøradaptere bør kode leverandørspesifikk brukssemantikk i stedet for å flate ut hver strøm til en generisk byteproxy.
Prediksjon: regnskap for strømming vil bli viktigere ettersom modellene avslører mer skjult arbeid: resonnementsymboler, bufret-tokenrabatter, multimodal behandling, sporing av verktøybruk og sikkerhetsstopp. Gatewayer som allerede skiller leverandørfakturert bruk fra klientsynlig utdata, vil tilpasse seg lettere enn gatewayer som kun teller strømmet tekst.
Aktiv konklusjon
Hvis gatewayen din støtter strømming, kontroller én bane i dag: tving en klient fra å koble fra etter de første delene og inspiser hovedbokraden. Hvis det står «suksess» med nøyaktige tokentellinger, lyver antakelig analysene dine.
Løsningen er å ikke forlate strømming. Behold den raske brukeropplevelsen, men gjør strømgjennomføring, kansellering, leverandørfeil, manglende sluttbruk og avstemming eksplisitte regnskapstilstander. Det gir produktteam responsive resultater, finansteam forsvarlige kostnader og støtteteam nok bevis til å forklare delvise svar uten å gjette.