開發文件
工具呼叫
工具呼叫(Function Calling)讓模型按你定義的格式請求呼叫外部函式,比如查天氣、查資料庫、執行程式碼。模型只負責決定「呼叫哪個工具、傳什麼參數」,真正執行由你的程式碼完成。
基本流程
- 在請求裡用 JSON Schema 描述可用的工具。
- 模型判斷需要時,回傳工具名和參數,而不是直接回答。
- 你的程式碼執行工具,把結果作為新訊息發回。
- 模型根據結果給出最終回答。如果還需要別的工具,會繼續請求,迴圈直到完成。
OpenAI 相容格式
tools_openai.py
import json
from openai import OpenAI
client = OpenAI(api_key="sk-...", base_url="https://api.flyrouter.ai/v1")
tools = [{
"type": "function",
"function": {
"name": "get_weather",
"description": "查詢某個城市目前的天氣",
"parameters": {
"type": "object",
"properties": {"city": {"type": "string", "description": "城市名,如 北京"}},
"required": ["city"],
},
},
}]
messages = [{"role": "user", "content": "上海現在天氣怎麼樣?"}]
resp = client.chat.completions.create(model="gpt-6.1-sol", messages=messages, tools=tools)
msg = resp.choices[0].message
if msg.tool_calls:
messages.append(msg)
for call in msg.tool_calls:
args = json.loads(call.function.arguments)
result = {"city": args["city"], "weather": "多雲", "temperature": 22} # 換成你的實作
messages.append({"role": "tool", "tool_call_id": call.id, "content": json.dumps(result, ensure_ascii=False)})
resp = client.chat.completions.create(model="gpt-6.1-sol", messages=messages, tools=tools)
print(resp.choices[0].message.content)Anthropic 原生格式
Claude 的工具定義用 input_schema,模型請求呼叫時回傳 tool_use 內容區塊,你用 tool_result 區塊回傳結果:
tools_claude.py
from anthropic import Anthropic
client = Anthropic(api_key="sk-...", base_url="https://api.flyrouter.ai")
tools = [{
"name": "get_weather",
"description": "查詢某個城市目前的天氣",
"input_schema": {
"type": "object",
"properties": {"city": {"type": "string"}},
"required": ["city"],
},
}]
messages = [{"role": "user", "content": "上海現在天氣怎麼樣?"}]
resp = client.messages.create(model="claude-sonnet-5-5", max_tokens=4096, tools=tools, messages=messages)
while resp.stop_reason == "tool_use":
messages.append({"role": "assistant", "content": resp.content})
results = []
for block in resp.content:
if block.type == "tool_use":
output = '{"weather": "多雲", "temperature": 22}' # 換成你的實作
results.append({"type": "tool_result", "tool_use_id": block.id, "content": output})
messages.append({"role": "user", "content": results})
resp = client.messages.create(model="claude-sonnet-5-5", max_tokens=4096, tools=tools, messages=messages)
print(next(b.text for b in resp.content if b.type == "text"))實用建議
- 把
description寫清楚:工具做什麼、什麼時候該用、參數格式,這比任何參數都影響呼叫品質。 - 並行呼叫:模型可能一次請求多個工具。請全部執行,並把所有結果放在同一條訊息裡回傳。
- 執行失敗也要回傳:OpenAI 格式回傳錯誤說明;Anthropic 格式在
tool_result上加"is_error": true。不要直接丟掉。 - 參數一律按 JSON 解析:用
json.loads/JSON.parse解析參數,不要對原始字串做匹配。
新款 Claude 不支援強制呼叫
claude-opus-5-5、claude-sonnet-5-5、claude-fable-5-1 不接受 tool_choice 為 any 或指定工具(會回傳 400)。請使用預設的 auto,並在提示詞裡說明應該呼叫哪個工具;需要保證參數嚴格符合 Schema 時,在工具定義上加 "strict": true。