ДокументацияРуководстваСтриминг

Стриминг

Форматы событий SSE в трёх диалектах и советы по разбору.

Все три диалекта поддерживают стриминг по Server-Sent Events (SSE): дельты приходят по мере генерации, ждать полного ответа не нужно. Форматы событий различаются по диалектам и совпадают с официальными API.

Формат OpenAI (Responses)

Укажите "stream": true в теле запроса. События содержат поле типа: response.created, response.output_text.delta, response.completed:

python
stream = client.responses.create(
    model="claude-fable-5",
    input="Tell me a story",
    stream=True,
)
for event in stream:
    if event.type == "response.output_text.delta":
        print(event.delta, end="", flush=True)

Формат Anthropic (Messages)

Тоже "stream": true, но события используют именованные события SSE (строки event: + data:): message_startcontent_block_start → серия content_block_deltacontent_block_stopmessage_deltamessage_stop.

SSE
event: message_start
data: {"type":"message_start","message":{...}}

event: content_block_delta
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"Once"}}

event: message_stop
data: {"type":"message_stop"}

Формат Gemini

Вызывайте действие :streamGenerateContent с ?alt=sse; каждая строка data: — фрагмент GenerateContentResponse, дельта-текст в candidates[].content.parts[].text. Без alt=sse вернётся полный JSON-массив (без стриминга).

stream.sh
curl "https://api.soleapi.com/v1beta/models/gemini-2.5-pro:streamGenerateContent?alt=sse" \
  -H "x-goog-api-key: $SOLEAPI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"contents": [{"parts": [{"text": "Tell me a story"}]}]}'

Советы по разбору

  • События SSE разделяются пустыми строками, но TCP-сегментация может разорвать событие между чтениями — буферизуйте ввод и разбирайте только целые кадры. Это самая частая ошибка в самописных парсерах.
  • Для долгих генераций увеличьте таймаут чтения до 5+ минут, чтобы клиент не обрывал reasoning-модели во время долгих пауз.
  • Повтор после обрыва — это новый запрос (поток нельзя возобновить с середины); рассмотрите откат на нестриминговый вызов.
  • При отрисовке UI группируйте дельты с троттлингом, чтобы каждая мелкая дельта не вызывала отдельную перерисовку.
  • Использование токенов при стриминге приходит в финальном событии; списание происходит после завершения потока.