Logo
Published on

第一次學 Kotlin Koog AI 就上手 Day 33:自定義 AI 模型設定:支援最新模型

在前一篇文章中,我們學習了歷史記錄壓縮技術,有效控制了對話上下文的長度和成本。隨著我們掌握越來越多 Koog 框架的進階功能,現在來到了系列文章的倒數第二篇,讓我們探討一個在實務應用中極為重要的主題:自定義 AI 模型設定

在快速發展的 AI 領域中,新的語言模型不斷推出,但框架的支援往往需要一些時間才能跟上。當 OpenAI 釋出全新的 GPT-5 系列模型,或是企業需要使用特殊的模型端點時,我們不能只是等待官方更新。今天我們要學習如何在 Koog 中自定義模型設定,讓你的 AI 應用能夠第一時間支援最新的模型技術,並根據不同的 context window 限制來搭配昨天學到的歷史壓縮策略

為什麼需要自定義模型設定

當新的 AI 模型釋出時,開發者通常面臨以下挑戰

時間差問題

  • 新模型釋出後,框架更新需要時間
  • 開發者想要立即體驗新模型的功能
  • 等待官方支援可能錯過最佳使用時機

特殊需求

  • 某些企業可能有自訂的模型端點
  • 需要特殊的能力配置組合
  • 想要微調模型的參數設定

GPT-5 系列模型自定義設定

OpenAI 在八月釋出了 GPT-5 系列模型,包含以下主要的型號

  • gpt-5:旗艦版本,專為複雜推理和高難度任務設計
  • gpt-5-mini:輕量級推理版本,提供成本優化和較低延遲
  • gpt-5-nano:最快速的變體,專為開發工具和低延遲環境優化

讓我們來看看如何在 Koog 中配置新模型,基本上,所有的模型都是一樣,依此類推,重點在於 LLMCapability 的部份

val gpt5 = LLModel(
    provider = LLMProvider.OpenAI,
    id = "gpt-5",
    capabilities = listOf(
        LLMCapability.Temperature,
        LLMCapability.Tools,
        LLMCapability.Schema.JSON.Full,
        // 看需要什麼能力,就加上就好
    )
)

深入了解 LLMCapability

LLMCapability 定義了模型支援的各種功能,讓我們詳細了解每種能力

核心能力

  • Speculation

    • 推測性回應功能,用於探索性或假設性場景
    • 適合需要創意或非確定性答案的情況
    • LLMCapability.Speculation
  • Temperature

    • 控制輸出的隨機性和創意程度
    • 較高的溫度值產生更多樣化的輸出,較低值則更聚焦和確定
    • LLMCapability.Temperature
  • Tools

    • 支援工具呼叫功能,允許模型與外部系統互動
    • 可執行特定工具或整合外部系統
    • LLMCapability.Tools
  • ToolChoice

    • 配置工具呼叫的行為方式
    • 可設定自動選擇、僅工具呼叫、僅文字輸出或強制呼叫特定工具
    • LLMCapability.ToolChoice
  • Completion

    • 文字完成和內容生成能力
    • 用於完成句子、生成建議或產生符合上下文的內容
    • LLMCapability.Completion

結構化資料處理

  • JSON Schema 支援
    • 簡化 JSON 支援(輕量級或基本處理)
      • LLMCapability.Schema.JSON.Simple
    • 完整 JSON 支援(全功能)
      • LLMCapability.Schema.JSON.Full

多模態能力

  • 視覺處理

    • 圖片分析和處理
      • LLMCapability.Vision.Image
    • 影片處理功能
      • LLMCapability.Vision.Video
  • 音訊處理

    • 音訊轉錄、生成或音訊互動
    • LLMCapability.Audio
  • 文件處理

    • 文件相關功能處理
    • LLMCapability.Document

進階功能

  • 多重選擇

    • 對單一提示生成多個獨立回覆選項
    • LLMCapability.MultipleChoices
  • 提示快取

    • 支援快取功能,提升效能和降低成本
    • LLMCapability.PromptCaching
  • 內容審核

    • 分析文字中的潛在有害內容
    • 可分類騷擾、仇恨言論、自我傷害、性內容、暴力等
    • LLMCapability.Moderation
  • 向量嵌入

    • 生成文字的向量表示,支援語意搜尋和相似性比較
    • LLMCapability.Embed

結構化資料處理實作範例

讓我們用一個天氣預報的範例來展示如何使用自定義模型處理結構化資料

定義資料結構

