- Published on
第一次學 Kotlin Koog AI 就上手 Day 04:多 LLM 供應商整合
在前面的學習中,我們已經建立了基本的 Koog AI Agent 並了解了提示系統的 DSL 語法。今天我們將探索 Koog 框架的重要特色:多 LLM 供應商整合
在實際應用中,依賴單一 LLM 供應商往往會面臨成本、效能和可靠性的挑戰。Koog 的多供應商支援讓我們能夠建立更穩健和更靈活的 AI 應用
為什麼需要多 LLM 整合?
在深入技術實作之前,讓我們先了解多 LLM 整合的重要性
能力互補優勢
每個 LLM 供應商都有其擅長領域,根據實際使用經驗,不同供應商適合不同的使用場景
實際使用場景分配
- OpenAI:日常使用、通用對話、問答互動
- Anthropic:程式設計、技術問題解決
- Google Gemini:大 Context 處理、處理大量資料、長文本分析
- 本地 Ollama:隱私保護、離線運行、無 API 限制
這裡的使用場景是根據我平常的使用習慣來區分的
可靠性和風險管控
多 LLM 策略可以顯著提升應用穩定性
實際效益
- 故障備用:當主要供應商服務中斷時,自動切換到備用供應商
- 過載分散:在高併發時段分散請求到多個供應商
- 限制管理:避免觸發單一供應商的 API 限制
- 成本控制:根據預算限制智能選擇模型
支援的 LLM 供應商
Koog 目前支援以下 LLM 供應商
模型選擇說明:每個 LLM 供應商都有眾多模型可選擇,不可能在文章中一一列出和介紹。這裡我只列舉比較常用或 CP 值比較高的模型作為範例,實際使用時請根據個人需求、預算和應用場景來選擇最適合的模型
雲端服務供應商
- OpenAI
- GPT-5 (mini)(2025年8月發布,最新模型)
- GPT-4.1 (mini)(2025年4月發布)
- 日常對話、問題解決
重要說明:雖然 GPT-5 是 OpenAI 最新的模型,但因為 Koog 框架還沒有更新相關的 model 程式碼支援,所以統一使用 GPT-4.1 (mini),包含先前的文章也是一樣
Anthropic
- Claude Opus 4.1(2025年8月發布,最新模型)
- Claude 4 Sonnet(程式設計專長)
- 優秀的程式碼設計、寫作能力
Google AI
- Gemini 2.5 Flash(2025年發布,支援 thinking 能力)
- 強大的多模態能力和大 Context 處理
OpenRouter
- 統一接入多種模型
- 自動路由和負載均衡
- 包含開源模型支援
本地部署
- Ollama
- gpt-oss:20b(OpenAI 2025年開源模型,16GB RAM 即可運行)
- Llama 3.1、Llama 3.2
- Code Llama、Mistral
- 完全離線運行
這裡只有列出部份支援的 LLM 供應商而已, 沒有全部
基本多供應商配置
IntelliJ IDEA 環境變數配置
注意:基於 API 測試費用考量,本教學僅使用兩個雲端 API(OpenAI、Google)和本地模型(Ollama)進行測試
在 IntelliJ IDEA 中設定環境變數(參考 Day 02 的設定方式)
- 編輯 Run Configuration
- 在
Environment variables
欄位中加入
OPENAI_API_KEY=你的OpenAI API金鑰
GOOGLE_API_KEY=你的Google API金鑰
OLLAMA_BASE_URL=http://localhost:11434
管理 Api Key 類別
object ApiKeyManager {
val openAIApiKey: String = System.getenv("OPENAI_API_KEY")
val googleApiKey: String = System.getenv("GOOGLE_API_KEY")
val ollamaBaseUrl: String = System.getenv("OLLAMA_BASE_URL")
// 檢查可用的供應商
fun getAvailableProviders(): List<String> {
val available = mutableListOf<String>()
if (openAIApiKey.isNotBlank()) {
available.add("OpenAI")
}
if (googleApiKey.isNotBlank()) {
available.add("Google")
}
if (ollamaBaseUrl.isNotBlank()) {
available.add("Ollama")
}
return available
}
}
建立多 LLM 執行器
Koog 提供了 MultiLLMPromptExecutor
來統一管理多個 LLM 客戶端
class BasicMultiLLMSetup {
fun createBasicMultiExecutor(): MultiLLMPromptExecutor {
val executors = mutableMapOf<LLMProvider, LLMClient>()
ApiKeyManager.openAIApiKey?.let { apiKey ->
executors[LLMProvider.OpenAI] = OpenAILLMClient(apiKey)
println("✅ OpenAI GPT 執行器已加入(大 Context 處理)")
}
ApiKeyManager.googleApiKey?.let { apiKey ->
executors[LLMProvider.Google] = GoogleLLMClient(apiKey)
println("✅ Google Gemini 執行器已加入(大 Context 處理)")
}
ApiKeyManager.ollamaBaseUrl?.let { baseUrl ->
executors[LLMProvider.Ollama] = OllamaClient(baseUrl)
println("✅ Ollama 執行器已加入(本地隱私保護)")
}
return MultiLLMPromptExecutor(executors)
}
}
實作基本多 LLM 應用
讓我們建立一個簡單的多 LLM 應用,展示基本的整合使用
suspend fun main() {
println("🤖 多 LLM 助手系統啟動中...")
// 顯示可用的供應商
println("📋 可用的 LLM 供應商:")
ApiKeyManager.getAvailableProviders().forEach { provider ->
println(" ✅ $provider")
}
try {
val setup = BasicMultiLLMSetup()
val multiExecutor = setup.createBasicMultiExecutor()
// 建立多 LLM Agent
val agent = AIAgent(
executor = multiExecutor,
systemPrompt = "你是一個智能助手,使用多個 LLM 供應商為使用者提供最佳服務。請用正體中文回答問題。",
llmModel = OpenAIModels.CostOptimized.GPT4_1Mini
)
println("\n✅ 多 LLM 助手系統已就緒!")
// 測試不同類型的問題
val testQuestions = listOf(
"你好,你現在正在使用哪個模型回答問題? 請具體回答出那一個模型"
)
println("\n👤 使用者:$question")
println("🤖 AI 回答:")
val response = agent.run(question)
println(response)
} catch (e: Exception) {
println("❌ 系統啟動失敗:${e.message}")
e.printStackTrace()
}
}
執行 AI 回應內容
基本上,這裡會根據你給它的 Model
來決定使用哪個 Executor
(供應商) 先使用 OpenAIModels.CostOptimized.GPT4_1Mini
來執行測試
🤖 多 LLM 助手系統啟動中...
📋 可用的 LLM 供應商:
✅ OpenAI (GPT-4.1 mini)
✅ Google (Gemini 2.5 Flash)
✅ Ollama (gpt-oss:20b)
✅ OpenAI GPT 執行器已加入(大 Context 處理)
✅ Google Gemini 執行器已加入(大 Context 處理)
✅ Ollama 執行器已加入(本地隱私保護)
✅ 多 LLM 助手系統已就緒!
👤 使用者:你好,你現在正在使用哪個模型回答問題? 請具體回答出那一個模型
🤖 AI 回答:
你好!我目前使用的是OpenAI的GPT-4模型來回答你的問題。如果你有任何需要,隨時告訴我!
如果我們把 Model
換成 GoogleModels.Gemini2_5Flash
🤖 多 LLM 助手系統啟動中...
📋 可用的 LLM 供應商:
✅ OpenAI
✅ Google
✅ Ollama
✅ OpenAI GPT 執行器已加入(大 Context 處理)
✅ Google Gemini 執行器已加入(大 Context 處理)
✅ Ollama 執行器已加入(本地隱私保護)
✅ 多 LLM 助手系統已就緒!
👤 使用者:你好,你現在正在使用哪個模型回答問題? 請具體回答出那一個模型
🤖 AI 回答:
你好!
我是一個大型語言模型,由 Google 訓練。
自動依任務選擇模型
在前面的範例,雖然 AIAgent
會自動根據模型來選擇 Executor
,不過還是需要寫死模型在程式碼裡面,我們是不是可以改成,自動根據任務類型來選擇合適的模型,這樣子就不用人工介入了
建立多供應商模型選擇
在 BasicMultiLLMSetup
裡增加一個依 task 來選擇模型的 fun
注意,這裡沒有考慮到 AI 供應商是否可用的問題,只是單純的選擇模型
// 簡單的供應商模型選擇
fun selectModelForTask(taskType: String): LLModel {
return when (taskType.lowercase()) {
// 日常對話的最佳選擇
"chat", "conversation" -> OpenAIModels.CostOptimized.GPT4_1Mini
// 大 Context 資料處理(
"data", "analysis" -> GoogleModels.Gemini2_5Flash
// Ollama
"privacy", "local" -> OllamaModels.Meta.LLAMA_3_2_3B
// 通用任務的平衡選擇
else -> OpenAIModels.CostOptimized.GPT4_1Mini
}
}
建立自動依 task 來產生 AI Agent
可以把相關對應 task 的 prompt 都先寫好,只要使用者輸入對應的 task,就會自動給它對應的 AI Agent
class BasicMultiLLMAssistant {
private val multiLLMSetup = BasicMultiLLMSetup()
fun createAgent(taskType: String): AIAgent<String, String> {
val multiExecutor = multiLLMSetup.createBasicMultiExecutor()
val modelSuggestion = multiLLMSetup.selectModelForTask(taskType)
println("Task: $taskType, 🎯 模型:${model.provider} - ${model.id}")
return AIAgent(
executor = multiExecutor,
systemPrompt = buildTaskPrompt(taskType),
llmModel = modelSuggestion,
maxIterations = 5
)
}
private fun buildTaskPrompt(taskType: String): String {
return when (taskType.lowercase()) {
"chat", "conversation" -> """
你是一個友善的 AI 助手,用正體中文回答問題
- 以自然、溫暖的方式回應
- 提供有用的資訊和建議
- 保持禮貌和專業的態度
""".trimIndent()
"data", "analysis" -> """
你是一個資料分析助手,用正體中文回答問題
- 仔細分析提供的大量資訊
- 提供結構化的分析結果
- 善於處理複雜的資料和長文本
""".trimIndent()
"privacy", "local" -> """
你是一個注重隱私的本地助手,用正體中文回答問題
- 優先保護使用者隱私
- 提供安全可靠的建議
- 不會將資料傳送到外部服務
""".trimIndent()
else -> """
你是一個通用 AI 助手,用正體中文回答問題
- 根據使用者需求提供協助
- 保持專業和有用的回應
- 適時詢問更多細節以提供更好的服務
""".trimIndent()
}
}
}
測試依 task 來自動選擇 AI Agent
建立一個簡單的測試程式來驗證多 LLM 設定
suspend fun main() {
println("🤖 多 LLM 助手系統啟動中...")
// 顯示可用的供應商
println("📋 可用的 LLM 供應商:")
ApiKeyManager.getAvailableProviders().forEach { provider ->
println(" ✅ $provider")
}
try {
val setup = BasicMultiLLMAssistant()
println("\n✅ 多 LLM 助手系統已就緒!")
// 顯示可用的任務類型
println("\n📋 可用的任務類型:")
println(" 1. chat - 日常對話")
println(" 2. data - 資料分析")
println(" 3. privacy - 隱私保護(本地處理)")
// 使用者輸入任務類型
print("\n請輸入任務類型(chat/data/privacy):")
val taskType = readlnOrNull()?.trim() ?: "chat"
// 建立對應的 Agent
val agent = setup.createAgent(taskType)
// 使用者輸入問題
print("請輸入您的問題:")
val question = "你好,你現在正在使用哪個模型回答問題? 請具體回答出那一個模型"
println("\n👤 使用者:$question")
println("🤖 AI 回答:")
val response = agent.run(question)
println(response)
} catch (e: Exception) {
println("❌ 系統啟動失敗:${e.message}")
e.printStackTrace()
}
}
執行 AI 回應內容
🤖 多 LLM 助手系統啟動中...
📋 可用的 LLM 供應商:
✅ OpenAI
✅ Google
✅ Ollama
✅ 多 LLM 助手系統已就緒!
📋 可用的任務類型:
1. chat - 日常對話
2. data - 資料分析
3. privacy - 隱私保護(本地處理)
請輸入任務類型(chat/data/privacy):chat
✅ OpenAI GPT 執行器已加入(大 Context 處理)
✅ Google Gemini 執行器已加入(大 Context 處理)
✅ Ollama 執行器已加入(本地隱私保護)
Task: chat, 🎯 模型:OpenAI - gpt-4.1-mini
請輸入您的問題:
👤 使用者:你好,你現在正在使用哪個模型回答問題? 請具體回答出那一個模型
🤖 AI 回答:
你好!我現在是基於 OpenAI 的 GPT-4 模型來回答你的問題。如果你有任何疑問或需要幫助,隨時告訴我哦!很高興為你服務。
實作錯誤處理與 Fallback 機制
在實際應用中,LLM 供應商可能會遇到服務中斷、API 限制或網路問題。讓我們繼承 BasicMultiLLMSetup
,實作一個簡單實用的 Fallback 機制,當主要供應商失敗時自動切換到備用供應商
這邊接續第一個範例來實作 Fallback 機制,暫不考慮 auto fallback 選擇供應商
建立簡單的 Fallback 系統
class FallbackMultiLLMSetup : BasicMultiLLMSetup() {
// 建立主要和備用執行器
private val primaryExecutor = simpleOpenAIExecutor(ApiKeyManager.openAIApiKey!!)
private val fallbackExecutor = simpleGoogleAIExecutor(ApiKeyManager.googleApiKey!!)
// 定義主要和備用模型
private val primaryModel = OpenAIModels.CostOptimized.GPT4_1Mini
private val fallbackModel = GoogleModels.Gemini2_5Flash
// 簡單的備用機制 - 主要邏輯
suspend fun executeWithFallback(prompt: Prompt): String {
return try {
println("🔄 嘗試使用 OpenAI 供應商...")
val result = primaryExecutor.execute(prompt, primaryModel)
println("✅ OpenAI 供應商回應成功")
// 假設回應格式,實際需要根據框架調整
result.firstOrNull()?.content ?: "無回應內容"
} catch (e: Exception) {
println("❌ OpenAI 供應商失敗:${e.message}")
println("🔄 切換到 Google 備用供應商...")
try {
val fallbackResult = fallbackExecutor.execute(prompt, fallbackModel)
println("✅ Google 供應商回應成功")
fallbackResult.firstOrNull()?.content ?: "無回應內容"
} catch (fallbackError: Exception) {
println("❌ Google 備用供應商也失敗:${fallbackError.message}")
throw Exception("所有 LLM 供應商都無法使用。主要錯誤:${e.message},備用錯誤:${fallbackError.message}")
}
}
}
// 建立簡化的對話介面
fun createSimpleFallbackChat(): SimpleFallbackChat {
return SimpleFallbackChat(this)
}
}
// 簡單的對話包裝器
class SimpleFallbackChat(private val setup: FallbackMultiLLMSetup) {
suspend fun chat(question: String): String {
// 建立簡單的文字提示
val prompt = prompt("fallback-chat") {
system("你是一個通用 AI 助手,用正體中文回答問題")
user(question)
}
return setup.executeWithFallback(prompt)
}
}
測試 Fallback 機制
suspend fun main() {
println("🤖 帶有 Fallback 機制的多 LLM 助手系統啟動中...")
// 顯示可用的供應商
println("📋 可用的 LLM 供應商:")
ApiKeyManager.getAvailableProviders().forEach { provider ->
println(" ✅ $provider")
}
try {
val setup = FallbackMultiLLMSetup()
println("\n✅ Fallback 多 LLM 助手系統已就緒!")
println("🛡️ 當主要供應商失敗時,系統會自動切換到備用供應商")
// 建立簡化的 Fallback 對話
val chat = setup.createSimpleFallbackChat()
val question = "你好,請介紹你自己,並告訴我你是使用哪個模型回答的?"
println("\n👤 使用者:$question")
println("🤖 AI 回答:")
val response = chat.chat(question)
println(response)
} catch (e: Exception) {
println("❌ 系統完全失敗:${e.message}")
e.printStackTrace()
}
}
執行 AI 回應內容
主要供應商正常運作
🤖 帶有 Fallback 機制的多 LLM 助手系統啟動中...
📋 可用的 LLM 供應商:
✅ OpenAI
✅ Google
✅ Ollama
✅ Fallback 多 LLM 助手系統已就緒!
🛡️ 當主要供應商失敗時,系統會自動切換到備用供應商
👤 使用者:你好,你現在正在使用哪個模型回答問題? 請具體回答出那一個模型
🤖 AI 回答:
🔄 嘗試使用 OpenAI 供應商...
✅ OpenAI 供應商回應成功
你好!我現在使用的是基於 OpenAI 的 GPT-4 架構的語言模型來回答你的問題。
主要供應商失敗,自動 Fallback
透過一個有問題的 OpenAI API Key,來模擬切換供應商
🤖 帶有 Fallback 機制的多 LLM 助手系統啟動中...
📋 可用的 LLM 供應商:
✅ OpenAI (模擬失敗)
✅ Google
✅ Ollama
✅ Fallback 多 LLM 助手系統已就緒!
🛡️ 當主要供應商失敗時,系統會自動切換到備用供應商
👤 使用者:你好,你現在正在使用哪個模型回答問題? 請具體回答出那一個模型
🤖 AI 回答:
🔄 嘗試使用 OpenAI 供應商...
❌ OpenAI 供應商失敗:Error from OpenAI API: 401 Unauthorized: {
"error": {
"message": "Incorrect API key provided: error. You can find your API key at https://platform.openai.com/account/api-keys.",
"type": "invalid_request_error",
"param": null,
"code": "invalid_api_key"
}
}
🔄 切換到 Google 備用供應商...
✅ Google 供應商回應成功
我是一個大型語言模型,由 Google 訓練。
Fallback 機制的優勢
這個 Fallback 實作提供了以下優勢
自動容錯
- 當主要供應商失敗時,無需人工介入即可自動切換
- 保證服務的持續性和可用性
優先級管理
- 可根據成本、效能、可靠性設定供應商優先順序
- 靈活調整不同場景下的選擇策略
透明的錯誤處理
- 清楚記錄每次嘗試和失敗的原因
- 方便除錯和監控系統狀態
成本優化
- 優先使用成本較低的供應商
- 只在必要時才使用較昂貴的備用方案
總結
今天我們學習了 Koog 框架的多 LLM 供應商整合基礎,掌握了以下核心概念
- 了解多 LLM 整合的基本概念和價值
- 學會配置多個 LLM 供應商環境
- 建立簡單的多 LLM 助手應用
- 學會根據任務類型選擇適合的模型
- 掌握錯誤處理和 Fallback 機制的基本概念
下一篇文章我們將探索 Koog 的工具系統入門,學習如何為 AI Agent 添加實際的操作能力,從純粹的對話系統進化為能夠執行具體任務的 AI 助手
參考文件
支持創作
如果這篇文章對您有幫助,歡迎透過 贊助連結 支持我持續創作優質內容。您的支持是我前進的動力!
圖片來源:AI 產生