到目前為止,我們與 AI 的互動模式都是一問一答:我們發送一段文字,AI 回傳一段文字或一張圖片。AI 就像一個知識淵博的顧問,能為我們提供資訊、生成內容,但它始終是個局外人。然而,一個真正的智慧助理,不應該只會「說」,還應該會「做」。
困惑點:如果我想讓 AI 變得更像一個真正的助理,該怎麼做?例如,當使用者對著 App 說:「幫我設定一個 10 分鐘後提醒我烤箱的計時器」,我希望 App 能直接啟動計時器功能,而不是只回傳一句「好的,我會提醒您」。我要如何賦予 AI 一雙「手」,讓它能夠實際操作我 App 內建的功能呢?
AI 協作
我發現目前的 AI 應用都只是單向的資訊獲取。我聽說了一個叫做「Function Calling」的概念,據說能讓 AI 控制 App。請問這到底是什麼原理?請簡單說明
AI 的回答:
您好,很高興能為您解說這個專業領域的議題。
您觀察得沒錯,早期的AI應用確實多數是單純的資訊提供者。然而,Function Calling(函數呼叫)是讓AI從「單向資訊獲取」轉變為「雙向互動與執行任務」的關鍵技術。
簡單來說,Function Calling 的原理可以拆解為以下步驟:
1. 意圖識別(Intent Recognition)
當您向AI提出請求時,AI模型會先分析您的自然語言輸入,理解您想執行的「意圖」。例如,當您說「幫我設定明天早上7點的鬧鐘」,AI會辨識出您的意圖是「設定鬧鐘」。
2. 函數選擇與參數生成(Function Selection & Parameter Generation)
AI模型內建或被告知了一系列可用的「工具」或「函數」,這些函數代表了AI可以執行的具體操作(例如:
set_alarm()
、send_email()
、get_weather()
等)。一旦AI識別出您的意圖,它會從這些工具中找到最匹配的函數(例如:
set_alarm()
)。同時,它會從您的輸入中提取出執行該函數所需的資訊,也就是參數(例如:time=7:00 AM
,day=tomorrow
)。3. 呼叫與執行(Execution)
這一步是Function Calling 最核心的環節。AI模型本身不會直接執行這個函數,而是會生成一個標準化的、結構化的請求(例如:JSON格式),描述「要呼叫哪個函數」以及「要傳入什麼參數」。
這個請求會被發送給一個外部的應用程式、服務或後端系統。這個系統收到請求後,才會真正執行
set_alarm(time='7:00 AM', day='tomorrow')
這個程式碼。4. 結果回饋與生成(Feedback & Response Generation)
外部系統執行完畢後,會將執行的結果(例如:「鬧鐘已成功設定」)回傳給AI模型。AI模型再根據這個結果,生成一個自然語言的回應給您(例如:「好的,明早7點的鬧鐘已為您設定完畢。」)。
總結
Function Calling 的本質,是讓大型語言模型(LLM)成為一個「智慧中樞」。它不再只是單純地回答問題,而是能根據您的需求,準確地理解意圖,並將任務委派給後台的特定應用程式或服務來執行。這就如同一個聰明的秘書,她知道您想做什麼,並且懂得打電話給正確的人或使用正確的工具來完成任務,最後再回報結果給您。
這種機制讓AI的應用從「查詢」進化到「控制」,這也是為什麼我們能看到AI可以透過這種技術來控制智慧家電、管理日曆、發送訊息等,實現您所說的「控制App」的應用。
如果您對這部分的程式設計有興趣,許多大型語言模型服務(例如:OpenAI 的 GPT、Google 的 Gemini)都提供了這類 API 接口,讓開發者能輕易地定義和使用自己的函數,將AI的能力擴展到各種應用場景中。
我的理解與總結
Function Calling 並不是讓 AI 直接入侵並控制我的 App,而是建立了一套協作流程:
setTimer
)打包成一份「說明書」。這徹底改變了 App 與 AI 的互動模式,從單向的資訊索取,變成了雙向的任務協作。
今天我們不從頭打造一個完整的專案,但理解其核心的程式碼結構至關重要。
首先,我們需要用程式碼來描述我們的工具。這通常會被轉換成 JSON 格式發送給 API。
// 這是一個概念性的結構,用來描述一個可被 AI 呼叫的函式
struct FunctionDeclaration {
let name: String // 函式名稱,例如 "setTimer"
let description: String // 函式功能的描述,幫助 AI 理解何時使用它
let parameters: [String: ParameterType] // 函式需要的參數及其類型
}
// 假設我們 App 有一個設定背景色的功能
let changeBackgroundColorTool = FunctionDeclaration(
name: "changeBackgroundColor",
description: "Changes the background color of the app screen.",
parameters: [
"colorName": .string // 需要一個名為 "colorName" 的字串參數
]
)
// 我們會將這個(或多個)工具的定義,連同使用者的 Prompt 一起發送給 AI
當 AI 認為應該使用我們的工具時,它回傳的 JSON 會包含一個特殊的 functionCall
或 tool_code
物件。
// AI 可能回傳的 JSON 響應
{
"candidates": [
{
"content": {
"parts": [
{
"functionCall": {
"name": "changeBackgroundColor",
"args": {
"colorName": "blue"
}
}
}
]
}
}
]
}
我們的 App 在收到這個 JSON 後,需要解析它,並根據 name
和 args
執行對應的程式碼。
// 在我們的 ViewController 中
func handleAIResponse(response: AIResponse) {
guard let functionCall = response.candidates.first?.content.parts.first?.functionCall else {
// 如果沒有 functionCall,就當作一般文字處理
return
}
// 根據函式名稱,決定要執行哪個本地方法
switch functionCall.name {
case "changeBackgroundColor":
if let colorName = functionCall.args["colorName"] as? String {
// 執行我們 App 真正改變顏色的程式碼
self.view.backgroundColor = colorFromName(colorName)
}
case "setTimer":
// ... 處理設定計時器的邏輯 ...
break
default:
print("AI 呼叫了一個未知的函式")
}
}
Function Calling 打破了 App 與 AI 之間的次元壁,讓 AI 不再只是一個資訊的來源。它將自然語言指令轉化為精確的程式碼執行。
明天,我們將稍微放緩腳步,回顧一下在打造 AI 應用的過程中,有哪些至關重要但容易被忽略的陷阱。