@Serializable
@SerialName("WeatherForecast")
data class WeatherForecast(
    @property:LLMDescription("攝氏溫度")
    val temperature: Int,

    @property:LLMDescription("天氣狀況描述,例如:晴朗、多雲、下雨")
    val conditions: String,

    @property:LLMDescription("降雨機率,範圍 0-100")
    val rainChance: Int,

    @property:LLMDescription("建議穿著")
    val clothingRecommendation: String,

    @property:LLMDescription("紫外線指數,範圍 0-11")
    val uvIndex: Int
)

實作範例

suspend fun main() {

    // 建立自定義的 GPT-5 模型配置
    val customGPT5 = LLModel(
        provider = LLMProvider.OpenAI,
        id = "gpt-5-mini",
        capabilities = listOf(
            LLMCapability.Temperature,
            LLMCapability.Tools,
            LLMCapability.Schema.JSON.Simple,
            LLMCapability.PromptCaching,
            LLMCapability.Completion
        )
    )

    // 建立執行器
    val executor = simpleOpenAIExecutor(ApiKeyManager.openAIApiKey!!)

    // 產生結構化資料定義
    val weatherStructure = JsonStructuredData.createJsonStructure<WeatherForecast>(
        schemaFormat = JsonSchemaGenerator.SchemaFormat.JsonSchema,
        schemaType = JsonStructuredData.JsonSchemaType.SIMPLE,
    )

    // 執行結構化查詢
    val forecast = executor.executeStructured(
        prompt = prompt("weather-forecast") {
            system(
                """
                你是一位專業的天氣預報員。
                請根據用戶提供的城市,提供詳細的天氣預報。
                請確保所有數值都在合理範圍內。
                (為了測試需要,請給我相關的假天氣資料)
                """.trimIndent()
            )
            user("請提供台北市明天的天氣預報")
        },
        mainModel = customGPT5,
        structure = weatherStructure,
        retries = 3
    )

    // 處理結果
    forecast.fold(
        onSuccess = { response ->
            val weatherData = response.structure
            println("天氣預報資訊:")
            println("溫度:${weatherData.temperature}°C")
            println("天氣狀況:${weatherData.conditions}")
            println("降雨機率:${weatherData.rainChance}%")
            println("穿著建議:${weatherData.clothingRecommendation}")
            println("紫外線指數:${weatherData.uvIndex}")
        },
        onFailure = { error ->
            println("取得天氣預報失敗:${error.message}")
        }
    )
}

執行 AI 回應內容

天氣預報資訊:
溫度:28°C
天氣狀況:多雲午後短暫陣雨
降雨機率:40%
穿著建議:建議穿著輕薄短袖並備雨具,傍晚外出可帶薄外套
紫外線指數:8

文件讀取的問題

還記得 Day 11:讓 AI 讀懂文件:文件內容處理 當時執行文件讀取時,發生了 model 錯誤 的問題,現在我們可以自訂 model 了,就可以自己先 fix 這個問題

可以建立一個自己的 Gemini 2.5 Flash 模型,記得要加上 LLMCapability.Document 讀文件的能力,然後把原本使用的模型換掉就好了

val geminiFlash = LLModel(
    provider = LLMProvider.Google,
    id = "gemini-2.5-flash",
    capabilities = listOf(
        LLMCapability.Schema.JSON.Simple,
        LLMCapability.Completion,
        LLMCapability.Document,
    )
)

執行 AI 回應內容

相關的程式碼、問題,可以回去參考之前的文章

=== PDF 文件摘要 ===
這份文件摘要如下:

1.  **主要主題和目的**
    這份文件主要報導AI搜尋引擎Perplexity向Google提出一項出人意料的收購要約,旨在以345億美元現金購買其Chrome瀏覽器。其目的在於揭露這項重磅提案的細節、背後由美國司法部反壟斷裁決所衍生的背景,以及Perplexity的策略考量。

2.  **核心內容概述**
    Perplexity的收購條件包括承諾維持Chrome底層的Chromium引擎開源,並投資30億美元於該開源專案,同時將Google保留為Chrome的預設搜尋引擎。這項提案發生在美國司法部建議強制Google出售Chrome,以解決其在線上搜尋市場壟斷行為之後。儘管Google正對此裁決提出上訴,但包括OpenAI在內的多家公司已對收購Chrome表達興趣。Perplexity的出價遠超其自身180億美元的估值和迄今募資的15億美元。此外,Perplexity近期亦推出了自家瀏覽器Comet,並曾傳出競標TikTok。

