Ускорение агентных рабочих процессов с WebSockets в API Responses
Авторы: Брайан Ю и Ашвин Натан, технические специалисты
Когда вы просите Codex исправить ошибку, он просматривает вашу кодовую базу в поисках связанных файлов, читает их, чтобы понять контекст, вносит изменения и запускает тесты, чтобы убедиться, что исправление сработало. На практике это означает десятки запросов к Responses API с многократным обменом данными: определить следующее действие модели, запустить инструмент на вашем компьютере, отправить результат работы инструмента обратно в API и повторить.
Все эти запросы в сумме могут означать, что пользователям придётся ждать несколько минут, пока Codex выполнит сложные задачи. С точки зрения задержки цикл агента Codex большую часть времени проводит на трёх основных этапах: в сервисах API (где выполняются проверка и обработка запросов), во время инференса модели и на стороне клиента (при запуске инструментов и формировании контекста модели). Инференс — это этап, на котором модель выполняется на GPU и генерирует новые токены. Раньше инференс LLM на GPU был самой медленной частью агентного цикла, поэтому накладные расходы сервисов API было легко замаскировать. По мере ускорения инференса совокупные накладные расходы API в ходе выполнения агентного цикла становятся гораздо заметнее.
В этой статье мы объясним, как нам удалось сделать циклы агента с использованием API на 40% быстрее в целом, позволив пользователям ощутить скачок скорости инференса с 65 почти до 1 000 токенов в секунду. Мы добились этого за счет кэширования, устранения ненужных сетевых переходов, улучшения нашего стека безопасности для быстрого выявления проблем и — что самое важное — создания способа устанавливать постоянное соединение с Responses API вместо необходимости выполнять серию синхронных вызовов API.

В Responses API предыдущие флагманские модели, такие как GPT‑5 и GPT‑5.2, работали со скоростью примерно 65 токенов в секунду (TPS). При запуске GPT‑5.3‑Codex‑Spark — быстрой модели для программирования — нашей целью было добиться ускорения на порядок: более 1 000 TPS благодаря специализированному оборудованию Cerebras, оптимизированному для вывода LLM. Чтобы пользователи могли оценить реальную скорость этой новой модели, нам пришлось сократить накладные расходы API.
Примерно в ноябре 2025 года мы запустили спринт по повышению производительности Responses API и внедрили множество оптимизаций, чтобы сократить задержку на критическом пути обработки одного запроса:
- Кэширование сгенерированных токенов и конфигурации модели в памяти, чтобы избежать затратной токенизации и сетевых вызовов при многошаговых взаимодействиях
- Снижение задержки из-за сетевых переходов за счёт устранения вызовов промежуточных сервисов (например, для определения разрешения при обработке изображений) и прямого вызова самого сервиса инференса
- Улучшение нашего стека безопасности, чтобы мы могли запускать определённые классификаторы для более быстрого выявления проблем в разговорах
Благодаря этим улучшениям нам удалось почти на 45% сократить время до первого токена (TTFT) — показатель, который отражает, насколько быстро API реагирует на запрос, — однако даже этого оказалось недостаточно для GPT‑5.3‑Codex‑Spark. Даже после этих улучшений накладные расходы Responses API оставались слишком высокими относительно скорости модели: пользователям приходилось ждать обработки на CPU, где работал наш API, прежде чем задействовать GPU, обслуживающие модель.
Более глубокая проблема носила структурный характер: мы рассматривали каждый запрос к Codex как независимый, обрабатывая состояние разговора и другой повторно используемый контекст в каждом последующем запросе. Даже когда большая часть разговора не менялась, нам всё равно приходилось платить за работу, связанную со всей историей чата. По мере того как разговоры становились длиннее, эта повторная обработка становилась все более затратной.
Чтобы сделать архитектуру стройнее, мы переосмыслили транспортный протокол: можно ли поддерживать постоянное соединение и кэшировать состояние, вместо того чтобы устанавливать новое соединение по HTTP и отправлять полную историю разговора при каждом последующем запросе? Идея заключалась в том, чтобы отправлять только новую информацию, требующую проверки и обработки, и кэшировать в памяти повторно используемое состояние на время существования соединения. Это позволило бы сократить накладные расходы, связанные с избыточной работой.
Мы рассмотрели несколько подходов, включая WebSockets и двунаправленную потоковую передачу gRPC. Мы остановились на WebSockets, потому что при использовании этого простого протокола передачи сообщений пользователям не пришлось бы менять структуру входных и выходных данных Responses API. Он был удобным для разработчиков и хорошо вписывался в нашу существующую архитектуру, требуя минимальных изменений.
Первый прототип WebSocket изменил наше представление о возможной задержке Responses API. Инженер команды Codex с глубокой экспертизой во всём стеке API собрал прототип, запустив агента Codex на ночь.
В этом прототипе агентные rollout-процессы моделировались как единый долгоживущий Response. Используя возможности asyncio, Responses API асинхронно приостанавливал выполнение в цикле сэмплирования после выбора вызова инструмента и отправлял клиенту событие response.done. После выполнения вызова инструмента клиенты отправляли обратно событие response.append с результатом работы инструмента, что разблокировало цикл выборки и позволяло модели продолжить работу.
Здесь можно провести аналогию: рассматривать локальный вызов инструмента как размещённый вызов инструмента. Когда модель вызывает веб-поиск, цикл инференса блокируется, вызывает сервис веб-поиска и помещает ответ сервиса в контекст модели. В нашей архитектуре мы сделали то же самое; но вместо вызова удалённого сервиса мы отправили вызов инструмента от модели обратно клиенту через WebSocket. Когда клиент присылал ответ, мы добавляли результат вызова инструмента в контекст и продолжали сэмплирование.
Это решение оказалось чрезвычайно эффективным, поскольку устранило необходимость в повторяющейся работе с API при развертывании агента. Мы могли выполнить прединференсную обработку один раз, приостановиться на время выполнения инструмента и выполнить постинференсную обработку один раз в конце.
К сожалению, это привело к менее привычной и более сложной структуре API. Мы хотели, чтобы разработчики могли добавить поддержку WebSocket без необходимости переписывать интеграцию с API под новую модель взаимодействия.
В выпущенной нами версии мы вернулись к привычному формату: по-прежнему использовать response.create с тем же телом запроса и использовать previous_response_id, чтобы продолжить контекст разговора из состояния предыдущего ответа.
В WebSocket-соединении сервер хранит привязанный к соединению кэш в памяти с предыдущим состоянием ответа. Когда последующий вызов response.create включает previous_response_id, мы получаем это состояние из кэша вместо того, чтобы заново собирать весь разговор с нуля.
Это кэшированное состояние включает:
- Предыдущий объект
response - Предыдущие элементы ввода и вывода
- Определения инструментов и пространства имён
- Повторно используемые артефакты сэмплирования, например ранее сгенерированные токены

