> · 5 мин

OpenAI WebSocket mode — Responses API переезжает на постоянное соединение, и агенты ускоряются на 40%

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-вызовами за сессию, обнови openai SDK до 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 и другие провайдеры, скорее всего, последуют

Как попробовать

  1. Обнови Python SDK: pip install openai>=2.22.0
  2. Используй previous_response_id в цепочках tool-вызовов — это работает и без WebSocket, но даёт основу для перехода
  3. Для warm-up попробуй generate: false в первом запросе — загрузи tools и instructions заранее
  4. Включи автоматическое сжатие: добавь context_management={"compact_threshold": 80000} в запрос
  5. Документация с полным описанием API: WebSocket Mode, Compaction
$ ls ./related/

Похожие статьи

subscribe.sh

$ cat /dev/blog/updates

> Свежие заметки о программировании,

> DevOps и AI — прямо в мессенджер

./subscribe