Računovodstvo strujanja tokena u pristupniku AI API-ja: konačna upotreba, otkazivanja i djelomični odgovori
Streaming poboljšava percipiranu latenciju, ali može pokvariti analizu upotrebe umjetne inteligencije i naplatu ako gateway koristi samo proxy bajtove. Ovdje je praktičan obrazac stanja stroja za bilježenje konačne upotrebe, prekinutih tokova, pogrešaka pružatelja i djelomičnih odgovora.
Streaming LLM odgovore lako je proxy, a teško ih je ispravno naplatiti. Ako AI API pristupnik proslijedi događaje poslane s poslužitelja klijentu, ali tretira prve dijelove kao zapis o korištenju, analitika stanara će se povući. Odstupanje se obično pojavljuje u sporovima kao što su: "korisnik je vidio samo pola odgovora", "pružatelj je naplatio više nego što pokazuje naša nadzorna ploča", "kvota je prerano puštena" ili "vrijeme čekanja proizvelo je tokene, ali nema retka fakture."
Osnovni problem je u tome što strujani pozivi nisu jedan događaj. Oni su slijed: zahtjev prihvaćen, uzvodni tok otvoren, bajtovi isporučeni, konačna upotreba prijavljena, pružatelj zaustavljen, klijent prekinut, pristupnik je istekao i naplata je podmirena. Pouzdan pristupnik trebao bi eksplicitno modelirati ta stanja umjesto da pretpostavlja da je dovršeni HTTP odgovor jedini uspješan put.
Način neuspjeha: strujanje skriva granicu obračuna
Dovršavanja bez strujanja obično vraćaju jedan objekt odgovora s metapodacima o upotrebi. Gateway može normalizirati tu upotrebu, napisati red knjige, ažurirati kvotu i emitirati analitiku u jednom prolazu.
Streaming mijenja granicu. Korisničko iskustvo je inkrementalno, ali istina o naplati može stići na kraju, u konačnom događaju specifičnom za pružatelja usluga, u kumulativnoj delti, putem agregiranog SDK odgovora ili kasnije putem API-ja za izvješćivanje pružatelja usluga. Ako klijent prekine vezu prije posljednjeg događaja upotrebe, pristupnik je možda isporučio samo dio odgovora dok je pružatelj još uvijek generirao i naplatio više tokena.
Činjenica: OpenAI dokumentira da pozivatelji strujanja koji žele podatke o upotrebi trebaju postaviti stream_options s include_usage. OpenAI također pruža krajnje točke upotrebe i troškova na razini organizacije, uz napomenu da upotreba i troškovi možda neće uvijek biti savršeno usklađeni u financijske svrhe.
Činjenica: Anthropic streaming koristi događaje poslane s poslužitelja kao što su message_start, content_block_delta, message_delta i message_stop. Njegove message_delta informacije o korištenju su kumulativne, tako da gateway ne smije dodati svaku deltu upotrebe zajedno.
Činjenica: Gemini i API-ji za strujanje u stilu Vertex-a mogu izložiti inkrementalne dijelove dok SDK-ovi također mogu pružiti agregirani objekt odgovora. Za pristupnike taj agregirani put može biti bolji izvor za dovršenu upotrebu od samih vidljivih dijelova.
Koristite stroj stanja toka, a ne Booleovu oznaku uspjeha
Streaming zahtjev treba imati trajni zapis o korištenju prije nego što započne uzlazni poziv. Taj bi se zapis trebao kretati kroz eksplicitna stanja. Praktični minimum je:
accepted: pristupnik je potvrdio autentičnost ključa, dodijelio stanara i stvorio otvoreni red glavne knjige.first_byte_sent: najmanje jedan izlazni događaj dosegao je dolaznog klijenta.provider_completed: uzvodni pružatelj emitirao je normalan signal za zaustavljanje ili je dovršio objekt odgovora.client_aborted: nizvodna utičnica zatvorena prije normalnog završetka pristupnika.provider_error: uzlazni pružatelj vratio je pogrešku nakon što je stream započeo ili prije nego što je stigla konačna upotreba.gateway_timeout: pristupnik je nametnuo svoj proračun latencije i završio zahtjev.settled: pristupnik je pretvorio upotrebu u trošak stanara i potrošnju kvote.reconciled: kasniji podaci o korištenju ili troškovima davatelja usluga potvrdili su ili prilagodili redak.
Ovaj model sprječava uobičajenu pogrešku analitike: označavanje svakog toka koji je proizveo tekst kao "uspješan i točan". Stream može biti koristan korisniku, nedovršen od davatelja usluga, procijenjen za naplatu i u isto vrijeme čeka usklađivanje.
Preporučena polja glavne knjige
Neka redak vremena zahtjeva bude mali, ali eksplicitan:
{
"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": "accepted",
"stream": true,
"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
}
Važno razdvajanje je output_tokens_billed u odnosu na output_tokens_delivered_estimate. Korisnicima je bitno što je stiglo do njihove aplikacije. Financije brinu što je pružatelj naplatio. Ti se brojevi mogu razlikovati nakon prekida veze, tokova poziva alata, skrivenih tokena razmišljanja, predmemoriranih tokena, sigurnosnih zaustavljanja ili isteka vremena pristupnika.
Pravila snimanja specifična za pružatelja usluga
Provajder neutralan OpenAI-kompatibilan API je koristan za programere aplikacija, ali gateway adapter i dalje treba računovodstvena pravila specifična za pružatelja usluga.
OpenAI-kompatibilno strujanje
Za OpenAI rute, izložite opciju pristupnika koja omogućuje izvješćivanje o upotrebi uzvodno tamo gdje je to podržano. Uobičajeni obrazac je prihvaćanje zadane postavke na razini pristupnika kao što je:
{
"stream": true,
"stream_options": {
"include_usage": true
}
}
Ako ga nizvodni pozivatelj izostavi, pristupnik može odlučiti hoće li ga ubaciti za rute gdje je to kompatibilno. Dokumentirajte ovo ponašanje jer neki klijenti očekuju točnu kompatibilnost žice, a neki modeli ili uzvodni kanali možda neće podržavati konačnu upotrebu na isti način.
Preporuka: nemojte podmirivati troškove zakupca iz ranih dijelova. Držite red knjige otvorenim sve dok se ne uhvati posljednji događaj upotrebe, odgovor pružatelja ne završi bez upotrebe ili tok uđe u pogrešku ili stazu otkazivanja.
Anthropic strujanje
Kumulativna upotrebaAnthropic zahtijeva drugačije pravilo. Ako pristupnik vidi tri message_delta događaja s izlaznim tokenima od 10, 25 i 40, izlazni broj je 40, a ne 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("cumulative_usage_regressed", requestId);
}
latestUsage = event.usage;
}
forwardToClient(event);
}
settleFromLatestCumulativeUsage(latestUsage);
Preporuka: zabilježite posljednju kumulativnu vrijednost upotrebe i emitirajte događaj vidljivosti ako se smanji. Regresija može ukazivati na pogreške parsera, duplicirane događaje, promjene pružatelja usluga ili miješane tokove.
Gemini i strujanje u Vertex stilu
Gemini podržava strujanje dijelova kako bi se smanjila percipirana latencija. U SDK-ovima u stilu Vertexa strujanje može izložiti i asinkroni tok i agregirani objekt odgovora. Gateway bi trebao sačuvati taj skupni put kada je dostupan.
const streamingResult = await model.generateContentStream(request);
for await (const chunk of streamingResult.stream) {
forwardChunk(chunk);
countDeliveredBytesOrText(chunk);
}
const aggregated = await streamingResult.response;
settleFromAggregatedUsage(aggregated);
Preporuka: izbjegavajte izgradnju cjelokupnog računovodstva od vidljivih dijelova ako SDK daje dovršeni zapis odgovora. Dijelovi su za kašnjenje. Konačni objekt često je bolji za naplatu i analitiku.
Prekid veze s klijentom tretirajte kao prvorazredne računovodstvene događaje
Klijentovi prekidi veze su mjesto gdje mnogi pristupnici gube novac ili preplaćuju klijente. Kartica preglednika se zatvara, mobilna mreža pada ili aplikacija poništava zahtjev. Gateway primjećuje da je nizvodna utičnica zatvorena, ali uzlazni pružatelj možda još uvijek generira.
Gateway bi trebao napraviti izričit izbor pravila:
- Odmah poništi uzvodno: smanjuje uzaludnu proizvodnju i troškove pružatelja, ali može prekinuti tijek rada gdje pozadina i dalje treba rezultat nakon što se UI prekine.
- Nastavak uzvodno u pozadini: može sačuvati posao za korisnike na strani poslužitelja, ali korisnik možda neće vidjeti sve generirane i naplaćene tokene.
- Ponašanje ovisno o ruti: odustani za interaktivni chat, nastavi za tijek rada nalik poslu i učini postavku vidljivom zakupcima.
Praktično zadano za interaktivno strujanje je otkazivanje uzvodnog protoka kada se nizvodni klijent prekine, a zatim označi red knjige kao client_aborted. Ako konačna uporaba stigne tijekom otkazivanja, podmirite iz te ovlaštene uporabe. Ako nije, označite red estimated ili pending_reconciliation umjesto da se pretvarate da je točan.
downstream.on("close", async () => {
if (!providerCompleted) {
ledger.markClientAborted(requestId);
await upstream.abort().catch(() => {
ledger.emit("upstream_cancel_failed", requestId);
});
}
});
Preporuka: izložite transparentne oznake naplate kao što su final, provider_reconciled, estimated, waived ili pending_reconciliation. To je lakše obraniti od prikazivanja svakog strujanog poziva kao neposrednog.
Provedba kvote tijekom streama
Točna naplata obično ovisi o konačnoj upotrebi pružatelja usluga, ali provedba kvote ne može uvijek čekati do kraja. Zakupcu s ograničenim proračunom ne bi se smjelo dopustiti strujanje na neodređeno vrijeme jer je točna upotreba nedostupna u tijeku.
Koristite dva mehanizma zajedno:
- Rezervacija prije leta: rezervirajte procijenjeni maksimum na temelju modela, zatraženog maksimalnog tokena, pravila zakupca i trenutnog stanja.
- Provjere pritiska strujanja: procjena isporučenog izlaza tijekom protoka i zaustavljanje ako zahtjev prijeđe konfiguriranu sigurnosnu granicu.
Ovo je kontrolni mehanizam, a ne konačni račun. Pružatelji mogu računati predmemorirane tokene, tokene rezoniranja, multimodalne tokene ili skrivene tokene drugačije od procjenitelja pristupnika.
Kompromis: procjene u stvarnom vremenu pomažu u provedbi proračuna, ali se mogu razlikovati od tokena koje naplaćuje pružatelj usluga. Konačna nagodba trebala bi koristiti mjerodavnu upotrebu pružatelja usluga kada je dostupna, a usklađivanje bi trebalo prilagoditi procjene kasnije.
Događaji vidljivosti koji otkrivaju greške u računovodstvu
Kvarove naplate strujanja lakše je otkloniti kada pristupnik emitira ciljane događaje umjesto samo generičkih zapisa zahtjeva. Dodajte događaje kao što su:
final_usage_missing: stream je završio bez autoritativne upotrebe.cumulative_usage_regressed: kumulativni broj tokena pomaknut unatrag.stream_ended_without_stop_event: nije primijećena normalna oznaka zaustavljanja pružatelja usluga.aborted_after_provider_completion: pružatelj je dovršio, ali se klijent na donjem dijelu zatvorio prije nego što je pristupnik završio prosljeđivanje.settled_from_estimate: knjiga stanara koristila je procjenu jer konačna upotreba nije bila dostupna.reconciliation_adjusted_usage: izvješćivanje pružatelja usluga kasnije je promijenilo red.
Činjenica: OpenTelemetry GenAI semantičke konvencije preporučuju korištenje informacija o korištenju koje vraća pružatelj usluga za strujanje odgovora kada su dostupni i upozoravaju da se ne izvještava o metrici upotrebe ako se broj tokena ne može dobiti učinkovito ili točno.
Za analizu upotrebe AI, to znači da nadzorne ploče trebaju podržavati razine pouzdanosti. Grafikon koji uključuje konačne, procijenjene i usklađene vrijednosti bez oznaka može izgledati čisto, ali dovesti u zabludu timove za financije i podršku.
Testovi usklađenosti za strujanje računovodstva
Nemojte se oslanjati na ručno testiranje s upitom za chat za sretan put. Svaki adapter pružatelja trebao bi imati testove usklađenosti za slučajeve koji kvare knjige:
- Normalni tok: stiže konačna upotreba, promatra se događaj zaustavljanja, glavna knjiga se postavlja kao
final. - Tool-call stream: delta poziva alata se prosljeđuju, korištenje se bilježi, strukturirani metapodaci ne oštećuju brojanje tokena.
- Sigurnosno ili odbijajuće zaustavljanje: pružatelj prestaje rano, korištenje se i dalje pravilno rješava.
- Prisilni prekid veze klijenta: nizvodno se zatvara nakon djelomičnog izlaza; uzvodno se otkazuje ili nastavlja u skladu s pravilima.
- Uzvodno 5xx nakon djelomičnog izlaza: pristupnik bilježi djelomičnu isporuku i ne označava zahtjev kao čisti uspjeh.
- Istek vremena pristupnika prije konačne upotrebe: red postaje procijenjen ili čeka usklađivanje.
- Nedostaje završni događaj: adapter emitira
final_usage_missingi izbjegava točne oznake naplate.
Ovi bi testovi trebali potvrditi prijelaze stanja, polja glavne knjige, emitirane događaje vidljivosti i nizvodno ponašanje. Kompatibilnost toka bajt za bajt nije dovoljna; računovodstvene nuspojave dio su ugovora.
Kontrolni popis za praktičnu implementaciju
- Izradite redak knjige korištenja prije slanja uzvodnog zahtjeva.
- Pohranite zakupca, ključ, korisnika, model, rutu, pružatelja i identifikator zahtjeva u trenutku zahtjeva.
- Omogući konačno izvješće o korištenju davatelja usluga tamo gdje je to podržano, kao što je OpenAI-kompatibilno
stream_options.include_usage. - Za kumulativne pružatelje, pohranite najnoviju vrijednost upotrebe umjesto zbrajanja događaja.
- Sačuvajte agregirane objekte odgovora kada ih SDK pruži.
- Praćenje isporučenog izlaza odvojeno od upotrebe koju naplaćuje pružatelj usluga.
- Nakon prekida veze, odustani uzvodno u skladu s politikom rute i označi
client_aborted. - Koristite transparentne statuse naplate: konačni, procijenjeni, na čekanju za usklađivanje, davatelj usklađen ili odustao.
- Emitira događaje vidljivosti specifične za računovodstvo.
- Kasnije usklađujte s izvješćima o korištenju ili troškovima pružatelja usluga kada su dostupna, uz očuvanje atribucije zakupca u vrijeme zahtjeva.
Što pokazati stanarima
Stanarima nije potreban svaki interni događaj, ali trebaju poštene oznake. Korisna tablica upotrebe može prikazati:
- Status: konačni, procijenjeni ili usklađeni.
- Ishod zahtjeva: dovršen, klijent prekinut, pogreška pružatelja ili isteklo vrijeme pristupnika.
- Isporučeni izlaz: približan tekst ili bajtovi poslani klijentu.
- Naplaćeni tokeni: normalizirana upotreba davatelja usluga koja se koristi za trošak.
- Prilagodba: svaka kasnija delta usklađivanja.
Ovaj dizajn smanjuje dvosmislenost podrške. Ako je korisnik vidio samo dio odgovora, nadzorna ploča može objasniti je li pružatelj već dovršio, je li pristupnik otkazao uzvodno i je li naplata konačna ili procijenjena.
Preporuke nasuprot predviđanjima
Preporuke: tretirajte streamane zahtjeve kao automate stanja, pričekajte mjerodavnu konačnu upotrebu prije točne nagodbe, odvojite isporučeni izlaz od naplaćene upotrebe i pošteno označite procijenjene retke. Adapteri davatelja usluga trebali bi kodirati semantiku upotrebe specifičnu za davatelja usluga, a ne izravnavati svaki tok u generički bajt proxy.
Predviđanje: strujanje računovodstva postat će važnije kako modeli otkrivaju sve više skrivenog rada: tokene za razmišljanje, popuste za tokene u predmemoriji, multimodalnu obradu, tragove upotrebe alata i sigurnosna zaustavljanja. Pristupnici koji već odvajaju korištenje koje naplaćuje pružatelj usluge od izlaza vidljivog klijentu lakše će se prilagoditi od pristupnika koji broje samo strujanje teksta.
Poduzimajući zaključak
Ako vaš gateway podržava strujanje, provjerite jedan put danas: prisilite klijenta da prekine vezu nakon prvih nekoliko dijelova i pregledajte red knjige. Ako piše "uspjeh" s točnim brojem tokena, vaša analitika vjerojatno laže.
Rješenje nije u napuštanju strujanja. Zadržite brzo korisničko iskustvo, ali neka budu eksplicitna računovodstvena stanja završetka streama, otkazivanja, pogrešaka pružatelja usluga, nedostatne konačne upotrebe i usklađivanja. To daje proizvodnim timovima odgovoran rezultat, financijskim timovima opravdane troškove, a timovima za podršku dovoljno dokaza da objasne djelomične odgovore bez nagađanja.