OpenAI WebSocket mode — Responses API переезжает на постоянное соединение, и агенты ускоряются на 40%
OpenAI WebSocket mode — Responses API переезжает на постоянное соединение, и агенты ускоряются на 40%
OpenAI тихо выкатили штуку, которая меняет правила игры для всех, кто строит AI-агентов с кучей tool-вызовов. Responses API теперь умеет работать через WebSocket — одно постоянное соединение вместо десятков HTTP-запросов.
TL;DR: WebSocket mode в Responses API — постоянное соединение на
wss://api.openai.com/v1/responses. Отправляешь только новые данные +previous_response_id, сервер держит стейт в памяти. На цепочках с 20+ tool-вызовами — до 40% быстрее. Для простых запрос-ответ смысла нет.
Зачем это вообще нужно
Представь типичный агентский сценарий: модель анализирует код, вызывает tool для чтения файла, получает результат, вызывает следующий tool для поиска, потом ещё один для записи — и так 20-30 раз за сессию.
До сих пор каждый такой виток означал полный HTTP round-trip: открыть соединение, отправить весь контекст (который растёт с каждым шагом), получить ответ, закрыть соединение. На 25-м вызове ты перегоняешь мегабайты JSON туда-сюда, и большая часть этих данных — повтор предыдущего контекста.
WebSocket mode это убирает. Одно соединение, инкрементальные данные, стейт на сервере.
Как это работает
Подключаешься к wss://api.openai.com/v1/responses с Bearer-токеном и шлёшь response.create:
{ "type": "response.create", "model": "gpt-5.2", "input": [ {"role": "user", "content": "Проанализируй auth модуль"} ], "tools": [...], "store": true }
Получаешь ответ с response_id. Дальше — самое интересное. Каждый следующий запрос содержит только новое:
{ "type": "response.create", "previous_response_id": "resp_abc123", "input": [ {"type": "function_call_output", "call_id": "call_1", "output": "содержимое файла..."} ] }
Никакого дублирования контекста. Сервер помнит всё по previous_response_id, потому что хранит стейт в оперативной памяти прямо на том инстансе, к которому ты подключён.
Warm-up: подготовь стейт заранее
Можно отправить response.create с generate: false — сервер загрузит tools, instructions, подготовит стейт, но не будет генерировать ответ:
{ "type": "response.create", "model": "gpt-5.2", "tools": [...], "instructions": "Ты code review бот...", "generate": false }
Следующий реальный запрос стартует быстрее, потому что вся подготовительная работа уже сделана. Для агентов, которые начинают с тяжёлого system prompt и десятка tool-описаний — ощутимая экономия на time-to-first-token.
Сжатие контекста — два способа
Даже с инкрементальными запросами контекст растёт. OpenAI предлагает два механизма сжатия.
Автоматическое сжатие — включаешь context_management с compact_threshold в запросе. Когда количество токенов превышает порог, сервер сам сжимает контекст прямо во время генерации. Ты продолжаешь работать как обычно с previous_response_id:
response = client.responses.create( model="gpt-5.2", previous_response_id=prev_id, input=new_items, context_management={"compact_threshold": 80000} )
Ручное сжатие — вызываешь POST /responses/compact, передаёшь текущий контекст целиком. Получаешь сжатую версию в виде зашифрованного compaction item. Подставляешь его в следующий запрос вместо всей истории:
compacted = client.responses.compact( model="gpt-5.2", input=long_input_items ) next_response = client.responses.create( model="gpt-5.2", input=[*compacted.output, new_user_message] )
Compaction item — непрозрачный зашифрованный блоб. Его нельзя прочитать или модифицировать, но он несёт в себе всё ключевое из предыдущего контекста в компактной форме.
Ограничения, о которых нужно знать
- 60 минут — максимальное время жизни соединения. После этого переподключаешься
- Один запрос за раз — нет мультиплексирования, следующий
response.createтолько после завершения предыдущего - Кэш на инстансе — стейт живёт в памяти конкретного сервера. Если с
store=falseи соединение упало, стейт потерян. Сstore=trueсервер может восстановить из персистентного хранилища, но медленнее - Ошибки чистят кэш — если turn завершился с 4xx/5xx,
previous_response_idудаляется из кэша, чтобы не тащить битый стейт дальше
На Python — уже в SDK
Поддержка WebSocket появилась в openai Python SDK начиная с версии 2.22.0. Для простых сценариев без WebSocket API выглядит знакомо:
from openai import OpenAI client = OpenAI() res1 = client.responses.create( model="gpt-5.2", input="Проанализируй архитектуру проекта", store=True ) res2 = client.responses.create( model="gpt-5.2", input="Теперь предложи рефакторинг", previous_response_id=res1.id, store=True )
WebSocket-режим активируется на уровне транспорта — клиент сам решает, когда переключиться с HTTP на WebSocket.
Это паттерн из Realtime API, но для текста
OpenAI по сути перенёс архитектуру из Realtime API (который работает с аудио) в текстовые агентские сценарии. Тот же принцип: постоянное соединение, серверный стейт, инкрементальные обновления.
Это сигнал: OpenAI видят будущее API не в stateless запрос-ответ, а в stateful сессиях. Агент подключается, работает час, делает десятки tool-вызовов — и всё через одно соединение. HTTP round-trip на каждый шаг становится узким местом, когда агент делает 30 вызовов подряд.
Кому это важно
- Разработчику — если строишь агента с 10+ tool-вызовами за сессию, обнови
openaiSDK до 2.22.0+ и попробуй WebSocket mode. Ускорение ощутимое: Cline уже протестировали и получили до 50% улучшения time-to-first-token - Тимлиду — для агентских пайплайнов в продакшене WebSocket mode снижает latency и нагрузку на сеть. Меньше round-trips — быстрее обратная связь для пользователей. Плюс warm-up через
generate: falseдаёт предсказуемую скорость старта - Следишь за рынком — OpenAI двигаются от stateless API к stateful сессиям. Это фундаментальный сдвиг: API перестаёт быть «послал запрос — получил ответ» и становится «открыл сессию — работаешь». Anthropic, Google и другие провайдеры, скорее всего, последуют
Как попробовать
- Обнови Python SDK:
pip install openai>=2.22.0 - Используй
previous_response_idв цепочках tool-вызовов — это работает и без WebSocket, но даёт основу для перехода - Для warm-up попробуй
generate: falseв первом запросе — загрузи tools и instructions заранее - Включи автоматическое сжатие: добавь
context_management={"compact_threshold": 80000}в запрос - Документация с полным описанием API: WebSocket Mode, Compaction