← 返回開發日記

Function Calling 是什麼?OpenAI、Gemini、Claude 如何透過 JSON 呼叫 API 和外部工具?

AI Agent · 2026.08.18 · 約 6分鐘閱讀

Function Calling 是什麼?OpenAI、Gemini、Claude 如何透過 JSON 呼叫 API 和外部工具?

Function Calling 的正確理解是:模型只依照工具 Schema 產生結構化呼叫請求,不會直接替你執行任意 API。如果你正在查 Function Calling JSON API,建議先用一個只讀工具跑通「宣告 → 模型呼叫 → 程式執行 → 結果回傳 → 最終回答」閉環,再決定是否加入多模型適配層。

本週建議動作:先選一個不會修改資料的查詢工具,分別記錄 OpenAI、Google Gemini 與 Claude API 的原始回應;若未來需要共用工具或切換模型,再建立內部事件契約。

這篇適合三類讀者:第一次建構工具型 AI 的後端開發者、多模型平台工程師,以及需要審核憑據與高風險動作的安全負責人。若你只想了解模型排名,本文不是選型榜單;本文處理的是「誰宣告、誰執行、誰批准、誰驗證」。

先看共同資料流,再看三家的結構差異

Function Calling 可以拆成五個責任節點:

  1. 模型接入開發者宣告工具名稱、用途、輸入欄位與 Schema。
  2. 模型根據使用者意圖,產生工具名稱與 JSON 引數。
  3. 供應商適配層解析不同 API 的回應格式,轉換成內部事件。
  4. 工具執行器負責認證、網路請求、逾時、重試、冪等與結果封裝。
  5. 安全與業務層決定是否允許動作,最後再把工具結果交回模型。

這條流程中最容易犯的錯,是把模型輸出的 JSON 當成已經完成的 API 結果。事實上,OpenAI 文件也提醒,模型產生的引數不一定永遠是有效 JSON,或可能包含 Schema 沒有定義的欄位;你的程式仍要驗證後才能執行。(OpenAI 官方 API 文件)

Function Calling 會直接執行 API 嗎?
不會。對自訂工具而言,模型只提出「應該呼叫哪個工具,以及要傳哪些引數」。真正的 HTTP 呼叫、資料庫查詢或 macOS 指令,都必須由你的應用程式或執行環境完成。Google Gemini 的官方流程同樣把「執行函式」列為開發者責任。(Google Gemini 官方 Function Calling 文件)

三家平台的核心欄位不是同一套

平台 工具宣告重點 模型呼叫資料 結果如何對回原呼叫
OpenAI tools 內的 function,包含 namedescriptionparameters;可用 strict 要求符合受支援的 Schema 子集 tool_calls 陣列;常見欄位包括 idfunction.namefunction.arguments tool_call_id 對應工具結果;實作時應保留原始訊息結構 (OpenAI 官方 API 文件)
Google Gemini function declaration 以 namedescriptionparameters 描述,格式採支援的 OpenAPI Schema 子集 舊式 Generate Content API 常見 functionCall part;新式流程可見 function_call step,並可能帶有呼叫 id 回傳 function response 時保留對應識別資訊;混合內建工具時不能假設呼叫位於 parts 陣列最後 (Google Gemini 官方 Function Calling 文件)
Claude tools 位於請求頂層,輸入欄位使用 input_schema 回應包含 tool_use content block,主要欄位是 idnameinput,並以 stop_reason: tool_use 表示意圖 tool_use_id 放入後續 tool_result,而且結果區塊必須緊接在對應工具使用之後 (Claude 官方 Tool Use 文件)

三家模型的工具呼叫 JSON 格式一樣嗎?
不一樣。三家都使用 JSON 表達工具引數,但外層訊息角色、呼叫區塊名稱、識別欄位與結果回傳方式不同。你可以統一「內部語意」,不能直接假設三家的請求或回應 JSON 可以互換。

第一層對比:模型宣告工具,還是執行器真正負責工具

工具宣告不是 API 文件的全文複製。你應該只提供模型判斷所需的資訊:

  • 工具名稱:保持穩定,避免同義工具同時出現。
  • 工具描述:說明何時使用、何時禁止使用。
  • 輸入 Schema:列出型別、必填欄位、列舉值與格式限制。
  • 呼叫策略:允許自動選擇、強制工具、禁止工具,或限制平行呼叫。
  • 業務前置條件:例如只能查詢目前登入使用者可存取的資源。

