שמירה במטמון של הקשר

בתהליך עבודה אופייני של AI, יכול להיות שתעבירו את אותם אסימוני קלט שוב ושוב למודל. ‫Gemini API מציע שני מנגנוני שמירה במטמון:

  • שמירה במטמון באופן משתמע (מופעלת באופן אוטומטי ב-Gemini 2.5 ובמודלים חדשים יותר, ללא הבטחה לחיסכון בעלויות)
  • שמירה מפורשת במטמון (אפשר להפעיל אותה ידנית במודלים של Gemini 3 ו-Gemini 2.5, והיא מבטיחה חיסכון בעלויות. אין תמיכה בהחל מ-Gemini 4 Argon)

שמירה מפורשת במטמון שימושית במקרים שבהם רוצים להבטיח חיסכון בעלויות, אבל היא דורשת עבודת פיתוח נוספת.

שמירה במטמון משתמעת

שמירה במטמון באופן משתמע מופעלת כברירת מחדל בכל המודלים של Gemini 2.5 ומעלה. אם הבקשה שלכם מגיעה למטמון, אנחנו מעבירים לכם באופן אוטומטי את החיסכון בעלויות. לא צריך להגדיר שום דבר כדי להפעיל אותה. בטבלה הבאה מפורטת כמות הטוקנים המינימלית לקלט בכל מודל:

דגם מגבלת טוקנים מינימלית
Gemini 4 Argon 4,096
Gemini 3.8 Flash 4,096
Gemini 3.6 Flash 4,096
‫Gemini 3.1 Pro Preview 4,096
Gemini ‎2.5 Flash 2,048
Gemini ‎2.5 Pro 2,048

כדי להגדיל את הסיכוי למציאה במטמון (cache hit) משתמע:

  • כדאי לנסות לשים תוכן ארוך ונפוץ בתחילת ההנחיה
  • לנסות לשלוח בקשות עם קידומת דומה בפרק זמן קצר

אפשר לראות את מספר הטוקנים שנמצאו במטמון בשדה usage_metadata של אובייקט התגובה.

שמירה מפורשת במטמון

באמצעות התכונה "שמירה מפורשת במטמון" של Gemini API, אתם יכולים להעביר תוכן מסוים למודל פעם אחת, לשמור את אסימוני הקלט במטמון ואז להפנות לאסימונים שנשמרו במטמון בבקשות הבאות. בנפחים מסוימים, השימוש בטוקנים שנשמרו במטמון זול יותר מאשר העברת אותו מאגר של טוקנים שוב ושוב.

כששומרים קבוצה של אסימונים במטמון, אפשר לבחור כמה זמן המטמון יישמר לפני שהאסימונים יימחקו באופן אוטומטי. משך השמירה במטמון נקרא אורך חיים (TTL). אם לא מגדירים את ה-TTL, ברירת המחדל היא שעה אחת. העלות של השמירה במטמון תלויה בגודל של טוקן הקלט ובמשך הזמן שבו רוצים שהטוקנים יישמרו.

בקטע הזה אנחנו מניחים שהתקנתם את Gemini SDK (או שהתקנתם את curl) ושהגדרתם מפתח API, כמו שמוסבר במדריך לתחילת הדרך.

יצירת תוכן באמצעות מטמון

Python

בדוגמה הבאה מוסבר איך ליצור תוכן באמצעות הוראות מערכת וקובץ וידאו שנשמרו במטמון.

סרטונים

import os
import pathlib
import requests
import time

from google import genai
from google.genai import types

client = genai.Client()

# Download a test video file and save it locally
url = 'https://storage.googleapis.com/generativeai-downloads/data/SherlockJr._10min.mp4'
path_to_video_file = pathlib.Path('SherlockJr._10min.mp4')
if not path_to_video_file.exists():
    path_to_video_file.write_bytes(requests.get(url).content)

# Upload the video using the Files API
video_file = client.files.upload(file=path_to_video_file)

# Wait for the file to finish processing
while video_file.state.name == 'PROCESSING':
    time.sleep(2.5)
    video_file = client.files.get(name=video_file.name)

print(f'Video processing complete: {video_file.uri}')

model='models/gemini-3.8-flash'

