Streaming
Réponses en temps réel token par token via Server-Sent Events.
Vue d'ensemble
AllToken prend en charge les réponses en streaming via Server-Sent Events (SSE). Lorsque stream: true est défini, l'API retourne les tokens progressivement au fur et à mesure de leur génération, sans attendre la réponse complète.
Cela permet des interfaces utilisateur en temps réel où le texte s'affiche mot à mot, réduisant considérablement la latence perçue.
Utilisation de base
Ajoutez stream: true à votre requête Chat Completions :
| 1 | import OpenAI from 'openai'; |
| 2 | |
| 3 | const client = new OpenAI({ |
| 4 | apiKey: process.env.ALLTOKEN_API_KEY, |
| 5 | baseURL: 'https://api.alltoken.ai/v1', |
| 6 | }); |
| 7 | |
| 8 | const stream = await client.chat.completions.create({ |
| 9 | model: 'claude-sonnet-4', |
| 10 | messages: [{ role: 'user', content: 'Expliquez l'informatique quantique' }], |
| 11 | stream: true, |
| 12 | }); |
| 13 | |
| 14 | for await (const chunk of stream) { |
| 15 | const content = chunk.choices[0]?.delta?.content; |
| 16 | if (content) process.stdout.write(content); |
| 17 | } |
Format de réponse SSE
Chaque événement SSE est un objet JSON préfixé par data: :
| 1 | data: {"choices":[{"delta":{"content":"Bonjour"},"index":0}]} |
| 2 | data: {"choices":[{"delta":{"content":" monde"},"index":0}]} |
| 3 | data: [DONE] |
Le flux se termine par data: [DONE], éventuellement suivi d'un commentaire de coût :
| 1 | : {"cost":"0.0012","input_price":"0.0003","output_price":"0.0009","prompt_tokens":15,"completion_tokens":42} |
Mode de réflexion (raisonnement étendu)
Certains modèles prennent en charge le raisonnement étendu. Lorsqu'il est activé, le modèle produit son processus de raisonnement interne avant la réponse finale :
| 1 | const stream = await client.chat.completions.create({ |
| 2 | model: 'deepseek-reasoner', |
| 3 | messages: [{ role: 'user', content: 'Prouvez que la racine carrée de 2 est irrationnelle' }], |
| 4 | stream: true, |
| 5 | }); |
| 6 | |
| 7 | for await (const chunk of stream) { |
| 8 | // Processus de raisonnement (chaîne de pensée) |
| 9 | const thinking = chunk.choices[0]?.delta?.reasoning_content; |
| 10 | if (thinking) process.stderr.write(thinking); |
| 11 | |
| 12 | // Réponse finale |
| 13 | const content = chunk.choices[0]?.delta?.content; |
| 14 | if (content) process.stdout.write(content); |
| 15 | } |
Le champ reasoning_content contient le raisonnement étape par étape du modèle, tandis que content contient la réponse finale.
Gestion des erreurs
Les erreurs survenant pendant le streaming sont transmises via le champ error des événements SSE :
| 1 | data: {"error":{"message":"Rate limit exceeded","type":"rate_limit_error","code":429}} |
Erreurs de streaming courantes :
- 401 — Clé API invalide ou expirée. AllToken tente automatiquement un rafraîchissement du token.
- 429 — Limite de débit dépassée. Implémentez un backoff avant de réessayer.
- 500 — Erreur du fournisseur en amont. La requête peut être automatiquement retentée auprès d'un autre fournisseur.
Annuler une requête
Utilisez AbortController pour annuler une requête de streaming en cours :
| 1 | const controller = new AbortController(); |
| 2 | |
| 3 | const stream = await client.chat.completions.create( |
| 4 | { |
| 5 | model: 'deepseek-chat', |
| 6 | messages: [{ role: 'user', content: 'Écris un long article' }], |
| 7 | stream: true, |
| 8 | }, |
| 9 | { signal: controller.signal } |
| 10 | ); |
| 11 | |
| 12 | // Annuler après 5 secondes |
| 13 | setTimeout(() => controller.abort(), 5000); |