從 Function Calling 到 MAF 中的 tool use

從 Function Calling 開始
還記得 Function Calling 嗎?
一開始的 LLM 只能聊天。你問,它答。但它就是個黑箱。
不會上網,不能查資料庫,不知道今天幾月幾號,現在是幾點,當然也不可能去執行你的 API。
後來模型的推理能力變強了,OpenAI 才提供了一個新的能力:讓模型可以「要求系統替它做事」。這基於模型能夠理解結構化輸出、做到多步驟推理的基礎上。
這就是 Function Calling。
模型回你一段結構化的需求,像是:
"function_call": {
"name": "leave_request",
"arguments": "{ start_date:2026-5-12,end_date:2026-5-13,leave_type:病假,substitute:張大寶 }"
}
很多人誤以為「模型會呼叫API」!? 但其實沒有。
真正執行 API 的,永遠是你的 Runtime、你的 Framework、或是你的AI Agent程式。
模型做的只有三件事:
- 依照對談或語意,判斷需不需要呼叫工具
- 決定呼叫哪個工具 (像是上面的 name)
- 推論呼叫工具時的參數 (像是上面的 arguments)
基於這個基礎,很多開發框架實作出了 AI Agent 很需要的能力,就是 Tool Call。
Kernel Function 是「掛在 Kernel 上、能被 AI 呼叫的能力」
很多人第一次碰到 Semantic Kernel 時,最有感的機制其實是 Kernel Function。
以前它也常被叫做 Semantic Function / Native Function,本質上就是:讓 LLM 可以呼叫的功能單位。
你可以把它想成「Tool 的前身」,掛在 Kernel 上,給模型用來做事。
而且它很務實:查天氣、查資料庫、發 email、呼叫 API、建立檔案…等,全部都能包裝成 Kernel Function。
最典型的寫法是 Native Function(用程式碼寫的 function),例如:
public class WeatherPlugin
{
[KernelFunction]
[Description("查詢指定城市天氣")]
public string GetWeather(
[Description("城市名稱")]
string city)
{
return $"{city} 晴天";
}
}
var builder = Kernel.CreateBuilder();
builder.Plugins.AddFromType<WeatherPlugin>();
var kernel = builder.Build();
上面的程式運行之後,模型註冊了WeatherPlugin,模型(嚴格來說是開發框架)就可能自動呼叫 GetWeather("Taipei")。
你會感覺「哇,AI (LLM) 真的幫我查天氣了耶」,但真正執行這個API的,仍然是你的程式碼(或者嚴格一點說,是你使用的開發框架幫你執行的)。
而LLM的角色,則是幫你(依照和用戶之間的對談來)判斷是否需要呼叫、以及如何呼叫這個查天氣的API。
另外,其實還有 Prompt Function(把 prompt 包成 function):
例如「請幫我摘要:{{$input}}」,包一層後也能被 LLM 當成 Kernel Function 來呼叫。
那呼叫 Kernel Function 到底怎麼做到?這個流程和 Function Calling 有何關係?
我們可以把它拆成兩個層面來講:
- 概念上怎麼做到:Kernel Function 是掛給 AI 用的「工具」。
- 實作上是不是透過 Function Calling:多數情境下,是,背後就是靠現代模型的 Function Calling(GPT系列) / Tool Calling(Claude系列) 能力。
簡化後的流程大概長這樣:
使用者提示詞
↓
Semantic Kernel 把可用的 Kernel Functions(名稱 / 描述 / 參數 schema)描述給模型
↓
模型判斷:這題需要呼叫哪個 function?
↓
模型回傳「要呼叫哪個 function」以及呼叫所需的參數(tool/function call intent + arguments)
↓
Semantic Kernel Runtime / 你建立的 App / Agent 真的去執行你的 C# / Python function
↓
把結果丟回模型
↓
模型整理成最後回答
所以,(重點再講一次)不是模型自己執行程式碼。
模型只是「決定要呼叫哪個 function、帶什麼參數」,真正執行的是 Semantic Kernel Runtime / 你的程式。
簡單的說:
Kernel Function 不直接等於 Function Calling,但 Kernel Function 的自動呼叫的內涵確實是透過 Function Calling 完成的。
所以從 Semantic Kernel 一直到今天的 Tool / MCP,核心思路一直沒變:
LLM 推理 → 依需建立呼叫參數 → 你的 App / AI Agent 負責執行。
各家模型的差別?名字不同,作法相似
這功能在每一個高階模型中,都有支援。
讓模型判斷何時需要呼叫外部 Function ,並且提供適當的參數,這是 Kernel Function 的基礎。
這機制在 OpenAI 叫 Function Calling,在 Claude 叫 Tool Use,在 Gemini 叫 Function Declaration。
到了 MAF 的時代,這功能依就是 AI Agent 開發的重點。
即便 API 長得不一樣:
最初 Function Calling 給出的是 JSON Schema,後來到了 Kernel Function 我們只需要給 function signature(類別參照)。到了MAF,我們也只需要跟框架登記一下類別即可。
雖然持續換了好幾個不同的稱呼,但核心流程一直都沒變:模型推理 → 依需選用 Tool 並建立參數 → 你的 App / AI Agent 執行。
看一段 MAF 的程式碼,你就會懂 Tool 的落地方式
在這段 MAF 範例中,我們把請假相關的方法變成 AI 可用的工具:
public class LeaveRequestTools
{
[Description("取得指定員工已請假的天數")]
public int GetLeaveRecordAmount(
[Description("要查詢請假天數的員工名稱")]
string employeeName)
{
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine($"\n[action] 查詢 {employeeName} 請假天數。\n");
Console.ResetColor();
return employeeName.ToLower() switch
{
"david" => 5,
"eric" => 8,
_ => 3
};
}
[Description("建立一筆員工請假申請")]
public bool LeaveRequest(
[Description("請假起始日期")]
DateTime startDate,
[Description("請假天數")]
string days,
[Description("請假事由")]
string reason,
[Description("代理人")]
string substitute,
[Description("請假者姓名")]
string employeeName)
{
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine($"""
[action] 建立假單:
{employeeName} 請假 {days} 天,
從 {startDate:yyyy-MM-dd} 開始,
事由為 {reason},
代理人 {substitute}
""");
Console.ResetColor();
return true;
}
}
AIAgent agent = new OpenAIClient(openAIApiKey)
.GetResponsesClient()
.AsAIAgent(
model: "gpt-4.1",
instructions: "...",
tools:
[
AIFunctionFactory.Create(leaveTools.GetLeaveRecordAmount),
AIFunctionFactory.Create(leaveTools.LeaveRequest),
]);
這裡有趣的不只是那個 AIFunctionFactory 的 Create 方法,而且, Description 修飾字變得很重要。
因為這些描述不是寫給人看的,是寫給模型「推理」用的。
以前的 API 是給前端程式呼叫,現在的 Tool 是給 AI 呼叫。
而前端開發者和AI,是兩種完全不同的「使用者」。
Tool 是 AI 世界的新 API Layer
以前, UI 的功能是給人操作系統。
現在,Tool / MCP 的功能則是給 AI 來操作系統。
這不是潮流,而是一種新的軟體介面設計。
當你開始用「AI 會怎麼理解」的角度來設計你類別中的 API,你其實是在替未來的系統打造一個良好的地基。
AI Agent 這條路,才剛開始。
接下來就看我們這些寫程式的人,如何繼續走下去。
留言