# Create a cache with a 5 minute TTL (300 seconds)
cache = client.caches.create(
    model=model,
    config=types.CreateCachedContentConfig(
        display_name='sherlock jr movie', # used to identify the cache
        system_instruction=(
            'You are an expert video analyzer, and your job is to answer '
            'the user\'s query based on the video file you have access to.'
        ),
        contents=[video_file],
        ttl="300s",
    )
)

response = client.models.generate_content(
    model = model,
    contents= (
    'Introduce different characters in the movie by describing '
    'their personality, looks, and names. Also list the timestamps '
    'they were introduced for the first time.'),
    config=types.GenerateContentConfig(cached_content=cache.name)
)

print(response.usage_metadata)

print(response.text)

קובצי PDF

from google import genai
from google.genai import types
import io
import httpx

client = genai.Client()

long_context_pdf_path = "https://sma.nasa.gov/SignificantIncidents/assets/a11_missionreport.pdf"

# Retrieve and upload the PDF using the File API
doc_io = io.BytesIO(httpx.get(long_context_pdf_path).content)

document = client.files.upload(
  file=doc_io,
  config=dict(mime_type='application/pdf')
)

model_name = "gemini-3.8-flash"
system_instruction = "You are an expert analyzing transcripts."

# Create a cached content object
cache = client.caches.create(
    model=model_name,
    config=types.CreateCachedContentConfig(
      system_instruction=system_instruction,
      contents=[document],
    )
)

print(f'{cache=}')

response = client.models.generate_content(
  model=model_name,
  contents="Please summarize this transcript",
  config=types.GenerateContentConfig(
    cached_content=cache.name
  ))

print(f'{response.usage_metadata=}')

print('\n\n', response.text)

JavaScript

בדוגמה הבאה מוסבר איך ליצור תוכן באמצעות הוראות מערכת במטמון וקובץ טקסט.

import {
  GoogleGenAI,
  createUserContent,
  createPartFromUri,
} from "@google/genai";

const ai = new GoogleGenAI({ apiKey: "GEMINI_API_KEY" });

async function main() {
  const doc = await ai.files.upload({
    file: "path/to/file.txt",
    config: { mimeType: "text/plain" },
  });
  console.log("Uploaded file name:", doc.name);

  const modelName = "gemini-3.8-flash";
  const cache = await ai.caches.create({
    model: modelName,
    config: {
      contents: createUserContent(createPartFromUri(doc.uri, doc.mimeType)),
      systemInstruction: "You are an expert analyzing transcripts.",
    },
  });
  console.log("Cache created:", cache);

  const response = await ai.models.generateContent({
    model: modelName,
    contents: "Please summarize this transcript",
    config: { cachedContent: cache.name },
  });
  console.log("Response text:", response.text);
}

await main();

Go

בדוגמה הבאה מוסבר איך ליצור תוכן באמצעות מטמון.

package main

import (
    "context"
    "fmt"
    "log"

    "google.golang.org/genai"
)

func main() {
    ctx := context.Background()
    client, err := genai.NewClient(ctx, &genai.ClientConfig{
        APIKey: "GOOGLE_API_KEY",
        Backend: genai.BackendGeminiAPI,
    })
    if err != nil {
        log.Fatal(err)
    }

    modelName := "gemini-3.8-flash"
    document, err := client.Files.UploadFromPath(
        ctx,
        "media/a11.txt",
        &genai.UploadFileConfig{
          MIMEType: "text/plain",
        },
    )
    if err != nil {
        log.Fatal(err)
    }
    parts := []*genai.Part{
        genai.NewPartFromURI(document.URI, document.MIMEType),
    }
    contents := []*genai.Content{
        genai.NewContentFromParts(parts, genai.RoleUser),
    }
    cache, err := client.Caches.Create(ctx, modelName, &genai.CreateCachedContentConfig{
        Contents: contents,
        SystemInstruction: genai.NewContentFromText(
          "You are an expert analyzing transcripts.", genai.RoleUser,
        ),
    })
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println("Cache created:")
    fmt.Println(cache)

    // Use the cache for generating content.
    response, err := client.Models.GenerateContent(
        ctx,
        modelName,
        genai.Text("Please summarize this transcript"),
        &genai.GenerateContentConfig{
          CachedContent: cache.Name,
        },
    )
    if err != nil {
        log.Fatal(err)
    }
    printResponse(response) // helper for printing response parts
}

