Skip to content

提示 API

提示 API 提供了一套全面的工具包,用於在生產環境應用程式中與 LLM 互動。它提供:

  • Kotlin DSL 用於建立具有型別安全的結構化提示
  • 多供應商支援,支援 OpenAI、Anthropic、Google 及其他 LLM 供應商
  • 生產功能,例如重試邏輯、錯誤處理和逾時設定
  • 多模態功能,用於處理文字、圖像、音訊和文件

架構概覽

提示 API 由三個主要層組成:

  1. LLM 用戶端 - 針對特定供應商 (OpenAI、Anthropic 等) 的低階介面
  2. 裝飾器 - 可選的包裝器,用於新增重試邏輯等功能
  3. 提示執行器 - 管理用戶端生命週期並簡化使用方式的高階抽象

建立提示

提示 API 使用 Kotlin DSL 建立提示。它支援以下類型的訊息:

  • system: 設定 LLM 的上下文和指令。
  • user: 代表使用者輸入。
  • assistant: 代表 LLM 回應。

以下是一個簡單的提示範例:

kotlin
val prompt = prompt("prompt_name", LLMParams()) {
    // Add a system message to set the context
    system("You are a helpful assistant.")

    // Add a user message
    user("Tell me about Kotlin")

    // You can also add assistant messages for few-shot examples
    assistant("Kotlin is a modern programming language...")

    // Add another user message
    user("What are its key features?")
}

執行提示

若要使用特定的 LLM 執行提示,您需要執行以下操作:

  1. 建立一個對應的 LLM 用戶端,用於處理應用程式與 LLM 供應商之間的連線。例如:
kotlin
// Create an OpenAI client
val client = OpenAILLMClient(apiKey)
  1. 呼叫 execute 方法,並以提示和 LLM 作為引數。
kotlin
// Execute the prompt
val response = client.execute(
    prompt = prompt,
    model = OpenAIModels.Chat.GPT4o  // You can choose different models
)

以下 LLM 用戶端可用:

以下是一個使用提示 API 的簡單範例:

kotlin

fun main() {
    runBlocking {
        // Set up the OpenAI client with your API key
        val token = System.getenv("OPENAI_API_KEY")
        val client = OpenAILLMClient(token)

        // Create a prompt
        val prompt = prompt("prompt_name", LLMParams()) {
            // Add a system message to set the context
            system("You are a helpful assistant.")

            // Add a user message
            user("Tell me about Kotlin")

            // You can also add assistant messages for few-shot examples
            assistant("Kotlin is a modern programming language...")

            // Add another user message
            user("What are its key features?")
        }

        // Execute the prompt and get the response
        val response = client.execute(prompt = prompt, model = OpenAIModels.Chat.GPT4o)
        println(response)
    }
}

重試功能

在使用 LLM 供應商時,您可能會遇到暫時性錯誤,例如速率限制或暫時性服務不可用。RetryingLLMClient 裝飾器會為任何 LLM 用戶端新增自動重試邏輯。

基本用法

將任何現有的用戶端包裝上重試功能:

kotlin
// Wrap any client with retry capability
val client = OpenAILLMClient(apiKey)
val resilientClient = RetryingLLMClient(client)

// Now all operations will automatically retry on transient errors
val response = resilientClient.execute(prompt, OpenAIModels.Chat.GPT4o)

配置重試行為

Koog 提供多種預設重試配置:

配置最大嘗試次數初始延遲最大延遲使用案例
DISABLED1 (不重試)--開發/測試
CONSERVATIVE32秒30秒正常生產用途
AGGRESSIVE5500毫秒20秒關鍵操作
PRODUCTION31秒20秒推薦預設值

直接使用它們,或建立自訂配置:

kotlin
// Use predefined configuration
val conservativeClient = RetryingLLMClient(
    delegate = client,
    config = RetryConfig.CONSERVATIVE
)

// Or create custom configuration
val customClient = RetryingLLMClient(
    delegate = client,
    config = RetryConfig(
        maxAttempts = 5,
        initialDelay = 1.seconds,
        maxDelay = 30.seconds,
        backoffMultiplier = 2.0,
        jitterFactor = 0.2
    )
)

可重試錯誤模式

預設情況下,重試機制會識別常見的暫時性錯誤:

  • HTTP 狀態碼:429 (速率限制)、500、502、503、504
  • 錯誤關鍵字:「速率限制」、「逾時」、「連線重設」、「過載」

您可以針對您的特定需求定義自訂模式:

kotlin
val config = RetryConfig(
    retryablePatterns = listOf(
        RetryablePattern.Status(429),           // 特定狀態碼
        RetryablePattern.Keyword("quota"),      // 錯誤訊息中的關鍵字
        RetryablePattern.Regex(Regex("ERR_\\d+")), // 自訂正規表示式模式
        RetryablePattern.Custom { error ->      // 自訂邏輯
            error.contains("temporary") && error.length > 20
        }
    )
)

