Réponses en streaming
Le streaming (Streaming) vous permet de recevoir la sortie en temps réel pendant la génération du modèle, améliorant l'expérience utilisateur et la vitesse perçue.
Principe de fonctionnement#
诺玛AI utilise le protocole Server-Sent Events (SSE) pour les réponses en streaming :
- Le client définit `stream: true` lors de l'envoi de la requête
- Le serveur renvoie progressivement les fragments de contenu générés (chunk)
- Chaque chunk est envoyé via SSE avec le préfixe `data: `
- À la fin de la génération, `data: [DONE]` est envoyé
Streaming au protocole OpenAI#
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": "Écris un poème sur la programmation"}],
"stream": true
}'Python
TypeScript
Streaming au protocole Anthropic#
Python
Code
import anthropic
client = anthropic.Anthropic(
base_url="https://as.apinoma.com/anthropic",
api_key="<votre APINOMA_API_KEY>"
)
with client.messages.stream(
model="anthropic/claude-sonnet-4.6",
max_tokens=1024,
messages=[{"role": "user", "content": "Écris un poème sur la programmation"}]
) as stream:
for text in stream.text_stream:
print(text, end="", flush=True)TypeScript
Streaming + Function Calling#
Le streaming prend aussi en charge les scénarios d'appel de fonctions. Le modèle diffuse d'abord la requête d'appel d'outil, puis vous poursuivez la conversation une fois le traitement terminé :
Code
stream = client.chat.completions.create(
model="openai/gpt-4o",
messages=[{"role": "user", "content": "Quel temps fait-il à Pékin aujourd'hui ?"}],
tools=[{
"type": "function",
"function": {
"name": "get_weather",
"description": "Obtenir la météo d'une ville donnée",
"parameters": {
"type": "object",
"properties": {
"city": {"type": "string", "description": "Nom de la ville"}
},
"required": ["city"]
}
}
}],
stream=True
)
for chunk in stream:
delta = chunk.choices[0].delta
if delta.tool_calls:
# Traiter l'appel d'outil
print(f"Appel d'outil : {delta.tool_calls[0].function}")
elif delta.content:
print(delta.content, end="", flush=True)Gestion des erreurs et reconnexion#
La connexion en streaming peut être interrompue en raison de problèmes réseau. Il est recommandé d'implémenter une logique de reconnexion.
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 # Terminé avec succès
except Exception as e:
if attempt < max_retries - 1:
wait = 2 ** attempt # Repli exponentiel
print(f"\nConnexion interrompue, nouvelle tentative dans {wait}s...")
time.sleep(wait)
else:
raise eBonnes pratiques#
- Toujours définir un délai d'expiration — pour éviter une attente infinie
- Gérer les chunks incomplets — certains chunks peuvent ne pas avoir de content
- Implémenter un mécanisme de reconnexion — utiliser une stratégie de repli exponentiel
- Utiliser `flush` côté frontend — pour garantir l'affichage immédiat du contenu
Dernière mise à jour le 23 juin 2026