Зачем нужен стриминг?
Без стриминга пользователь ждёт до конца генерации — иногда это 10-30 секунд. Со стримингом первые слова появляются через 0.5-1 секунду, и текст «печатается» в реальном времени. Это кардинально улучшает UX.
Как работает SSE
Server-Sent Events (SSE) — стандартный протокол HTTP для однонаправленной потоковой передачи. Сервер держит соединение открытым и отправляет события по мере готовности:
data: {"choices":[{"delta":{"content":"Привет"}}]}
data: {"choices":[{"delta":{"content":","}}]}
data: {"choices":[{"delta":{"content":" мир!"}}]}
data: [DONE]
Python: синхронный стриминг
from openai import OpenAI
client = OpenAI(
api_key="ваш_ключ",
base_url="https://api.polza.ai/v1"
)
# Включаем стриминг через stream=True
stream = client.chat.completions.create(
model="anthropic/claude-sonnet-4-6",
messages=[{"role": "user", "content": "Напиши стихотворение о космосе"}],
stream=True
)
for chunk in stream:
if chunk.choices[0].delta.content is not None:
print(chunk.choices[0].delta.content, end="", flush=True)
print() # новая строка в конце
Python: async стриминг
import asyncio
from openai import AsyncOpenAI
async def stream_response():
client = AsyncOpenAI(
api_key="ваш_ключ",
base_url="https://api.polza.ai/v1"
)
async with client.chat.completions.stream(
model="openai/gpt-4o",
messages=[{"role": "user", "content": "Объясни квантовую механику просто"}]
) as stream:
async for text in stream.text_stream:
print(text, end="", flush=True)
asyncio.run(stream_response())
Node.js / TypeScript
import OpenAI from 'openai';
const client = new OpenAI({
apiKey: process.env.POLZA_API_KEY,
baseURL: 'https://api.polza.ai/v1',
});
async function streamChat() {
const stream = client.chat.completions.stream({
model: 'google/gemini-2.0-flash',
messages: [{ role: 'user', content: 'Расскажи о машинном обучении' }],
});
for await (const chunk of stream) {
process.stdout.write(chunk.choices[0]?.delta?.content ?? '');
}
const finalCompletion = await stream.finalChatCompletion();
console.log('\nТокенов использовано:', finalCompletion.usage?.total_tokens);
}
Стриминг в браузере (React)
async function fetchStreamedResponse(prompt: string) {
const response = await fetch('https://api.polza.ai/v1/chat/completions', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${apiKey}`,
},
body: JSON.stringify({
model: 'anthropic/claude-sonnet-4-6',
messages: [{ role: 'user', content: prompt }],
stream: true,
}),
});
const reader = response.body!.getReader();
const decoder = new TextDecoder();
while (true) {
const { done, value } = await reader.read();
if (done) break;
const lines = decoder.decode(value).split('\n');
for (const line of lines) {
if (line.startsWith('data: ') && line !== 'data: [DONE]') {
const data = JSON.parse(line.slice(6));
const content = data.choices[0]?.delta?.content;
if (content) {
setResponse(prev => prev + content); // обновляем React state
}
}
}
}
}
Советы
- Устанавливайте таймаут соединения достаточно большим (60+ секунд)
- Обрабатывайте разрывы соединения и делайте retry
- Не забывайте обрабатывать
[DONE]— сигнал завершения стрима