Oltre i limiti di frequenza: scalare l'accesso a Codex e Sora
Di Jonah Cohen, membro del personale tecnico
Nell'ultimo anno, sia Codex che Sora hanno registrato una rapida diffusione, con un utilizzo che ha rapidamente superato le nostre aspettative iniziali. Abbiamo osservato un modello costante: gli utenti si affacciano al servizio, ne scoprono il valore reale e poi si imbattono nei limiti di frequenza.
I limiti di frequenza possono aiutare a regolare il flusso di richieste e garantire un accesso equo; tuttavia, quando gli utenti stanno usufruendo di un servizio, raggiungere un limite massimo può essere piuttosto snervante. Per questo motivo, abbiamo cercato un modo per consentire agli utenti di continuare a utilizzare il servizio, proteggendo al contempo le prestazioni del sistema e la fiducia degli utenti nel nostro approccio.
Per risolvere questo problema, abbiamo creato un motore di accesso in tempo reale che conteggia l'utilizzo. Una delle funzioni di questo motore è la possibilità di acquistare crediti. Quando gli utenti superano i propri limiti di frequenza, possono continuare a utilizzare i nostri prodotti utilizzando i crediti a loro disposizione.
Alla base di tutto questo c'è un sistema complesso che combina limiti, monitoraggio dell'utilizzo in tempo reale e saldi di credito in un unico modello di accesso. Questo post spiega perché la scalabilità di Codex e Sora ha richiesto un ripensamento del controllo degli accessi, come un sistema in tempo reale di comprovata efficacia combini limiti di frequenza e crediti per ogni richiesta e come questa base ora sblocchi un accesso aggiuntivo per entrambi i prodotti.
Considerando il quadro generale, i modelli di accesso tradizionali tendono a imporre una scelta:
- I limiti di frequenza possono essere utili all'inizio, ma creano un'esperienza negativa agli utenti quando vengono esauriti: "torna più tardi".
- La fatturazione basata sull'utilizzo è flessibile, ma richiede agli utenti di pagare fin dal primo token, il che non è l'ideale se si desidera favorire una fase iniziale di sperimentazione
Per Codex e Sora, nessuna delle due soluzioni era sufficiente da sola. Se avessimo semplicemente aumentato i limiti di frequenza, avremmo perso importanti controlli di regolazione della domanda e di equità e avremmo esaurito la capacità di servire tutti. Se ci fossimo affidati interamente alla fatturazione asincrona dell'utilizzo, avremmo introdotto ritardi, eccedenze o problemi di riconciliazione, proprio il tipo di problemi che gli utenti notano quando sono più coinvolti.
Ciò di cui avevamo bisogno era invece un unico sistema ibrido che combinasse limiti in tempo reale con accesso con pagamento a consumo:
Questo sistema doveva:
- Applica i limiti di frequenza fino a quando non vengono raggiunti
- Transizione senza problemi ai crediti all'interno della stessa richiesta
- Prendere quella decisione in tempo reale
- Essere rigorosamente accurato e verificabile nel monitoraggio del consumo di credito
Uno dei principali cambiamenti concettuali che abbiamo apportato è stato quello di modellare l'accesso come una cascata decisionale. Invece di chiedere "è consentito?", chiediamo "quanto è consentito e da dove?" Quando conta l'utilizzo, il sistema segue la seguente sequenza:
Il modello riflette l'esperienza effettiva degli utenti con il prodotto. Limiti di frequenza, piani gratuiti, crediti, promozioni e diritti aziendali sono solo livelli dello stesso stack decisionale Dal punto di vista dell'utente, non si verifica alcun “cambio di sistema”: gli utenti continuano semplicemente a utilizzare Codex e Sora. Ecco perché i crediti sembrano invisibili: sono solo un altro elemento della cascata.
Abbiamo valutato piattaforme di fatturazione e misurazione dell'utilizzo di terze parti per gestire il consumo di crediti. Sebbene siano adatte alla fatturazione e alla rendicontazione, non soddisfacevano due requisiti fondamentali:
Quando un utente raggiunge un limite e dispone di crediti disponibili, il sistema deve esserne immediatamente informato. Il conteggio approssimativo o ritardato si traduce in blocchi imprevisti, saldi incoerenti e addebiti errati. Per prodotti interattivi come Codex e Sora, questi errori diventano evidenti e frustranti.
Dovevamo anche garantire la trasparenza di ogni risultato:
- Perché una richiesta era stata accettata o bloccata
- Quanto è stato effettivamente utilizzato
- Quali limiti o crediti sono stati applicati
Questa funzionalità doveva essere strettamente integrata nel nostro processo decisionale a cascata, piuttosto che risolta in modo isolato su una piattaforma di fatturazione separata che vedeva solo una parte di ciò che stava accadendo. Per consentire agli utenti di accedere ai nostri prodotti senza compromettere la fiducia, avevamo bisogno di un controllo completo sulla correttezza, sulla tempistica e sull'osservabilità. Questo ci ha spinto verso una soluzione interna.
Per alimentare tutto questo, abbiamo creato un sistema di utilizzo e bilanciamento distribuito progettato specificamente per le decisioni di accesso sincrono.
A livello generale, il sistema:
- Tiene traccia dell'utilizzo per utente e per funzione
- Mantiene le finestre di limite di frequenza
- Mantiene i saldi dei crediti in tempo reale
- Addebita i saldi in modo idempotente attraverso un processore di trasmissione asincrono
Ogni richiesta passa attraverso un unico percorso di valutazione che prende una decisione in tempo reale sull'utilizzo consentito, attingendo allo stesso tempo dai limiti di frequenza e, se necessario, verificando la disponibilità di crediti sufficienti; quindi restituisce un risultato definitivo, regolando in modo asincrono eventuali addebiti di credito. Ciò garantisce un comportamento coerente tra i prodotti ed elimina il rischio di logica duplicata tra i team.
Uno dei principi fondamentali alla base della progettazione di questo sistema è che dobbiamo essere in grado di dimostrare la correttezza della nostra fatturazione. Ciò riflette le basi del nostro supporto al credito, originariamente rivolto ai clienti aziendali. Nel diagramma di sistema sopra riportato, abbiamo tre set di dati separati che sono tutti collegati tra loro:
- Eventi relativi all'utilizzo del prodotto: ciò che l'utente ha effettivamente fatto
- Eventi di monetizzazione: cosa addebitiamo all'utente per l'uso del servizio
- Aggiornamenti del saldo: di quanto abbiamo modificato il saldo di credito dell'utente e perché
Questi set di dati non sono un semplice sottoprodotto, in realtà, sono alla base del funzionamento del sistema, poiché ogni set di dati ne attiva uno successivo. Distinguendo ciò che è avvenuto, gli addebiti associati e gli importi che abbiamo addebitato, siamo in grado di verificare, riprodurre e riconciliare ogni livello in modo indipendente. Si tratta di un compromesso intenzionale, in cui diamo priorità alla correttezza dimostrabile, a scapito di un leggero ritardo nell'aggiornamento del saldo del credito. Come abbiamo raggiunto questo obiettivo:
- Gli eventi relativi all'utilizzo del prodotto vengono pubblicati per tutte le attività degli utenti, indipendentemente dal fatto che comportino o meno il consumo di crediti. Ciò fornisce una tracciabilità delle attività degli utenti e ci consente di spiegare perché abbiamo addebitato o meno dei crediti.
- Ogni evento include una chiave di idempotenza stabile, quindi i tentativi, le riproduzioni o i riavvii dei lavoratori non possono mai addebitare due volte un saldo, evitando così il doppio addebito. Questo ci consente anche di eseguire una riconciliazione batch per verificare il nostro lavoro offline.
- Eseguiamo aggiornamenti asincroni (ma comunque quasi in tempo reale) del saldo, anziché aggiornamenti sincroni, per creare una tracciabilità delle operazioni. Tolleriamo un leggero ritardo nell'aggiornamento del saldo dell'utente, in modo da poter dimostrare che il sistema funziona correttamente e garantire ai nostri utenti che non stiamo emettendo fatture errate. Quando questo breve ritardo ci porta a superare il saldo a credito di un utente, provvediamo automaticamente al rimborso. Preferiamo la correttezza dimostrabile e la fiducia degli utenti a un'applicazione rigorosa delle regole.
- Riduciamo il saldo di credito e inseriamo un record di aggiornamento del saldo in un'unica transazione atomica del database Gli aggiornamenti del saldo vengono serializzati per conto, quindi le richieste simultanee non possono mai contendersi lo stesso credito. Il record di aggiornamento del saldo contiene sia l'importo addebitato che l'attribuzione all'evento di monetizzazione che ha attivato l'aggiornamento; racchiudere tutto questo in un'unica transazione del database garantisce che abbiamo una tracciabilità di controllo per ogni adeguamento del saldo di credito.
Tutto questo rigore è finalizzato a un unico obiettivo: rendere l'accesso semplice e sicuro. Quando le persone creano o programmano, non dovrebbero chiedersi se una richiesta verrà accettata, se pagheranno più del dovuto o se il loro saldo è corretto. Rendendo l'utilizzo, la fatturazione e i saldi corretti e verificati, offriamo agli utenti un sistema che non interferisce con la loro esperienza. È questo che ci consente di sostituire le interruzioni brusche con un accesso continuo ed è ciò che rende i crediti utilizzabili nel bel mezzo del lavoro reale, non solo su una fattura.
Il principio fondamentale alla base del nostro approccio è proteggere la dinamicità degli utenti. Ogni decisione architettonica si riflette su un risultato per l'utente: i saldi in tempo reale evitano interruzioni inutili, il consumo atomico impedisce la doppia fatturazione e la logica di accesso unificata garantisce un comportamento prevedibile. Il risultato è che le persone possono lavorare più a lungo, approfondire maggiormente e portare avanti i progetti senza incontrare ostacoli o cambiamenti di programma prematuri.
Quando gli utenti sono coinvolti, il sistema dovrebbe aiutarli a continuare, senza creare ostacoli. Limiti e crediti passano in secondo piano.
Per costruire questa esperienza è stato necessario ripensare l'accesso, l'utilizzo e la fatturazione come un unico sistema e creare un'infrastruttura che considerasse la correttezza come una caratteristica fondamentale del prodotto. La stessa struttura può essere estesa nel tempo ad altri prodotti; Codex e Sora sono solo l'inizio.


