Aller au contenu principal

Performance en production

Mis à jour le 29 juillet 2026

Au-delà du cache : la performance globale

Le cache réduit la facture, mais une intégration en production se juge sur davantage de critères : la latence ressentie par l’utilisateur, le débit soutenu, la fiabilité face aux erreurs transitoires et la capacité à diagnostiquer une dégradation. Une application qui coûte peu mais répond en douze secondes ou échoue une fois sur cinquante n’est pas une application performante. Cette leçon couvre les quatre dimensions qui restent une fois le coût maîtrisé.

Le streaming, ou comment gagner du temps sans en gagner

Pour toute interface où un humain attend une réponse, le streaming SSE (Server-Sent Events) change radicalement la perception. Sans lui, l’utilisateur fixe un curseur pendant que le modèle génère 500 tokens ; avec lui, les premiers mots apparaissent au bout de quelques centaines de millisecondes et la lecture commence pendant la génération. Le temps total est le même, le temps ressenti est divisé par plusieurs.

import requests
import json

def appel_streaming(messages, model="grok-4.20"):
    reponse = requests.post(
        "https://api.x.ai/v1/chat/completions",
        headers={
            "Authorization": f"Bearer {api_key}",
            "Content-Type": "application/json"
        },
        json={
            "model": model,
            "messages": messages,
            "stream": True
        },
        stream=True
    )

    for ligne in reponse.iter_lines():
        if ligne and ligne.startswith(b"data: "):
            donnees = ligne[6:]
            if donnees == b"[DONE]":
                break
            chunk = json.loads(donnees)
            token = chunk["choices"][0]["delta"].get("content", "")
            yield token

Le paramètre stream: True ne modifie ni le nombre de tokens facturés ni leur tarif. Ce que vous améliorez, c’est le TTFT — le time to first token. Notez que la fonction est un générateur : elle rend la main token par token, ce qui vous permet d’écrire directement dans la réponse HTTP de votre serveur sans garder toute la génération en mémoire.

Choisir son modèle pour la latence

Le second levier de latence est le choix du modèle, et il se joue surtout sur l’effort de raisonnement. Un modèle qui raisonne produit d’abord des tokens de réflexion invisibles avant de rédiger sa réponse : la qualité monte, le délai aussi. Aux extrêmes, grok-build-0.1 est le plus rapide du catalogue, ce qui le destine aux usages temps réel comme la classification à la volée ou l’autocomplétion ; grok-4.20-0309 en variante non-reasoning et grok-4.3 offrent un compromis raisonnable entre qualité et vitesse ; grok-4.5 avec un raisonnement poussé occupe l’autre bord, à réserver aux tâches qui l’exigent vraiment.

La conséquence pratique est qu’on ne choisit pas un modèle pour une application, mais pour une étape. Un schéma répandu consiste à faire trancher un premier appel rapide — cette demande est-elle triviale, ambiguë, ou complexe ? — puis à n’envoyer vers un modèle raisonnant que la fraction des cas qui le justifient. Vous divisez à la fois la latence moyenne et le coût moyen, sans dégrader les cas difficiles.

Gérer les erreurs sans aggraver la situation

Le code 429 traité à la leçon 3 n’est pas le seul que vous rencontrerez. La distinction structurante est celle entre les erreurs qui méritent un nouvel essai et celles où réessayer ne fera qu’ajouter du trafic inutile.

CodeNatureConduite
429 Too Many Requestsrécupérablebackoff exponentiel (leçon 3)
500 Internal Server Errorrécupérableretry avec backoff, l’erreur est côté serveur
502 / 503 Service Unavailablerécupérableretry après quelques secondes
400 Bad Requestdéfinitiverequête malformée, corrigez le payload
401 Unauthorizeddéfinitiveclé API invalide ou expirée
413 Payload Too Largedéfinitivele prompt dépasse la limite de contexte

Cette règle se code en trois lignes et vaut d’être isolée dans une fonction plutôt que dispersée en if un peu partout :

def classifier_erreur(status_code):
    recuperable = {429, 500, 502, 503}
    return status_code in recuperable

Timeouts et résilience

Un timeout mal réglé produit deux pathologies opposées : trop court, il abandonne des requêtes qui allaient aboutir ; trop long, il immobilise vos workers pendant que la file s’allonge. Réglez-en trois séparément. La connexion doit s’établir en 10 secondes ; au-delà, le problème est réseau. La lecture en mode non-streaming se cale sur le modèle : 120 secondes pour un modèle raisonnant, 60 secondes pour grok-build-0.1. En streaming, le seuil pertinent n’est pas la durée totale mais l’intervalle entre deux chunks, à fixer autour de 30 secondes.

Un point mérite une vraie prudence : lorsqu’un timeout expire sur une génération longue, ne relancez pas automatiquement. Le modèle a peut-être déjà consommé des tokens de raisonnement que vous paierez une seconde fois, et rien ne garantit que la première requête n’a pas abouti côté serveur. Un mécanisme d’idempotence — une clé de requête que vous conservez pour reconnaître un doublon — ou une reprise explicite vaut mieux qu’un retry aveugle.

Ce qu’il faut instrumenter

Quatre familles de métriques suffisent à diagnostiquer l’essentiel des incidents.

MétriqueCe qu’elle révèleCible
TTFTlatence initiale ressentieà surveiller par modèle
Taux de succèsfiabilité de l’intégrationsupérieur à 99,5 %
Taux de cachequalité de la structure des promptssupérieur à 50 %
Coût par requêtedérive budgétaire, en moyenne glissantestable dans le temps

Ajoutez-y la latence au 95e percentile. La moyenne masque toujours les cas extrêmes, et ce sont eux qui déclenchent les tickets de support : une P95 à huit secondes signifie qu’un utilisateur sur vingt attend huit secondes, ce qu’aucune moyenne à 1,2 seconde ne laissera deviner.

Points clés à retenir

  • Le streaming SSE réduit la latence perçue sans affecter le coût
  • Choisissez un modèle rapide pour le temps réel et un modèle raisonnant pour la qualité
  • Distinguez les erreurs récupérables (429, 500, 502/503) des erreurs définitives (400, 401)
  • Configurez des timeouts adaptés au modèle utilisé
  • Surveillez le TTFT, le taux de succès, le taux de cache et le coût moyen par requête