Function Calling 的四步流程是什麼?LLM 本身有沒有真正執行工具?
Function Calling 的完整流程分四步,理解這四步是理解 AI Agent 工作原理的關鍵:
第一步,告訴 LLM 有哪些工具可用:你在呼叫 LLM 的 API 時,同時傳入一個工具清單,描述每個工具的名稱、功能和參數格式(例如:「get_eth_price:取得 ETH 的現價,參數:currency(字串,'USD' 或 'EUR')」)。LLM 讀取這份清單,知道有哪些工具可以用。
第二步,LLM 輸出工具調用請求:當 LLM 在推理過程中判斷需要某個工具時,它不是直接執行,而是在回應裡輸出一個結構化的 JSON 格式請求,例如:{"tool": "get_eth_price", "parameters": {"currency": "USD"}}。
第三步,後端程式碼真正執行:你的應用程式(不是 LLM)讀取這個 JSON 請求,調用真正的 get_eth_price 函數,從 CoinGecko API 取得真實的 ETH 現價。
第四步,結果回傳給 LLM:你把函數的執行結果(例如 {"price": 3420.50, "currency": "USD"})傳回給 LLM,LLM 基於這個結果繼續推理並生成最終回應。
關鍵認知:LLM 本身從不執行任何工具。 它只是「說」它想調用什麼,真正執行的永遠是你的後端程式碼。這個設計讓你可以在執行層加入任何安全驗證邏輯。
Function Calling 和 MCP 是同一件事嗎?我在文件裡看到這兩個詞,有什麼區別?
不是同一件事,但它們緊密相關,很容易混淆。
Function Calling / Tool Use 是 LLM 和工具之間溝通的「通訊機制」——它定義了 LLM 怎麼「說」它想調用一個工具(輸出結構化 JSON),以及工具結果怎麼傳回給 LLM。這是 LLM API 層面的標準,GPT 和 Claude 都支援。
MCP(Model Context Protocol) 是在 Function Calling 之上的「工具標準化打包層」——它定義了工具要怎麼被描述、怎麼被發現、怎麼被不同的 LLM 和框架重用。簡單的類比:Function Calling 是「HTTP 協議」,定義了通訊方式;MCP 是「REST API 規範」,定義了在 HTTP 上怎麼組織資源和操作。有了 MCP,一個工具只需要寫一次,就能被 Claude、GPT、LangChain、ElizaOS 等所有支援 MCP 的系統使用;沒有 MCP,每次你想讓不同系統用同一個工具,都要各自適配一次。
對初學者的實際建議:如果你只是想讓自己的 Agent 調用一個工具,直接使用框架(LangChain 的 @tool 裝飾器,ElizaOS 的 Action 插件)就夠了,不需要自己實作 MCP。MCP 在你想「把工具發布給其他 Agent 使用」或「讓工具跨框架可用」時才真正需要。
我怎麼讓 LLM 知道「什麼時候應該調用工具,什麼時候應該直接回答」?
這個問題的答案在工具的「描述文字」裡——LLM 根據你給每個工具寫的描述來判斷何時應該調用。幾個讓 LLM 做出正確判斷的設計原則:
第一,工具描述要說明「適用場景」:不要只說工具做什麼,要說清楚在什麼情況下應該用它。好的描述:「查詢 ETH 的現時美元價格。當用戶問到加密貨幣的當前價格、最新報價、或需要進行價格比較時,調用此工具。」壞的描述:「取得 ETH 價格。」
第二,讓 LLM 知道什麼時候不應該調用工具:如果你的 Agent 有多個工具,在 System Prompt 裡說清楚各工具的使用邊界,例如:「只有需要即時數據時才調用工具;如果問題關於概念解釋(如『什麼是 DeFi』),直接回答,不調用工具。」
第三,工具數量不宜太多:傳給 LLM 的工具越多,LLM 需要讀的工具描述越多(消耗 Token),且在大量工具裡選擇正確的工具難度更高。建議每次 LLM 呼叫傳入的工具不超過 10-15 個;如果有更多工具,用 LangGraph 在不同節點分配不同工具子集,而不是一次傳入全部。
第四,觀察 LLM 的實際選擇:在開發階段開啟 verbose 模式,觀察 LLM 在什麼情況下選擇了哪個工具。如果它頻繁選錯工具,多半是工具描述不夠清楚,而不是模型能力不足。
Function Calling 的安全設計有哪些基本原則?特別是在加密 Agent 場景
因為 LLM 本身不執行工具(執行在你的後端),安全設計的核心在後端的「執行層」。幾個針對加密 Agent 的基本安全原則:
第一,讀寫工具嚴格分類:把工具分成兩類——只讀工具(查詢數據、讀取鏈上狀態,出錯後果是資訊錯誤)和寫入工具(簽署交易、移動資金,出錯後果是資產損失)。兩類工具在後端執行層有不同的授權要求,不能混在一起。
第二,寫入工具必須有參數驗證:在後端執行寫入工具之前,驗證 LLM 傳來的參數是否合理——金額是否在設定上限內、地址是否在白名單裡、操作類型是否被允許。這個驗證邏輯寫在你的後端程式碼裡,LLM 無法繞過。
第三,高金額操作加人工確認:對超過閾值(例如 $100)的寫入操作,在後端加一個人工確認步驟(通知你,等待你確認後才執行)。這一層和 LLM 的推理完全獨立,即使 LLM 被 Prompt Injection,攻擊者也無法繞過這個人工確認層。
第四,記錄所有工具調用:每次工具調用的完整記錄(工具名稱、輸入參數、輸出結果、執行時間)寫入日誌。沒有日誌就沒有事後審計能力——如果 Agent 做了一個你不理解的操作,日誌是你找出根本原因的唯一途徑。
Function Calling 的最小工作示例:讓 Agent 查詢 ETH 現價
以下是一個使用 LangChain(Python)實作 Function Calling 的最簡範例,展示從工具定義到 Agent 調用的完整流程:
首先定義工具:用 @tool 裝飾器標記一個 Python 函數,函數的 docstring 就是工具的描述,LLM 會讀取這段描述來決定何時調用。函數本身調用 CoinGecko API 取得真實的 ETH 現價,並返回格式化的結果字串。
然後初始化 Agent:把工具列表和 LLM(例如 Claude Sonnet)傳給 LangChain 的 Agent,設定最大迭代次數(避免無限迴圈),加入 System Prompt 說明 Agent 的角色。
最後執行任務:當用戶輸入「ETH 現在多少錢?」,Agent 的 Thought 步驟判斷「需要調用 get_eth_price 工具」→ 輸出工具調用 JSON → 後端執行 Python 函數 → 結果回傳給 LLM → LLM 生成自然語言回應:「ETH 現在的價格是 $3,420.50 美元。」
這個示例展示了 Function Calling 的完整閉環:LLM 只負責「決定調用什麼」,後端負責「真正執行」,結果再回傳給 LLM 生成最終回應。整個流程的 Token 消耗包括:工具描述(約 50 Token)+ 用戶問題(約 10 Token)+ LLM 的 Thought(約 30 Token)+ 工具結果(約 20 Token)+ 最終回應(約 30 Token)= 約 140 Token,成本約 $0.0004。
Function Calling 的核心取捨是「靈活性 vs 可預測性」。LLM 自主決定何時調用工具,讓 Agent 能應對各種意外情況,但也意味著有時 LLM 可能在不該調用工具時調用(例如概念解釋問題不需要工具,但 LLM 仍然試圖調用),或者在應該調用工具時憑記憶回答(使用了訓練數據裡可能過時的數字)。另一個取捨是「工具數量 vs 選擇準確性」:提供更多工具讓 Agent 能力更強,但 LLM 在更多工具裡選擇正確工具的準確性可能下降,也消耗更多 Token。對加密 Agent 的建議:只傳當前任務需要的工具,不要把所有可能用到的工具都傳進去——LangGraph 的 DAG 設計允許在不同節點分配不同工具子集,是處理大量工具的最佳實踐。