Ускорение агентных сценариев в Responses API с помощью WebSockets

Прослушать статью

Когда вы просите Codex исправить ошибку, он просматривает кодовую базу в поиске нужных файлов, читает их, чтобы собрать контекст, вносит правки и запускает тесты, чтобы проверить, сработало ли исправление. Под капотом это означает десятки обратных вызовов Responses API: определить следующее действие модели, запустить инструмент на вашем компьютере, отправить результат инструмента обратно в API и повторять цикл.

Все эти запросы могут складываться в минуты ожидания, пока Codex завершает сложные задачи. С точки зрения задержки цикл агента Codex в основном тратит время на три этапа: работу в сервисах API (проверка и обработка запросов), инференс модели и время на стороне клиента (запуск инструментов и построение контекста модели). Инференс — это этап, на котором модель работает на GPU и генерирует новые токены. Раньше инференс LLM на GPU был самым медленным участком агентного цикла, поэтому накладные расходы API было легко скрыть. Но по мере ускорения инференса совокупные накладные расходы API в агентном сценарии становятся гораздо заметнее.

В этом материале мы объясняем, как нам удалось ускорить агентные циклы, использующие API, на 40% end-to-end, чтобы пользователи почувствовали скачок скорости инференса с 65 до почти 1 000 токенов в секунду. Мы добились этого за счет кеширования, устранения лишних сетевых переходов, улучшения нашего safety stack для более быстрого выявления проблем и — что важнее всего — создания способа поддерживать постоянное соединение с Responses API вместо серии синхронных API-вызовов.

В Responses API предыдущие флагманские модели, такие как GPT‑5 и GPT‑5.2, работали примерно со скоростью 65 токенов в секунду (TPS). Для запуска GPT‑5.3‑Codex‑Spark, быстрой модели для программирования, нашей целью была производительность на порядок выше: более 1 000 TPS, обеспеченная специализированным оборудованием Cerebras, оптимизированным для инференса LLM. Чтобы пользователи могли ощутить настоящую скорость этой новой модели, нам нужно было снизить накладные расходы API.

Примерно в ноябре 2025 года мы запустили performance sprint для Responses API и внедрили множество оптимизаций критического пути задержки для одного запроса:

  • кеширование отрендеренных токенов и конфигурации модели в памяти, чтобы пропускать дорогостоящую токенизацию и сетевые вызовы для многоходовых ответов;
  • снижение задержки сетевых переходов за счет устранения вызовов к промежуточным сервисам (например, для обработки изображений и определения разрешения) и прямого обращения к сервису инференса;
  • улучшение safety stack, чтобы мы могли быстрее запускать отдельные классификаторы и помечать разговоры.

Благодаря этим улучшениям мы увидели почти 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 на ночь.

В этом прототипе агентные rollouts моделировались как один долгоживущий Response. Используя возможности asyncio, Responses API асинхронно блокировался в цикле сэмплирования после того, как был сэмплирован вызов инструмента, и отправлял событие response.done обратно клиенту. После выполнения вызова инструмента клиенты отправляли событие response.append с результатом инструмента, которое разблокировало цикл сэмплирования и позволяло модели продолжить работу.

Аналогия здесь — воспринимать локальный вызов инструмента как hosted tool call. Когда модель вызывает web search, цикл инференса блокируется, обращается к сервису web search и помещает ответ сервиса в контекст модели. В нашем дизайне мы делали то же самое, но вместо обращения к удаленному сервису отправляли вызов инструмента модели обратно клиенту через WebSocket. Когда клиент отвечал, мы помещали ответ на вызов инструмента клиента в контекст и продолжали сэмплирование.

Этот дизайн оказался чрезвычайно эффективным, потому что устранял повторяющуюся работу API в течение всего агентного rollout. Мы могли один раз выполнить preinference-работу, приостановиться на выполнение инструмента и один раз выполнить postinference-работу в конце.

К сожалению, это имело цену: API-форма стала менее привычной и более сложной. Мы хотели, чтобы разработчики могли подключить поддержку WebSocket без необходимости переписывать интеграцию с API под новый режим взаимодействия.

В версии, которую мы выпустили, мы вернулись к привычной форме: по-прежнему использовать response.create с тем же body и применять previous_response_id, чтобы продолжать контекст разговора из состояния предыдущего ответа.

При соединении WebSocket сервер хранит привязанный к соединению in-memory cache предыдущего состояния ответа. Когда последующий вызов response.create включает previous_response_id, мы берем это состояние из кеша вместо того, чтобы заново собирать весь разговор с нуля.

Это кешированное состояние включает:

  • предыдущий объект response;
  • предыдущие input- и output-элементы;
  • определения инструментов и namespaces;
  • переиспользуемые артефакты сэмплирования, например ранее отрендеренные токены.

Используя in-memory previous response state, мы смогли внедрить несколько крупных оптимизаций:

  • некоторые наши safety classifiers и validators запросов теперь обрабатывают только новый ввод, а не всю историю каждый раз;
  • мы храним в памяти кеш отрендеренных токенов и дополняем его, чтобы пропускать ненужную токенизацию;
  • мы переиспользуем успешную логику resolution/routing модели между запросами;
  • мы перекрываем неблокирующую postinference-работу, такую как биллинг, с последующими запросами.

Цель состояла в том, чтобы максимально приблизиться к прототипу с минимальными накладными расходами, но при этом сохранить форму API, которую разработчики уже понимали и вокруг которой выстроили свои интеграции.

Результаты запуска проявились сразу. Codex быстро перевел большую часть трафика Responses API в WebSocket mode, увидев заметное снижение задержки. Для GPT‑5.3‑Codex‑Spark мы достигли целевого уровня 1 000 TPS и увидели всплески до 4 000 TPS, что показало: Responses API способен выдерживать гораздо более быстрый инференс в реальном продакшн-трафике. Эффект быстро проявился и в сообществе разработчиков:

WebSocket mode — одна из самых значимых новых возможностей Responses API с момента его запуска в марте 2025 года. Мы прошли путь от идеи до продакшена всего за несколько недель благодаря тесному сотрудничеству команд API и Codex в OpenAI. Это не только резко улучшает задержку агентных rollout, но и отвечает на растущую потребность разработчиков: по мере ускорения инференса модели сервисы и системы вокруг него тоже должны ускоряться, чтобы передавать эти выигрыши пользователям.


Материал — перевод статьи с английского.

Оригинал: Speeding up agentic workflows with WebSockets in the Responses API