Agent不聽話、總犯錯? Claude官方開發指南:手把手教你打造高效工具,讓大模型秒變“靠譜員工”

Anthropic 這篇《Writing effective tools for AI agents — with agents》把給智能體寫工具從零散經驗上升為可復現的方法論:強調以評估驅動的迭代流程、以Agents為中心的工具設計原則(namespacing、簡潔響應、token 效率等),並展示用影響Claude 對行業的最佳設計路徑

過去我們把API 當成給程式設計師用的契約,現在要把介面重新設計成能被會思考的模型理解的工具。 Anthropic 這篇工程帖子,把這件事從經驗總結,推演成一套可執行的工程流程——從原型、評估、到讓Claude 自己參與改進工具。讀完它,你會發現:未來的後端介面設計,不再只為了機器──而是為了會推理的機器

Agent的效能取決於提供給它們的工具。本文將分享如何編寫高品質的工具和評估方法,以及如何利用Claude 來為它自己優化工具,從而提升效能

模型上下文協議(Model Context Protocol, MCP)可以為大語言模型代理賦予數百種工具來解決現實世界的任務。但如何讓這些工具的效能最大化呢?

本文將介紹在多種代理AI 系統中提升效能最有效的技巧

首先,本文將涵蓋如何:

1.建構和測試工具的原型

2.建立並運行針對代理使用工具的全面評估

3.與像Claude Code 這樣的代理協作,自動提升工具的效能

最後,本文將總結在此過程中總結出的編寫高品質工具的關鍵原則:

選擇正確的工具進行實現(以及不實現)

通過命名空間為工具定義清晰的功能邊界

從工具向代理傳回有意義的上下文

優化工具響應的詞元(token)效率

通過提示工程優化工具描述和規範

什麼是工具?

在計算領域,確定性系統在給定相同輸入時總是產生相同的輸出,而非確定性系統——例如代理——即使在起始條件相同的情況下也可能產生不同的響應。

在傳統軟件編寫中,是在確定性系統之間建立契約。例如,像 getWeather("NYC") 這樣的函數呼叫,每次執行時都會以完全相同的方式獲取紐約市的天氣。

工具是一種新型軟件,它反映了確定性系統與非確定性代理之間的契約。當使用者問“我今天需要帶傘嗎?”,代理商可能會呼叫天氣工具,也可能根據常識回答,甚至可能先詢問地點等澄清性問題。偶爾,代理可能會產生幻覺,或無法理解如何使用某個工具。

這意味著在為代理程式編寫軟件時,需要從根本上反思方法:不能像為其他開發者或系統編寫函數和API 那樣來編寫工具和MCP 服務器,而是需要為代理進行設計。

目標是透過使用工具來追求各種成功的策略,從而擴大代理人能夠有效解決各類任務的範圍。幸運的是,根據經驗,那些對代理人而言最「易於使用」的工具,最終對人類來說也出乎意料地直觀易懂。

如何編寫工具

本節將介紹如何與代理協作來編寫並改進提供給它們的工具。首先,快速建立一個工具原型並在本地進行測試。接著,運行一次全面的評估來衡量後續的改動效果。透過與代理商協同工作,可以重複評估和改進工具的流程,直到代理商在真實世界任務上取得優異的效能。

建構原型

在沒有親身實踐的情況下,很難預見那些工具對代理商來說是易於使用的,那些不是。首先應快速建構一個工具原型。如果使用Claude Code 編寫工具(可能是一次性生成),向Claude 提供工具所依賴的任何軟體庫、API 或SDK(可能包括MCP SDK)的檔案會很有幫助。大語言模型友善的檔案通常可以在官方檔案網站的扁平化 llms.txt 檔案中找到。

將工具包裝在本機MCP 服務器或桌面擴展(DXT)中,就可以在Claude Code 或Claude 桌面應用中連接並測試工具。

若要將本機MCP 伺服器連接到Claude Code,請運行 claude mcp add <name> <command> [args...]

若要將本機MCP 服務器或DXT 連接至Claude 桌面應用,分別導航至“設定> 開發者”或“設定> 擴充”

工具也可以直接傳遞到Anthropic API 通話中進行程式設計測試

親自測試這些工具,找出任何不順手的地方。收集使用者的回饋,以便對工具所要支援的用例和提示建立直觀的理解。

運行評估

接下來,需要透過運行評估來衡量Claude 使用工具的效果。首先,基於真實世界用例產生大量的評估任務。建議與代理協作,幫助分析結果並確定如何改進工具