Повторно используя хранящееся в памяти состояние предыдущего ответа, мы смогли внедрить несколько значимых оптимизаций:
- Обеспечить, чтобы некоторые наши классификаторы безопасности и валидаторы запросов обрабатывали только новый ввод, а не всю историю каждый раз
- Хранение кэша в памяти с сгенерированными токенами, который мы дополняем, чтобы избежать лишней токенизации
- Повторное использование нашей логики выбора и маршрутизации модели между запросами
- Параллельное выполнение неблокирующих постинференсных задач, например биллинга, вместе с последующими запросами
Цель состояла в том, чтобы максимально приблизиться к прототипу с минимальными накладными расходами, но при этом сохранить структуру API, которую разработчики уже понимали и вокруг которой строили свои решения.
После двухмесячного спринта по созданию режима WebSocket мы запустили альфа-версию с ключевыми стартапами, разрабатывающими агентов для программирования, чтобы они могли интегрировать её в свою инфраструктуру и безопасно наращивать трафик. Альфа-пользователям это очень понравилось: они сообщили о повышении эффективности до 40%(открывается в новом окне) в своих агентных рабочих процессах. Учитывая положительные отзывы об альфа-версии, мы были готовы к запуску.
Результаты запуска проявились сразу. Codex быстро перевёл большую часть трафика Responses API на режим WebSocket, добившись значительного снижения задержки. Для GPT‑5.3‑Codex‑Spark мы достигли целевого показателя в 1 000 TPS и наблюдали всплески до 4 000 TPS, что показало, что Responses API мог справляться со значительно более быстрым инференсом в реальном производственном трафике. Этот эффект быстро стал заметен и в сообществе разработчиков:
- Codex быстро перевёл большую часть своего трафика на WebSockets. Пользователи Codex, использующие новейшие модели, такие как GPT‑5.3‑Codex(открывается в новом окне), GPT‑5.4(открывается в новом окне), и более новые, получают преимущества от ускорения, обеспечиваемого режимом WebSocket.
- Vercel интегрировала режим WebSocket в AI SDK и добилась снижения задержки до 40 %(открывается в новом окне).
- Рабочие процессы Cline с несколькими файлами на 39 % быстрее(открывается в новом окне).
- Модели OpenAI в Cursor стали работать до 30% быстрее(открывается в новом окне).
Режим WebSocket — одна из наиболее значимых новых возможностей в Responses API с момента его запуска в марте 2025 года. Мы прошли путь от идеи до запуска в продакшене всего за несколько недель благодаря тесному сотрудничеству команд API OpenAI и Codex. Он не только значительно сокращает задержку при выполнении агентных циклов, но и отвечает растущей потребности разработчиков: по мере ускорения инференса модели сервисы и системы вокруг инференса тоже должны становиться быстрее, чтобы пользователи могли ощутить этот прирост.
Авторы
Brian Yu, Ashwin Nathan
Благодарности
Особая благодарность командам Responses API и Codex, работавшим над созданием режима WebSocket.