REST

בדוגמה הבאה מוסבר איך ליצור מטמון ואז להשתמש בו כדי ליצור תוכן.

סרטונים

wget https://storage.googleapis.com/generativeai-downloads/data/a11.txt
echo '{
  "model": "models/gemini-3.8-flash",
  "contents":[
    {
      "parts":[
        {
          "inline_data": {
            "mime_type":"text/plain",
            "data": "'$(base64 $B64FLAGS a11.txt)'"
          }
        }
      ],
    "role": "user"
    }
  ],
  "systemInstruction": {
    "parts": [
      {
        "text": "You are an expert at analyzing transcripts."
      }
    ]
  },
  "ttl": "300s"
}' > request.json

curl -X POST "https://generativelanguage.googleapis.com/v1beta/cachedContents?key=$GEMINI_API_KEY" \
-H 'Content-Type: application/json' \
-d @request.json \
> cache.json

CACHE_NAME=$(cat cache.json | grep '"name":' | cut -d '"' -f 4 | head -n 1)

curl -X POST "https://generativelanguage.googleapis.com/v1beta/models/gemini-3.8-flash:generateContent?key=$GEMINI_API_KEY" \
-H 'Content-Type: application/json' \
-d '{
      "contents": [
        {
          "parts":[{
            "text": "Please summarize this transcript"
          }],
          "role": "user"
        },
      ],
      "cachedContent": "'$CACHE_NAME'"
    }'

קובצי PDF

DOC_URL="https://sma.nasa.gov/SignificantIncidents/assets/a11_missionreport.pdf"
DISPLAY_NAME="A11_Mission_Report"
SYSTEM_INSTRUCTION="You are an expert at analyzing transcripts."
PROMPT="Please summarize this transcript"
MODEL="models/gemini-3.8-flash"
TTL="300s"

# Download the PDF
wget -O "${DISPLAY_NAME}.pdf" "${DOC_URL}"

MIME_TYPE=$(file -b --mime-type "${DISPLAY_NAME}.pdf")
NUM_BYTES=$(wc -c < "${DISPLAY_NAME}.pdf")

echo "MIME_TYPE: ${MIME_TYPE}"
echo "NUM_BYTES: ${NUM_BYTES}"

tmp_header_file=upload-header.tmp

# Initial resumable request defining metadata.
# The upload url is in the response headers dump them to a file.
curl "${BASE_URL}/upload/v1beta/files?key=${GOOGLE_API_KEY}" \
  -D upload-header.tmp \
  -H "X-Goog-Upload-Protocol: resumable" \
  -H "X-Goog-Upload-Command: start" \
  -H "X-Goog-Upload-Header-Content-Length: ${NUM_BYTES}" \
  -H "X-Goog-Upload-Header-Content-Type: ${MIME_TYPE}" \
  -H "Content-Type: application/json" \
  -d "{'file': {'display_name': '${DISPLAY_NAME}'}}" 2> /dev/null

upload_url=$(grep -i "x-goog-upload-url: " "${tmp_header_file}" | cut -d" " -f2 | tr -d "\r")
rm "${tmp_header_file}"

# Upload the actual bytes.
curl "${upload_url}" \
  -H "Content-Length: ${NUM_BYTES}" \
  -H "X-Goog-Upload-Offset: 0" \
  -H "X-Goog-Upload-Command: upload, finalize" \
  --data-binary "@${DISPLAY_NAME}.pdf" 2> /dev/null > file_info.json

file_uri=$(jq ".file.uri" file_info.json)
echo "file_uri: ${file_uri}"

# Clean up the downloaded PDF
rm "${DISPLAY_NAME}.pdf"

# Create the cached content request
echo '{
  "model": "'$MODEL'",
  "contents":[
    {
      "parts":[
        {"file_data": {"mime_type": "'$MIME_TYPE'", "file_uri": '$file_uri'}}
      ],
    "role": "user"
    }
  ],
  "system_instruction": {
    "parts": [
      {
        "text": "'$SYSTEM_INSTRUCTION'"
      }
    ],
    "role": "system"
  },
  "ttl": "'$TTL'"
}' > request.json

# Send the cached content request
curl -X POST "${BASE_URL}/v1beta/cachedContents?key=$GOOGLE_API_KEY" \
-H 'Content-Type: application/json' \
-d @request.json \
> cache.json

