> ## Documentation Index
> Fetch the complete documentation index at: https://docs.apimart.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Guide de mise en cache du contexte Gemini

> Créez et réutilisez des caches de contexte Gemini (Context Cache) avec l'API Chat Completions compatible OpenAI ou l'API Gemini native. Utilisez cache_control pour mettre en cache les préfixes stables et réduire le coût en tokens des longs contenus répétés.

Ce guide explique comment créer et réutiliser des caches de contexte Gemini (Context Cache) avec l'API Chat Completions compatible OpenAI ou l'API Gemini native.

Avant de commencer :

```bash theme={null}
export API_KEY="VOTRE_CLE_API"
```

<Note>Les exemples de ce guide utilisent `gemini-3.6-flash`. Consultez la documentation des modèles et la page des tarifs de la plateforme pour savoir si d'autres modèles prennent en charge Context Cache.</Note>

## Cas d'utilisation

Lorsque plusieurs requêtes contiennent de façon répétée le même contenu volumineux, vous pouvez mettre en cache le préfixe stable. Par exemple :

* Un prompt système très long
* Une base de connaissances ou une documentation produit fixe
* Un historique de messages stable dans une conversation à plusieurs tours
* Des définitions et instructions de tools réutilisées

Context Cache convient aux requêtes dont le contenu initial reste inchangé tandis que la question finale varie.

## Utilisation principale

Ajoutez `cache_control` au bloc de contenu du dernier message du préfixe stable :

```json theme={null}
{
  "type": "text",
  "text": "Voici la dernière partie du préfixe stable",
  "cache_control": {
    "type": "ephemeral",
    "ttl": "5m"
  }
}
```

Valeurs TTL prises en charge :

| TTL  | Signification                   |
| ---- | ------------------------------- |
| `5m` | Mise en cache pendant 5 minutes |
| `1h` | Mise en cache pendant 1 heure   |

<Note>Si `ttl` est omis, la valeur par défaut est `5m`.</Note>

## Structure des messages

Nous recommandons la structure suivante :

```text theme={null}
system
→ Texte long ou historique de messages stable
→ Limite du préfixe stable avec cache_control
→ Question actuelle de l’utilisateur (non mise en cache)
```

Le message contenant `cache_control` et tous les messages qui le précèdent constituent le préfixe mis en cache. Ils doivent être suivis d'au moins un message en temps réel.

## Exemple de requête compatible OpenAI

```bash theme={null}
curl "https://api.apimart.ai/v1/chat/completions" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gemini-3.6-flash",
    "stream": false,
    "messages": [
      {
        "role": "system",
        "content": "Répondez aux questions uniquement à partir des documents de référence fournis."
      },
      {
        "role": "user",
        "content": "Insérez ici les longs documents de référence à réutiliser..."
      },
      {
        "role": "assistant",
        "content": [
          {
            "type": "text",
            "text": "J’ai lu et compris les documents de référence ci-dessus.",
            "cache_control": {
              "type": "ephemeral",
              "ttl": "5m"
            }
          }
        ]
      },
      {
        "role": "user",
        "content": "Résumez les trois idées principales des documents de référence."
      }
    ]
  }'
```

Lors de la première requête, le système tente de créer un cache et utilise ce nouveau cache pour traiter la requête en cours.

<Note>Il n'est pas nécessaire d'appeler un endpoint distinct pour créer le cache. `cache_control` définit à la fois la limite du cache et sa durée de validité.</Note>

## Exemple de requête Gemini native

L'endpoint Gemini natif `generateContent` permet également d'ajouter `cache_control` dans `contents[].parts[]` :

```bash theme={null}
curl "https://api.apimart.ai/v1beta/models/gemini-3.6-flash:generateContent" \
  -H "x-goog-api-key: $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "systemInstruction": {
      "parts": [
        {
          "text": "Répondez aux questions uniquement à partir des documents de référence fournis."
        }
      ]
    },
    "contents": [
      {
        "role": "user",
        "parts": [
          {
            "text": "Insérez ici les longs documents de référence à réutiliser..."
          }
        ]
      },
      {
        "role": "model",
        "parts": [
          {
            "text": "J’ai lu et compris les documents de référence ci-dessus.",
            "cache_control": {
              "type": "ephemeral",
              "ttl": "5m"
            }
          }
        ]
      },
      {
        "role": "user",
        "parts": [
          {
            "text": "Résumez les trois idées principales des documents de référence."
          }
        ]
      }
    ]
  }'
```

`cache_control` est une extension de la plateforme appliquée au format de requête Gemini. Une fois la limite détectée, la plateforme supprime ce champ avant de transmettre la requête, puis crée ou réutilise automatiquement le contenu mis en cache (`cachedContent`).

L'endpoint de streaming utilise le même corps de requête. Il suffit de remplacer l'URL par :

