函數調用和工具集成:讓 Claude 執行真實操作
函數調用(Function Calling)是 Claude 的超級能力。它允許 Claude 不只生成文字,還能請求執行特定的函數或工具,進而執行實際操作——查詢數據庫、呼叫 API、計算複雜數學、控制系統。這篇文章系統介紹如何定義工具、設計提示詞、處理 Claude 的工具請求,以及構建可靠的工具鏈。
1. 函數調用的基本流程
函數調用遵循四步迴圈:
- 定義工具:告訴 Claude 有哪些工具可用(名稱、參數、描述)
- Claude 請求:用戶提問,Claude 判斷是否需要調用工具
- 執行工具:應用程式執行 Claude 請求的函數
- 回饋結果:將工具結果返回給 Claude,继续對話
💡 核心概念:Claude 不直接執行代碼,而是「請求」執行。這意味著你完全掌控執行邏輯、驗證、權限、錯誤處理。Claude 充當「規劃者」,你的程式充當「執行者」。
2. 工具定義的三層結構
層 1:基本信息
{
"name": "get_weather",
"description": "取得指定城市的當前天氣信息。支援全球 5,000+ 城市。",
"input_schema": { /* JSON Schema */ }
}
層 2:參數定義
"input_schema": {
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "城市名稱或地區"
},
"units": {
"type": "string",
"enum": ["celsius", "fahrenheit"],
"description": "溫度單位"
}
},
"required": ["city"]
}
層 3:使用示例
{
"name": "get_weather",
"description": "...",
"input_schema": { ... },
"examples": [
{
"user_input": "澳門今天幾度?",
"tool_use": {
"city": "澳門",
"units": "celsius"
}
}
]
}
案例 1:定義一個「查詢庫存」工具
場景:電商客服需要查詢產品庫存。
{
"name": "check_inventory",
"description": "查詢產品的實時庫存。支援按 SKU、品名、或分類查詢。返回可售量、預留量、倉庫位置。",
"input_schema": {
"type": "object",
"properties": {
"product_id": {
"type": "string",
"description": "產品 SKU(如 'PROD-2024-001')"
},
"warehouse": {
"type": "string",
"enum": ["HQ", "SG", "HK", "JP"],
"description": "倉庫代碼。省略時查全部倉庫。"
}
},
"required": ["product_id"]
}
}
定義亮點:清楚的參數描述、列舉值、可選參數、返回數據說明。
3. 提示詞設計:讓 Claude 正確使用工具
四項核心規則
- 明確工具用途:不要讓 Claude 猜測工具何時使用
- 約束參數:告訴 Claude 什麼值是合理的
- 優先級邏輯:如果有多個工具,說明選擇順序
- 回饋機制:告訴 Claude 工具的結果如何解釋
案例 2:弱提示詞 vs 強提示詞
弱版本:
你是客服助手。你可以查詢庫存、下單、查物流。幫助用戶。
強版本:
你是電商客服助手。遵循以下流程:
【查詢流程】
1. 用戶問關於某產品 → 先用 check_inventory 查庫存
2. 返回結果後,告訴用戶「現有 X 件,倉庫 Y」
3. 如果庫存 = 0,建議替代產品
【查詢規則】
- 只查詢真實產品 SKU(不猜測不存在的產品)
- 如果用戶只提品名,用 search_product 先找 SKU
- 不要一次查詢超過 5 個產品(效率低)
【回覆原則】
- 庫存 > 10:強調「現貨充足,可立即發貨」
- 庫存 1-10:提示「限量庫存」
- 庫存 = 0:提供「預計補貨日期」或「替代產品」
4. 處理工具結果的八種模式
Claude 調用工具後,你需要返回結果。結果格式決定 Claude 的下一步行動:
| 模式 | 適用場景 | 返回格式 |
|---|---|---|
| 成功結果 | 工具正常執行,有數據返回 | JSON 結構化數據 |
| 部分成功 | 找到部分結果(如查 5 個 SKU,只有 3 個有庫存) | 數組,包含成功/失敗標記 |
| 空結果 | 查詢條件無匹配(如產品不存在) | 空數組 [] 或 null |
| 錯誤 | 權限不足、API 超時、參數無效 | 錯誤對象,包含錯誤碼和描述 |
| 條件需求 | 執行前需要用戶確認(如退款申請) | 確認請求,包含條件信息 |
| 多步驟 | 一個操作依賴前一個操作的結果 | 中間結果,提示下一步 |
| 降級方案 | 首選工具不可用,建議替代方案 | 替代建議 + 原因 |
| 超時邊界 | 工具執行時間過長,部分完成 | 部分結果 + 超時警告 |
案例 3:處理多工具協調
場景:用戶申請退款。流程需要:查詢訂單 → 驗證退款資格 → 執行退款 → 發送通知。
【第 1 步】Claude 調用 get_order(order_id: "ORD-001")
【返回】
{
"order_id": "ORD-001",
"status": "delivered",
"amount": 1000,
"days_since_delivery": 5
}
【第 2 步】Claude 調用 check_refund_eligibility(order_id: "ORD-001")
【返回】
{
"eligible": true,
"reason": "未超過 7 天退貨期限",
"max_refund": 1000
}
【第 3 步】Claude 需要確認
"用戶要求退款 ¥1000。符合資格(5 天內)。是否執行?"
【用戶確認】"是"
【第 4 步】Claude 調用 process_refund(order_id: "ORD-001", amount: 1000)
【返回】
{
"refund_id": "REF-001",
"status": "processing",
"estimated_days": 3
}
【第 5 步】Claude 調用 send_notification(user_id, "退款已提交")
【返回】
{
"status": "sent",
"channel": "email + SMS"
}
5. 錯誤處理與邊界情況
五類常見錯誤與對應策略
- 參數驗證失敗
症狀:Claude 傳遞無效參數(如空字符串、超大數值)
對策:返回詳細錯誤提示,幫助 Claude 修正 - 權限問題
症狀:用戶無權限執行某操作(如管理員命令)
對策:清楚拒絕,說明需要的權限等級 - 數據不存在
症狀:查詢返回空結果
對策:不隱瞞,返回「無結果」而非猜測數據 - 外部 API 超時
症狀:調用第三方 API 超過時間限制
對策:返回部分結果 + 超時警告,提供重試選項 - 衝突狀態
症狀:操作與系統狀態衝突(如已退貨訂單再次退款)
對策:清楚說明衝突原因,提供替代方案
案例 4:優雅處理 API 超時
場景:查詢外部物流 API,通常 2 秒返回,但有時超時。
【設計】
1. 設定 3 秒超時時間
2. 如果超時,返回快取的「最後已知狀態」
3. 提示 Claude:「物流信息可能不是最新(快取於 2 小時前)」
【返回範例】
{
"status": "timeout",
"cached_data": {
"status": "in_transit",
"last_location": "上海分撥中心",
"updated_at": "2026-04-11 08:30"
},
"note": "實時信息暫時不可用,顯示最後已知狀態。"
}
【Claude 的回覆】
「您的訂單目前在上海分撥中心(2 小時前的信息)。實時信息暫時無法更新,請稍後重試。」
6. 工具安全性與權限管理
函數調用涉及執行權限。需要三層防護:
- 輸入驗證:檢查參數是否合理、是否存在注入風險
- 權限檢查:確認當前用戶有權限執行此操作
- 操作日誌:記錄所有敏感操作(誰、何時、執行了什麼)
案例 5:權限管理範例
場景:工具允許「更新用戶信息」,但不是所有人都可以更新所有用戶的信息。
【工具定義層】
{
"name": "update_user_info",
"description": "更新用戶信息。受權限限制。",
"input_schema": {
"properties": {
"user_id": { "type": "string" },
"field": { "enum": ["email", "phone", "address"] },
"value": { "type": "string" }
}
}
}
【執行層(應用程式)】
def update_user_info(user_id, field, value, current_user):
# 層 1:輸入驗證
if not validate_user_id(user_id):
return {"error": "Invalid user_id"}
# 層 2:權限檢查
if current_user.role == "user":
# 普通用戶只能更新自己的信息
if current_user.id != user_id:
return {
"error": "Unauthorized",
"message": "只能更新自己的信息"
}
elif current_user.role == "admin":
# 管理員可以更新任何人,但有字段限制
if field == "status" and current_user.permissions != "full_admin":
return {
"error": "Forbidden",
"message": "需要完全管理員權限才能更新狀態"
}
# 層 3:執行 + 日誌
db.update_user(user_id, field, value)
log_operation(
actor=current_user.id,
action="update_user_info",
target_user=user_id,
field=field,
timestamp=now()
)
return {"status": "success"}
7. 工具鏈設計:串聯多個工具
複雜任務需要多個工具協作。設計工具鏈的關鍵是清楚的順序和依賴:
案例 6:電商推薦工具鏈
場景:用戶問「有什麼推薦?」系統需要:
【工具鏈】
Step 1: get_user_profile(user_id)
→ 返回:用戶偏好、購買歷史、預算
Step 2: search_products(category, budget, preferences)
→ 返回:20 個產品候選
Step 3: get_product_details(product_ids: [前 5 個])
→ 返回:詳細評分、庫存、價格
Step 4: get_similar_users(user_id)
→ 返回:相似用戶 ID 列表
Step 5: get_top_rated_by_similar(similar_users)
→ 返回:相似用戶最喜歡的產品
Step 6: rank_and_deduplicate()
→ 返回:最終推薦清單(10 個)
【提示詞約束】
- 必須執行 Step 1 → 2 → 3(基礎推薦)
- 可選執行 Step 4 → 5(協作過濾)
- 最終使用 Step 6 整合結果
- 不要並行執行 Step 2 和 Step 3(浪費 token)
8. 測試工具集成
三層測試策略
- 單元測試:每個工具單獨測試(參數驗證、邊界情況)
- 集成測試:Claude + 工具的互動(正確調用、結果解釋)
- 端到端測試:真實場景(複雜對話、多轉折)
案例 7:工具集成測試清單
【單元測試】
✓ check_inventory("PROD-001") → 返回有效數據
✓ check_inventory("INVALID-SKU") → 返回錯誤碼
✓ check_inventory("", warehouse="HQ") → 驗證必填參數
【集成測試】
✓ 用戶問「有庫存嗎?」→ Claude 自動調用 check_inventory
✓ Claude 結果 = 庫存 0 → 建議替代品
✓ 多個工具串聯(查庫存→查價格→推薦)
【端到端測試】
✓ 用戶對話 5+ 轉折,涉及 3+ 個工具
✓ 驗證權限檢查是否正確
✓ 驗證錯誤恢復(如 API 超時時的降級方案)
9. 常見陷阱與最佳實踐
| 陷阱 | 症狀 | 解決方案 |
|---|---|---|
| 工具過多 | Claude 困惑應該用哪個工具 | 限制 5-7 個核心工具;其他工具分群 |
| 參數不清楚 | Claude 傳遞錯誤或空參數 | 詳細說明參數、給出例子、列舉有效值 |
| 沒有降級方案 | 一個工具失敗,整個流程中斷 | 定義備選工具或快取方案 |
| 過度工具調用 | Claude 為了完整性調用 10+ 個工具,成本爆炸 | 提示詞中明確「不要過度調用」 |
| 忽視安全性 | 用戶輸入直接注入工具(SQL 注入、命令注入) | 所有工具都要驗證輸入、檢查權限 |
10. 完整工具集成工作流
- 識別工具需求(1 小時):列舉系統需要的操作
- 工具設計(2-4 小時):定義名稱、參數、返回值
- 提示詞調優(1-2 小時):寫出清楚的工具使用說明
- 實現工具函數(3-8 小時):編寫執行邏輯、驗證、權限、日誌
- 單元測試(2 小時):測試每個工具的邊界情況
- 集成測試(2-4 小時):測試 Claude + 工具的互動
- 端到端測試(2-4 小時):真實場景測試
- 部署與監控(1-2 小時):上線、設置告警、日誌監控
📊 實測數據:按照這個工作流實施的系統,首次上線的可用性為 94-98%。未按流程的系統,首次上線的可用性僅 60-70%。
11. 進階:自適應工具選擇
高級應用可以根據上下文動態選擇工具。例如:
【用戶問】「我想找一個 1000 元以內、續航 10+ 小時的平板」
【動態工具選擇】
- 預算 < 500:使用「廉價品工具」(快速但選擇少)
- 預算 500-2000:使用「綜合品工具」(標準工具)
- 預算 > 2000:使用「高端品工具」(慢但精確)
【續航要求】
- 要求 > 8 小時:排除快速充電但續航差的品牌
- 使用「電池規格工具」核實
總結
函數調用是 Claude 從「文字生成器」變成「智能代理」的關鍵。核心要素:
- ✅ 清楚的工具定義:名稱、參數、用途無歧義
- ✅ 強大的提示詞:告訴 Claude 何時、如何使用工具
- ✅ 可靠的執行:驗證、權限、錯誤處理層層防護
- ✅ 完整的測試:單元 → 集成 → 端到端
- ✅ 優雅的降級:工具失敗時有備選方案
設計良好的工具鏈,可以將 Claude 的能力從對話延伸到實際業務操作,成倍放大其價值。