Claude 能夠與外部客戶端工具和函數交互,允許您使用自己的自定義工具來裝備 Claude,以執行更廣泛的任務。

現在,使用 Anthropic Messages API、Amazon Bedrock 和 Google Vertex AI 的開發人員可以在整個 Claude 3 模型系列中普遍使用工具!請繼續使用此表單分享您的想法和建議。

以下是使用 Messages API 為 Claude 提供工具的示例:


工具使用的工作原理

使用 Claude 的工具涉及以下步驟:

  1. 為 Claude 提供工具和用戶提示:(API 請求)
    • 定義您希望 Claude 訪問的工具集,包括它們的名稱、描述和輸入模式。
    • 提供一個用戶提示,可能需要使用一個或多個這些工具來回答,例如”舊金山的天氣如何?“。
  2. Claude 使用工具:(API 響應)
    • Claude 評估用戶提示,並決定是否有任何可用的工具可以幫助用戶的查詢或任務。如果是,它還會決定使用哪些工具以及使用什麼輸入。
    • Claude 構造格式正確的工具使用請求。
    • API 響應將具有 stop_reasontool_use,表示 Claude 想要使用外部工具。
  3. 提取工具輸入、運行代碼並返回結果:(API 請求)
    • 在客戶端,您應該從 Claude 的工具使用請求中提取工具名稱和輸入。
    • 在客戶端運行實際的工具代碼。
    • 通過使用包含 tool_result 內容塊的新 user 消息繼續對話,將結果返回給 Claude。
  4. Claude 使用工具結果來制定響應:(API 響應)
    • 在收到工具結果後,Claude 將使用該信息來制定對原始用戶提示的最終響應。

步驟 (3) 和 (4) 是可選的 - 對於某些工作流,Claude 使用工具就是您需要的所有信息,您可能不需要將工具結果返回給 Claude。

所有工具都是用戶提供的

請注意,Claude 無法訪問任何內置的服務器端工具。所有工具都必須由您(用戶)在每個 API 請求中明確提供。這使您可以完全控制和靈活地使用 Claude 可以使用的工具。


指定工具

工具在 API 請求的 tools 頂級參數中指定。每個工具定義包括:

  • name:工具的名稱。必須匹配正則表達式 ^[a-zA-Z0-9_-]{1,64}$
  • description:對工具的功能、何時應該使用以及如何運作的詳細純文本描述。
  • input_schema:定義工具的預期參數的 JSON Schema 對象。

以下是一個簡單的工具定義示例:

JSON
{
  "name": "get_weather",
  "description": "獲取給定位置的當前天氣",
  "input_schema": {
    "type": "object",
    "properties": {
      "location": {
        "type": "string",
        "description": "城市和州,例如 San Francisco, CA"
      },
      "unit": {
        "type": "string",
        "enum": ["celsius", "fahrenheit"],
        "description": "溫度單位,'celsius' 或 'fahrenheit'"
      }
    },
    "required": ["location"]
  }
}

這個名為 get_weather 的工具需要一個輸入對象,其中包含一個必需的 location 字符串和一個可選的 unit 字符串,該字符串必須是 “celsius” 或 “fahrenheit”。

工具定義的最佳實踐

為了在使用工具時獲得 Claude 的最佳性能,請遵循以下準則:

  • 提供極其詳細的描述。 這是工具性能中最重要的因素。您的描述應該解釋工具的每個細節,包括:
    • 工具的功能
    • 何時應該使用它(以及何時不應該使用)
    • 每個參數的含義以及它如何影響工具的行為
    • 任何重要的注意事項或限制,例如如果工具名稱不明確,工具不返回哪些信息 您可以為 Claude 提供有關工具的更多上下文,它就會更好地決定何時以及如何使用它們。每個工具描述至少要有 3-4 個句子,如果工具很複雜,則更多。
  • 優先考慮描述而不是示例。 雖然您可以在工具的描述或附帶的提示中包含如何使用工具的示例,但這不如對工具的目的和參數進行清晰全面的解釋重要。只有在充分完善描述之後才添加示例。

以下是一個好的工具描述示例:

JSON
{
  "name": "get_stock_price",
  "description": "檢索給定股票代碼的當前股價。股票代碼必須是在紐約證券交易所或納斯達克等主要美國證券交易所上市的公司的有效代碼。該工具將以美元返回最新交易價格。當用戶詢問特定股票的當前或最近價格時,應使用它。它不會提供有關股票或公司的任何其他信息。",
  "input_schema": {
    "type": "object",
    "properties": {
      "ticker": {
        "type": "string",
        "description": "股票代碼,例如 Apple Inc. 的 AAPL"
      }
    },
    "required": ["ticker"]
  }
}

