Skip to content

Prompt 快取控制

Prompt 快取控制可讓您指示支援的 LLM 提供者在伺服器端儲存 Prompt 的一部分,以便共用相同前綴的後續請求可以從快取中提供服務,而不是重新處理 Token。 這可以降低多輪對話、大型系統 Prompt 或固定工具定義等重複工作負載的延遲和成本。

Prompt 快取 vs. 回應快取

Prompt 快取控制是一項 提供者端 (provider-side) 的功能:提供者儲存的是 Prompt 前綴,而非回應。這與 CachedPromptExecutor 不同,後者是在本機儲存完整的 LLM 回應,以便相同的 Prompt 可以完全跳過網路呼叫。

Koog 支援 AnthropicAmazon Bedrock 的 Prompt 快取控制。

Anthropic

Anthropic 支援兩種互補的 Prompt 快取方法。

自動快取 (請求層級)

AnthropicParams 上設定 cacheControl 屬性,並將其傳遞給您的 Prompt。 Anthropic 會自動將快取中斷點放置在請求中最後一個可快取的區塊,您無需手動為個別訊息標註。 這是多輪對話的建議做法。

=== "Kotlin"

<!--- INCLUDE
import ai.koog.prompt.dsl.prompt
import ai.koog.prompt.executor.clients.anthropic.AnthropicCacheControl
import ai.koog.prompt.executor.clients.anthropic.AnthropicLLMClient
import ai.koog.prompt.executor.clients.anthropic.AnthropicModels
import ai.koog.prompt.executor.clients.anthropic.AnthropicParams
import kotlinx.coroutines.runBlocking

fun main() = runBlocking {
    val client = AnthropicLLMClient(System.getenv("ANTHROPIC_API_KEY"))
-->
<!--- SUFFIX
}
-->

```kotlin
// 啟用預設 5 分鐘 TTL 的自動快取
val params = AnthropicParams(cacheControl = AnthropicCacheControl.Default)

val prompt = prompt("assistant", params = params) {
    system("You are a helpful assistant with a very long system prompt...")
    user("What can you help me with?")
}

val response = client.execute(prompt, AnthropicModels.Sonnet_4)
println(response)
```
<!--- KNIT example-cache-control-01.kt -->

=== "Java"

<!--- INCLUDE
/**
-->
<!--- SUFFIX
**/
-->
```java
// 啟用預設 5 分鐘 TTL 的自動快取
AnthropicParams params = new AnthropicParams(
    null, null, null, null, null, null, null, null,
    null, null, null, null, null, null, null,
    AnthropicCacheControl.Default.INSTANCE
);

Prompt prompt = Prompt.builder("assistant")
    .system("You are a helpful assistant with a very long system prompt...")
    .user("What can you help me with?")
    .build()
    .withParams(params);
```
<!--- KNIT example-cache-control-java-01.java -->

手動快取 (區塊層級)

cacheControl 引數附加到個別訊息或工具定義中,以將快取中斷點放置在特定位置。到該標註區塊為止(包含該區塊)的所有內容皆符合快取資格。

系統訊息

=== "Kotlin"

<!--- INCLUDE
import ai.koog.prompt.dsl.prompt
import ai.koog.prompt.executor.clients.anthropic.AnthropicCacheControl
import ai.koog.prompt.executor.clients.anthropic.AnthropicLLMClient
import ai.koog.prompt.executor.clients.anthropic.AnthropicModels
import kotlinx.coroutines.runBlocking

fun main() = runBlocking {
    val client = AnthropicLLMClient(System.getenv("ANTHROPIC_API_KEY"))
-->
<!--- SUFFIX
}
-->

```kotlin
val prompt = prompt("assistant") {
    // 將系統 Prompt 快取 1 小時
    system("You are a knowledgeable assistant...", AnthropicCacheControl.OneHour)
    user("Summarize the latest AI research.")
}

val response = client.execute(prompt, AnthropicModels.Sonnet_4)
println(response)
```
<!--- KNIT example-cache-control-02.kt -->

=== "Java"