CACHE_NAME=$(cat cache.json | grep '"name":' | cut -d '"' -f 4 | head -n 1)
echo "CACHE_NAME: ${CACHE_NAME}"
# Send the generateContent request using the cached content
curl -X POST "${BASE_URL}/${MODEL}:generateContent?key=$GOOGLE_API_KEY" \
-H 'Content-Type: application/json' \
-d '{
      "contents": [
        {
          "parts":[{
            "text": "'$PROMPT'"
          }],
          "role": "user"
        }
      ],
      "cachedContent": "'$CACHE_NAME'"
    }' > response.json

cat response.json

echo jq ".candidates[].content.parts[].text" response.json

הצגת רשימה של מטמונים

אי אפשר לאחזר או להציג תוכן שנשמר במטמון, אבל אפשר לאחזר מטא-נתונים של המטמון (name,‏ model,‏ display_name,‏ usage_metadata,‏ create_time,‏ update_time ו-expire_time).

Python

כדי להציג את המטא-נתונים של כל המטמונים שהועלו, משתמשים ב-CachedContent.list():

for cache in client.caches.list():
  print(cache)

כדי לאחזר את המטא-נתונים של אובייקט מטמון אחד, אם אתם יודעים את השם שלו, השתמשו ב-get:

client.caches.get(name=name)

JavaScript

כדי להציג את המטא-נתונים של כל המטמונים שהועלו, משתמשים ב-GoogleGenAI.caches.list():

console.log("My caches:");
const pager = await ai.caches.list({ config: { pageSize: 10 } });
let page = pager.page;
while (true) {
  for (const c of page) {
    console.log("    ", c.name);
  }
  if (!pager.hasNextPage()) break;
  page = await pager.nextPage();
}

Go

בדוגמה הבאה מוצגת רשימה של כל המטמונים.

caches, err := client.Caches.All(ctx)
if err != nil {
    log.Fatal(err)
}
fmt.Println("Listing all caches:")
for _, item := range caches {
    fmt.Println("   ", item.Name)
}

בדוגמה הבאה מוצגת רשימה של מטמונים עם גודל דף "2".

page, err := client.Caches.List(ctx, &genai.ListCachedContentsConfig{PageSize: 2})
if err != nil {
    log.Fatal(err)
}

pageIndex := 1
for {
    fmt.Printf("Listing caches (page %d):\n", pageIndex)
    for _, item := range page.Items {
        fmt.Println("   ", item.Name)
    }
    if page.NextPageToken == "" {
        break
    }
    page, err = page.Next(ctx)
    if err == genai.ErrPageDone {
        break
    } else if err != nil {
        return err
    }
    pageIndex++
}

REST

curl "https://generativelanguage.googleapis.com/v1beta/cachedContents?key=$GEMINI_API_KEY"

עדכון מטמון

אפשר להגדיר ttl או expire_time חדשים למטמון. אי אפשר לשנות שום דבר אחר במטמון.

Python

בדוגמה הבאה מוסבר איך לעדכן את ה-ttl של מטמון באמצעות client.caches.update().

from google import genai
from google.genai import types

client.caches.update(
  name = cache.name,
  config  = types.UpdateCachedContentConfig(
      ttl='300s'
  )
)

כדי להגדיר את מועד התפוגה, אפשר להשתמש באובייקט datetime או במחרוזת תאריך ושעה בפורמט ISO (dt.isoformat(), כמו 2025-01-27T16:02:36.473528+00:00). השעה חייבת לכלול אזור זמן (datetime.utcnow() לא מצרף אזור זמן, datetime.now(datetime.timezone.utc) כן מצרף אזור זמן).

from google import genai
from google.genai import types
import datetime

# You must use a time zone-aware time.
in10min = datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(minutes=10)

client.caches.update(
  name = cache.name,
  config  = types.UpdateCachedContentConfig(
      expire_time=in10min
  )
)

JavaScript

בדוגמה הבאה מוסבר איך לעדכן את ה-ttl של מטמון באמצעות GoogleGenAI.caches.update().

const ttl = `${2 * 3600}s`; // 2 hours in seconds
const updatedCache = await ai.caches.update({
  name: cache.name,
  config: { ttl },
});
console.log("After update (TTL):", updatedCache);

Go

