Tool schema 怎麼寫
name、description、input_schema 三件事。schema 寫得好決定 Claude 選不選對 tool;description 其實就是 tool 的 system prompt。
TL;DR
description寫得好 = Claude 選對 tool;它其實是「tool 的 system prompt」- 三件事最重要:name 動詞化、description 寫使用時機、required 寫死
- 別把 10 個以上 tool 塞進同一個 request——選擇正確率會掉,先合併或分組
一個情境:兩個 tool 撞名
你寫了一個聊天機器人,給 Claude 兩個 tool:
search—— 搜公司內部 wikilookup—— 查公司客戶 DB
跑了一天發現 user 問「客戶 X 上次下單的金額」,Claude 用了 search,回了一篇 wiki 文章。為什麼?因為兩個 name 都模糊,description 又只寫了「searches things」、「looks up data」,Claude 沒辦法分辨。
換個寫法立刻好:
search_internal_wiki—— 「搜尋公司 Confluence 內部 wiki,只用於找 onboarding 文件、流程說明、技術 spec。不適合找客戶資料、訂單、財報。」lookup_customer_record—— 「查詢 customer table,回傳該客戶的 profile、訂單歷史、最近聯絡紀錄。傳 customer_id 或 email。」
Description 寫對使用時機後,Claude 一次就選對。Schema 不是給機器看的,而是給 model 看的散文。
Schema 的三層結構
每個 tool 三個 top-level field:
{
"name": "get_current_datetime",
"description": "...",
"input_schema": { ... }
}
| 欄位 | 像什麼 | 重點 |
|---|---|---|
name | 函式名 | snake_case、動詞開頭、唯一 |
description | 函式 docstring + 用法注意事項 | 3–4 句最佳,寫做什麼 + 何時用 + 回什麼 |
input_schema | TypeScript interface / Pydantic model | 標準 JSON Schema,每個 property 也要寫 description |
input_schema 就是 JSON Schema spec。這不是 Anthropic 發明的,是已經存在十幾年的 data validation 標準,LLM 圈剛好拿來描述函式參數。
一個完整範例
get_current_datetime_schema = {
"name": "get_current_datetime",
"description": (
"Returns the current server-side date and time, formatted "
"according to the specified strftime pattern. Use this when "
"the user asks about today's date, current time, or needs a "
"timestamp for logging. Does NOT support timezones other than "
"UTC—use convert_timezone for that."
),
"input_schema": {
"type": "object",
"properties": {
"date_format": {
"type": "string",
"description": (
"Python strftime format string. Default: "
"'%Y-%m-%d %H:%M:%S'. Use '%H:%M' for time only."
),
"default": "%Y-%m-%d %H:%M:%S",
}
},
"required": [],
},
}
幾個細節:
name用動詞get_、set_、search_、create_開頭——讓 Claude 一眼看出意圖description不只寫做什麼,還寫何時用、何時不用- 每個 property 也要
description——這對 enum-like / 格式特殊的參數特別重要 required是「必填欄位」陣列;空的話放[]
Description 的「what + when + edge cases」
寫 description 想成你在交接這個 tool 給新同事:
| 段落 | 內容 |
|---|---|
| What | 一句話講做什麼,輸入什麼、輸出什麼 |
| When to use | 適用情境、典型 user query 例子 |
| When NOT to use | 跟其他 tool 重疊時誰先誰後、不適合的場景 |
| Edge cases / errors | 失敗會回什麼,常見參數陷阱 |
Anthropic 自己的建議是 3–4 句。一句太少、十句太多。model 看的是 token,太長會稀釋其他 tool 的 description。
跟 OpenAI function calling 的差別
兩家 schema 結構超像,差別小但會踩:
| Anthropic | OpenAI | |
|---|---|---|
| Schema 包裝 | { name, description, input_schema } | { "type": "function", "function": { name, description, parameters } } |
| Schema 欄位名 | input_schema | parameters |
| API 參數 | tools=[...] | tools=[...](兩家都這樣) |
| Tool result 格式 | tool_result block 在 user message | tool role message |
Migration 兩邊互轉的時候 input_schema ↔ parameters 是最常忘的點。
Type safety:用 ToolParam
純 dict 沒 type check,schema 拼錯只能 runtime 才發現。Anthropic SDK 提供 ToolParam 包一層:
from anthropic.types import ToolParam
get_current_datetime_schema: ToolParam = {
"name": "get_current_datetime",
"description": "...",
"input_schema": { ... },
}
不必須,但寫多 tool 的時候 IDE 會幫你抓掉很多 typo。
一個 request 給幾個 tool 才合理
實務經驗:
| Tool 數 | 行為 |
|---|---|
| 1–5 | 選擇正確率最高 |
| 6–10 | 仍 OK,但 description 要寫得清楚 |
| 10+ | 開始混淆——考慮動態裁切(依 user query 分類後只送相關的 tool) |
| 50+ | 很慢、很貴、很容易選錯 |
實務上,超過 10 個 tool 通常代表你在做 agent——這時候要做 tool routing(先用一個分類 prompt 決定哪批 tool 進 request),或上 MCP 把 tool 模組化。
接下來
寫好 schema 只是入場券——真的開始 tool use 之後,response 會變成 text / tool_use 這種 content block 陣列,需要新的處理方式。下一篇講 response 怎麼解、tool_result 怎麼包、tool_use_id 怎麼對。