<!--- INCLUDE
/**
-->
<!--- SUFFIX
**/
-->
```java
Prompt prompt = Prompt.builder("assistant")
    // 將系統 Prompt 快取 1 小時
    .system("You are a knowledgeable assistant...", AnthropicCacheControl.OneHour.INSTANCE)
    .user("Summarize the latest AI research.")
    .build();
```
<!--- KNIT example-cache-control-java-02.java -->

使用者與助手訊息

=== "Kotlin"

<!--- INCLUDE
import ai.koog.prompt.dsl.prompt
import ai.koog.prompt.executor.clients.anthropic.AnthropicCacheControl
import ai.koog.prompt.executor.clients.anthropic.AnthropicLLMClient
import ai.koog.prompt.executor.clients.anthropic.AnthropicModels
import ai.koog.prompt.message.ContentPart
import kotlinx.coroutines.runBlocking

fun main() = runBlocking {
    val client = AnthropicLLMClient(System.getenv("ANTHROPIC_API_KEY"))
-->
<!--- SUFFIX
}
-->

```kotlin
val prompt = prompt("conversation") {
    system("You are a helpful assistant.")
    // 在大型使用者訊息(例如:文件內容)之後進行快取
    user(listOf(ContentPart.Text("Here is a long document: ...")), AnthropicCacheControl.Default)
    assistant("I have read the document.", AnthropicCacheControl.Default)
    user("Summarize it.")
}

val response = client.execute(prompt, AnthropicModels.Sonnet_4)
println(response)
```
<!--- KNIT example-cache-control-03.kt -->

=== "Java"

<!--- INCLUDE
/**
-->
<!--- SUFFIX
**/
-->
```java
Prompt prompt = Prompt.builder("conversation")
    .system("You are a helpful assistant.")
    // 在大型使用者訊息(例如:文件內容)之後進行快取
    .user(List.of(new ContentPart.Text("Here is a long document: ...")), AnthropicCacheControl.Default.INSTANCE)
    .assistant("I have read the document.", AnthropicCacheControl.Default.INSTANCE)
    .user("Summarize it.")
    .build();
```
<!--- KNIT example-cache-control-java-03.java -->

工具定義

當工具列表在多個請求中保持不變時,快取最後一個工具定義意味著所有工具結構 (schema) 都會被一起快取。

=== "Kotlin"

<!--- INCLUDE
import ai.koog.agents.core.tools.ToolDescriptor
import ai.koog.agents.core.tools.ToolParameterDescriptor
import ai.koog.agents.core.tools.ToolParameterType
import ai.koog.prompt.executor.clients.anthropic.AnthropicCacheControl
-->

```kotlin
val searchTool = ToolDescriptor(
    name = "web_search",
    description = "Search the web for information.",
    requiredParameters = listOf(
        ToolParameterDescriptor("query", "Search query", ToolParameterType.String)
    ),
    // 快取到此工具定義為止(包含此定義)的所有工具定義
    cacheControl = AnthropicCacheControl.Default
)
```
<!--- KNIT example-cache-control-04.kt -->

=== "Java"

<!--- INCLUDE
/**
-->
<!--- SUFFIX
**/
-->
```java
ToolDescriptor searchTool = new ToolDescriptor(
    "web_search",
    "Search the web for information.",
    List.of(
        new ToolParameterDescriptor("query", "Search query", ToolParameterType.String.INSTANCE)
    ),
    Collections.emptyList(),
    // 快取到此工具定義為止(包含此定義)的所有工具定義
    AnthropicCacheControl.Default.INSTANCE
);
```
<!--- KNIT example-cache-control-java-04.java -->

快取 TTL 選項

選項TTL價格倍率
AnthropicCacheControl.Default5 分鐘1.25× 基礎輸入價格
AnthropicCacheControl.OneHour1 小時2× 基礎輸入價格

快取寫入的費用高於一般輸入 Token,但快取讀取更便宜。請參閱 Anthropic Prompt 快取文件 以瞭解最新定價。

監控快取使用情況

Anthropic 在回應的使用情況 (usage) 中回報快取統計資訊。這些資訊可透過原始 API 回應存取,並可透過追蹤或記錄功能進行觀察。