בדוגמה הבאה אפשר לראות איך מעדכנים את ה-TTL של מטמון.

// Update the TTL (2 hours).
cache, err = client.Caches.Update(ctx, cache.Name, &genai.UpdateCachedContentConfig{
    TTL: 7200 * time.Second,
})
if err != nil {
    log.Fatal(err)
}
fmt.Println("After update:")
fmt.Println(cache)

REST

בדוגמה הבאה אפשר לראות איך מעדכנים את ה-ttl של מטמון.

curl -X PATCH "https://generativelanguage.googleapis.com/v1beta/$CACHE_NAME?key=$GEMINI_API_KEY" \
-H 'Content-Type: application/json' \
-d '{"ttl": "600s"}'

מחיקת מטמון

שירות השמירה במטמון מספק פעולת מחיקה להסרה ידנית של תוכן מהמטמון. בדוגמה הבאה אפשר לראות איך מוחקים מטמון:

Python

client.caches.delete(cache.name)

JavaScript

await ai.caches.delete({ name: cache.name });

Go

_, err = client.Caches.Delete(ctx, cache.Name, &genai.DeleteCachedContentConfig{})
if err != nil {
    log.Fatal(err)
}
fmt.Println("Cache deleted:", cache.Name)

REST

curl -X DELETE "https://generativelanguage.googleapis.com/v1beta/$CACHE_NAME?key=$GEMINI_API_KEY"

שמירה מפורשת במטמון באמצעות ספריית OpenAI

אם אתם משתמשים בספריית OpenAI, אתם יכולים להפעיל שמירה מפורשת במטמון באמצעות המאפיין cached_content ב-extra_body.

מתי כדאי להשתמש בשמירה מפורשת במטמון

שמירת הקשר במטמון מתאימה במיוחד לתרחישים שבהם הקשר ראשוני משמעותי משמש כהפניה שוב ושוב על ידי בקשות קצרות יותר. כדאי להשתמש בשמירת הקשר במטמון בתרחישים לדוגמה כמו:

  • צ'אט בוטים עם הוראות מערכת נרחבות
  • ניתוח חוזר של קובצי וידאו ארוכים
  • שאילתות חוזרות על קבוצות גדולות של מסמכים
  • ניתוח תכוף של מאגר המקורות של הקוד או תיקון באגים

איך שמירה מפורשת במטמון מפחיתה את העלויות

שמירת הקשר במטמון היא תכונה בתשלום שנועדה להפחית את העלויות. החיוב מבוסס על הגורמים הבאים:

  1. מספר הטוקנים במטמון: מספר טוקני הקלט שנשמרו במטמון, שמחויבים בתעריף מופחת כשהם נכללים בהנחיות הבאות.
  2. משך האחסון: משך הזמן שבו הטוקנים נשמרים במטמון (TTL), והחיוב מתבצע על סמך משך ה-TTL של מספר הטוקנים שנשמרו במטמון. אין גבולות מינימום או מקסימום ל-TTL.
  3. גורמים אחרים: חיובים אחרים חלים, למשל על טוקנים של קלט ופלט שלא נשמרו במטמון.

פרטי התמחור העדכניים מופיעים בדף התמחור של Gemini API. איך סופרים טוקנים

שיקולים נוספים

כשמשתמשים בשמירת הקשר במטמון, חשוב לזכור את הנקודות הבאות:

  • מספר המינימום של טוקנים לקלט בשמירת הקשר במטמון משתנה בהתאם למודל. הערך המקסימלי זהה לערך המקסימלי של המודל הנתון. (למידע נוסף על ספירת טוקנים, עיינו במדריך בנושא טוקנים).
  • המודל לא מבדיל בין טוקנים במטמון לבין טוקנים רגילים של קלט. התוכן שנשמר במטמון הוא תחילית להנחיה.
  • אין מגבלות מיוחדות על הקצב או מכסות שימוש בשמירת הקשר במטמון. הגבלת קצב של יצירת בקשות הרגילות של GenerateContent חלות, ומכסות הטוקנים כוללות טוקנים שנשמרו במטמון.
  • מספר האסימונים שנשמרו במטמון מוחזר ב-usage_metadata מהפעולות create,‏ get ו-list של שירות המטמון, וגם ב-GenerateContent כשמשתמשים במטמון.