За рамками лимитов: масштабирование доступа к Codex и Sora
Автор: Джона Коэн (Jonah Cohen), сотрудник технического штата
За последний год Codex и Sora продемонстрировали стремительный рост популярности: темпы использования быстро превзошли наши изначальные ожидания. Мы столкнулись с устойчивой закономерностью: пользователи начинают работу, находят для себя реальную ценность, а затем упираются в лимиты запросов (rate limits).
Лимиты запросов помогают сглаживать пиковые нагрузки и обеспечивать справедливый доступ; однако, когда пользователь получает пользу от продукта, неожиданная блокировка может вызывать разочарование. Нам хотелось найти способ позволить пользователям продолжать работу, одновременно защищая производительность системы и сохраняя доверие пользователей к нашему подходу.
Для решения этой задачи мы создали механизм доступа в реальном времени, который ведет учет использования. Одним из уровней этого механизма является возможность приобретения кредитов. Когда пользователи превышают свои лимиты, кредиты позволяют им продолжать использовать наши продукты за счет списания средств с баланса кредитов.
В основе этого лежит сложная система, объединяющая лимиты, отслеживание использования в реальном времени и балансы кредитов в единую модель доступа. В этой статье рассказывается о том, почему масштабирование Codex и Sora потребовало переосмысления контроля доступа, как доказано корректная система реального времени объединяет лимиты запросов и кредиты для каждого отдельного запроса, и как эта база теперь открывает дополнительные возможности доступа для обоих продуктов.
Почему существующие модели доступа оказались неэффективными
Если взглянуть на ситуацию шире, традиционные модели доступа обычно заставляют делать выбор:
- Лимиты запросов могут быть полезны на начальном этапе, но портят впечатление пользователям, когда ресурс исчерпан: «возвращайтесь позже»
- Биллинг на основе использования гибок, но заставляет пользователей платить с самого первого токена — что не идеально для поддержки этапа первоначального знакомства с продуктом
Для Codex и Sora ни один из подходов по отдельности не был достаточным. Если бы мы просто повысили лимиты запросов, мы бы потеряли важные инструменты сглаживания спроса и обеспечения справедливости, а также исчерпали бы пропускную способность для обслуживания всех пользователей. Если бы мы полностью полагались на асинхронный биллинг использования, мы бы столкнулись с задержками, перерасходом средств или проблемами сверки расчетов — именно с теми трудностями, которые пользователи замечают в моменты наибольшей вовлеченности.
Вместо этого нам потребовалась единая гибридная система, объединяющая лимиты в реальном времени с моделью оплаты по мере использования (pay-as-you-go):
Эта система должна была:
- Применять лимиты запросов до тех пор, пока они не будут исчерпаны
- Плавный переход на кредиты в рамках того же запроса
- Принимать это решение в режиме реального времени
- Обладать безупречной точностью и прозрачностью при отслеживании расхода кредитов
Доступ как водопад, а не как шлагбаум
Одним из ключевых концептуальных сдвигов стало представление доступа в виде каскада решений (decision waterfall). Вместо вопроса «разрешено ли это?», мы спрашиваем: «сколько разрешено и откуда?» При подсчете использования система проходит через следующую последовательность:
Эта модель отражает реальный опыт взаимодействия пользователей с продуктом. Лимиты запросов, бесплатные тарифы, кредиты, промоакции и корпоративные льготы — все это просто уровни в едином стеке принятия решений. С точки зрения пользователя, они не «переключаются между системами» — они просто продолжают использовать Codex и Sora. Именно поэтому кредиты кажутся незаметными: они представляют собой лишь еще один элемент в водопаде.
Почему мы создали это решение собственными силами
Мы оценивали сторонние платформы биллинга использования и учета ресурсов для обработки расхода кредитов. Они отлично подходят для выставления счетов и отчетности, но не отвечали двум критически важным требованиям:
Корректность в реальном времени
Когда пользователь исчерпывает лимит и у него есть доступные кредиты, система должна узнать об этом немедленно. Подсчет по принципу «лучших усилий» (best-effort) или с задержкой приводит к неожиданным блокировкам, несогласованным балансам и неверным списаниям. Для интерактивных продуктов, таких как Codex и Sora, подобные сбои становятся заметными и вызывают раздражение.
Возможность сверки и доверие
Нам также требовалось обеспечить прозрачность каждого результата:
- Почему запрос был разрешен или заблокирован
- Какой объем ресурсов он потребил
- Какие лимиты или балансы были применены
Эту возможность необходимо было тесно интегрировать в наш каскад принятия решений, а не решать изолированно в рамках отдельной платформы биллинга, которая видит лишь часть происходящего. Чтобы предоставить пользователям доступ к нашим продуктам без ущерба для доверия, нам потребовался полный контроль над корректностью, таймингом и наблюдаемостью. Именно это подтолкнуло нас к созданию собственного решения.
Создание высокомасштабируемой системы учета использования и балансов
Для реализации этой задачи мы построили распределенную систему учета использования и балансов, разработанную специально для принятия синхронных решений о доступе.
На высоком уровне система выполняет следующие функции:
- Отслеживает использование для каждого отдельного пользователя и функции
- Поддерживает окна лимитов запросов
- Поддерживает кредитные балансы в реальном времени
- Идемпотентно списывает средства с балансов с помощью потокового асинхронного процессора
Каждый запрос проходит через единый путь оценки, который в режиме реального времени принимает решение о том, какой объем использования разрешен, путем синхронного списания из лимитов запросов и, при необходимости, проверки достаточности кредитов; затем система возвращает один окончательный результат, одновременно урегулируя любые списания кредитов асинхронно. Это обеспечивает согласованное поведение продуктов и исключает дублирование логики между командами.
Доказуемо корректная биллинговая система
Один из ключевых принципов проектирования этой системы заключается в том, что мы должны иметь возможность доказать корректность нашего биллинга. Это отражает истоки нашей поддержки кредитов, которая изначально зарождалась для корпоративных клиентов. На приведенной выше схеме системы у нас есть три отдельных набора данных, которые тесно связаны между собой:
- События использования продукта: то, что пользователь действительно сделал
- События монетизации: то, за что мы берем с пользователя плату
- Обновления баланса: насколько и почему мы скорректировали баланс кредитов пользователя
Эти наборы данных не являются случайным побочным продуктом; они фактически управляют системой, причем каждый набор данных запускает следующий. Разделение того, что произошло, любых связанных начислений и того, что мы списали, позволяет нам независимо аудировать, воспроизводить и сверять каждый уровень. Это осознанный компромисс, при котором мы отдаем приоритет доказуемой корректности ценой небольшой задержки в обновлении баланса кредитов. Как мы этого добились:
- События использования продукта публикуются для всей активности пользователей, независимо от того, приводит ли она к потреблению кредитов. Это обеспечивает след для аудита пользовательской активности и позволяет нам объяснить, почему мы списали (или не списали) кредиты.
- Каждое событие содержит устойчивый ключ идемпотентности, поэтому повторные попытки, воспроизведения или перезапуски воркеров никогда не смогут дважды списать средства с баланса, что предотвращает двойное списание. Это также позволяет нам запускать пакетную сверку для проверки нашей работы в автономном режиме.
- Мы выполняем асинхронные (но близкие к реальному времени) обновления баланса вместо синхронных, чтобы сформировать аудиторский след. Мы допускаем небольшую задержку при обновлении баланса пользователя, чтобы доказать работоспособность системы и заверить наших пользователей в отсутствии ошибок в биллинге. Когда из-за этой краткой задержки баланс кредитов пользователя уходит в небольшой минус, мы автоматически возвращаем средства; мы выбираем доказуемую корректность и доверие пользователей в ущерб строгому принудительному контролю.
- Мы уменьшаем кредитный баланс и вставляем запись об обновлении баланса в рамках одной атомарной транзакции базы данных. Обновления баланса сериализуются для каждого аккаунта, поэтому параллельные запросы никогда не смогут соревноваться за траты одних и тех же кредитов. Запись об обновлении баланса содержит как сумму списания, так и привязку к событию монетизации, которое инициировало это обновление; объединение этого в одну транзакцию базы данных гарантирует наличие аудиторского следа для каждого изменения кредитного баланса.
Вся эта строгость служит одной цели: сделать доступ простым и безопасным. Когда люди занимаются творчеством или пишут код, они не должны гадать, пройдет ли запрос, не переплатят ли им или точен ли их баланс. Делая использование, биллинг и балансы доказуемо корректными, мы предоставляем пользователям систему, которая не отвлекает их от работы. Именно это позволяет нам заменить жесткие блокировки непрерывным доступом — и именно это делает кредиты применимыми прямо в процессе реальной работы, а не только в счете на оплату.
Архитектура на службе продуктивности
Руководящим принципом нашего подхода является защита продуктивности пользователя. Каждое архитектурное решение напрямую связано с пользовательским опытом: балансы в реальном времени предотвращают ненужные прерывания, атомарное списание защищает от двойной оплаты, а логика единого доступа обеспечивает предсказуемое поведение. В результате люди могут работать дольше, глубже погружаться в процесс и продвигать проекты дальше, не сталкиваясь с жесткими ограничениями или преждевременной сменой тарифных планов.
Когда пользователи увлечены процессом, система должна помогать им продолжать работу, а не мешать. Лимиты и кредиты уходят на задний план.
Создание такого опыта потребовало переосмысления доступа, использования и биллинга как единой системы, а также создания инфраструктуры, в которой корректность рассматривается как первоклассная функция продукта. Со временем этот же фундамент может быть распространен и на другие продукты; Codex и Sora — это только начало.
Автор
Благодарности
Особая благодарность всей команде FinEng, которая создала систему кредитов.
Полный текст статьи читайте на OpenAI
