從 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程式。

模型做的只有三件事:

  1. 依照對談或語意,判斷需不需要呼叫工具
  2. 決定呼叫哪個工具 (像是上面的 name)
  3. 推論呼叫工具時的參數 (像是上面的 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),
        ]);

這裡有趣的不只是那個 AIFunctionFactoryCreate 方法,而且, Description 修飾字變得很重要
因為這些描述不是寫給人看的,是寫給模型「推理」用的。

以前的 API 是給前端程式呼叫,現在的 Tool 是給 AI 呼叫。
而前端開發者和AI,是兩種完全不同的「使用者」。

Tool 是 AI 世界的新 API Layer

以前, UI 的功能是給人操作系統。
現在,Tool / MCP 的功能則是給 AI 來操作系統。

這不是潮流,而是一種新的軟體介面設計。
當你開始用「AI 會怎麼理解」的角度來設計你類別中的 API,你其實是在替未來的系統打造一個良好的地基。

AI Agent 這條路,才剛開始。
接下來就看我們這些寫程式的人,如何繼續走下去。

留言

這個網誌中的熱門文章

實際嘗試使用DeepSeek API

開啟 teams 中的『會議轉錄(謄寫)』與Copilot會議記錄、摘要功能

使用 Dify API 快速建立一個包含前後文記憶的對談機器人

使用LM Studio輕鬆在本地端以API呼叫大語言模型(LLM)

使用 Dify 串接 LINE Bot