相比之下,以下是一個不好的工具描述示例:

JSON
{
  "name": "get_stock_price",
  "description": "獲取股票代碼的股價。",
  "input_schema": {
    "type": "object",
    "properties": {
      "ticker": {
        "type": "string"
      }
    },
    "required": ["ticker"]
  }
}

好的描述清楚地解釋了工具的功能、何時使用它、它返回的數據以及 ticker 參數的含義。不好的描述太簡短,讓 Claude 對工具的行為和用法有許多未解答的問題。


工具使用和工具結果內容塊

當 Claude 決定使用您提供的工具之一時,它將返回一個 stop_reasontool_use 的響應,並在 API 響應中包含一個或多個 tool_use 內容塊,其中包括:

  • id:此特定工具使用塊的唯一標識符。這將用於稍後匹配工具結果。
  • name:正在使用的工具的名稱。
  • input:包含傳遞給工具的輸入的對象,符合工具的 input_schema

以下是包含 tool_use 內容塊的 API 響應示例:

JSON
{
  "id": "msg_01Aq9w938a90dw8q",
  "model": "claude-3-opus-20240229",
  "stop_reason": "tool_use",
  "role": "assistant",
  "content": [
    {
      "type": "text",
      "text": "<thinking>我需要使用 get_weather,用戶想要 SF,這可能是 San Francisco, CA。</thinking>"
    },
    {
      "type": "tool_use",
      "id": "toolu_01A09q90qw90lq917835lq9",
      "name": "get_weather",
      "input": {"location": "San Francisco, CA", "unit": "celsius"}
    }
  ]
}

當您收到工具使用響應時,您應該:

  1. tool_use 塊中提取 nameidinput
  2. 在您的代碼庫中運行與該工具名稱對應的實際工具,傳入工具 input
  3. [可選] 通過發送一個新消息來繼續對話,其中 roleusercontent 塊包含 tool_result 類型和以下信息:
    • tool_use_id:這是結果的工具使用請求的 id
    • content:工具的結果,作為字符串(例如 "content": "15 度")或嵌套內容塊的列表(例如 "content": [{"type": "text", "text": "15 度"}])。這些內容塊可以使用 textimage 類型。
    • is_error(可選):如果工具執行導致錯誤,則設置為 true

以下是返回成功工具結果的示例:

JSON
{
  "role": "user",
  "content": [
    {
      "type": "tool_result",
      "tool_use_id": "toolu_01A09q90qw90lq917835lq9",
      "content": "15 度"
    }
  ]
}

content 中也支持圖像:

JSON
{
  "role": "user",
  "content": [
    {
      "type": "tool_result",
      "tool_use_id": "toolu_01A09q90qw90lq917835lq9",
      "content": [
        {"type": "text", "text": "15 度"},
        {
          "type": "image",
          "source": {
            "type": "base64",
            "media_type": "image/jpeg",
            "data": "/9j/4AAQSkZJRg...",
          }
        }
      ]
    }
  ]
}

以下是返回錯誤結果的示例:

JSON
{
  "role": "user",
  "content": [
    {
      "type": "tool_result",
      "tool_use_id": "toolu_01A09q90qw90lq917835lq9",
      "content": "ConnectionError: 天氣服務 API 不可用(HTTP 500)",
      "is_error": true
    }
  ]
}

收到工具結果後,Claude 將使用該信息繼續生成對原始用戶提示的響應。

您還可以返回一個非錯誤的工具結果,其中 content 為空,表示工具成功運行而沒有任何輸出:

JSON
{
  "role": "user",
  "content": [
    {
      "type": "tool_result",
      "tool_use_id": "toolu_01A09q90qw90lq917835lq9",
    }
  ]
}

與其他 API 的區別

您可能熟悉其他 API,它們將工具使用作為與模型的主要輸出分開返回,或者使用特殊用途的 toolfunction 消息 role

相比之下,Anthropic 的模型和 API 圍繞交替的 userassistant 消息構建,其中每個消息都是豐富內容塊的數組:textimagetool_usetool_result

在此格式中,user 消息表示客戶端和用戶/人工管理的內容,而 assistant 消息表示服務器端和 AI 管理的內容。因此,沒有特殊的 toolfunction 消息 role,您應該在 user 消息的 content 中包含 tool_result 塊。


強制使用工具