生成評估任務

利用早期原型,Claude Code 可以快速探索工具並建立數十個提示和回應對。提示應受到真實世界用例的啟發,並基於現實的資料來源和服務(例如,內部知識庫和微服務)。建議避免使用過於簡單或膚淺的「沙盒」環境,因為它們無法以足夠的複雜性對工具進行壓力測試。一個好的評估任務可能需要多次工具呼叫——甚至可能多達數十次

以下是一些好的任務範例:

安排下周與Jane 開會,討論最新的Acme 公司項目。附上我們上次項目規劃會議的紀要,並預訂一間會議室

客戶ID 9182 報告稱,他們的一次購買嘗試被收取了三次費用。找出所有相關的日誌條目,並確定是否有其他客戶受到相同問題的影響

客戶Sarah Chen 剛剛提交了取消請求。準備一份挽留方案。確定:(1) 他們離開的原因,(2) 那種挽留方案最具吸引力,以及(3) 在提出方案前需要注意的任何風險因素。

以下是一些較弱的任務範例:

安排下周與 jane@acme.corp 開會

在支付日誌中搜尋 purchase_complete 和 customer_id=9182

根據客戶ID 45892 尋找取消請求

每個評估提示都應配有一個可驗證的回應或結果。驗證器可以像基準真相與採樣響應之間的精確字串比較一樣簡單,也可以像讓Claude 來評判響應一樣高級。避免使用過於嚴格的驗證器,它們可能會因為格式、標點或有效的替代表述等無關緊要的差異而拒絕正確的回應。

對於每個提示-響應對,可以選擇性地指定期望代理在解決任務時呼叫的工具,以衡量代理在評估過程中是否成功掌握了每個工具的用途。然而,由於解決任務可能存在多種有效路徑,因此應盡可能避免過度指定或對特定策略過擬合。

運行評估

建議透過直接呼叫LLM API 以編程方式運行評估。使用簡單的代理循環(包裹著交替的LLM API 和工具呼叫的 while 循環):每個評估任務一個循環。每個評估代理都應被賦予一個任務提示和相應的工具。

在評估代理程式的系統提示中,建議不僅指示代理輸出結構化的響應塊(用於驗證),還要輸出推理和反饋塊。指示代理在工具呼叫和響應塊之前輸出這些內容,可能會觸發思維鏈(CoT)行為,從而提高大語言模型的有效智能

如果使用Claude 執行評估,可以開啟「交錯思考」(interleaved thinking)功能以獲得類似的效果。這將有助於探查代理呼叫或不呼叫某些工具的原因,並突出工具描述和規範中需要改進的具體方面。

除了頂層精準率外,還建議收集其他指標,如單一工具呼叫和任務的總執行階段間、總工具呼叫次數、總詞元消耗量和工具錯誤。追蹤工具呼叫可以揭示代理常用的工作流程,並為工具的整合提供一些機會

分析結果

代理是發現問題和提供反饋的得力助手,它們能就從矛盾的工具描述到低效的工具實現和令人困惑的工具模式等一切問題提供反饋。但請記住,代理在反饋和回應中遺漏的內容往往比它們包含的內容更重要。大語言模型並不總能言如其意。

觀察代理在何處遇到困難或感到困惑。通讀評估代理人的推理和回饋(或思維鏈),以找出不順手的地方。審查原始互動記錄(包括工具呼叫和工具回應),以捕捉代理思維鏈中未明確描述的任何行為。要讀懂言外之意;記住,評估代理人不一定知道正確的答案和策略。

分析工具呼叫指標。大量的冗餘工具呼叫可能表示需要調整分頁或詞元限制參數;大量因參數無效而導致的工具錯誤可能表示工具需要更清晰的描述或更好的範例。在推出Claude 的網路搜尋工具時,發現Claude 會不必要地將「2025」附加到工具的查詢參數中,這導致搜尋結果出現偏差並降低了效能(透過改進工具描述引導Claude 回到了正確的方向)。

與代理協作

甚至可以讓代理來分析結果並改進工具。只需將評估代理的互動記錄拼接起來,然後貼上到Claude Code 中。 Claude 是分析互動記錄和一次性重構大量工具的專家——例如,在進行新更改時,確保工具的實現和描述保持自洽。

實際上,本文中的大部分建議都來自於重複使用Claude Code 優化內部工具實現的過程。這些評估建立在內部工作空間之上,反映了內部工作流程的複雜性,包括真實的項目、檔案和訊息。

