Bortom begränsningar: utöka åtkomsten till Codex och Sora
Av Jonah Cohen, medlem av den tekniska personalen
Under det senaste året har både Codex och Sora upplevt en snabb adoption, där användningen snabbt har överträffat våra ursprungliga förväntningar. Vi har sett ett konsekvent mönster: användare dyker in, hittar verkligt värde och stöter sedan på begränsningar i användningsfrekvens.
Hastighetsbegränsningar kan bidra till att jämna ut efterfrågan och säkerställa rättvis tillgång, men när användarna får värde för pengarna kan det vara frustrerande att stöta på ett hårt stopp. Vi ville ha ett sätt för användare att fortsätta, samtidigt som vi skyddar systemets prestanda och användarnas förtroende för vår metod.
För att lösa detta skapade vi en realtidsmotor för åtkomst som räknar användning. En av funktionerna i den motorn är möjligheten att köpa krediter. När användare överskrider sina hastighetsgränser kan de fortsätta använda våra produkter genom att använda sitt kreditsaldo.
Under detta finns ett komplext system som integrerar begränsningar, realtidsanvändningsspårning och kreditsaldon i en enda åtkomstmodell. Det här inlägget handlar om varför skalningen av Codex och Sora krävde en omprövning av åtkomstkontrollen, hur ett bevisligen korrekt realtidssystem kombinerar hastighetsbegränsningar och krediter per begäran, och hur den grunden nu öppnar upp ytterligare åtkomst för båda produkterna.
Om man zoomar ut tenderar traditionella åtkomstmodeller att tvinga fram ett val:
- Hastighetsbegränsningar kan vara hjälpsamma i början, men ger användarna en dålig upplevelse när de tar slut: “kom tillbaka senare”
- Användningsbaserad fakturering är flexibel, men innebär att användare betalar från första token – vilket inte är idealiskt för att stödja tidig utforskning
För Codex och Sora var ingen av dem tillräckligt på egen hand. Om vi helt enkelt höjde gränserna för hastighetsbegränsningar skulle vi förlora viktiga kontroller för att jämna ut efterfrågan och rättvisa, och vi skulle få slut på kapacitet för att betjäna alla. Om vi helt och hållet förlitade oss på asynkron användningsfakturering skulle vi få problem med fördröjningar, överskridanden eller avstämningar – precis den typ av problem som användarna märker när de är som mest engagerade.
Vad vi istället behövde var ett enda hybridsystem som kombinerade realtidsbegränsningar med pay-as-you-go-åtkomst:
Detta system var tvunget att:
- Tillämpa hastighetsbegränsningar tills de uppnås
- Övergå smidigt till krediter inom samma begäran
- Fatta beslutet i realtid
- Var noggrant korrekt och reviderbar när du följer kreditförbrukning
En av de viktigaste konceptuella förändringarna vi gjorde var att modellera åtkomst som en beslutsprocess. Istället för att fråga “är detta tillåtet?“, frågar vi “hur mycket är tillåtet och varifrån?“ När systemet räknar användningen går det igenom följande sekvens:
Den här modellen återspeglar hur användare faktiskt upplever produkten. Hastighetsbegränsningar, gratistjänster, krediter, kampanjer och företagsrättigheter är alla lager i samma beslutsprocess. Ur en användares perspektiv byter de inte system – de fortsätter bara att använda Codex och Sora. Därför känns krediter osynliga: de är bara ytterligare ett element i vattenfallet.
Vi utvärderade tredjepartsplattformar för fakturering och mätning av användning för att hantera kreditförbrukning. De är väl lämpade för fakturering och rapportering, men uppfyllde inte två viktiga krav:
När en användare når en gräns och har krediter tillgängliga måste systemet veta omedelbart. Räkning enligt bästa förmåga eller fördröjd räkning visar sig som överraskande blockeringar, inkonsekventa saldon och felaktiga avgifter. För interaktiva produkter som Codex och Sora blir dessa misslyckanden synliga och frustrerande.
Vi behövde också erbjuda insyn i varje resultat:
- Varför en begäran tilläts eller blockerades
- Hur mycket användning har det förbrukat
- Vilka begränsningar eller balanser tillämpades
Denna funktionalitet behövde integreras tätt i vårt beslutsflöde istället för att lösas isolerat i en separat plattform för användningsfakturering som bara såg en del av vad som hände. För att ge användare åtkomst till våra produkter utan att äventyra förtroendet behövde vi full kontroll över korrekthet, tidpunkt och observerbarhet. Det fick oss att välja en intern lösning.
För att möjliggöra detta byggde vi ett distribuerat system för användning och balans, särskilt utformat för synkrona åtkomstbeslut.
På hög nivå kommer systemet att:
- Spåra användning per användare och per funktion
- Upprätthålla kvotgränsfönster
- Hålla kreditsaldon uppdaterade i realtid.
- Debitera saldon idempotent genom en strömmande asynkron processor
Varje begäran passerar genom en enda utvärderingsväg som i realtid fattar ett beslut om hur mycket användning som tillåts genom att synkront förbruka från hastighetsbegränsningar och, vid behov, verifiera att det finns tillräckligt med krediter; den returnerar sedan ett enda definitivt resultat samtidigt som eventuella kreditdebiteringar regleras asynkront. Detta säkerställer ett konsekvent beteende över produkter och eliminerar duplicerad logik mellan team.
En av de centrala designprinciperna för det här systemet är att vi måste kunna bevisa att vår fakturering är korrekt. Detta återspeglar rötterna till vår kreditsupport, som har sitt ursprung hos företagskunder. I systemdiagrammet ovan har vi tre separata datamängder som alla är sammanlänkade:
- Produktanvändningshändelser: Vad användaren faktiskt gjorde
- Monetiseringshändelser: Vad vi tar betalt av användaren för deras användning
- Saldojusteringar: Hur mycket vi har justerat användarens kreditsaldo och varför
Dessa datamängder är inte en tillfällig biprodukt; de driver faktiskt systemet, där varje datamängd triggar nästa. Genom att separera det som inträffade, eventuella tillhörande avgifter och det vi debiterade kan vi oberoende granska, återspela och stämma av varje lager. Detta är en medveten avvägning där vi prioriterar bevisbar korrekthet, även om det innebär att uppdateringar av kreditsaldot blir något fördröjda. Så här lyckades vi med detta:
- Produktanvändningshändelser publiceras för all användaraktivitet, oavsett om det leder till kreditförbrukning eller inte. Detta ger en revisionsspårning för användaraktivitet och gör att vi kan förklara varför vi debiterade, eller inte debiterade, krediter.
- Varje händelse har en stabil idempotensnyckel, så att nya försök, omspelningar eller omstarter av arbetare aldrig kan leda till dubbeldebitering av ett saldo, vilket förhindrar dubbeldebitering. Detta gör det också möjligt för oss att utföra en batchavstämning för att kontrollera vårt arbete offline.
- Vi utför asynkrona (men fortfarande nästan i realtid) saldouppdateringar istället för synkrona uppdateringar för att skapa ett revisionsspår. Vi tolererar en liten fördröjning i uppdateringen av användarens saldo för att kunna bevisa att systemet fungerar och försäkra våra användare om att vi inte feldebiterar dem. När den korta fördröjningen gör att vi överskrider en användares kreditsaldo, återbetalar vi det automatiskt; vi väljer bevisbar korrekthet och användarnas förtroende framför strikt efterlevnad.
- Vi minskar kreditsaldot och infogar en saldo-uppdatering i en enda atomär databastransaktion. Saldouppdateringar serialiseras per konto, så samtidiga begäranden kan aldrig tävla om att använda samma krediter. Posten saldo-uppdatering innehåller både debetbeloppet och kopplingen tillbaka till den intäktsgenereringshändelse som utlöste uppdateringen; genom att kapsla in detta i en enda databastransaktion säkerställer vi att vi har ett revisionsspår för varje justering av kreditsaldot.
All denna noggrannhet har ett syfte: att göra åtkomsten enkel och säker. När människor skapar eller kodar ska de inte behöva oroa sig för om en begäran kommer att gå igenom, om de blir överdebiterade eller om deras saldo är korrekt. Genom att säkerställa att användning, fakturering och saldon är bevisligen korrekta, erbjuder vi användarna ett system som inte stör deras upplevelse. Det är det som låter oss ersätta hårda stopp med kontinuerlig åtkomst – och det är det som gör krediter användbara mitt under verkligt arbete, inte bara på en faktura.
Den vägledande principen bakom vår strategi är att bevara användarnas drivkraft. Varje arkitekturbeslut leder till ett användarorienterat resultat: realtidssaldon förhindrar onödiga avbrott, atomär förbrukning förhindrar dubbeldebitering och enhetlig åtkomstlogik säkerställer förutsägbart beteende. Resultatet är att människor kan arbeta längre, utforska djupare och driva projekt längre utan att stöta på tvärstopp eller behöva ändra planer i förtid.
När användare är engagerade bör systemet hjälpa dem att fortsätta, inte hindra dem. Begränsningar och krediter försvinner i bakgrunden.
Att skapa den upplevelsen krävde att vi omprövade åtkomst, användning och fakturering som ett enhetligt system och byggde en infrastruktur som betraktar korrekthet som en förstklassig produktfunktion. Samma grund kan utökas till fler produkter över tid; Codex och Sora är bara början.