在某些情況下,您可能希望 Claude 使用特定工具來回答用戶的問題,即使 Claude 認為它可以在不使用工具的情況下提供答案。您可以通過在 tool_choice 字段中指定工具來做到這一點,如下所示:

tool_choice = {"type": "tool", "name": "get_weather"}

通過明確告訴 Claude 使用 get_weather 工具,您可以鼓勵它使用您想要的工具。這種技術對於測試和調試您的工具集成很有用,或者當您知道無論輸入如何,都應該始終使用該工具時。

您還可以通過 {"type": "any"} 告訴 Claude 使用任何提供的工具。默認的 tool_choice{"type": "auto"},它允許 Claude 決定是否使用工具。

請注意,當您將 tool_choice 設置為 anytool 時,我們將預填助手消息以強制使用工具。這意味著即使明確要求模型這樣做,它也不會在 tool_use 內容塊之前發出思維鏈 text 內容塊。我們的測試表明,這不應降低性能。如果您想在仍然請求模型使用特定工具的同時保留思維鏈(特別是使用 Opus),您可以將 tool_choice 設置為 {"type": "auto"} (默認值),並在 user 消息中添加明確的指示。例如:“倫敦的天氣如何?在您的回答中使用 get_weather 工具。”


JSON 輸出

工具不一定需要是客戶端函數 - 您可以在希望模型返回符合提供的模式的 JSON 輸出時使用工具。例如,您可以使用具有特定模式的 record_summary 工具。有關完整的工作示例,請參閱工具使用示例


錯誤處理

在使用 Claude 的工具時,可能會發生幾種不同類型的錯誤:

工具執行錯誤

如果工具本身在執行過程中拋出錯誤(例如獲取天氣數據時的網絡錯誤),您可以在 content 中返回錯誤消息以及 "is_error": true

JSON
{
  "role": "user",
  "content": [
    {
      "type": "tool_result",
      "tool_use_id": "toolu_01A09q90qw90lq917835lq9",
      "content": "ConnectionError: 天氣服務 API 不可用(HTTP 500)",
      "is_error": true
    }
  ]
}

然後,Claude 將在其對用戶的響應中納入此錯誤,例如”對不起,我無法檢索當前天氣,因為天氣服務 API 不可用。請稍後再試。”

超過最大令牌數

如果由於達到 max_tokens 限制而截斷 Claude 的響應,並且截斷的響應包含不完整的工具使用塊,則需要使用更高的 max_tokens 值重試請求以獲取完整的工具使用。

無效的工具使用

如果 Claude 嘗試使用工具無效(例如缺少必需參數),這通常意味著沒有足夠的信息供 Claude 正確使用工具。在開發過程中,您最好的選擇是使用更詳細的工具定義中的 description 值重試請求。

但是,您也可以通過指示錯誤的 tool_result 繼續對話,Claude 將嘗試使用填充了缺失信息的工具再次使用:

JSON
{
  "role": "user",
  "content": [
    {
      "type": "tool_result",
      "tool_use_id": "toolu_01A09q90qw90lq917835lq9",
      "content": "錯誤:缺少必需的 'location' 參數",
      "is_error": true
    }
  ]
}

思維鏈工具使用

在使用工具時,Claude 通常會展示其”思維鏈”,即它用來分解問題並決定使用哪些工具的步驟。如果 tool_choice 設置為 auto(這是默認值,請參閱強制使用工具),Claude 3 Opus 模型將執行此操作,Sonnet 和 Haiku 可以通過提示來執行此操作。

例如,給定提示”現在舊金山的天氣如何,那裡現在幾點?“,Claude 可能會回答:

JSON
{
  "role": "assistant",
  "content": [
    {
      "type": "text",
      "text": "<thinking>要回答這個問題,我將:1. 使用 get_weather 工具獲取舊金山當前的天氣。2. 使用 get_time 工具獲取覆蓋舊金山的 America/Los_Angeles 時區的當前時間。</thinking>"
    },
    {
      "type": "tool_use",
      "id": "toolu_01A09q90qw90lq917835lq9",
      "name": "get_weather",
      "input": {"location": "San Francisco, CA"}
    }
  ]
}

這個思維鏈提供了對 Claude 推理過程的洞察,可以幫助您調試意外行為。

使用 Claude 3 Sonnet 模型時,默認情況下思維鏈不太常見,但您可以通過在用戶消息或系統提示中添加類似”在回答之前,請在標籤中逐步解釋您的推理。“來提示 Claude 展示其推理。有關更深入的示例,請參閱思維鏈工具使用示例