通過使用獨立的測試集來確保沒有對“訓練”用的評估集過擬合。這些測試集表明,即使是基於「專家」編寫的工具實現——無論是研究員手動編寫的還是由Claude 自己生成的——也仍然可以獲得額外的性能提升。

編寫高效工具的原則

本節將把所學的經驗提煉為幾個編寫高效工具的指導原則。

為代理選擇正確的工具

更多的工具並不總是能帶來更好的結果。一個常見的錯誤是,工具只是對現有軟件功能或API 端點的簡單包裝——而不管這些工具是否適合代理。這是因為代理相對於傳統軟件有不同的「功能可見性」(affordances)——也就是說,它們感知其可以採取的潛在行動的方式不同。

大語言模型代理的「上下文」(即它們一次能處理的資訊量)是有限的,而電腦內存則是廉價且充足。考慮在通訊錄中搜尋聯絡人的任務。傳統軟件程式可以有效率地儲存和逐個處理聯絡人列表,檢查完一個再移至下一個。

然而,如果一個大語言模型代理使用的工具返回了所有聯繫人,然後它必須逐個詞元地閱讀每個聯繫人,那麼它就是在不相關的資訊上浪費其有限的上下文空間(想像一下通過從頭到尾閱讀每一頁來在地址簿中尋找聯繫人——也就是通過暴力搜尋)。更好、更自然的方法(對代理人和人類都一樣)是先跳到相關的頁面(也許是按字母順序尋找)。

建議先建構少數幾個經過深思熟慮的工具,針對特定的高影響力工作流程,這些工作流程應與評估任務相匹配,然後在此基礎上逐步擴展。在地址簿的例子中,可以選擇實現一個 search_contacts 或 message_contact 工具,而不是一個 list_contacts 工具。

工具可以整合功能,在底層處理可能多個離散的操作(或API 通話)。例如,工具可以用相關的中繼資料豐富工具來回應,或是在一個工具呼叫中處理頻繁鍊式呼叫的多步驟任務。

以下是一些範例:

與其實現 list_userslist_events 和 create_event 工具,不如考慮實現一個 schedule_event 工具,該工具可以尋找空閒時間並安排事件

與其實現一個 read_logs 工具,不如考慮實現一個 search_logs 工具,它只會傳回相關的日誌行和一些上下文

與其實現 get_customer_by_idlist_transactions 和 list_notes 工具,不如實現一個 get_customer_context 工具,該工具一次彙編客戶所有近期和相關的資訊。

確保建構的每個工具都有一個清晰、獨特的目的。工具應能讓代理人像人類在擁有相同底層資源的情況下那樣,對任務進行細分和解決,並同時減少本應被中間輸出消耗的上下文。

過多的工具或功能重疊的工具也可能分散代理的注意力,使其無法採取高效的策略。謹慎、有選擇地規劃要建構(或不建構)的工具,可以帶來巨大的回報。

為工具使用命名空間

AI 代理程式可能會接觸到數十個MCP 服務器和數百個不同的工具——包括其他開發者開發的工具。當工具功能重疊或目的模糊時,代理可能會混淆該使用那個。

命名空間(將相關工具按共同的前綴分組)有助於在眾多工具之間劃定界限;MCP 客戶端有時會默認這樣做。例如,按服務(如 asana_searchjira_search)和按資源(如 asana_projects_searchasana_users_search)對工具進行命名空間劃分,可以幫助代理在正確的時間選擇正確的工具。

實踐發現,選擇基於前綴還是後綴的命名空間方案,對工具使用評估有不可忽視的影響。這種影響因大語言模型而異,建議根據自己的評估選擇命名方案。

代理可能會呼叫錯誤的工具,用錯誤的參數呼叫正確的工具,呼叫過少的工具,或錯誤地處理工具回應。透過選擇性地實現其名稱能反映任務自然劃分的工具,可以同時減少載入到代理上下文中的工具和工具描述的數量,並將代理計算從代理的上下文中轉移回工具呼叫本身。這降低了代理犯錯的總體風險。

從工具中傳回有意義的上下文

同樣地,工具的實現應注意只向代理傳回高資訊量的訊號。它們應優先考慮情境相關性而非靈活性,並避免使用低等級的技術識別碼(例如:uuid256px_image_urlmime_type)。像 nameimage_url 和 file_type 這樣的欄位更有可能直接為代理的後續行動和回應提供資訊。