```bash theme={null}
curl -N "https://api.apimart.ai/v1beta/models/gemini-3.6-flash:streamGenerateContent?alt=sse" \
  -H "x-goog-api-key: $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "contents": [
      {
        "role": "user",
        "parts": [
          {
            "text": "Insérez ici les longs documents de référence à réutiliser...",
            "cache_control": {
              "type": "ephemeral",
              "ttl": "5m"
            }
          }
        ]
      },
      {
        "role": "user",
        "parts": [
          {
            "text": "Résumez les trois idées principales des documents de référence."
          }
        ]
      }
    ]
  }'
```

Lors de la réutilisation, conservez `systemInstruction`, les `contents` situés avant la limite, le TTL et les tools sans modification. Modifiez uniquement le contenu en temps réel situé après la limite.

## Processus de création et de réutilisation

Lorsque vous envoyez pour la première fois une requête contenant `cache_control` :

```text theme={null}
Identifier le préfixe stable
→ Créer Context Cache
→ Référencer le nouveau cache dans la requête en cours
→ Renvoyer le résultat du modèle
```

Lorsque vous renvoyez le même préfixe stable :

```text theme={null}
Identifier le même préfixe stable
→ Réutiliser le Context Cache non expiré
→ Envoyer uniquement le contenu actuel en temps réel
→ Renvoyer le résultat du modèle
```

La première requête peut donc déjà renvoyer un nombre élevé de tokens provenant du cache. Ce comportement est normal et ne nécessite pas de requête de préchauffage distincte.

## Réutiliser un cache

Pour les requêtes suivantes, conservez les éléments ci-dessous sans modification :

* Le modèle
* Tous les messages précédant `cache_control`
* `cache_control.ttl`
* Les définitions de tools (si vous utilisez des tools)
* `systemInstruction` dans les requêtes Gemini natives

Modifiez uniquement la question en temps réel située après la limite :

```json theme={null}
{
  "role": "user",
  "content": "Quels risques sont mentionnés dans les documents de référence ?"
}
```

Le système réutilise le cache existant tant que le préfixe stable est identique et que le cache n'a pas expiré.

Les modifications suivantes créent un cache différent :

* Modifier le texte ou l'ordre des messages dans le préfixe stable
* Changer de modèle
* Remplacer `5m` par `1h`
* Modifier les tools ou les définitions de leurs paramètres
* Utiliser un autre utilisateur ou canal API

## Exemple Python

```python theme={null}
from openai import OpenAI

client = OpenAI(
    api_key="YOUR_API_KEY",
    base_url="https://api.apimart.ai/v1",
)

stable_messages = [
    {
        "role": "system",
        "content": "Répondez aux questions uniquement à partir des documents de référence fournis.",
    },
    {
        "role": "user",
        "content": "Insérez ici les longs documents de référence à réutiliser...",
    },
    {
        "role": "assistant",
        "content": [
            {
                "type": "text",
                "text": "J’ai lu et compris les documents de référence ci-dessus.",
                "cache_control": {
                    "type": "ephemeral",
                    "ttl": "5m",
                },
            }
        ],
    },
]

response = client.chat.completions.create(
    model="gemini-3.6-flash",
    messages=[
        *stable_messages,
        {
            "role": "user",
            "content": "Résumez les trois idées principales des documents de référence.",
        },
    ],
)

print(response.choices[0].message.content)
print(response.usage)
```

Pour les requêtes suivantes, réutilisez les mêmes `stable_messages` et remplacez uniquement le dernier message utilisateur.

## Vérifier si le cache a été utilisé

### Réponse compatible OpenAI

Consultez les champs suivants dans la réponse :

```json theme={null}
{
  "usage": {
    "prompt_tokens": 14430,
    "prompt_tokens_details": {
      "cached_tokens": 14420,
      "cache_write_tokens": 0
    }
  }
}
```

Description des champs :

| Champ                | Signification                                           |
| -------------------- | ------------------------------------------------------- |
| `prompt_tokens`      | Tous les tokens d'entrée de cette requête               |
| `cached_tokens`      | Tokens d'entrée lus depuis le cache pour cette requête  |
| `cache_write_tokens` | Tokens écrits dans le cache ; la valeur `0` est normale |

La première requête peut également présenter une valeur `cached_tokens` élevée, car le système peut créer un cache et le référencer lors du même appel au modèle.

### Réponse Gemini native

Consultez `usageMetadata.cachedContentTokenCount` dans la réponse :

```json theme={null}
{
  "usageMetadata": {
    "promptTokenCount": 13926,
    "cachedContentTokenCount": 13916,
    "totalTokenCount": 13954
  }
}
```

Description des champs :

| Champ                     | Signification                                                 |
| ------------------------- | ------------------------------------------------------------- |
| `promptTokenCount`        | Tous les tokens d'entrée de cette requête                     |
| `cachedContentTokenCount` | Tokens d'entrée lus depuis le cache pour cette requête        |
| `totalTokenCount`         | Nombre total de tokens d'entrée et de sortie de cette requête |

