工具呼叫 Tools / Function Calling

Agent 能做事的關鍵:LLM 怎麼定義工具、怎麼決定呼叫哪一個、結果又怎麼回到迴圈裡,完整拆解 Function Calling 流程。

這是 AI 系列第三篇。建議先讀 AI Agent 是什麼——本篇要拆解的「工具」正是 Agent 的手腳。


目錄


什麼是 Tool Use?

Tool Use(工具使用)/ Function Calling(函式呼叫)讓 LLM 能呼叫外部功能,去做它自己做不到的事。

回顧 LLM 基礎:LLM 本質只會「輸出文字」。它不能真的上網、不能算大數字、不能讀你的檔案。工具就是補上這些能力的橋樑。

為什麼 LLM 需要工具?

LLM 單獨做不到 配上工具就能做
查今天的天氣、即時股價 呼叫天氣 API、查詢工具
精確計算 38172 × 9043 呼叫計算器工具
讀取/修改你電腦上的檔案 呼叫讀檔、寫檔工具
查公司內部資料庫 呼叫資料庫查詢工具
寄信、建立行事曆 呼叫對應的 API 工具

💡 關鍵心態:工具讓 LLM 從「靠記憶硬答」變成「去查、去算、去做」。這也是緩解幻覺最有效的手段之一——與其讓它猜,不如給它工具去查真實資料。

一句話定義

Function Calling = LLM 判斷「該用哪個工具、帶什麼參數」,再由外部系統實際執行、把結果回傳給它。

注意:模型本身不執行工具,它只負責「決定要呼叫」並輸出一個結構化的呼叫請求;真正去執行的是外部的程式(你的應用 / Agent 框架)。


Tool 的定義

要讓 LLM 知道「有哪些工具可用」,得先用一套規格把每個工具描述清楚。一個工具定義通常包含三部分:

欄位 作用 例子
name(名稱) 工具的識別名 get_weather
description(描述) 這工具是做什麼的、何時該用 「查詢指定城市的目前天氣」
parameters(參數) 需要哪些輸入,用 JSON Schema 描述 city(字串,必填)

範例:一個查天氣工具的定義

{
  "name": "get_weather",
  "description": "查詢指定城市的目前天氣狀況,包含溫度與天氣描述。",
  "parameters": {
    "type": "object",
    "properties": {
      "city": {
        "type": "string",
        "description": "城市名稱,例如「台北」「東京」"
      }
    },
    "required": ["city"]
  }
}

重點

  • description 是最關鍵的欄位。LLM 完全靠它判斷「這個工具能不能解決我現在的問題」。描述寫得含糊,模型就會選錯或不會用。
  • parameters 用 JSON Schema 定義型別與必填欄位。這讓模型輸出的呼叫請求是結構化、可被程式直接解析的,而不是一段自由文字。

LLM 怎麼選工具

把工具清單交給 LLM 後,每一輪它會自己判斷:

1. 看使用者的需求
2. 掃過手上每個工具的 description
3. 判斷:這個需求需不需要用工具?需要的話用哪個?
4a. 需要 → 輸出一個「工具呼叫請求」(工具名 + 填好的參數)
4b. 不需要 → 直接用文字回答

模型輸出的「呼叫請求」長怎樣

當 LLM 決定查台北天氣,它不會自己去查,而是輸出類似這樣的結構化請求:

{
  "tool_call": {
    "name": "get_weather",
    "arguments": { "city": "台北" }
  }
}

這份請求會交給外部系統去真正執行。

為什麼能「填對參數」?

因為模型理解了你的話(「台北現在天氣如何」),對照工具的 parameters schema,把 city 填成 "台北"。這正是 LLM 的強項:把自然語言對應到結構化欄位。

⚠️ 模型仍可能選錯工具或填錯參數(一樣會誤判)。所以好的工具描述、清楚的參數定義,會大幅提升正確率。


完整呼叫流程

Function Calling 是一個來回的過程,剛好對應 Agent Loop 的「行動 → 觀察」:

┌──────────────────────────────────────────────────────┐
│                                                      │
│  ① 使用者提問                                         │
│     「台北現在天氣如何?」                               │
│            │                                         │
│            ▼                                         │
│  ② LLM 判斷要用工具,輸出呼叫請求                        │
│     get_weather(city="台北")                          │
│            │                                         │
│            ▼                                         │
│  ③ 外部系統實際執行工具                                 │ ← 模型在這裡「停下來等」
│     呼叫天氣 API,拿到 { temp: 28, desc: "晴" }         │
│            │                                          │
│            ▼                                          │
│  ④ 把工具結果「回傳」給 LLM(塞回上下文視窗)              │
│            │                                          │
│            ▼                                          │
│  ⑤ LLM 根據結果,生成給人看的回答                         │
│     「台北現在 28°C,天氣晴朗。」                         │
│                                                       │
└───────────────────────────────────────────────────────┘