欄位意義
cacheReadInputTokens從現有快取項目中讀取的 Token 數量
cacheCreationInputTokens寫入新快取項目的 Token 數量

結合自動快取與區塊層級快取

這兩種模式可以同時使用。區塊層級的 cacheControl 標記可讓您精細控制中斷點位置,而 AnthropicParams 中的請求層級 cacheControl 則會自動處理對話的尾端。

=== "Kotlin"

<!--- INCLUDE
import ai.koog.prompt.dsl.prompt
import ai.koog.prompt.executor.clients.anthropic.AnthropicCacheControl
import ai.koog.prompt.executor.clients.anthropic.AnthropicParams
-->

```kotlin
// 區塊層級:將系統 Prompt 固定在 1 小時快取層級
// 自動:讓 Anthropic 管理對話尾端的中斷點
val params = AnthropicParams(cacheControl = AnthropicCacheControl.Default)

val prompt = prompt("combined", params = params) {
    system("You are a helpful assistant...", AnthropicCacheControl.OneHour)
    user("Hello!")
}
```
<!--- KNIT example-cache-control-05.kt -->

=== "Java"

<!--- INCLUDE
/**
-->
<!--- SUFFIX
**/
-->
```java
// 區塊層級:將系統 Prompt 固定在 1 小時快取層級
// 自動:讓 Anthropic 管理對話尾端的中斷點
AnthropicParams params = new AnthropicParams(
    AnthropicCacheControl.Default.INSTANCE
);

Prompt prompt = Prompt.builder("combined")
    .system("You are a helpful assistant...", AnthropicCacheControl.OneHour.INSTANCE)
    .user("Hello!")
    .build()
    .withParams(params);
```
<!--- KNIT example-cache-control-java-05.java -->

Amazon Bedrock

Amazon Bedrock 透過 Converse API 使用區塊層級快取模型。 當在訊息或工具上設定 cacheControl 時,Bedrock 會在被標註的元素之後立即插入一個 CachePoint 區塊。

NOTE

Bedrock Prompt 快取是僅限 JVM 的功能,因為 Bedrock 用戶端本身僅限 JVM 使用。

系統訊息

=== "Kotlin"

<!--- INCLUDE
import ai.koog.prompt.dsl.prompt
import ai.koog.prompt.executor.clients.bedrock.BedrockCacheControl
import ai.koog.prompt.executor.clients.bedrock.BedrockClientSettings
import ai.koog.prompt.executor.clients.bedrock.BedrockLLMClient
import ai.koog.prompt.executor.clients.bedrock.BedrockModels
import ai.koog.prompt.executor.clients.bedrock.BedrockRegions
import ai.koog.prompt.executor.clients.bedrock.StaticBearerTokenProvider
import kotlinx.coroutines.runBlocking

fun main() = runBlocking {
    val client = BedrockLLMClient(
        identityProvider = StaticBearerTokenProvider(token = "test-token"),
        settings = BedrockClientSettings(region = BedrockRegions.US_EAST_1.regionCode),
    )
-->
<!--- SUFFIX
}
-->

```kotlin
val prompt = prompt("assistant") {
    // 使用預設 TTL 快取系統 Prompt
    system("You are a knowledgeable assistant...", BedrockCacheControl.Default)
    user("What is prompt caching?")
}

val response = client.execute(prompt, BedrockModels.AnthropicClaude4Sonnet)
println(response)
```
<!--- KNIT example-cache-control-06.kt -->

=== "Java"

<!--- INCLUDE
/**
-->
<!--- SUFFIX
**/
-->
```java
Prompt prompt = Prompt.builder("assistant")
    // 使用預設 TTL 快取系統 Prompt
    .system("You are a knowledgeable assistant...", BedrockCacheControl.Default.INSTANCE)
    .user("What is prompt caching?")
    .build();
```
<!--- KNIT example-cache-control-java-06.java -->

使用者與助手訊息

=== "Kotlin"

