Потоковые ответы
Потоковая передача (Streaming) позволяет получать вывод модели в реальном времени по мере генерации, улучшая взаимодействие с пользователем и ощущение скорости.
Принцип работы#
诺玛AI использует протокол Server-Sent Events (SSE) для реализации потоковых ответов:
- При отправке запроса клиент устанавливает `stream: true`
- Сервер постепенно возвращает сгенерированные фрагменты содержимого (chunk)
- Каждый chunk отправляется через SSE с префиксом `data: `
- По завершении генерации отправляется `data: [DONE]`
Потоковая передача по протоколу OpenAI#
cURL
Код
curl https://as.apinoma.com/v1/chat/completions \
-H "Authorization: Bearer $APINOMA_API_KEY" \
-H "Content-Type: application/json" \
-N \
-d '{
"model": "openai/gpt-4o",
"messages": [{"role": "user", "content": "Напиши стихотворение о программировании"}],
"stream": true
}'Python
TypeScript
Потоковая передача по протоколу Anthropic#
Python
Код
import anthropic
client = anthropic.Anthropic(
base_url="https://as.apinoma.com/anthropic",
api_key="<ваш APINOMA_API_KEY>"
)
with client.messages.stream(
model="anthropic/claude-sonnet-4.6",
max_tokens=1024,
messages=[{"role": "user", "content": "Напиши стихотворение о программировании"}]
) as stream:
for text in stream.text_stream:
print(text, end="", flush=True)TypeScript
Потоковая передача + Function Calling#
Потоковые ответы также поддерживают сценарии вызова функций. Модель сначала потоково выводит запрос на вызов инструмента, а после его обработки вы продолжаете диалог:
Код
stream = client.chat.completions.create(
model="openai/gpt-4o",
messages=[{"role": "user", "content": "Какая сегодня погода в Пекине?"}],
tools=[{
"type": "function",
"function": {
"name": "get_weather",
"description": "Получить погоду указанного города",
"parameters": {
"type": "object",
"properties": {
"city": {"type": "string", "description": "Название города"}
},
"required": ["city"]
}
}
}],
stream=True
)
for chunk in stream:
delta = chunk.choices[0].delta
if delta.tool_calls:
# Обработка вызова инструмента
print(f"Вызов инструмента: {delta.tool_calls[0].function}")
elif delta.content:
print(delta.content, end="", flush=True)Обработка ошибок и переподключение#
Потоковое соединение может прерваться из-за проблем с сетью. Рекомендуется реализовать логику переподключения.
Код
import time
def stream_with_retry(client, max_retries=3, **kwargs):
for attempt in range(max_retries):
try:
stream = client.chat.completions.create(stream=True, **kwargs)
for chunk in stream:
yield chunk
return # Успешно завершено
except Exception as e:
if attempt < max_retries - 1:
wait = 2 ** attempt # Экспоненциальная задержка
print(f"\nСоединение прервано, повтор через {wait}s...")
time.sleep(wait)
else:
raise eЛучшие практики#
- Всегда устанавливайте тайм-аут — избегайте бесконечного ожидания
- Обрабатывайте неполные chunk — в некоторых chunk может не быть content
- Реализуйте механизм переподключения — используйте стратегию экспоненциальной задержки
- На фронтенде используйте `flush` — чтобы содержимое отображалось мгновенно
Последнее обновление: 23 июня 2026 г.