載入中

嚴格工具使用:停止拒絕您自己的呼叫

第 2 課10 分鐘
載入中

嚴格工具使用:停止拒絕您自己的呼叫

摘要逐字稿

當您的後端拒絕 Claude 自己產生的工具呼叫時,嚴格工具使用就是解方。本影片在 Meridian(一家虛構的工程顧問公司)為一個工具開啟了此功能,並在開啟與關閉該功能的情況下執行相同的 100 個請求。

本影片中的示範錄製於 2026 年 9 月,執行於 Claude Haiku 4.5(claude-haiku-4-5)上。較新的模型可能會得到不同的結果。

Claude 通常會遵循工具的 input_schema,但預設情況下沒有任何機制強制執行這一點。因此,有時您的後端會拒絕 Claude 所發出的工具呼叫,因為該呼叫的輸入包含以下情況之一:

  • 字串 "2" 而非整數 2
  • 缺少必填欄位

嚴格工具使用可以解決這個問題。只要一個旗標 strict: true,就能讓 Claude 所寫的輸入符合您的 schema。

在 Meridian,一個助手使用 queue_stamp_request 工具來將圖紙集排入隊列,以取得持證工程師的印章。Meridian 的驗證器是用來檢查每個工具呼叫的程式碼。在關閉嚴格模式的情況下,它會拒絕 100 個請求中的 79 個。在開啟嚴格模式,並使用從驗證器產生的 schema 的情況下,它則不會拒絕任何一個。

嚴格工具使用的運作方式

在 strict: true 的情況下,API 會先將您的 JSON Schema 編譯成一套文法(grammar)。文法是一組規則,規定在輸入的每個位置接下來可以出現哪些 token。 然後,每當 Claude 要選擇工具呼叫的下一個 token 時,它只能選擇文法所允許的 token。這稱為文法約束取樣(grammar-constrained sampling)。

該 schema 表示 revision 是一個整數,而 Claude 已經寫到 "revision": 的位置。在未啟用嚴格模式時,可以選擇五個接下來的 token:3、"3"、three、3.0 和 null。在 strict: true 的情況下,只能選擇 3,其餘四個都被排除。

在 strict: true 的情況下,只能選擇您的 schema 所允許的 token,因此整數欄位會得到一個整數。

這是 Meridian 工具定義的精簡版本。嚴格模式需要其中兩行:旗標本身,以及該旗標所要求的一項設定。

json
{
  "name": "queue_stamp_request",
  "description": "Queues a drawing set for a professional engineer's stamp.",
  "strict": true,
  "input_schema": {
    "type": "object",
    "properties": {
      "drawing_set_id": {"type": "string"},
      "revision": {"type": "integer"}
    },
    "required": ["drawing_set_id", "revision"],
    "additionalProperties": false
  }
}
  • "strict": true 就是該旗標。它位於頂層,與 name、description 和 input_schema 並列,位於 schema 之外。
  • "additionalProperties": false 就是該設定。它表示輸入不能帶有 schema 中未指名的欄位,而嚴格模式要求每個物件都必須有這項設定。

從您的驗證器建構 schema

嚴格工具使用會讓 Claude 所寫的輸入符合您的 schema,因此 schema 必須說明與您的驗證器相同的內容。當您手動編寫 schema 時,兩者就會產生落差。這時工具呼叫即使符合 schema,仍可能被拒絕。 在 Meridian,一個手動編寫的 schema 將證照編號設定為沒有 pattern 的純字串。因此 "PE 46196" 通過了 schema 的驗證,卻未通過驗證器的驗證,因為驗證器要求格式必須是 PE- 加上五位數字。

請只在驗證器中撰寫一次規則,並由此產生 schema。在 Python 中,驗證器通常是一個 Pydantic 類別;在 TypeScript 中,則通常使用 Zod 來撰寫。