關鍵理解

  • 第 ③ 步是分水嶺:模型輸出呼叫請求後會「暫停」,把控制權交給外部系統。系統執行完,才把結果送回去。
  • 第 ④ 步的結果會佔用 token(回顧 上下文視窗)。工具回傳一大坨資料,就吃掉一大塊視窗——所以工具最好只回「需要的部分」。
  • 如果一個任務要用很多次工具,這個來回就會跑很多圈,正是 Agent Loop 的本質。

實戰範例

範例 1:單一工具呼叫

使用者:「東京現在幾度?」

→ LLM 輸出:get_weather(city="東京")
→ 系統執行,回傳:{ "temp": 22, "desc": "多雲" }
→ LLM 回答:「東京現在 22°C,多雲。」

範例 2:需要多個工具、多圈

使用者:「比較台北和東京哪裡比較熱。」

第 1 圈 → get_weather(city="台北") → { temp: 28 }
第 2 圈 → get_weather(city="東京") → { temp: 22 }
第 3 圈 → 兩個結果都有了,LLM 回答:
         「台北 28°C,比東京 22°C 熱 6 度。」

模型會自己判斷「要呼叫兩次」,這就是 Agent Loop 在運作。

範例 3:平行呼叫

有些情況工具之間沒有先後依賴(查台北、查東京互不影響),模型/框架可以同時發出多個呼叫,一起拿回結果,省下來回的時間。這也是為什麼「彼此獨立的操作盡量平行」是 Agent 效率的關鍵。


最佳實踐

1. 工具描述要寫清楚(最重要)

✅ 好:「查詢指定城市的目前天氣,包含溫度與天氣描述。輸入城市名稱。」
❌ 差:「天氣工具」

模型完全靠 description 決策,描述越精準,選對工具的機率越高。

2. 參數定義明確、善用 required

✅ 標明型別、必填、給範例:city(string,必填,例:「台北」)
❌ 含糊的 input(string)讓模型猜要填什麼

3. 工具結果只回必要的部分

工具回傳會佔 上下文視窗。與其回傳整包 JSON,不如只回模型需要的欄位,省 token 也減少干擾。

4. 錯誤要回成「模型看得懂的訊息」

✅ 回:「錯誤:找不到城市『火星』,請確認城市名稱。」
❌ 直接 throw 例外或回一串 stack trace

把錯誤以清楚文字回傳,模型才能據此調整(換個參數重試、或告訴使用者)。

5. 高風險工具要設防護

刪除、付款、寄信這類不可逆操作,應搭配人工核准,別讓模型全自動執行。


常見問題

問題 1:工具是模型自己執行的嗎?

不是。模型只負責「決定呼叫哪個工具、帶什麼參數」並輸出請求;實際執行的是外部系統(你的程式或 Agent 框架)。模型拿到結果後才繼續生成回答。

問題 2:Function Calling 和 Tool Use 是同一件事嗎?

基本上是。「Function Calling」是 OpenAI 早期的叫法,「Tool Use」是更通用的講法,指的都是「LLM 透過結構化呼叫使用外部功能」。

問題 3:模型會不會選錯工具或填錯參數?

會。模型的判斷一樣可能誤判或幻覺。降低出錯的關鍵是:清楚的工具描述、明確的參數 schema、以及把錯誤訊息好好回傳讓它能修正。

問題 4:工具一多會不會有問題?

會。工具太多時,模型挑選的難度上升、也佔用更多 token 來描述工具。實務上會「只給當下任務相關的工具」,這也是下一篇 MCP 與第五篇 Skills 漸進式揭露 要解決的問題。


總結

核心要點

Function Calling = LLM 決定「呼叫哪個工具、帶什麼參數」
                   → 外部系統執行 → 結果回傳 → LLM 續寫

關鍵認知:
  ├─ 模型只「決定呼叫」,不親自執行
  ├─ 工具靠 name + description + parameters(JSON Schema) 定義
  ├─ description 是模型選工具的唯一依據,要寫清楚
  └─ 呼叫流程=Agent Loop 的「行動 → 觀察」,結果會佔上下文視窗

快速記憶

概念 一句話
Tool Use 讓 LLM 呼叫外部功能去查/算/做
工具定義 name + description + parameters
description 模型選工具的唯一依據,最關鍵
呼叫流程 模型發請求 → 系統執行 → 回傳 → 模型續寫
與 Agent 關係 就是 Agent Loop 的「行動 → 觀察」

學習路徑

1. 理解 LLM 為何需要工具 ✓
2. 看懂工具的三段定義 ✓
3. 掌握「發請求→執行→回傳→續寫」流程 ✓
4. 知道工具描述與錯誤處理的最佳實踐 ✓
5. 下一步 → 工具多了、跨應用了,怎麼標準化?

下一篇

👉 MCP(Model Context Protocol):每個工具都自己接一套很麻煩。MCP 是一套開放標準,讓工具像 USB-C 一樣「插上就能用」,下一篇拆解它的架構與三種能力。


建立日期:2026-06-01 最後更新:2026-06-01

🔗相關文章