搭配提示執行器使用重試

使用提示執行器時,請在建立執行器之前包裝底層用戶端:

kotlin
// 帶有重試功能的單一供應商執行器
val resilientClient = RetryingLLMClient(
    OpenAILLMClient(System.getenv("OPENAI_API_KEY")),
    RetryConfig.PRODUCTION
)
val executor = SingleLLMPromptExecutor(resilientClient)

// 帶有靈活用戶端配置的多供應商執行器
val multiExecutor = MultiLLMPromptExecutor(
    LLMProvider.OpenAI to RetryingLLMClient(
        OpenAILLMClient(System.getenv("OPENAI_API_KEY")),
        RetryConfig.CONSERVATIVE
    ),
    LLMProvider.Anthropic to RetryingLLMClient(
        AnthropicLLMClient(System.getenv("ANTHROPIC_API_KEY")),
        RetryConfig.AGGRESSIVE  
    ),
    // Bedrock 用戶端已內建 AWS SDK 重試
    LLMProvider.Bedrock to BedrockLLMClient(
        awsAccessKeyId = System.getenv("AWS_ACCESS_KEY_ID"),
        awsSecretAccessKey = System.getenv("AWS_SECRET_ACCESS_KEY"),
        awsSessionToken = System.getenv("AWS_SESSION_TOKEN"),
    ))

搭配重試進行串流

串流操作可以選擇重試 (預設為停用):

kotlin
val config = RetryConfig(
    maxAttempts = 3
)

val client = RetryingLLMClient(baseClient, config)
val stream = client.executeStreaming(prompt, OpenAIModels.Chat.GPT4o)

注意:串流重試僅適用於在收到第一個 Token 之前的連線失敗。一旦串流開始,錯誤將直接傳遞,以保留內容完整性。

逾時設定

所有 LLM 用戶端都支援逾時設定,以防止掛起請求:

kotlin
val client = OpenAILLMClient(
    apiKey = apiKey,
    settings = OpenAIClientSettings(
        timeoutConfig = ConnectionTimeoutConfig(
            connectTimeoutMillis = 5000,    // 5 秒鐘以建立連線
            requestTimeoutMillis = 60000    // 60 秒鐘以完成整個請求
        )
    )
)

錯誤處理最佳實踐

在生產環境中處理 LLM 時:

  1. 始終將操作包裝在 try-catch 區塊中,以處理意外錯誤
  2. 記錄帶有上下文的錯誤,用於偵錯
  3. 實作備用策略,用於關鍵操作
  4. 監控重試模式,以識別系統性問題

全面錯誤處理範例:

kotlin
try {
    val response = resilientClient.execute(prompt, model)
    processResponse(response)
} catch (e: Exception) {
    logger.error("LLM operation failed", e)
    
    when {
        e.message?.contains("rate limit") == true -> {
            // 專門處理速率限制
            scheduleRetryLater()
        }
        e.message?.contains("invalid api key") == true -> {
            // 處理身份驗證錯誤
            notifyAdministrator()
        }
        else -> {
            // 退回到替代解決方案
            useDefaultResponse()
        }
    }
}

多模態輸入

除了在提示中提供文字訊息外,Koog 還允許您在 user 訊息中向 LLM 傳送圖像、音訊、視訊和檔案。與標準的純文字提示一樣,您也可以使用提示建構的 DSL 結構將媒體新增至提示中。

kotlin
val prompt = prompt("multimodal_input") {
    system("You are a helpful assistant.")

    user {
        +"Describe these images"

        attachments {
            image("https://example.com/test.png")
            image(Path("/User/koog/image.png"))
        }
    }
}

文字提示內容

為了支援各種附件類型,並在提示中明確區分文字和檔案輸入,您將文字訊息放入使用者提示中專用的 content 參數中。若要新增檔案輸入,請將其作為列表提供給 attachments 參數。

包含文字訊息和附件列表的使用者訊息的一般格式如下:

kotlin
user(
    content = "This is the user message",
    attachments = listOf(
        // Add attachments
    )
)

檔案附件

若要包含附件,請在 attachments 參數中提供檔案,格式如下:

kotlin
user(
    content = "Describe this image",
    attachments = listOf(
        Attachment.Image(
            content = AttachmentContent.URL("https://example.com/capture.png"),
            format = "png",
            mimeType = "image/png",
            fileName = "capture.png"
        )
    )
)