當代理處理自然語言名稱、術語或識別碼時,也比處理晦澀的識別碼成功得多。實踐發現,僅僅將任意的字母數字UUID 解析為更具語義意義和可解釋性的語言(甚至是0 索引的ID 方案),就能通過減少幻覺顯著提高Claude 在檢索任務中的精確度。

在某些情況下,代理可能需要靈活地與自然語言和技術識別碼輸出進行互動,即使只是為了觸發後續的工具呼叫(例如,search_user(name=’jane’) → send_message(id=12345))。可以透過在工具中暴露一個簡單的 response_format 列舉參數來實現這一點,讓代理控制工具是傳回「簡潔」還是「詳細」的回應。

可以加入更多格式以獲得更大的靈活性,類似於GraphQL,可以選擇確切地想要接收那些資訊。以下是一個用於控制工具響應詳細程度的 ResponseFormat 枚舉範例:

enum ResponseFormat {
   DETAILED = "detailed",
   CONCISE = "concise"
}

這是一個詳細工具響應的範例(206 個詞元):

這是一個簡潔工具響應的範例(72 個詞元):

即使是工具的回應結構——例如XML、JSON 或Markdown——也可能對評估效能產生影響:沒有萬能的解決方案。這是因為大語言模型是基於下一個詞元預測進行訓練的,它們往往在處理與其訓練資料格式相符的格式時表現更好。最佳的響應結構會因任務和代理的不同而有很大差異。建議根據自己的評估選擇最佳的響應結構。

優化工具響應的詞元效率

優化上下文的品質很重要,但優化工具回應中傳回給代理程式的上下文數量也同樣重要。

建議為任何可能消耗大量上下文的工具回應,實施分頁、範圍選擇、過濾和/或截斷的組合,並設定合理的預設參數值。對於Claude Code,工具響應默認限制在25,000 個詞元。預計代理的有效上下文長度會隨著時間的推移而增長,但對上下文高效的工具的需求將持續存在。

如果選擇截斷響應,請務必用有用的指令來引導代理。可以直接鼓勵代理人採取更節省詞元的策略,例如在知識檢索任務中進行多次小範圍、有針對性的搜尋,而不是一次大範圍的搜尋。同樣,如果工具呼叫引發錯誤(例如,在輸入驗證期間),可以通過提示工程優化錯誤響應,以清晰地傳達具體且可操作的改進建議,而不是返回不透明的錯誤代碼或追溯資訊。

這是一個截斷工具響應的範例:

這是一個無益的錯誤響應範例:

這是一個有益的錯誤響應範例:

通過提示工程優化工具描述

現在介紹一種最有效的工具改進方法:通過提示工程優化工具的描述和規範。因為這些內容會被載入到代理的上下文中,它們可以共同引導代理採取有效的工具呼叫行為。

在編寫工具描述和規範時,可以想像如何向團隊中的新成員描述這個工具。考慮那些可能隱含的背景資訊——專門的查詢格式、小眾術語的定義、底層資源之間的關係——並將它們明確化。通過清晰地描述(並用嚴格的數據模型強制執行)預期的輸入和輸出來避免歧義。特別是,輸入參數應明確命名:與其使用名為 user 的參數,不如嘗試使用名為 user_id 的參數。

透過評估,可以更有信心地衡量提示工程帶來的影響。即使是對工具描述進行微小的改進,也可能帶來顯著的效能提升。在對工具描述進行精確優化後,Claude Sonnet 3.5 在SWE-bench Verified 評估中取得了業界領先的效能,錯誤率大幅降低,任務完成率顯著提高。

可以在開發者指南中找到有關工具定義的其他最佳實踐。如果正在為Claude 建立工具,也建議閱讀關於工具如何動態載入到Claude 系統提示中的內容。最後,如果正在為MCP 服務器編寫工具,工具註解有助於說明那些工具需要訪問開放世界或會進行破壞性更改。

展望未來

要為代理程式建構有效的工具,需要將軟件開發實踐從可預測的、確定性的模式轉向非確定性的模式。

透過本文所描述的迭代、評估驅動的流程,已經識別出成功工具的一致模式:有效的工具目標明確、定義清晰,能明智地使用代理上下文,可以組合成多樣化的工作流程,並能讓代理直觀地解決真實世界的任務。

未來,預計代理與世界互動的具體機制將會演變——從MCP 協議的更新到基礎大語言模型本身的升級。透過系統化、評估驅動的方法來改進代理工具,可以確保隨著代理能力的增強,它們使用的工具也將與之共同進化 (AI寒武紀)