Aller au contenu

Mise en cache des invites

La mise en cache des invitations signifie que le fournisseur de modèles peut réutiliser les préfixes d’invitation inchangés (généralement les instructions système/développeur et d’autres contextes stables) sur plusieurs tours au lieu de les retraiter à chaque fois. OpenClaw normalise l’utilisation du fournisseur en cacheRead et cacheWrite lorsque l’API amont expose ces compteurs directement.

Les surfaces d’état peuvent également récupérer les compteurs de cache à partir du journal d’utilisation de la transcription la plus récente lorsque l’instantané de la session en direct ne les contient pas, de sorte que /status peut continuer à afficher une ligne de cache après une perte partielle des métadonnées de session. Les valeurs de cache en direct non nulles existantes prennent toujours le pas sur les valeurs de secours de la transcription.

Pourquoi c’est important : coût de jetons réduit, réponses plus rapides et performances plus prévisibles pour les sessions de longue durée. Sans mise en cache, les invitations répétées paient le coût complet de l’invitation à chaque tour, même si la plupart des entrées n’ont pas changé.

Les sections ci-dessous couvrent chaque contrôle lié au cache qui affecte la réutilisation des invitations et le coût des jetons.

Références des fournisseurs :

cacheRetention (par défaut global, modèle et par agent)

Section intitulée « cacheRetention (par défaut global, modèle et par agent) »

Définir la rétention du cache comme valeur par défaut globale pour tous les modèles :

agents:
defaults:
params:
cacheRetention: "long" # none | short | long

Remplacer par modèle :

agents:
defaults:
models:
"anthropic/claude-opus-4-6":
params:
cacheRetention: "short" # none | short | long

Remplacement par agent :

agents:
list:
- id: "alerts"
params:
cacheRetention: "none"

Ordre de fusion de la configuration :

  1. agents.defaults.params (par défaut global — s’applique à tous les modèles)
  2. agents.defaults.models["provider/model"].params (remplacement par modèle)
  3. agents.list[].params (id d’agent correspondant ; remplace par clé)

Supprime l’ancien contexte de résultat d’outil après les fenêtres TTL du cache afin que les requêtes post-inactivité ne remettent pas en cache un historique trop volumineux.

agents:
defaults:
contextPruning:
mode: "cache-ttl"
ttl: "1h"

Consultez Session Pruning pour le comportement complet.

La pulsation peut maintenir les fenêtres de cache au chaud et réduire les écritures de cache répétées après les périodes d’inactivité.

agents:
defaults:
heartbeat:
every: "55m"

