Skip to content

使用 Gemini 进行上下文缓存

Supported in ADKPython v1.15.0Java v0.1.0Kotlin v0.7.0

在使用智能体完成任务时,你可能希望在多个智能体请求之间重用扩展指令或大量数据。

对每个智能体请求重新发送这些数据很慢、效率低下且可能很昂贵。利用生成式 AI 模型中的上下文缓存功能可以显著加快响应速度,并减少每次请求发送到模型的令牌 (Token) 数量。

ADK 上下文缓存功能允许你将请求数据缓存到支持该功能的生成式 AI 模型中(包括 Gemini 2.0 及更高版本)。本文档解释如何配置和使用此功能。

配置上下文缓存

你可以在 ADK App 对象级别配置上下文缓存功能,该对象包装了你的智能体。

使用 ContextCacheConfig 类来配置这些设置,如下列代码示例所示:

from google.adk import Agent
from google.adk.apps.app import App
from google.adk.agents.context_cache_config import ContextCacheConfig

root_agent = Agent(
  name='my_caching_agent',
  # 配置使用 Gemini 2.0 或更高版本的智能体
)

# 创建带有上下文缓存配置的应用 (App)
app = App(
    name='my-caching-agent-app',
    root_agent=root_agent,
    context_cache_config=ContextCacheConfig(
        min_tokens=2048,    # 触发缓存所需的最小令牌数
        ttl_seconds=600,    # 最多存储 10 分钟 (600 秒)
        cache_intervals=5,  # 使用 5 次后刷新
    ),
)
import com.google.adk.agents.BaseAgent;
import com.google.adk.agents.ContextCacheConfig;
import com.google.adk.apps.App;
import java.time.Duration;

// 创建带有上下文缓存配置的应用 (App)
App app = App.builder()
             .name("my-caching-agent-app")
             .rootAgent(rootAgent)
             .contextCacheConfig(
                 new ContextCacheConfig(
                     5, /* cache_intervals (最大调用次数) */
                     Duration.ofMinutes(10), /* ttl (生存时间) */
                     2048 /* min_tokens (最小令牌数) */))
             .build();
import com.google.adk.kt.agents.ContextCacheConfig
import com.google.adk.kt.agents.LlmAgent
import com.google.adk.kt.annotations.ExperimentalContextCachingFeature
import com.google.adk.kt.apps.App
import com.google.adk.kt.models.Gemini
import com.google.adk.kt.types.HttpOptions
import kotlin.time.Duration.Companion.minutes
import kotlin.time.Duration.Companion.seconds

val rootAgent =
    LlmAgent(
        name = "my_caching_agent",
        // 配置使用 Gemini 2.0 或更高版本的智能体
        model = Gemini(name = "gemini-flash-latest"),
    )

// 创建带有上下文缓存配置的应用 (App)
@OptIn(ExperimentalContextCachingFeature::class)
val app =
    App(
        appName = "my-caching-agent-app",
        rootAgent = rootAgent,
        contextCacheConfig =
            ContextCacheConfig(
                // Gemini 对最小可缓存大小有自己的要求,因模型而异
                minTokens = 8192,
                ttl = 10.minutes, // 最多存储 10 分钟
                cacheIntervals = 5, // 使用 5 次后刷新
                // 超时时创建失败,请求将在不缓存的情况下继续。
                createHttpOptions = HttpOptions(timeout = 10.seconds),
            ),
    )

配置设置

ContextCacheConfig 类包含以下用于控制智能体缓存行为的设置。当你配置这些设置时,它们将应用于该应用 (App) 内的所有智能体。

  • min_tokens (int): 请求中启用缓存所需的最小令牌数。此设置允许你避免为非常小的请求承担缓存开销,因为此时性能收益微乎其微。默认为 0
  • ttl_seconds (int): 缓存的生存时间(TTL),以秒为单位。此设置决定缓存内容在刷新之前存储多长时间。默认为 1800(30 分钟)。
  • cache_intervals (int): 相同的缓存内容在过期前可以使用的最大次数。此设置允许你控制缓存更新的频率,即使 TTL 尚未到期。默认为 10
  • create_http_options (HttpOptions): 缓存创建调用的 HTTP 选项,允许你为其设置超时。如果调用超时,它会失败且请求将在不缓存的情况下继续。在 Python 和 Kotlin 中可用;默认无。

检查缓存是否正在使用

Supported in ADKKotlin v0.6.0

当启用缓存时,由 LLM 响应支持的事件可以携带 CacheMetadata,报告缓存在该调用中的行为。当缓存被禁用时,或者当调用未产生缓存信息时,它为 null,因此在读取之前请检查它。当存在时,它有两种状态:活跃缓存,其中 cacheNameexpireTimeinvocationsUsed 都已设置;以及仅指纹状态,其中三者都为 null。

/** Reports whether the context cache was used for the LLM call behind [event]. */
fun logCacheUse(event: Event) {
    // Null when caching is disabled, and on any event whose LLM call produced
    // no cache information.
    val cache = event.cacheMetadata ?: return

    if (!cache.isActive) {
        // Fingerprint-only: ADK measured the cacheable prefix but no cache is in
        // use. That is the first turn, a prefix that changed since the last turn,
        // or a cache ADK did not create -- most often because the cacheable
        // prefix was below minTokens.
        println("Not cached yet; fingerprinted ${cache.contentsCount} contents.")
        return
    }

    println("Cache ${cache.cacheName} reused ${cache.invocationsUsed} time(s).")
    if (cache.expireSoon) {
        // Advisory only. ADK goes on reusing the cache until it actually expires,
        // so this is a heads-up for your own code, not a prediction about the
        // next turn.
        println("Cache is at or near expiry.")
    }
}

expireSoon 表示缓存在大约两分钟内过期,或者已经过期。这是为你自己的代码提供的信号,ADK 不会对此采取行动:ADK 会继续重用缓存,直到它实际超过 expireTime、超过 cacheIntervals,或者其缓存前缀发生变化。

令牌计数不在 CacheMetadata 上;请从 LlmResponse.usageMetadata 中读取。

下一步

有关上下文缓存功能的完整实现和测试示例,请参阅:

  • cache_analysis: 一个演示如何分析上下文缓存性能的代码示例。

如果你的用例需要在会话期间共用指令,请考虑为智能体使用 static_instruction 参数,这允许你修改生成式模型的系统指令。更多详细信息请参阅: