在典型的 AI 工作流中,您可能会反复向模型传递相同的输入词元。Gemini API 提供了两种不同的缓存机制:
- 隐式缓存(在 Gemini 2.5 及更新的模型上自动启用,不保证节省费用)
- 显式缓存(可在 Gemini 3 和 2.5 模型上手动启用,保证节省费用;Gemini 4 Argon 及后续模型不支持)
如果您希望保证节省费用,但需要增加一些开发者工作,则显式缓存非常有用。
隐式缓存
对于所有 Gemini 2.5 及更新的模型,隐式缓存默认处于启用状态。如果您的请求命中缓存,我们会自动将节省的费用返还给您。您无需进行任何配置即可开启此功能。下表列出了每个模型的输入 token 数量下限:
| 模型 | 词元数量下限 |
|---|---|
| Gemini 4 Argon | 4096 |
| Gemini 3.8 Flash | 4096 |
| Gemini 3.6 Flash | 4096 |
| Gemini 3 Pro 预览版 | 4096 |
| Gemini 2.5 Flash | 2048 |
| Gemini 2.5 Pro | 2048 |
如要提高隐式缓存命中的几率,可以:
- 尝试将较大且常见的内容放置在提示的开头
- 尝试在短时间内发送具有相似前缀的请求
您可以在回答对象的 usage_metadata 字段中查看缓存命中的 token 数量。
显式缓存
使用 Gemini API 显式缓存功能,您可以将一些内容传递给模型一次,缓存输入 token,然后在后续请求中引用缓存的 token。在达到一定数量后,使用缓存的词元比重复传入相同的词元语料库成本更低。
缓存一组 token 时,您可以选择缓存的存在时长,超出该时长后,系统会自动删除这些 token。此缓存时长称为存留时间 (TTL)。如果未设置,TTL 默认为 1 小时。缓存费用取决于输入 token 大小以及您希望 token 保留多长时间。
本部分假定您已安装 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)
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'"
}'
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
以下示例展示了如何使用 client.caches.update() 更新缓存的 ttl。
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
以下示例展示了如何使用 GoogleGenAI.caches.update() 更新缓存的 ttl。
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 库,则可以使用 extra_body 上的 cached_content 属性启用显式缓存。
何时使用显式缓存
上下文缓存特别适合较短的请求重复引用大量初始上下文的场景。例如,对于以下使用场景,可以考虑使用上下文缓存:
- 有大量系统指令的聊天机器人
- 对较长的视频文件进行的重复分析
- 针对大型文档集的定期查询
- 频繁的代码库分析或 bug 修复
显式缓存如何降低费用
上下文缓存是一项付费功能,旨在降低费用。结算取决于以下因素:
- 缓存词元数:缓存的输入词元数,如果相同的词元在后续提示中被重复使用,则按折扣费率计费。
- 存储时长:所缓存词元的存储时长 (TTL),根据缓存词元数的 TTL 时长计费。TTL 没有下限或上限。
- 其他因素:可能还会产生其他费用,例如非缓存输入词元和输出词元的费用。
如需了解最新价格详情,请参阅 Gemini API 价格页面。如需了解如何计算 token 数量,请参阅 Token 指南。
其他注意事项
使用上下文缓存时,请注意以下事项:
- 上下文缓存的最低输入 token 数量因模型而异。最大值与给定模型的最大值相同。(如需详细了解如何统计 token 数量,请参阅 Token 指南)。
- 模型不会区分缓存的 token 和常规输入 token。缓存的内容是提示的前缀。
- 上下文缓存没有特殊的速率或用量限额;
GenerateContent的标准速率限制适用,并且 token 限制包括缓存的 token。 - 缓存服务的创建、获取和列出操作会在
usage_metadata中返回缓存的 token 数量,使用缓存时也会在GenerateContent中返回。