Le heartbeat par agent est pris en charge à agents.list[].heartbeat.

  • cacheRetention est pris en charge.
  • Avec les profils d’authentification par clé Anthropic de API, OpenClaw amorce cacheRetention: "short" pour les références de modèle Anthropic lorsqu’il n’est pas défini.
  • Les réponses Messages natives de Anthropic exposent à la fois cache_read_input_tokens et cache_creation_input_tokens, donc OpenClaw peut afficher à la fois cacheRead et cacheWrite.
  • Pour les requêtes natives Anthropic, cacheRetention: "short" correspond au cache éphémère par défaut de 5 minutes, et cacheRetention: "long" passe à la TTL de 1 heure uniquement sur les hôtes api.anthropic.com directs.
  • La mise en cache des prompts est automatique sur les modèles récents pris en charge. OpenClaw n’a pas besoin d’injecter des marqueurs de cache au niveau du bloc.
  • OpenClaw utilise prompt_cache_key pour maintenir le routage du cache stable entre les tours et utilise prompt_cache_retention: "24h" uniquement lorsque cacheRetention: "long" est sélectionné sur les hôtes OpenAI directs.
  • Les fournisseurs de complétions compatibles avec OpenAI ne reçoivent prompt_cache_key que lorsque leur configuration de modèle définit explicitement compat.supportsPromptCacheKey: true ; cacheRetention: "none" le supprime toujours.
  • Les réponses OpenAI exposent les jetons de prompts mis en cache via usage.prompt_tokens_details.cached_tokens (ou input_tokens_details.cached_tokens sur les événements de l’API Responses). OpenClaw mappe cela vers cacheRead.
  • OpenAI n’expose pas de compteur de jetons d’écriture de cache distinct, donc cacheWrite reste 0 sur les chemins OpenAI même lorsque le fournisseur réchauffe un cache.
  • OpenAI renvoie des en-têtes de traçage et de limite de taux utiles tels que x-request-id, openai-processing-ms et x-ratelimit-*, mais la comptabilité des succès de cache doit provenir de la charge utile d’utilisation, et non des en-têtes.
  • En pratique, OpenAI se comporte souvent comme un cache de préfixe initial plutôt qu’une réutilisation de l’historique complet mobile à la manière de Anthropic. Les tours de texte longs avec un préfixe stable peuvent atteindre un plateau de 4864 jetons mis en cache lors des sondages en direct actuels, tandis que les transcriptions lourdes en outils ou de style MCP atteignent souvent un plateau près de 4608 jetons mis en cache, même lors de répétitions exactes.
  • Les modèles Anthropic sur Vertex AI (anthropic-vertex/*) prennent en charge cacheRetention de la même manière que Anthropic direct.
  • cacheRetention: "long" correspond au temps de vie réel (TTL) de 1 heure du cache de prompt sur les points de terminaison Vertex AI.
  • La rétention du cache par défaut pour anthropic-vertex correspond aux valeurs par défaut de Anthropic direct.
  • Les requêtes Vertex sont acheminées via une mise en forme de cache tenant compte des limites, afin que la réutilisation du cache reste alignée sur ce que les fournisseurs reçoivent réellement.
  • Les références de modèles Claude de Anthropic (amazon-bedrock/*anthropic.claude*) prennent en charge le passage explicite de cacheRetention.
  • Les modèles Bedrock non Anthropic sont forcés à cacheRetention: "none" lors de l’exécution.

Pour les références de modèle openrouter/anthropic/*, OpenClaw injecte les cache_control de Anthropic sur les blocs de prompt système/développeur pour améliorer la réutilisation du cache de prompt uniquement lorsque la demande cible toujours une route OpenRouter vérifiée (openrouter sur son point de terminaison par défaut, ou toute URL de base/provider qui résout à openrouter.ai).

Pour les références de modèle openrouter/deepseek/*, openrouter/moonshot*/* et openrouter/zai/*, contextPruning.mode: "cache-ttl" est autorisé car OpenRouter gère automatiquement la mise en cache du prompt côté provider. OpenClaw n’injecte pas les marqueurs cache_control de Anthropic dans ces demandes.

La construction du cache DeepSeek est effectuée au mieux et peut prendre quelques secondes. Une suite immédiate peut toujours afficher cached_tokens: 0 ; vérifiez avec une demande répétée de même préfixe après un court délai et utilisez usage.prompt_tokens_details.cached_tokens comme signal de succès du cache.

Si vous redirigez le modèle vers une URL de proxy arbitraire compatible OpenAI, OpenClaw arrête d’injecter ces marqueurs de cache OpenRouter spécifiques à Anthropic.

Si le provider ne prend pas en charge ce mode de cache, cacheRetention n’a aucun effet.

  • Le transport direct Gemini (api: "google-generative-ai") signale les succès de cache via le cachedContentTokenCount en amont ; OpenClaw mappe cela vers cacheRead.
  • Lorsque cacheRetention est défini sur un modèle Gemini direct, OpenClaw crée, réutilise et actualise automatiquement les ressources cachedContents pour les invites système lors des exécutions sur Google AI Studio. Cela signifie que vous n’avez plus besoin de pré-créer manuellement un identifiant de contenu mis en cache.
  • Vous pouvez toujours transmettre un identifiant de contenu mis en cache Gemini existant en tant que params.cachedContent (ou l’ancien params.cached_content) sur le modèle configuré.
  • Ceci est distinct de la mise en cache des préfixes d’invite Anthropic/OpenAI. Pour Gemini, OpenClaw gère une ressource cachedContents native du fournisseur plutôt que d’injecter des marqueurs de cache dans la requête.
  • La sortie JSON CLI Gemini peut également afficher les succès de cache via stats.cached ; OpenClaw mappe cela vers cacheRead.
  • Si la CLI omet une valeur directe stats.input, OpenClaw déduit les jetons d’entrée à partir de stats.input_tokens - stats.cached.
  • Il ne s’agit que d’une normalisation de l’utilisation. Cela ne signifie pas que OpenClaw crée des marqueurs de cache d’invite de type Anthropic/OpenAI pour la CLI Gemini.

OpenClaw divise l’invite système en un préfixe stable et un suffixe volatile séparés par une limite interne de préfixe de cache. Le contenu au-dessus de la limite (définitions d’outils, métadonnées de compétences, fichiers de l’espace de travail et autre contexte relativement statique) est ordonné de manière à rester identique octet pour octet d’un tour à l’autre. Le contenu sous la limite (par exemple HEARTBEAT.md, horodatages d’exécution et autres métadonnées par tour) est autorisé à changer sans invalider le préfixe mis en cache.

Choix de conception clés :

  • Les fichiers de contexte de projet d’espace de travail stables sont ordonnés avant HEARTBEAT.md afin que l’activité du heartbeat ne brise pas le préfixe stable.
  • La limite est appliquée à travers le façonnement du transport de la famille Anthropic, de la famille OpenAI, de Google et de la CLI afin que tous les fournisseurs pris en charge bénéficient de la même stabilité de préfixe.
  • Les réponses Codex et les requêtes Anthropic Vertex sont acheminées via une mise en forme de cache sensible aux limites, afin que la réutilisation du cache reste alignée avec ce que les providers reçoivent réellement.
  • Les empreintes de système-prompt sont normalisées (espaces, fins de ligne, contexte ajouté par les hooks, ordre des capacités d’exécution) afin que les invites sémantiquement inchangées partagent le KV/cache entre les tours.

Si vous constatez des pics inattendus de cacheWrite après un changement de configuration ou d’espace de travail, vérifiez si le changement se situe au-dessus ou en dessous de la limite du cache. Le déplacement de contenu volatil en dessous de la limite (ou sa stabilisation) résout souvent le problème.

OpenClaw maintient également plusieurs formes de payloads sensibles au cache de manière déterministe avant que la demande n’atteigne le provider :

  • Les catalogues d’outils MCP de bundle sont triés de manière déterministe avant l’enregistrement de l’outil, afin que les changements d’ordre listTools() ne fassent pas tourner le bloc d’outils et ne brisent pas les préfixes de cache d’invite.
  • Les sessions héritées avec des blocs d’images persistants conservent les 3 tours terminés les plus récents intacts ; les blocs d’images plus anciens déjà traités peuvent être remplacés par un marqueur afin que les suites riches en images ne continuent pas à renvoyer de gros payloads obsolètes.

Conservez une ligne de base de longue durée sur votre agent principal, désactivez la mise en cache sur les agents de notification par rafales :

agents:
defaults:
model:
primary: "anthropic/claude-opus-4-6"
models:
"anthropic/claude-opus-4-6":
params:
cacheRetention: "long"
list:
- id: "research"
default: true
heartbeat:
every: "55m"
- id: "alerts"
params:
cacheRetention: "none"
  • Définissez la ligne de base cacheRetention: "short".
  • Activez contextPruning.mode: "cache-ttl".
  • Maintenez le heartbeat en dessous de votre TTL uniquement pour les agents qui bénéficient de caches chauds.

OpenClaw expose des diagnostics de trace de cache dédiés pour les exécutions d’agents intégrés.

Pour les diagnostics normaux orientés utilisateur, /status et autres résumés d’utilisation peuvent utiliser la dernière entrée d’utilisation de transcription comme source de secours pour cacheRead / cacheWrite lorsque l’entrée de session en direct ne possède pas ces compteurs.

OpenClaw maintient une seule porte de régression de cache en direct combinée pour les préfixes répétés, les tours d’outils, les tours d’images, les transcriptions d’outils de style MCP et un contrôle de non-cache Anthropic.

  • src/agents/live-cache-regression.live.test.ts
  • src/agents/live-cache-regression-baseline.ts

Exécutez la porte en direct étroite avec :

Fenêtre de terminal
OPENCLAW_LIVE_TEST=1 OPENCLAW_LIVE_CACHE_TEST=1 pnpm test:live:cache

Le fichier de référence stocke les derniers nombres observés en direct ainsi que les planchers de régression spécifiques au fournisseur utilisés par le test. Le lanceur utilise également des identifiants de session frais par exécution et des espaces de noms de prompt afin que l’état du cache précédent ne pollue pas l’échantillon de régression actuel.

Ces tests n’utilisent volontairement pas des critères de succès identiques pour tous les providers.

  • Attendre des écritures de préchauffage explicites via cacheWrite.
  • Attendre une réutilisation presque complète de l’historique lors des tours répétés car le contrôle de cache Anthropic fait avancer le point de rupture du cache tout au long de la conversation.
  • Les assertions en direct actuelles utilisent toujours des seuils de taux de réussite élevés pour les chemins stables, tool et image.
  • Attendre uniquement cacheRead. cacheWrite reste 0.
  • Considérer la réutilisation du cache sur les tours répétés comme un plateau spécifique au provider, et non comme une réutilisation mobile de l’historique complet à la manière Anthropic.
  • Les assertions en direct actuelles utilisent des vérifications de planchers conservatrices dérivées du comportement en direct observé sur gpt-5.4-mini :
    • préfixe stable : cacheRead >= 4608, taux de réussite >= 0.90
    • transcript tool : cacheRead >= 4096, taux de réussite >= 0.85
    • transcript image : cacheRead >= 3840, taux de réussite >= 0.82
    • transcript style MCP : cacheRead >= 4096, taux de réussite >= 0.85

Une vérification combinée en direct fraîche le 2026-04-04 a donné :

  • préfixe stable : cacheRead=4864, taux de réussite 0.966
  • transcript tool : cacheRead=4608, taux de réussite 0.896
  • transcript image : cacheRead=4864, taux de réussite 0.954
  • transcript style MCP : cacheRead=4608, taux de réussite 0.891

Le temps de mur horloge local récent pour la porte combinée était d’environ 88s.

Pourquoi les assertions diffèrent :

  • Anthropic expose des points de rupture de cache explicites et une réutilisation mobile de l’historique de conversation.
  • Le mise en cache de prompt de OpenAI reste sensible au préfixe exact, mais le préfixe réellement réutilisable dans le trafic des réponses en direct peut atteindre un plateau plus tôt que le prompt complet.
  • En raison de cela, comparer Anthropic et OpenAI à l’aide d’un seul seuil de pourcentage inter-fournisseurs crée de fausses régressions.
diagnostics:
cacheTrace:
enabled: true
filePath: "~/.openclaw/logs/cache-trace.jsonl" # optional
includeMessages: false # default true
includePrompt: false # default true
includeSystem: false # default true

Valeurs par défaut :

  • filePath : $OPENCLAW_STATE_DIR/logs/cache-trace.jsonl
  • includeMessages : true
  • includePrompt : true
  • includeSystem : true
  • OPENCLAW_CACHE_TRACE=1 active le traçage du cache.
  • OPENCLAW_CACHE_TRACE_FILE=/path/to/cache-trace.jsonl remplace le chemin de sortie.
  • OPENCLAW_CACHE_TRACE_MESSAGES=0|1 bascule la capture de la charge utile complète des messages.
  • OPENCLAW_CACHE_TRACE_PROMPT=0|1 bascule la capture du texte du prompt.
  • OPENCLAW_CACHE_TRACE_SYSTEM=0|1 bascule la capture du prompt système.
  • Les événements de trace du cache sont au format JSONL et incluent des instantanés intermédiaires tels que session:loaded, prompt:before, stream:context et session:after.
  • L’impact des jetons de cache par tour est visible dans les surfaces d’utilisation normales via cacheRead et cacheWrite (par exemple /usage full et les résumés d’utilisation de session).
  • Pour Anthropic, attendez-vous à la fois à cacheRead et cacheWrite lorsque le cache est actif.
  • Pour OpenAI, attendez-vous à cacheRead lors des succès de cache et à ce que cacheWrite reste 0 ; OpenAI ne publie pas de champ distinct pour les jetons d’écriture de cache.
  • Si vous avez besoin du traçage des requêtes, consignez les ID de requête et les en-têtes de limite de taux séparément des métriques de cache. La sortie actuelle du traçage de cache de OpenClaw est axée sur la forme du prompt/de la session et l’utilisation normalisée des jetons plutôt que sur les en-têtes de réponse bruts du fournisseur.
  • cacheWrite élevé sur la plupart des tours : vérifiez la présence d’entrées de prompt système volatiles et assurez-vous que le modèle/le fournisseur prend en charge vos paramètres de cache.
  • Élevé cacheWrite sur Anthropic : signifie souvent que le point d’arrêt du cache tombe sur un contenu qui change à chaque requête.
  • Faible OpenAI cacheRead : vérifiez que le préfixe stable est au début, que le préfixe répété fait au moins 1024 jetons et que le même prompt_cache_key est réutilisé pour les tours qui devraient partager un cache.
  • Aucun effet de cacheRetention : confirmez que la clé du modèle correspond à agents.defaults.models["provider/model"].
  • Requêtes Bedrock Nova/Mistral avec paramètres de cache : forçage attendu de l’exécution vers none.

Documentation connexe :