在前面的章節中,我們學會了如何透過Prompt與Context精準控制模型的輸入,並利用Structured Output確保模型產出100%型別安全的結構化資料
然而,單純具備輸入與輸出能力的LLM,本質上依然是一個被困在「知識截止日(Knowledge Cutoff)」與「純文字空間」的大腦
它不知道現在幾點、無法查詢資料庫當下的庫存、更不可能主動發送一封Slack警報
要讓LLM從一個「只會動嘴的顧問」進化為能「自主行動的 Agent」,關鍵就在於 Tool Calling Engineering(工具調用工程 / Function Calling)
今天我們就來深入拆解:甚麼是Tool Calling?
它的底層運作協議是什麼?
又有哪些工程細節決定了工具調用的成敗?
剛接觸Agent的開發者常有一種誤解:「LLM 會自己去打 API 或連資料庫」
事實上,LLM 本身永遠無法直接執行任何Python程式碼或發出HTTP請求
Tool Calling 的本質:
是一種人機協作協議(Protocol)
開發者向模型提供一份「可用工具清單(Schema)」,模型根據使用者需求進行推理,決定「是否需要用工具」以及「該使用哪個工具並傳入什麼參數」
最後,由外部宿主程式(Host Program)執行該工具,並將結果餵回給模型
+----------+ 1. 使用者提問 + 工具清單 (Schema) +-------+
| | ──────────────────────────────────────────> | |
| | | LLM |
| | <────────────────────────────────────────── | (大腦) |
| | 2. 決策:我想呼叫 get_weather(city="台北") | |
| 宿主環境 | +-------+
| (Python) | ───┐
| | │ 3. 本地執行 get_weather()
| | <──┘ 取得結果: {"temp": 28, "rain": "80%"}
| |
| | 4. 注入工具執行結果 (Tool Message) +-------+
| | ──────────────────────────────────────────> | LLM |
| | <────────────────────────────────────────── | (大腦) |
+----------+ 5. 生成最終自然語言回覆給使用者 +-------+
LLM判斷「何時調用工具」與「如何組裝參數」,完全取決於你在 Tool Schema 中寫了什麼
在底層,一個標準的Tool定義通常遵循JSON Schema規範,包含三個核心要素:
{
"type": "function",
"function": {
"name": "query_inventory",
"description": "根據商品 SKU 查詢目前倉庫中的即時現貨庫存量。當用戶詢問是否有現貨、庫存剩多少時調用。",
"parameters": {
"type": "object",
"properties": {
"sku": {
"type": "string",
"description": "商品的唯一庫存單位代碼,例如 'SKU-HEADPHONE-01'"
},
"warehouse_id": {
"type": "string",
"enum": ["NORTH_01", "SOUTH_02"],
"description": "可選的特定倉庫代碼,若用戶未指定則預設查詢北區倉庫"
}
},
"required": ["sku"]
}
}
}
name(語意明確的函數名稱):使用動詞 + 名詞(如 get_user_profile、send_email_alert),避免模糊的命名。description(工具觸發條件與時機):這是最重要的 Prompt!必須清楚說明這個工具「能做什麼」以及「在什麼情況下應該調用它」。parameters(型別與參數註解):定義各參數的型別、是否必填(required)、枚舉限制(enum)以及欄位說明。在Demo環境中呼叫一兩個工具非常順暢,但在複雜的生產級Agent系統中,Tool Calling面臨以下嚴峻挑戰:
當使用者沒有提供必填資訊時(例如只說「幫我查庫存」,沒說查哪件商品),模型可能會自行捏造一個 sku="SKU-9999" 去呼叫工具,而不是先向使用者追問
當系統掛載了 30 個以上的工具,且多個工具功能相近時(例如 get_user_info vs get_account_details),模型常會調用錯誤的工具,或是陷入無法決策的猶豫中
複雜任務往往需要連續調用工具(例如:先調用 search_user 拿 ID ➔ 再調用 get_order_history 查訂單 ➔ 最後調用 apply_refund 退款)。如何管理這些中間狀態與回傳結果,是工作流設計的核心
這三者是 LLM 能力演進的連續光譜:
| 比較維度 | 一般對話 (Chat) | 結構化輸出 (Structured Output) | 工具調用 (Tool Calling) |
|---|---|---|---|
| 互動模式 | 單向文字生成 | 單向結構化轉換 | 雙向閉環通訊(模型 ➔ 系統 ➔ 模型) |
| 外界連結 | 無法獲取外部狀態 | 無法獲取外部狀態 | 可主動讀取即時數據、觸發外部副作用 |
| 觸發時機 | 每次請求必定輸出 | 每次請求必定輸出 | 由模型自主判斷「要調用工具」還是「直接回覆」 |
| 系統角色 | 終端回答者 | 資料轉換節點 | 工作流中的指揮官 / 決策路由節點 |
Tool Calling Engineering將LLM從一個封閉的語言模型,轉變成現代軟體架構中的「智慧調度中心(Orchestrator)」
它掌握了呼叫外部世界的能力,使Agent能夠真正落實各類自動化任務
理解了Tool Calling的原理與Schema定義後,在實戰中我們該如何用Python實作?
如果工具執行失敗該如何容錯?
多工具同時調用(Parallel Tool Calling)又該如何處理?
明天 【Day 9】怎麼應用Tool Calling Engineering,我們將進入實戰篇,透過LangChain / OpenAI SDK實作自訂工具註冊、平行工具調用(Parallel Tool Calling)與工具異常攔截重試管線!