attachments 參數接受檔案輸入的列表,其中每個項目都是以下類別之一的實例:

  • Attachment.Image: 圖像附件,例如 jpgpng 檔案。
  • Attachment.Audio: 音訊附件,例如 mp3wav 檔案。
  • Attachment.Video: 視訊附件,例如 mpgavi 檔案。
  • Attachment.File: 檔案附件,例如 pdftxt 檔案。

上述每個類別都接受以下參數:

名稱資料類型必填說明
contentAttachmentContent提供的檔案內容來源。有關更多資訊,請參閱 AttachmentContent
formatString提供的檔案格式。例如,png
mimeTypeString僅限 Attachment.File提供的檔案 MIME 類型。例如,image/png
fileNameString提供的檔案名稱,包括副檔名。例如,screenshot.png

AttachmentContent

AttachmentContent 定義了作為 LLM 輸入提供的內容的類型和來源。支援以下類別:

AttachmentContent.URL(val url: String)

從指定的 URL 提供檔案內容。接受以下參數:

名稱資料類型必填說明
urlString提供的內容 URL。

AttachmentContent.Binary.Bytes(val data: ByteArray)

以位元組陣列形式提供檔案內容。接受以下參數:

名稱資料類型必填說明
dataByteArray以位元組陣列形式提供的檔案內容。

AttachmentContent.Binary.Base64(val base64: String)

提供編碼為 Base64 字串的檔案內容。接受以下參數:

名稱資料類型必填說明
base64String包含檔案資料的 Base64 字串。

AttachmentContent.PlainText(val text: String)

僅適用於附件類型為 Attachment.File。從純文字檔案(例如 text/plain MIME 類型)提供內容。接受以下參數:

名稱資料類型必填說明
textString檔案內容。

混合附件內容

除了在單獨的提示或訊息中提供不同類型的附件外,您還可以在單一 user 訊息中提供多種和混合類型的附件,如下所示:

kotlin
val prompt = prompt("mixed_content") {
    system("You are a helpful assistant.")

    user {
        +"Compare the image with the document content."

        attachments {
            image(Path("/User/koog/page.png"))
            binaryFile(Path("/User/koog/page.pdf"), "application/pdf")
        }
    }
}

提示執行器

雖然 LLM 用戶端提供對供應商的直接存取,但 提示執行器 提供更高層次的抽象,可簡化常見的使用案例並處理用戶端生命週期管理。當您希望達成以下目標時,它們是理想的選擇:

  • 快速建立原型,而無需管理用戶端配置
  • 透過統一介面與多個供應商協同運作
  • 在大型應用程式中簡化依賴注入
  • 抽象化供應商特定細節

執行器類型

Koog 框架提供多種提示執行器:

  • 單一供應商執行器

    • simpleOpenAIExecutor:用於執行 OpenAI 模型的提示。
    • simpleAnthropicExecutor:用於執行 Anthropic 模型的提示。
    • simpleGoogleExecutor:用於執行 Google 模型的提示。
    • simpleOpenRouterExecutor:用於執行 OpenRouter 的提示。
    • simpleOllamaExecutor:用於執行 Ollama 的提示。
  • 多供應商執行器

    • DefaultMultiLLMPromptExecutor:用於處理多個 LLM 供應商

建立單一供應商執行器

若要為特定的 LLM 供應商建立提示執行器,請使用對應的函數。例如,若要建立 OpenAI 提示執行器,您需要呼叫 simpleOpenAIExecutor 函數,並提供與 OpenAI 服務驗證所需的 API 金鑰:

  1. 建立提示執行器:
kotlin
// Create an OpenAI executor
val promptExecutor = simpleOpenAIExecutor(apiToken)
  1. 使用特定的 LLM 執行提示:
kotlin
// Execute a prompt
val response = promptExecutor.execute(
    prompt = prompt,
    model = OpenAIModels.Chat.GPT4o
).single()

建立多供應商執行器

若要建立可與多個 LLM 供應商協同運作的提示執行器,請執行以下操作:

  1. 配置所需 LLM 供應商的用戶端,並提供對應的 API 金鑰。例如:
kotlin
val openAIClient = OpenAILLMClient(System.getenv("OPENAI_KEY"))
val anthropicClient = AnthropicLLMClient(System.getenv("ANTHROPIC_KEY"))
val googleClient = GoogleLLMClient(System.getenv("GOOGLE_KEY"))
  1. 將已配置的用戶端傳遞給 DefaultMultiLLMPromptExecutor 類別建構函式,以建立一個具有多個 LLM 供應商的提示執行器:
kotlin
val multiExecutor = DefaultMultiLLMPromptExecutor(openAIClient, anthropicClient, googleClient)
  1. 使用特定的 LLM 執行提示:
kotlin
val response = multiExecutor.execute(
    prompt = prompt,
    model = OpenAIModels.Chat.GPT4o
).single()