Cache du contexte
Quand deux requêtes partagent le même début (un prompt système, un document de référence, l'historique d'une conversation), la partie commune n'est pas recalculée. Elle vous est facturée à tarif réduit, automatiquement, sans changer une ligne de code.
Rien à activer#
Le cache fonctionne par défaut. Envoyez vos requêtes normalement : si un préfixe identique a déjà été traité récemment, il est réutilisé.
Lire ce qui a été mis en cache#
Chaque réponse le dit dans usage :
"usage": {
"prompt_tokens": 2014,
"completion_tokens": 12,
"total_tokens": 2026,
"prompt_cache_hit_tokens": 1920, // servis depuis le cache → tarif réduit
"prompt_cache_miss_tokens": 94, // recalculés → tarif normal
"prompt_tokens_details": { "cached_tokens": 1920 }
}
Les deux conventions du marché sont renseignées (prompt_cache_hit_tokens et
prompt_tokens_details.cached_tokens) : vos outils existants lisent l'une ou
l'autre sans adaptation.
Ce que ça change sur la facture#
Les jetons servis depuis le cache sont facturés au tarif cache du modèle, très inférieur au tarif d'entrée :
| Modèle | Entrée / 1M | Entrée depuis le cache / 1M |
|---|---|---|
mina-flash | 250 DA | 8 DA |
mina-low | 350 DA | 10 DA |
mina-full | 1300 DA | 45 DA |
Exemple de calcul#
Une requête mina-low de 2 014 jetons d'entrée et 1 de sortie :
sans cache : 2 014 × 350 = 704 900 µDA
avec cache : 94 × 350 + 1 920 × 10 = 52 100 µDA
─────────────
−92,6 % sur l'entrée
Les tarifs en vigueur sont toujours ceux de plateforme.cloudzir.com/pricing.
En tirer le maximum#
Le cache porte sur le préfixe, c'est-à-dire le début de la requête. Il faut donc mettre ce qui ne bouge pas au début, et ce qui change à la fin.
messages = [
# 1. stable : identique d'une requête à l'autre → mis en cache
{"role": "system", "content": INSTRUCTIONS + CATALOGUE_PRODUITS},
# 2. variable : à la fin
{"role": "user", "content": question_du_client},
]messages = [
# l'horodatage change à CHAQUE requête : il invalide tout ce qui suit,
# le cache ne sert jamais
{"role": "system", "content": f"Nous sommes le {datetime.now()}. " + INSTRUCTIONS},
{"role": "user", "content": question_du_client},
]- Aucune valeur volatile en tête : date, heure, identifiant de session, compteur. Placez-les dans le message utilisateur, à la fin.
- Ordre stable : si vous construisez le prompt à partir d'un dictionnaire, triez les clés : un ordre qui change casse le préfixe commun.
- Conversations : en ajoutant les tours à la fin, tout l'historique précédent reste un préfixe commun. C'est là que le gain est le plus fort.
Durée de vie#
Un préfixe inutilisé finit par être évincé (de quelques minutes à quelques heures selon la charge). Aucune garantie n'est donnée : le cache est une optimisation de prix, pas un stockage. Une absence de cache n'est jamais une erreur, seulement un coût normal.
Le cache ne stocke que des calculs intermédiaires du moteur, jamais vos réponses : il ne modifie ni le contenu ni la qualité de ce qui vous est renvoyé, uniquement le prix. Il est géré par le moteur d'inférence, pas par CloudZIR : nous ne pouvons donc pas garantir qu'un préfixe identique envoyé par deux clients différents soit compté séparément. Si un contenu ne doit jamais côtoyer celui d'un tiers, ne comptez pas sur le cache pour l'isoler.
Compléter par un cache applicatif#
Pour des questions strictement répétitives (FAQ, classification d'un même libellé), le moins cher reste de cacher la réponse chez vous : coût zéro, latence zéro.
import hashlib, json
cache: dict[str, str] = {}
def repondre(client, messages, model="mina-flash"):
cle = hashlib.sha256(
json.dumps([model, messages], ensure_ascii=False, sort_keys=True).encode()
).hexdigest()
if cle in cache:
return cache[cle] # aucun appel, aucun jeton facturé
r = client.chat.completions.create(model=model, messages=messages)
cache[cle] = r.choices[0].message.content
return cache[cle]
Suivi#
La page Usage affiche, pour chaque requête, la part servie depuis le cache, de quoi vérifier que votre prompt est bien construit.
cache_control (format Anthropic) est accepté et sans effet : la mise en
cache est automatique, il n'y a rien à marquer manuellement.