`streamGenerateContent` renvoie les mêmes `usageMetadata` dans une trame de réponse SSE. Le client doit lire la trame contenant ce champ au lieu de consulter uniquement la première trame de texte.

## Recommandations

<Tip>
  1. Mettez en cache uniquement les contenus longs qui sont réellement stables et seront réutilisés plusieurs fois.
  2. Placez la question qui varie à chaque requête après la limite `cache_control`.
  3. N'incluez pas d'horodatage, d'ID aléatoire ni d'informations utilisateur dynamiques dans le préfixe stable.
  4. Utilisez `5m` si vous prévoyez des appels répétés sur une courte période.
  5. Utilisez `1h` si vous avez besoin d'une fenêtre de réutilisation plus longue.
  6. Si le préfixe est trop court, si le modèle ne prend pas en charge la mise en cache ou si le cache est temporairement indisponible, la requête peut être exécutée automatiquement en mode standard.
  7. Pour les requêtes Gemini natives, la limite du cache doit être placée dans `contents[].parts[]` et non dans `systemInstruction`.
</Tip>

## Questions fréquentes

<AccordionGroup>
  <Accordion title="Le format de requête Gemini natif peut-il créer automatiquement un cache ?">
    Oui. `generateContent` et `streamGenerateContent` utilisent la même structure `cache_control`. La limite doit être placée dans `contents[].parts[]`, et au moins un élément de contenu en temps réel doit rester après celui qui porte cette limite.

    Si la requête fournit explicitement le nom d'une ressource `cachedContent` native, la plateforme utilise en priorité la ressource fournie par l'utilisateur et ne crée pas automatiquement de cache.
  </Accordion>

  <Accordion title="Pourquoi le cache n'a-t-il pas été utilisé ?">
    Les causes courantes sont les suivantes :

    * Le préfixe stable ne correspond pas exactement à celui de la requête précédente
    * Le TTL a expiré
    * Le modèle ou les tools ont été modifiés
    * Le contenu mis en cache n'atteint pas le nombre minimal de tokens requis par le modèle
    * `cache_control` a été placé sur le dernier message, sans laisser de question en temps réel après celui-ci
  </Accordion>

  <Accordion title="cache_control peut-il être placé sur le dernier message ?">
    Ce n'est pas recommandé. Le dernier message correspond généralement à la question actuelle en temps réel et ne doit pas être mis en cache. Si aucun message en temps réel ne suit la limite, la requête est exécutée en mode standard.
  </Accordion>

  <Accordion title="Puis-je définir un autre TTL ?">
    Non. Seules les valeurs `5m` et `1h` sont actuellement prises en charge. Toute autre valeur renvoie une erreur HTTP 400.
  </Accordion>

  <Accordion title="Puis-je définir plusieurs limites de cache ?">
    Oui, mais toutes les limites doivent utiliser le même TTL, et le système retient la dernière. En général, il est recommandé de ne définir qu'une seule limite par requête afin de préserver une structure claire.
  </Accordion>

  <Accordion title="La requête échoue-t-elle si le cache est indisponible ?">
    Généralement non. Si les conditions de création ou de réutilisation d'un cache ne sont pas remplies, le système envoie automatiquement une requête standard. Les erreurs de paramètres, telles qu'un TTL non valide ou l'utilisation de plusieurs valeurs de TTL différentes, font exception.
  </Accordion>

  <Accordion title="Que se passe-t-il si Context Cache n'est pas activé pour le modèle ?">
    La requête est automatiquement exécutée en mode standard, sans créer de cache explicite ni générer de frais de stockage du cache. Les entrées et sorties standard, ainsi que toute mise en cache implicite disponible, restent facturées selon les règles habituelles du modèle.
  </Accordion>

  <Accordion title="Pourquoi cache_write_tokens vaut-il 0 ?">
    Il s'agit du comportement attendu pour la mise en cache du contexte Gemini. Le coût de création du cache est comptabilisé sous forme de frais de stockage distincts ; contrairement aux formats OpenAI ou Claude, `cache_write_tokens` n'est pas utilisé pour indiquer le volume écrit dans le cache.
  </Accordion>

  <Accordion title="Une valeur cached_tokens supérieure à 0 signifie-t-elle toujours qu'un cache explicite a été créé ?">
    Pas nécessairement. Le système peut également enregistrer des accès à un cache implicite. Pour les utilisateurs ordinaires, les tokens lus depuis le cache indiquent si la requête a bénéficié de cette lecture. Pour vérifier les frais de création d'un cache explicite, consultez les entrées Context Cache storage dans les journaux d'utilisation de la plateforme.
  </Accordion>

  <Accordion title="Comment la mise en cache est-elle facturée ?">
    La création d'un cache peut entraîner des frais de stockage ponctuels. Lorsque le cache est utilisé, les tokens correspondants sont facturés au tarif de lecture du cache. Consultez les tarifs des modèles affichés sur la plateforme pour connaître les prix exacts.
  </Accordion>
</AccordionGroup>
