Разделы

Стриминг ответов (SSE)

Функции могут стримить вывод вместо одного финального ответа. Платформа оформляет каждый фрагмент как сообщение Server-Sent Events (SSE), поэтому браузеры, CLI-инструменты и оркестраторы показывают прогресс — токены LLM, статус задачи, долгие вычисления — пока обработчик ещё работает.

Стриминг — это обычный HTTP: без WebSocket-апгрейда и специальных клиентских библиотек. Читать поток может всё, что умеет читать HTTP-ответ построчно: fetch с reader, curl -N, EventSource.

Пишем стриминговый обработчик

В Node.js экспортируйте асинхронный генератор (или верните его из обработчика): каждый yield становится одним SSE-фреймом. Python-обработчики стримят так же — yield из генератора или асинхронного генератора, и каждое значение уходит фреймом data:.

index.js
// Return an async generator and the platform streams each chunk
// to the client as Server-Sent Events over /invoke/stream.
exports.handler = async function* (event, context) {
  yield { type: 'status', message: 'starting' };

  for (const token of ['Hello', ' from', ' a', ' stream']) {
    // Objects are framed as `data: {...}` SSE events automatically;
    // yield a string to write a raw SSE frame yourself.
    yield { token };
  }

  yield { type: 'done' };
};

Отдадите объект — рантайм сериализует его в JSON внутри фрейма data:; отдадите строку — запишете сырой SSE-фрейм сами. Если обработчик вернул одно значение вместо генератора, поток завершается одним фреймом event: done с результатом — вызывающая сторона обрабатывает оба варианта одинаково.

Вызываем стриминговый эндпоинт

Любую функцию можно вызвать в стриминговом режиме через POST /functions/{functionId}/invoke/stream. Ответ начинается сразу и остаётся открытым, пока обработчик не завершится:

curl
# -N disables buffering so events render as they arrive
curl -N -X POST "https://api.inquir.org/functions/{functionId}/invoke/stream" \
  -H "Authorization: Bearer $INQUIR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"event": {"prompt": "stream me"}}'

# data: {"type":"status","message":"starting"}
# data: {"token":"Hello"}
# …
# event: log   — console output is interleaved as log events
# event: done  — emitted when the handler returns a value instead of a generator

Стриминг через API-шлюз

Маршруты шлюза тоже стримят: маршрут, привязанный к стриминговому обработчику, пересылает SSE-фреймы на публичный URL по мере их появления. Так выглядит собственный эндпоинт со стримингом токенов LLM:

  • Соединение живёт весь таймаут функции — стриминг не продлевает лимит, он лишь доставляет вывод раньше.
  • Для стриминговых путей отключена буферизация прокси, поэтому фреймы доходят до клиента без задержек на батчинг.
  • Авторизация на маршруте (API key или Bearer) действует для стриминговых маршрутов так же, как для обычных.

Особенности поведения

  • Вывод console.log вплетается в поток фреймами event: log — живые логи приходят вместе с данными без второго соединения.
  • Если обработчик упал посреди потока, поток завершится фреймом event: error с сообщением — проверяйте его, прежде чем считать закрытый поток успешным.
  • Стриминг работает и из тёплых, и из холодных контейнеров; на холодном пути просто позже приходит первый фрейм.