JSON Schema 的價值,不只是讓 JSON 看起來整齊。它把模型可產生的輸入範圍縮小,讓執行器可以在進入外部 API 前做機械式驗證。OpenAI 的 strict 可要求工具呼叫遵循指定 Schema,但文件同時指出嚴格模式只支援 JSON Schema 的部分能力;Google Gemini 也使用 OpenAPI Schema 的支援子集。(OpenAI Structured Outputs 官方文件) (Google Gemini 官方 Function Calling 文件)

Function Calling 為什麼需要 JSON Schema?
因為自然語言無法直接作為可靠的函式輸入。Schema 能清楚區分字串、數字、布林值、陣列、必填欄位與允許值。不過 Schema 只處理「形狀」,不能確認使用者是否擁有資源,也不能替你完成授權。

例如,order_id 符合字串格式,不代表它屬於目前登入者。action: "delete" 符合列舉值,也不代表刪除動作已獲得批准。

第二層對比:適配層統一事件,但不要抹平原始回應

多模型專案最值得投資的部分,通常不是再包一層相似 SDK,而是定義內部事件。可以採用以下概念模型:

json
{
  "event_type": "tool_call_requested",
  "provider": "openai",
  "conversation_id": "internal-session-id",
  "call_id": "provider-call-id",
  "tool_name": "get_order_status",
  "arguments": {
    "order_id": "A-1001"
  },
  "raw_response_ref": "stored-response-id"
}

這個事件不是三家平台的通用請求格式,而是你自己的內部契約。供應商適配層應把不同欄位映射到 call_idtool_namearguments,同時保留原始回應、模型版本、SDK 版本與 API 入口。

原因很實際:

  • 後續排查時,你需要知道原始回應究竟是 tool_callsfunctionCall 還是 tool_use
  • 平行工具呼叫可能改變事件順序,不能只取最後一個文字區塊。
  • 某些平台有額外狀態或上下文欄位,過度正規化會讓重播與除錯失去依據。
  • 供應商更新格式後,你可以只修改適配器,不必重寫工具執行器。

如果你的專案還在驗證單一模型,直接使用官方 SDK 通常較快。若已有多個模型、共享工具目錄、集中審計或供應商故障切換,就應建立內部契約。你也可以先閱讀 AI Coding Agent 選型方向,再判斷是否需要把工具層抽成獨立服務。

第三層對比:模型提出請求,執行器承擔真實風險

工具執行器不是一個簡單的 eval(function_name, args)。最少要處理以下邊界:

  • 名稱白名單:模型只能呼叫註冊工具,不能自行拼接程式或命令。
  • Schema 驗證:先驗證型別、必填欄位、字串長度與列舉值。
  • 認證隔離:API 金鑰放在伺服器端的密鑰管理系統,不放入提示詞、對話內容或模型可讀檔案。
  • 逾時與重試:外部 API 失敗時要區分可重試錯誤與不可重試錯誤。
  • 冪等設計:建立訂單、寄信、付款等動作要有去重鍵,避免模型重試造成重複操作。
  • 結果封裝:回傳可讀的錯誤代碼與必要內容,不要把整個內部堆疊追蹤交給模型。
  • 資源所有權:以目前使用者的身分重新檢查資料權限。

模型生成錯誤引數時應該怎麼處理?
不要直接重試同一個請求。先把錯誤分成三類:

  1. JSON 無法解析:記錄原始輸出,要求模型重新產生。
  2. Schema 不合規:回傳欄位錯誤,限制重試次數。
  3. 業務規則不允許:停止執行,要求使用者補充或確認。

如果是高風險工具,應在執行前建立人工批准狀態。Schema 合規只代表輸入格式正確,不代表這個動作符合使用者授權、業務規則或資源所有權。

工具權限的條件分支

  • 若工具只讀取公開或已授權資料,則可考慮自動執行,但仍保留稽核記錄。
  • 若工具讀取私人資料,則必須先驗證登入身分與資源歸屬。
  • 若工具會寫入資料,則加入預覽、確認或可回滾機制。
  • 若工具具破壞性,例如刪除、停機或撤銷權限,則預設人工批准。
  • 若工具可連線開放網路,則限制網域、方法、頻寬與傳出資料,否則回退到受控代理服務。
  • 若工具需要長期執行、持續自動化或存取本機環境,則不要把整個伺服器權限交給模型,應使用隔離執行節點。

