使用 Gemini 进行上下文缓存¶
在使用智能体完成任务时,你可能希望在多个智能体请求之间重用扩展指令或大量数据。
对每个智能体请求重新发送这些数据很慢、效率低下且可能很昂贵。利用生成式 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 中可用;默认无。
检查缓存是否正在使用¶
当启用缓存时,由 LLM 响应支持的事件可以携带 CacheMetadata,报告缓存在该调用中的行为。当缓存被禁用时,或者当调用未产生缓存信息时,它为 null,因此在读取之前请检查它。当存在时,它有两种状态:活跃缓存,其中 cacheName、expireTime 和 invocationsUsed 都已设置;以及仅指纹状态,其中三者都为 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 参数,这允许你修改生成式模型的系统指令。更多详细信息请参阅:
static_instruction: 一个使用静态指令的数字宠物智能体实现。