- Published on
第一次學 Kotlin Koog AI 就上手 Day 07:打造更穩健的 AI:錯誤處理基礎
在前一篇文章中,我們學習了如何調校 AIAgent 的配置參數。但是,即使配置得再完美的 AI 系統,在真實世界中也難免會遇到各種問題:API 金鑰失效、網路連線中斷、服務暫停等。今天我們將學習如何建立基礎的錯誤處理機制,讓你的 AI 應用能夠優雅地應對這些常見問題
為什麼需要錯誤處理?
想像一下以下場景
- 用戶正在與智慧客服機器人對話,突然 API 金鑰過期,系統直接崩潰顯示技術錯誤
- AI 助手正在處理問題,網路連線中斷導致程式拋出異常
如果沒有適當的錯誤處理,這些情況會造成糟糕的用戶體驗。一個具備基礎錯誤處理的 AI 應用應該能夠
預期常見的錯誤情況,提供友善的錯誤訊息,避免程式直接崩潰
Koog 應用中的兩種常見錯誤
API 相關錯誤
最常見的錯誤是 API 金鑰問題或模型不支援
suspend fun main() {
try {
val agent = AIAgent(
// executor = simpleOpenAIExecutor(ApiKeyManager.openAIApiKey!!),
// 使用假的 api key 來模擬錯誤
executor = simpleOpenAIExecutor("fake api key"),
systemPrompt = "你是一個友善的 AI 助手",
llmModel = OpenAIModels.CostOptimized.GPT4_1Mini
)
// 測試是否能正常運作
val result = agent.run("你好")
println("✅ Agent 建立成功:$result")
} catch (e: Exception) {
when {
// API 金鑰相關錯誤
e.message?.contains("api", ignoreCase = true) == true ||
e.message?.contains("key", ignoreCase = true) == true ||
e.message?.contains("auth", ignoreCase = true) == true -> {
println("❌ API 金鑰問題:請檢查您的 API 金鑰是否正確且有效")
}
// 配額相關錯誤
e.message?.contains("quota", ignoreCase = true) == true ||
e.message?.contains("limit", ignoreCase = true) == true -> {
println("⏱️ API 配額已滿:請稍後再試或檢查您的使用配額")
}
// 其他 API 錯誤
else -> {
println("原始錯誤訊息:${e.message}")
println("❓ 無法連接到 AI 服務,請稍後再試")
}
}
}
}
相關的錯誤判斷這裡只是大概的示意,但實際上可能還會有更多細節需要考慮,例如錯誤代碼、錯誤訊息的格式等。請根據實體的情況進行調整。
執行 AI 回應內容
正常情況
✅ Agent 建立成功:你好!很高興見到你,有什麼我可以幫忙的嗎?
使用一個假的 API Key 來模擬錯誤的情況
❌ API 金鑰問題:請檢查您的 API 金鑰是否正確且有效
網路連線錯誤
網路問題也是常見的錯誤來源
suspend fun main() {
val agent = AIAgent(
executor = simpleOpenAIExecutor(ApiKeyManager.openAIApiKey!!),
systemPrompt = "你是一個友善的 AI 助手",
llmModel = OpenAIModels.CostOptimized.GPT4_1Mini
)
try {
// 設定 5 秒超時
withTimeout(5000) {
val result = agent.run("你好")
// delay 6 秒來模擬錯誤的情況
delay(6000)
println("✅ Agent 建立成功:$result")
}
} catch (e: TimeoutCancellationException) {
println("⏰ 回應時間過長,請檢查網路連線後再試")
} catch (e: Exception) {
when {
// 網路連線問題
e.message?.contains("network", ignoreCase = true) == true ||
e.message?.contains("connection", ignoreCase = true) == true ||
e.message?.contains("timeout", ignoreCase = true) == true -> {
println("🌐 網路連線問題,請檢查網路設定後再試")
}
// 服務不可用
e.message?.contains("service", ignoreCase = true) == true ||
e.message?.contains("unavailable", ignoreCase = true) == true -> {
println("🚫 AI 服務暫時不可用,請稍後再試")
}
else -> {
println("網路錯誤詳情:${e.message}") // 開發時用於除錯
println("❓ 處理請求時發生問題,請稍後再試")
}
}
}
}
執行 AI 回應內容
正常情況
✅ Agent 建立成功:你好!很高興見到你,有什麼我可以幫忙的嗎?
使用 delay 來模擬回應時間過長的情況
⏰ 回應時間過長,請檢查網路連線後再試
基礎重試機制
有時候錯誤是暫時的,我們可以實作簡單的重試機制
suspend fun <T> simpleRetry(
maxAttempts: Int = 3,
delayMs: Long = 1000,
operation: suspend () -> T
): T {
repeat(maxAttempts) { attempt ->
try {
return operation()
} catch (e: Exception) {
println("嘗試 ${attempt + 1} 失敗:${e.message}")
delay(delayMs)
}
}
// 最後一次嘗試,如果失敗就讓異常拋出
return operation()
}
// 使用範例
suspend fun main() {
val agent = AIAgent(
executor = simpleOpenAIExecutor(ApiKeyManager.openAIApiKey!!),
systemPrompt = "你是一個友善的 AI 助手",
llmModel = OpenAIModels.CostOptimized.GPT4_1Mini
)
try {
simpleRetry(maxAttempts = 3, delayMs = 2000) {
val result= agent.run("你好")
// 直接丟出 error 來模擬未知的錯誤
throw Exception("unknown error")
println("✅ Agent 建立成功:$result")
}
} catch (e: Exception) {
println("❌ 經過多次嘗試後仍無法處理您的請求,請稍後再試")
}
}
執行 AI 回應內容
正常情況
✅ Agent 建立成功:你好!很高興見到你,有什麼我可以幫忙的嗎?
直接 throw Exception 來模擬未知錯誤的發生情況
嘗試 1 失敗:unknown error
嘗試 2 失敗:unknown error
嘗試 3 失敗:unknown error
❌ 經過多次嘗試後仍無法處理您的請求,請稍後再試
多供應商 Fallback 機制
除了基本的重試機制,我們還可以建立多供應商的 Fallback 機制。當主要的 LLM 供應商服務中斷或發生錯誤時,系統可以自動切換到備用供應商,確保服務的持續性
多供應商 Fallback 機制提供了以下優勢
- 提高可靠性:單一供應商故障時仍能維持服務
- 改善使用者體驗:無縫切換,使用者感受不到服務中斷
- 成本優化:可優先使用成本較低的供應商
- 負載分散:避免過度依賴單一服務商
💡 延伸學習:這裡只是簡單介紹多供應商 Fallback 的概念。如果您想了解完整的多 LLM 供應商整合實作,可以參考 Day 04:多 LLM 供應商整合 文章,裡面有詳細的程式碼範例和實作說明
整合範例:SafeAIHelper
現在讓我們把前面學到的錯誤處理技術整合起來,建立一個安全的 AI 助手
/**
* 安全的 AI 助手 - 整合錯誤處理技術
*/
class SafeAIHelper {
fun createSafeAIAgent(): AIAgent<String, String>? {
return try {
AIAgent(
executor = simpleOpenAIExecutor(ApiKeyManager.openAIApiKey!!),
systemPrompt = "你是一個友善的 AI 助手,用正體中文回答問題",
llmModel = OpenAIModels.CostOptimized.GPT4_1Mini
)
} catch (e: Exception) {
println("建立 Agent 時發生錯誤:${e.message}")
null
}
}
suspend fun askAI(question: String): String {
val agent = createSafeAIAgent()
// 如果 Agent 建立失敗
if (agent == null) {
return "❌ AI 助手暫時無法使用,請稍後再試"
}
return try {
// 使用重試機制 + 超時處理
simpleRetry() {
// 5秒超時
withTimeout(5000) {
// delay 6 秒來模擬錯誤的情況
delay(6000)
agent.run(question)
}
}
} catch (e: TimeoutCancellationException) {
"⏰ 回應時間過長,請稍後再試"
} catch (e: Exception) {
"❓ 處理問題時發生錯誤,請稍後再試"
}
}
suspend fun <T> simpleRetry(
maxAttempts: Int = 3,
delayMs: Long = 1000,
operation: suspend () -> T
): T {
repeat(maxAttempts) { attempt ->
try {
return operation()
} catch (e: Exception) {
println("嘗試 ${attempt + 1} 失敗:${e.message}")
delay(delayMs)
}
}
// 最後一次嘗試,如果失敗就讓異常拋出
return operation()
}
}
這個範例整合了我們這次學到的幾種錯誤處理技術
- API 錯誤處理:安全建立 Agent
- 網路超時處理:設定 5 秒超時限制
- 重試機制:失敗時自動重試 3 次
為了版面的程式碼不要過長,這裡並沒有把所有的錯誤的情況都放到這個範例中判斷,有興趣的可以寫一個更加完整的錯誤處理元件
使用範例
讓我們測試一下這個安全的 AI 助手
suspend fun main() {
val aiHelper = SafeAIHelper()
println("🤖 測試安全 AI 助手")
println("=".repeat(30))
val questions = listOf(
"你好",
"什麼是 Kotlin 協程? 請簡單回答"
)
questions.forEach { question ->
println("\n💬 問題:$question")
val answer = aiHelper.askAI(question)
println("🤖 回答:$answer")
println("-".repeat(30))
}
}
執行 AI 回應內容
正常情況
🤖 測試安全 AI 助手
==============================
💬 問題:你好
🤖 回答:你好!有什麼我可以幫忙的嗎?
------------------------------
💬 問題:什麼是 Kotlin 協程? 請簡單回答
🤖 回答:Kotlin 協程是一種輕量級的非同步程式設計工具,讓你可以用類似同步的方式撰寫非同步代碼,簡化異步操作和多線程管理。
使用 delay 來模擬回應時間過長的情況
🤖 測試安全 AI 助手
==============================
💬 問題:你好
嘗試 1 失敗:Timed out waiting for 5000 ms
嘗試 2 失敗:Timed out waiting for 5000 ms
嘗試 3 失敗:Timed out waiting for 5000 ms
🤖 回答:⏰ 回應時間過長,請稍後再試
------------------------------
💬 問題:什麼是 Kotlin 協程? 請簡單回答
嘗試 1 失敗:Timed out waiting for 5000 ms
嘗試 2 失敗:Timed out waiting for 5000 ms
嘗試 3 失敗:Timed out waiting for 5000 ms
🤖 回答:⏰ 回應時間過長,請稍後再試
------------------------------
錯誤處理最佳實踐
友善的錯誤訊息
- ❌ 不好:
Exception: OpenAI API key is invalid
- ✅ 好:
API 金鑰問題:請檢查您的 API 金鑰是否正確且有效
提供解決方案
fun createHelpfulErrorMessage(error: Exception): String {
return when {
error.message?.contains("key") == true ->
"🔑 API 金鑰問題:請到 OpenAI 官網檢查您的金鑰是否有效"
error.message?.contains("network") == true ->
"🌐 網路問題:請檢查網路連線,或稍後再試"
else -> "❓ 遇到問題了,請稍後再試或聯繫客服"
}
}
記錄重要資訊
fun logErrorForDebugging(error: Exception, context: String) {
// 開發環境:詳細記錄
if (System.getProperty("environment") == "development") {
println("錯誤詳情 [$context]: ${error.message}")
error.printStackTrace()
}
// 生產環境:簡化記錄
println("錯誤 [$context]: ${error.javaClass.simpleName}")
}
總結
今天我們學習了 Koog 應用的基礎錯誤處理技巧
- API 金鑰問題和網路連線錯誤
- 將技術錯誤轉換為用戶易懂的說明
- 簡單重試機制處理暫時性的問題
- 建立安全的 AI 助手,整合相關的錯誤處理技術
下一篇文章中,我們將探討實戰專案的開發,建立一個完整的 AI 聊天機器人
參考資料
支持創作
如果這篇文章對您有幫助,歡迎透過 贊助連結 支持我持續創作優質內容。您的支持是我前進的動力!
圖片來源:AI 產生