第四層對比:用同一業務樣例測試三家,而不是只測成功案例

測試時,三家平台應使用同一個只讀工具,例如「查詢訂單狀態」。但你要分別記錄平台、模型、SDK、API 入口與介面日期,不能只保存最後顯示給使用者的文字。

建議照以下步驟執行:

  1. 定義相同語意的工具:名稱可按平台規則調整,但輸入欄位與業務意思保持一致。
  2. 準備正常案例:使用合法訂單編號,確認模型能產生正確工具名稱與引數。
  3. 加入缺失欄位:故意省略訂單編號,觀察模型是追問、猜測,還是產生不完整呼叫。
  4. 加入錯誤資料:測試不存在的訂單、無權限訂單與格式錯誤輸入。
  5. 測試平行呼叫:準備兩個互不依賴的只讀查詢,確認事件解析不依賴固定順序。
  6. 模擬工具失敗:讓執行器回傳逾時、認證失敗與業務錯誤,觀察模型是否誤報成功。
  7. 測試歷史遺失:移除部分工具呼叫或結果,確認適配層能拒絕不完整狀態,而不是繼續執行。
  8. 驗證最終回答:工具回傳錯誤時,模型不得把錯誤結果包裝成已完成的動作。
測試項目 你要觀察的結果 不合格時的處理
引數缺失 模型是否追問或產生可識別的驗證錯誤 不執行外部 API,回傳欄位錯誤
多個工具呼叫 是否正確保存每個呼叫識別碼與順序 以事件佇列重組,不依賴文字位置
工具逾時 是否明確表示工具未完成 停止重試或套用冪等策略
權限不足 是否阻止跨使用者讀取 在執行器重新驗證所有權
歷史不完整 是否拒絕缺少結果的狀態 標記工作階段失效並要求重新開始
最終回答錯誤 是否把失敗說成成功 以工具執行狀態作為回覆依據

Claude API 的工具流程特別值得留意:tool_use 後,工具結果要用 tool_result 回傳,並透過 tool_use_id 對應;結果區塊的位置也有明確要求。這類訊息歷史規則若在適配層被忽略,通常會在多輪或失敗重試時才暴露。(Claude 官方 Tool Use 文件)

最後決策:直接用官方 SDK,還是建立多模型適配層?

你可以用以下分支做架構決定:

  • 目前只有一個模型、工具數量少、沒有供應商切換需求,先用官方 SDK,將執行器和權限檢查獨立出來。
  • 同一套工具要服務 OpenAI、Google Gemini 與 Claude API,建立內部工具目錄與事件契約,並保留每家平台的原始訊息。
  • 需要平行呼叫、長對話、重試或工作階段恢復,加入事件佇列、狀態儲存與重播機制,不要只靠一次 API 回應。
  • 工具會修改資料或觸發付款、刪除、部署,把批准流程放在模型之外。
  • 工具需要 macOS 指令、Xcode、iOS 模擬器或 Apple 自動化,再評估獨立的遠端 Mac 執行節點,而不是把本機權限直接暴露給模型。

這也是 Function Calling 與 MCP 等工具協議需要分開理解的原因:前者主要描述模型如何提出結構化工具請求,後者更偏向工具與 AI 應用之間的連線與發現方式。若你正在設計共享工具層,可延伸閱讀 MCP 與 AI Agent 工具整合方向

如果你目前用的是單一雲端執行環境,常見問題是權限邊界不清、長時間任務難以維持,以及涉及 Xcode 或 Apple 自動化時缺少原生 macOS 工具鏈。這些限制不一定能靠更複雜的提示詞解決。當你的 Agent 工具需要固定的 macOS、Xcode 或持續自動化環境時,租用 Hashvps 的遠端 Mac 資源會比把高權限工具塞進一般伺服器更容易隔離、測試與回收;若只是長期穩定重負載、必須接觸實體裝置,或已有固定本機設備,則自購 Mac 可能更合適。

為 AI 工具串接提供穩定的遠端 Mac 與算力

使用 Hashvps 遠端 Mac,快速建立適合 API 整合、Function Calling 與自動化測試的開發環境。
透過 Hashvps Mac 租賃,彈性取得獨立資源,方便驗證不同模型、工具流程及 JSON Schema。

前往首頁

Hashvps · Mac 雲端服務

獨享 Mac 雲端,物理原生 IP

專屬算力 + 獨享出口,穩定運行跨境業務。了解方案與定價。

前往首頁
限時優惠