<!--- INCLUDE
import ai.koog.prompt.dsl.prompt
import ai.koog.prompt.executor.clients.bedrock.BedrockCacheControl
import ai.koog.prompt.executor.clients.bedrock.BedrockClientSettings
import ai.koog.prompt.executor.clients.bedrock.BedrockLLMClient
import ai.koog.prompt.executor.clients.bedrock.BedrockModels
import ai.koog.prompt.executor.clients.bedrock.BedrockRegions
import ai.koog.prompt.executor.clients.bedrock.StaticBearerTokenProvider
import kotlinx.coroutines.runBlocking

fun main() = runBlocking {
    val client = BedrockLLMClient(
        identityProvider = StaticBearerTokenProvider(token = "test-token"),
        settings = BedrockClientSettings(region = BedrockRegions.US_EAST_1.regionCode),
    )
-->
<!--- SUFFIX
}
-->

```kotlin
val prompt = prompt("conversation") {
    system("You are a helpful assistant.")
    // 在大型內容訊息之後進行快取
    user("Here is the document: ...", BedrockCacheControl.FiveMinutes)
    assistant("I have read the document.", BedrockCacheControl.Default)
    user("Summarize it.")
}

val response = client.execute(prompt, BedrockModels.AnthropicClaude4Sonnet)
println(response)
```
<!--- KNIT example-cache-control-07.kt -->

=== "Java"

<!--- INCLUDE
/**
-->
<!--- SUFFIX
**/
-->
```java
Prompt prompt = Prompt.builder("conversation")
    .system("You are a helpful assistant.")
    // 在大型內容訊息之後進行快取
    .user("Here is the document: ...", BedrockCacheControl.FiveMinutes.INSTANCE)
    .assistant("I have read the document.", BedrockCacheControl.Default.INSTANCE)
    .user("Summarize it.")
    .build();
```
<!--- KNIT example-cache-control-java-07.java -->

工具定義

=== "Kotlin"

<!--- INCLUDE
import ai.koog.agents.core.tools.ToolDescriptor
import ai.koog.agents.core.tools.ToolParameterDescriptor
import ai.koog.agents.core.tools.ToolParameterType
import ai.koog.prompt.executor.clients.bedrock.BedrockCacheControl
-->

```kotlin
val searchTool = ToolDescriptor(
    name = "web_search",
    description = "Search the web for information.",
    requiredParameters = listOf(
        ToolParameterDescriptor("query", "Search query", ToolParameterType.String)
    ),
    // 快取到此工具定義為止(包含此定義)的所有工具定義
    cacheControl = BedrockCacheControl.Default
)
```
<!--- KNIT example-cache-control-08.kt -->

=== "Java"

<!--- INCLUDE
/**
-->
<!--- SUFFIX
**/
-->
```java
ToolDescriptor searchTool = new ToolDescriptor(
    "web_search",
    "Search the web for information.",
    List.of(
        new ToolParameterDescriptor("query", "Search query", ToolParameterType.String.INSTANCE)
    ),
    Collections.emptyList(),
    // 快取到此工具定義為止(包含此定義)的所有工具定義
    BedrockCacheControl.Default.INSTANCE
);
```
<!--- KNIT example-cache-control-java-08.java -->

快取 TTL 選項

選項TTL
BedrockCacheControl.Default提供者預設值(不傳送明確的 TTL)
BedrockCacheControl.FiveMinutes5 分鐘
BedrockCacheControl.OneHour1 小時

請參閱 Amazon Bedrock Prompt 快取文件 以瞭解支援的模型與定價。


選擇快取策略

情境建議做法
具有大型固定系統 Prompt 的多輪聊天Anthropic 自動快取或 Bedrock 在系統訊息上的區塊層級快取
在請求之間重複使用的穩定工具定義在最後一個工具定義上設定區塊層級 cacheControl
作為使用者內容傳遞的長文件在使用者訊息上設定區塊層級 cacheControl
任意多輪對話 (Anthropic)透過 AnthropicParams.cacheControl 進行自動快取
需要 1 小時的快取保留時間AnthropicCacheControl.OneHour / BedrockCacheControl.OneHour