> ## 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.

# Guía de uso de la caché de contexto de Gemini

> Crea y reutiliza la caché de contexto de Gemini (Context Cache) mediante la API Chat Completions compatible con OpenAI o la API nativa de Gemini. Usa cache_control para almacenar en caché un prefijo estable y reducir el coste en tokens del contenido largo repetido.

En esta guía se explica cómo crear y reutilizar la caché de contexto de Gemini (Context Cache) mediante la API Chat Completions compatible con OpenAI o la API nativa de Gemini.

Antes de empezar:

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

<Note>Los ejemplos de esta guía usan `gemini-3.6-flash`. Para saber si otros modelos admiten Context Cache, consulta la descripción del modelo y la página de precios de la plataforma.</Note>

## Casos de uso

Cuando varias solicitudes incluyen repetidamente el mismo bloque grande de contenido, puedes almacenar en caché un prefijo estable, por ejemplo:

* Un system prompt muy largo
* Una base de conocimientos fija o documentación de producto
* Mensajes históricos estables de una conversación de varios turnos
* Definiciones e instrucciones de herramientas que se reutilizan

Context Cache es adecuado para solicitudes en las que «el contenido inicial permanece igual y solo cambia la pregunta final».

## Uso básico

Añade `cache_control` al bloque de contenido del último mensaje del prefijo estable:

```json theme={null}
{
  "type": "text",
  "text": "Este es el último fragmento de contenido del prefijo estable",
  "cache_control": {
    "type": "ephemeral",
    "ttl": "5m"
  }
}
```

TTL admitidos:

| TTL  | Significado             |
| ---- | ----------------------- |
| `5m` | Caché durante 5 minutos |
| `1h` | Caché durante 1 hora    |

<Note>Si omites `ttl`, se usa `5m` de forma predeterminada.</Note>

## Estructura de los mensajes

Se recomienda usar la siguiente estructura:

```text theme={null}
system
→ Texto largo estable o mensajes históricos
→ Límite del prefijo estable con cache_control
→ Pregunta actual del usuario (no se almacena en caché)
```

El mensaje que contiene `cache_control` y todos los mensajes anteriores forman el prefijo almacenado en caché. Después debe haber al menos un mensaje en tiempo real.

## Ejemplo de solicitud compatible con 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": "Responde estrictamente de acuerdo con el material de referencia proporcionado."
      },
      {
        "role": "user",
        "content": "Aquí se incluye el material de referencia extenso que se reutilizará…"
      },
      {
        "role": "assistant",
        "content": [
          {
            "type": "text",
            "text": "He leído y comprendido el material de referencia anterior.",
            "cache_control": {
              "type": "ephemeral",
              "ttl": "5m"
            }
          }
        ]
      },
      {
        "role": "user",
        "content": "Resume los tres puntos principales del material de referencia."
      }
    ]
  }'
```

La primera vez que envíes la solicitud, el sistema intentará crear una caché y la utilizará para completar la solicitud actual.

<Note>No es necesario llamar a un endpoint independiente para crear la caché. `cache_control` define tanto el «límite de la caché» como su «periodo de validez».</Note>

## Ejemplo de solicitud nativa de Gemini

El endpoint nativo `generateContent` de Gemini también permite añadir `cache_control` dentro de `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": "Responde estrictamente de acuerdo con el material de referencia proporcionado."
        }
      ]
    },
    "contents": [
      {
        "role": "user",
        "parts": [
          {
            "text": "Aquí se incluye el material de referencia extenso que se reutilizará…"
          }
        ]
      },
      {
        "role": "model",
        "parts": [
          {
            "text": "He leído y comprendido el material de referencia anterior.",
            "cache_control": {
              "type": "ephemeral",
              "ttl": "5m"
            }
          }
        ]
      },
      {
        "role": "user",
        "parts": [
          {
            "text": "Resume los tres puntos principales del material de referencia."
          }
        ]
      }
    ]
  }'
```

`cache_control` es un campo de extensión de la plataforma para el formato de solicitud de Gemini. Una vez identificado el límite, la plataforma elimina este campo antes de reenviar la solicitud y crea o reutiliza automáticamente el contenido almacenado en caché (`cachedContent`).

La interfaz de streaming usa el mismo cuerpo de solicitud; solo debes cambiar la dirección por:

```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": "Aquí se incluye el material de referencia extenso que se reutilizará…",
            "cache_control": {
              "type": "ephemeral",
              "ttl": "5m"
            }
          }
        ]
      },
      {
        "role": "user",
        "parts": [
          {
            "text": "Resume los tres puntos principales del material de referencia."
          }
        ]
      }
    ]
  }'