以下是 Meridian 的 Pydantic 類別 StampRequest,以及使用它的程式碼,接著是 StampRequest.model_json_schema() 所回傳的 schema。每個 # ... 代表未顯示的程式碼,而該 schema 只顯示證照編號的部分。

python
class StampRequest(BaseModel):
    model_config = {"extra": "forbid"}
    # ...
    pe_license_number: str | None = Field(pattern=r"^PE-\d{5}$")
    # ...
stamp_tool = {
    # ...
    "input_schema": StampRequest.model_json_schema(),
    "strict": True,
}
stamp_request = StampRequest.model_validate(call.input)
json
{
  "additionalProperties": false,
  "properties": {
    "pe_license_number": {
      "anyOf": [
        {"pattern": "^PE-\\d{5}$", "type": "string"},
        {"type": "null"}
      ],
      "title": "Pe License Number"
    }
  }
}
  • "extra": "forbid" 會變成 "additionalProperties": false,這是嚴格模式所要求的設定。
  • str | None 會變成 anyOf,因此證照編號會是一個符合該 pattern 的字串,或是 null。
  • model_validate() 會針對同一個類別,檢查 call.input(即 Claude 所寫的輸入)。

比較關閉與開啟嚴格模式的執行結果

Meridian 的測試會使用 queue_stamp_request 工具,向 Claude Haiku 4.5 發送 100 個以一般語言撰寫的印章請求,並由 StampRequest 驗證每一個工具呼叫。相同的 100 個請求會執行兩次:第一次使用手動編寫的 schema 並關閉嚴格模式,第二次則使用產生出來的 schema 並開啟嚴格模式。

請在下方重播這兩次執行結果。

載入中

schema 的 pattern 說明了允許的格式,而嚴格模式則讓 Claude 遵守這項格式。

嚴格模式控制輸入的結構,但無法提供請求本身從未給出的事實。在這 100 個請求中,有 28 個從未提及證照,而產生出來的 schema 允許證照編號為 null,因此這 28 個全部都回傳了 null。

嚴格工具使用的限制

截至 2026 年 10 月,您需要了解以下六件事:

  1. 不要放入受保護健康資訊(PHI)。 已編譯的 schema 不會像提示與回應那樣受到相同的 PHI 保護,因此請勿在屬性名稱、enum 值、const 值和 pattern 表達式中放入 PHI。
  2. 不支援邊界限制。 若請求的 schema 使用了 minimum、maximum、minLength 或 maxLength,將會回傳 400 錯誤。請在驗證器函式(例如 Pydantic 的 @field_validator)中檢查邊界限制,並在欄位的 description 中加以說明。
  3. 限制會跨工具累加。 一個請求最多可以包含 20 個嚴格工具。在這些工具中,最多可以包含 24 個選用參數。它也最多可以包含 16 個使用 anyOf 或型別陣列的參數,而像 str | None 這種可為 null 的欄位所產生的正是這種參數。
  4. 輸入仍可能無法符合 schema。 這種情況會發生在拒絕之後、回應因 max_tokens 而被截斷時,或是 enum 或 const 字串以不同大小寫回傳時。
  5. 部分模型會拒絕強制性的工具呼叫。 將 tool_choice 設為 any 或 tool 會強制進行工具呼叫。在 Claude Opus 5.5、Claude Sonnet 5.5、Claude Fable 5.1 和 Claude Mythos 5.1 上,這會回傳 400 錯誤。在這些模型上,請將 tool_choice 保留為預設值 auto。
  6. 程式化工具呼叫無法使用嚴格工具。 在程式化工具呼叫中,Claude 會撰寫呼叫您工具的程式碼。第 8 課將會說明這項內容。

重點整理

  • strict: true 會讓工具輸入符合您的 schema,但在拒絕或回應被截斷後,或是 enum 或 const 字串變更大小寫時除外。
  • 請從您的驗證器(例如 Pydantic 類別)產生 schema。
  • 請勿在 schema 中加入邊界限制,並在整個請求範圍內計算工具、選用參數和可為 null 的參數數量。