Streaming
Streaming lets you receive output in real time as the model generates it, improving the user experience and perceived speed.
How it works#
诺玛AI implements streaming using the Server-Sent Events (SSE) protocol:
- The client sets `stream: true` when sending the request
- The server returns generated content chunks incrementally
- Each chunk is sent over SSE with a `data: ` prefix
- When generation ends, `data: [DONE]` is sent
OpenAI-compatible streaming#
cURL
Code
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": "Write a poem aboutprogramming"}],
"stream": true
}'Python
TypeScript
Anthropic-compatible streaming#
Python
Code
import anthropic
client = anthropic.Anthropic(
base_url="https://as.apinoma.com/anthropic",
api_key="<your APINOMA_API_KEY>"
)
with client.messages.stream(
model="anthropic/claude-sonnet-4.6",
max_tokens=1024,
messages=[{"role": "user", "content": "Write a poem aboutprogramming"}]
) as stream:
for text in stream.text_stream:
print(text, end="", flush=True)TypeScript
Streaming + function calling#
Streaming also works with function calling. The model first streams the tool-call request, and after you handle it you continue the conversation:
Code
stream = client.chat.completions.create(
model="openai/gpt-4o",
messages=[{"role": "user", "content": "What is the weather like in Beijing today?"}],
tools=[{
"type": "function",
"function": {
"name": "get_weather",
"description": "Get weather for a specified city",
"parameters": {
"type": "object",
"properties": {
"city": {"type": "string", "description": "City name"}
},
"required": ["city"]
}
}
}],
stream=True
)
for chunk in stream:
delta = chunk.choices[0].delta
if delta.tool_calls:
# Handle the tool call
print(f"Calling tool: {delta.tool_calls[0].function}")
elif delta.content:
print(delta.content, end="", flush=True)Error handling and reconnection#
A streaming connection can drop due to network issues. We recommend implementing reconnection logic.
Code
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 # Completed successfully
except Exception as e:
if attempt < max_retries - 1:
wait = 2 ** attempt # Exponential backoff
print(f"\nConnection interrupted; retrying in {wait}s...")
time.sleep(wait)
else:
raise eBest practices#
- Always set a timeout — avoid waiting indefinitely
- Handle incomplete chunks — some chunks may have no content
- Implement reconnection — use an exponential backoff strategy
- Use `flush` on the frontend — ensure content displays immediately
Last updated on June 23, 2026