```

Al reutilizar la caché, mantén sin cambios `systemInstruction`, los `contents` anteriores al límite, el TTL y las tools; modifica únicamente el contenido en tiempo real posterior al límite.

## Flujo de creación y reutilización

La primera vez que envíes una solicitud con `cache_control`:

```text theme={null}
Identificar el prefijo estable
→ Crear Context Cache
→ Referenciar la nueva caché en la solicitud actual
→ Devolver el resultado del modelo
```

Cuando vuelvas a enviar el mismo prefijo estable:

```text theme={null}
Identificar el mismo prefijo estable
→ Reutilizar un Context Cache que no haya caducado
→ Enviar únicamente el contenido actual en tiempo real
→ Devolver el resultado del modelo
```

Por este motivo, la primera solicitud también puede devolver directamente una cantidad elevada de tokens procedentes de la caché. Es un comportamiento normal y no requiere enviar antes una «solicitud de calentamiento».

## Reutilizar la caché

En las solicitudes posteriores, mantén sin cambios lo siguiente:

* El modelo
* Todos los mensajes anteriores a `cache_control`
* `cache_control.ttl`
* Las definiciones de herramientas (si usas tools)
* `systemInstruction` en las solicitudes nativas de Gemini

Modifica únicamente la pregunta en tiempo real posterior al límite:

```json theme={null}
{
  "role": "user",
  "content": "¿Qué riesgos se mencionan en el material de referencia?"
}
```

Siempre que el prefijo estable sea idéntico y la caché no haya caducado, el sistema reutilizará la caché existente.

Los siguientes cambios generan una caché diferente:

* Modificar el texto o el orden de los mensajes del prefijo estable
* Cambiar de modelo
* Cambiar `5m` por `1h`
* Modificar las tools o la definición de sus parámetros
* Usar un usuario o canal de API diferente

## Ejemplo en 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": "Responde estrictamente de acuerdo con el material de referencia proporcionado.",
    },
    {
        "role": "user",
        "content": "Aquí se incluye el material de referencia extenso que se reutilizará…",
    },
    {
        "role": "assistant",
        "content": [
            {
                "type": "text",
                "text": "He leído y comprendido el material de referencia anterior.",
                "cache_control": {
                    "type": "ephemeral",
                    "ttl": "5m",
                },
            }
        ],
    },
]

response = client.chat.completions.create(
    model="gemini-3.6-flash",
    messages=[
        *stable_messages,
        {
            "role": "user",
            "content": "Resume los tres puntos principales del material de referencia.",
        },
    ],
)

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

En las solicitudes posteriores, reutiliza el mismo `stable_messages` y sustituye únicamente el último mensaje del usuario.

## Comprobar si se utilizó la caché

### Respuesta compatible con OpenAI

Consulta los siguientes campos de la respuesta:

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

Descripción de los campos:

| Campo                | Significado                                             |
| -------------------- | ------------------------------------------------------- |
| `prompt_tokens`      | Total de tokens de entrada de esta solicitud            |
| `cached_tokens`      | Tokens de entrada leídos de la caché en esta solicitud  |
| `cache_write_tokens` | Tokens escritos en la caché; que devuelva `0` es normal |

La primera solicitud también puede mostrar un valor elevado de `cached_tokens`, ya que el sistema puede crear la caché y referenciarla en la misma llamada al modelo.

### Respuesta nativa de Gemini

Consulta `usageMetadata.cachedContentTokenCount` en la respuesta:

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

Descripción de los campos:

| Campo                     | Significado                                            |
| ------------------------- | ------------------------------------------------------ |
| `promptTokenCount`        | Total de tokens de entrada de esta solicitud           |
| `cachedContentTokenCount` | Tokens de entrada leídos de la caché en esta solicitud |
| `totalTokenCount`         | Total de tokens de entrada y salida de esta solicitud  |

`streamGenerateContent` devuelve el mismo `usageMetadata` en un frame de la respuesta SSE. El cliente debe leer el frame que contiene este campo, no comprobar únicamente el primer fragmento de texto.

## Recomendaciones

<Tip>
  1. Almacena en caché únicamente contenido largo que sea realmente estable y vaya a reutilizarse varias veces.
  2. Coloca después del límite de `cache_control` la pregunta que cambia en cada solicitud.
  3. No incluyas marcas de tiempo, ID aleatorios ni información dinámica del usuario en el prefijo estable.
  4. Usa `5m` si prevés repetir las llamadas en un periodo breve.
  5. Usa `1h` cuando necesites una ventana de reutilización más larga.
  6. Si el prefijo es demasiado corto, el modelo no es compatible o la caché no está disponible temporalmente, la solicitud puede procesarse automáticamente de la forma habitual.
  7. En el formato nativo de Gemini, el límite de la caché debe estar dentro de `contents[].parts[]`, no en `systemInstruction`.
</Tip>

## Preguntas frecuentes

<AccordionGroup>
  <Accordion title="¿El formato de solicitud nativo de Gemini puede crear una caché automáticamente?">
    Sí. `generateContent` y `streamGenerateContent` usan la misma estructura de `cache_control`. El límite debe estar dentro de `contents[].parts[]` y debe quedar al menos un content en tiempo real después del content que contiene el límite.

    Si la solicitud ya proporciona explícitamente el nombre de un recurso `cachedContent` nativo, la plataforma da prioridad al recurso indicado por el usuario y no vuelve a crear una caché automáticamente.
  </Accordion>

  <Accordion title="¿Por qué no se utilizó la caché?">
    Estas son algunas causas habituales:

    * El prefijo estable no coincide exactamente con el de la solicitud anterior
    * El TTL ha caducado
    * Se ha modificado el modelo o las tools
    * El contenido almacenado en caché no alcanza el número mínimo de tokens exigido por el modelo
    * `cache_control` está en el último mensaje y no queda ninguna pregunta en tiempo real
  </Accordion>

  <Accordion title="¿Puedo colocar cache_control en el último mensaje?">
    No se recomienda. El último mensaje suele ser la pregunta actual en tiempo real y no debería almacenarse en caché. Si no hay ningún mensaje en tiempo real después del límite, la solicitud se procesa de la forma habitual.
  </Accordion>

  <Accordion title="¿Puedo configurar otro TTL?">
    No. Actualmente solo se admiten `5m` y `1h`. Cualquier otro valor devuelve un error HTTP 400.
  </Accordion>

  <Accordion title="¿Puedo configurar varios límites de caché?">
    Sí, pero todos los límites deben usar el mismo TTL y el sistema utilizará el último. En general, se recomienda configurar un solo límite por solicitud para que la estructura sea más clara.
  </Accordion>

  <Accordion title="¿La solicitud fallará si la caché no está disponible?">
    Normalmente, no. Si no se cumplen las condiciones para crear o reutilizar la caché, el sistema procesa automáticamente la solicitud de la forma habitual. Se exceptúan los errores de parámetros, como un TTL no válido o el uso combinado de distintos TTL.
  </Accordion>

  <Accordion title="¿Qué ocurre si el modelo no tiene habilitado Context Cache?">
    La solicitud se procesa automáticamente de la forma habitual, sin crear una caché explícita ni generar costes de almacenamiento en caché. La entrada y salida normales, así como cualquier posible coincidencia en una caché implícita, se siguen facturando según las reglas existentes del modelo.
  </Accordion>

  <Accordion title="¿Por qué cache_write_tokens es 0?">
    Es el comportamiento normal de la caché de contexto de Gemini. El coste de creación se registra como un cargo independiente por almacenamiento en caché; no se usa `cache_write_tokens`, al estilo de OpenAI o Claude, para indicar cuántos tokens se han escrito en la caché.
  </Accordion>

  <Accordion title="¿Un valor de cached_tokens superior a 0 significa que se ha creado una caché explícita?">
    No necesariamente. El propio sistema también puede producir coincidencias en una caché implícita. Para un usuario normal, los tokens leídos de la caché permiten determinar si la solicitud se benefició de una lectura en caché. Si necesitas comprobar el coste de creación de una caché explícita, consulta los registros de consumo de Context Cache storage en la plataforma.
  </Accordion>

  <Accordion title="¿Cómo se factura la caché?">
    Al crear una caché, puede aplicarse una tarifa única de almacenamiento. Al usarla, los tokens coincidentes se facturan al precio de lectura de caché. Consulta los precios específicos en la página de precios de los modelos de la plataforma.
  </Accordion>
</AccordionGroup>