3.  **重要結論或建議**
    Perplexity的這項大膽收購提案,顯示其正試圖利用Google面臨的反壟斷壓力,進軍瀏覽器市場並擴大其AI搜尋業務的影響力。如果法院最終裁定Google必須剝離Chrome,預計將引發全球科技公司的激烈競標,而Perplexity的出價對比Chrome的預估價值而言,可能被視為一個潛在的划算交易。

=== 文字文件關鍵要點 ===
以下是從文件中提取的 7 個最重要的關鍵要點:

*   AI 搜尋引擎 Perplexity 已向 Google 提出 345 億美元現金的非請自來報價,欲收購 Chrome 瀏覽器。
*   此舉是因應美國司法部建議 Google 應被強制出售 Chrome,此前一名法官裁定 Google 透過非法行為維持線上搜尋壟斷。
*   Perplexity 的出價遠高於其迄今籌集的資金(約 15 億美元)和目前估值(180 億美元)。
*   Perplexity 承諾保持 Chrome 的底層引擎 Chromium 開源,並將投資 30 億美元於此項目。
*   Perplexity 同意不更改 Chrome 用戶的預設設定,包括維持 Google 為預設搜尋引擎。
*   Chrome 是市場主導瀏覽器,市佔率高達 68%,使其成為極具價值的資產。
*   Perplexity 最近動作頻頻,包括上月推出自己的瀏覽器 Comet,並據報曾競標與 TikTok 合併。

=== Markdown 文件結構分析 ===
這份文件是一篇**新聞報導/科技新聞文章**。它的性質是即時、資訊性、報導一項重要的商業/科技動態,並提供相關背景和分析。

以下是針對其結構和組織方式的詳細分析:

### 1. 文件類型和性質

*   **文件類型:** 科技新聞報導 (Tech News Article) 或商業新聞報導 (Business News Report)*   **性質:**
    *   **即時性 (Timely):** 報導Perplexity對Google Chrome提出收購要約的最新消息。
    *   **資訊性 (Informative):** 提供收購金額、條款、相關背景(如美國司法部的反壟斷訴訟)、Perplexity的財務狀況等資訊。
    *   **事實性 (Factual):** 引用路透社、TechCrunch的確認、Statcounter的市場份額數據、PitchBook的融資估計以及彭博社的報導作為消息來源。
    *   **分析性 (Analytical, partially):** 透過對比Perplexity的報價與其自身估值、Chrome的潛在價值,提供一定程度的洞察。

### 2. 主要章節或段落結構

該文章沒有明確的章節標題,但可以根據內容將其劃分為以下邏輯段落:

*   **引言 (Introduction / Lead Paragraph):**
    *   第一段:直接點出核心新聞——Perplexity提出以345億美元收購Chrome的「月球射擊」(moonshot) 舉動,並確認消息來源。
*   **要約細節 (Offer Details):**
    *   第二段:詳述要約條款1——承諾保持Chromium開源並投入30億美元。
    *   第三段:詳述要約條款2——承諾不改變Chrome用戶預設設定(包括預設搜尋引擎)。
*   **即時回應 (Immediate Reaction):**
    *   第四段:Google對此要約尚未回應。
*   **背景與動機 (Background & Context):**
    *   第五段:解釋此收購提議的背景——美國司法部提議Google出售Chrome,

=== 問答 ===
根據這份文件,文中沒有提及任何與 Apple 有關的資訊。

總結

透過本篇文章的學習,我們掌握了 Koog 框架中自定義 AI 模型設定的完整技能。這項能力讓我們能夠快速適應 AI 技術的快速發展,不受框架更新速度的限制

  • 立即支援新模型:不需等待框架更新就能使用最新的 AI 模型(如 GPT-5 系列)
  • 精確控制功能:透過 LLMCapability 精確配置模型的各種能力
  • 優化效能與成本:根據 contextLength 和 maxOutputTokens 選擇最適合的模型參數
  • 靈活應對變化:快速調整配置以適應不同的使用場景和業務需求

明天我們將迎來這個系列的完結篇,回顧整個 33 天的學習旅程,總結 Koog 框架的核心優勢和最佳實踐,並展望 AI Agent 開發的未來趨勢

參考文件


支持創作

如果這篇文章對您有幫助,歡迎透過 贊助連結 支持我持續創作優質內容。您的支持是我前進的動力!


圖片來源:AI 產生