重要的是要注意,雖然 <thinking> 標籤是 Claude 用來表示其思維鏈的常見約定,但確切的格式(例如這個 XML 標籤的名稱)可能會隨時間而改變。您的代碼應該將思維鏈視為任何其他助手生成的文本,而不是依賴 <thinking> 標籤的存在或特定格式。


工具使用最佳實踐和限制

在使用 Claude 的工具時,請記住以下限制和最佳實踐:

  • 使用 Claude 3 Opus 導航複雜的工具使用,如果處理簡單的工具,則使用 Haiku:與其他模型相比,Opus 能夠處理最多的同時工具,並且在捕獲缺失參數方面更好。在參數未明確給出或不需要工具來完成用戶請求的模糊情況下,它更有可能要求澄清。Haiku 默認嘗試更頻繁地使用工具(即使與查詢無關),並且如果未明確給出參數,它將推斷缺失的參數。
  • 工具數量:即使使用數百個簡單工具和少量複雜工具,所有 Claude 3 模型都可以保持 >90% 的準確性。“複雜”工具是指具有大量參數或具有複雜模式(例如嵌套對象)的參數的工具。
  • 複雜和深度嵌套的工具:就像人類一樣,Claude 可以更好地使用更簡單的接口和更簡單的工具。如果 Claude 難以正確使用您的工具,請嘗試將輸入模式從深度嵌套的 JSON 對象扁平化,並減少輸入的數量。
  • 順序工具使用:Claude 通常更喜歡一次使用一個工具,然後使用該工具的輸出來指導其下一個操作。雖然您可以通過仔細設計提示和工具來提示 Claude 並行使用多個工具,但這可能會導致 Claude 為依賴早期工具使用結果的參數填充虛擬值。為了獲得最佳結果,請設計您的工作流程和工具,以引出並處理來自 Claude 的一系列順序工具使用。
  • 重試:如果 Claude 的工具使用請求無效或缺少必需參數,您可以返回錯誤響應,Claude 通常會使用填充了缺失信息的工具重試請求。但是,在 2-3 次失敗嘗試後,Claude 可能會放棄並向用戶返回道歉,而不是進一步重試。
  • 調試:在調試意外的工具使用行為時,請注意 Claude 的思維鏈輸出(如果有),以了解它為什麼做出這些選擇。您還可以嘗試提示 Claude 使用特定工具,看看是否會導致預期的行為。如果 Claude 誤用工具,請仔細檢查您的工具描述和模式是否清晰明確。
  • <search_quality_reflection> 標籤:有時在使用搜索工具時,模型可能會在其響應中返回 <search_quality_reflection> XML 標籤和搜索質量分數。要停止模型這樣做,請在提示的末尾添加句子”不要在您的響應中反映返回的搜索結果的質量。“。

通過牢記這些限制和準則,您可以設計有效的工具和主動編排,顯著擴展 Claude 處理各種任務的能力。


Beta 版本歷史(舊版)

截至 2024 年 5 月 30 日,工具使用不再處於 beta 版本,並且已普遍可用。

  • tools-2024-05-16
    • 系統提示更改為 Opus,以更好地處理在單個回合中可能需要多次工具使用的情況
  • tools-2024-04-04:工具使用的初始 beta 版本

後續步驟

工具使用是一種強大的技術,通過將 Claude 連接到外部數據源和功能來擴展其能力。使用一組精心設計的工具,您可以使 Claude 能夠處理大量單憑其基礎知識無法完成的任務。

一些可能的後續步驟包括:

  • 瀏覽我們的工具使用手冊:探索我們的現成工具使用代碼示例存儲庫,例如:
  • 提高工具使用質量和可靠性:迭代和改進您的工具描述和提示,以引出 Claude 更可靠和準確的工具使用
  • 擴展 Claude 的能力
    • 嘗試不同的工具和模式,看看 Claude 如何處理不同類型的輸入和輸出格式。
    • 將多個工具鏈接在一起,將複雜的任務分解為一系列更簡單的步驟。
    • 構建主動編排,讓 Claude 可以像助手一樣端到端地完成各種任務。
    • 探索複雜的工具使用架構,例如為 Claude 提供工具以執行 RAG 搜索,或調用較小的模型子代理(如 Haiku)代表它執行任務

在您使用工具構建時,我們很樂意聽取您的反饋並了解您的創作!加入我們的開發者 Discord,與其他開發者分享您的項目並討論技巧和技術。

我們很高興看到您如何使用工具使用來突破 Claude 的可能性界限。祝您構建愉快!