Гайд · TNWS AI
Как настроить streaming в OpenAI Responses API и правильно собрать ответ
Потоковая выдача OpenAI: stream:true, типы SSE-событий, text delta, завершение, tool calls и восстановление после обрыва.
Укажите stream:true и обрабатывайте события по event.type. Текст добавляется только из предназначенных для него delta-событий; завершение подтверждается финальным событием, а не закрытием TCP-соединения. Аргументы tool call также приходят частями и выполняются только после полной сборки и валидации.
Рабочий пример
const stream = await client.responses.create({
model: "gpt-5",
input: "Объясни три причины ошибки 429",
stream: true
});
let text = "";
for await (const event of stream) {
if (event.type === "response.output_text.delta") {
text += event.delta;
process.stdout.write(event.delta);
}
if (event.type === "response.failed") {
throw new Error(JSON.stringify(event.response?.error));
}
}
console.log("\nСобрано:", text.length);
Конкретные факты и поля
- SSE-поток содержит разные типы событий: текст, создание элементов, дельты аргументов и финальное состояние.
- Один сетевой chunk не равен одному событию или слову; используйте SDK либо полноценный SSE-парсер.
- Показываемая дельта ещё не прошла проверку полного ответа. Для чувствительных интерфейсов нужна стратегия буферизации и модерации.
- После обрыва нельзя просто дописать новую генерацию к старому тексту: возможны повторы и логические разрывы.
Как внедрить
- Создайте state machine по документированным типам событий.
- На text delta обновляйте черновой UI, но храните отдельно финально подтверждённый объект.
- Аргументы инструмента аккумулируйте до done-события, затем парсите JSON и проверяйте права.
- На completed сохраните результат и usage; на failed покажите контролируемую ошибку.
- Добавьте кнопку остановки через AbortController и пометьте ответ как незавершённый.
Как проверить результат
Разорвите соединение посередине длинного ответа. Интерфейс должен показать «ответ прерван», а не зелёную галочку. Отправьте tool call с JSON длиннее одного chunk и убедитесь, что функция не запускается до полного объекта.
Ограничения
Streaming сокращает время до первого фрагмента, но не обязательно полное время обработки. Он усложняет прокси, таймауты и модерацию. Для короткого JSON, который нужен только backend, обычный ответ чаще проще и надёжнее.
Чего не делать
- Не парсите SSE через
split("\n")без учёта протокола. - Не выполняйте tool call по первой дельте аргументов.
- Не считайте закрытый сокет доказательством completed.
FAQ
Можно ли копировать пример как есть?
Для прототипа — да. В production добавьте таймаут, обработку ошибок, лимиты, журнал request ID и защиту ключа.
Где хранить API-ключ?
В секретах серверной среды. Не в браузере, мобильном приложении, репозитории или тексте статьи.
Как проверить, что функция реально сработала?
Разбирать структурированные поля ответа и проводить контрольный тест, а не судить по убедительности текста.
Почему пример не фиксирует цену?
Тарифы и набор поддерживаемых моделей меняются; актуальные значения проверяются на официальной странице Pricing перед запуском.
Официальный источник
Документация OpenAI, проверена 11 сентября 2026 года: https://platform.openai.com/docs/guides/streaming-responses
Читайте также
Как подключить удалённый MCP-сервер к OpenAI API и проверить его инструменты
Remote MCP в Responses API: адрес сервера, список инструментов, approvals, проверка аргументов и защита от prompt injection.
Как подключить веб-поиск к OpenAI Responses API и получить проверяемые источники
Рабочий web_search в Responses API: вызов инструмента, доменные ограничения, чтение URL-цитат и проверка актуальности ответа.
Как сохранять контекст диалога в OpenAI Responses API без повторной отправки истории
Диалог через previous_response_id: хранение цепочки, инструкции, ветвление, контроль владельца и тест на смешивание пользователей.
Комментарии
Пока тихо. Скажите первое слово