建立一個 Agent 的動作空間,最困難的部分之一就是設計它的行動範圍。
Claude 透過 Tool Calling 來行動,但在 Claude API 中,有許多方式可以建構工具,例如使用 bash、技能,以及最近的程式碼執行功能(更多關於 Claude API 程式化工具呼叫的資訊,請參閱 @RLanceMartin 的新文章)。
在這麼多選擇之下,你要如何設計你的 Agent 工具?你只需要一個像程式碼執行或 bash 這樣的工具就夠了嗎?如果你有 50 個工具,每個對應一個 Agent 可能遇到的用例,又該怎麼辦?
為了讓自己站在模型的角度思考,我喜歡想像自己面對一個困難的數學問題。你會想要哪些工具來解決它?這取決於你自己的技能!
紙筆是最基本的,但你會受限於手動計算。計算機更好,但你得知道如何操作進階功能。最快、最強大的選項是電腦,但你必須知道如何使用它來編寫和執行程式碼。
這是一個設計 Agent 很有用的框架。你希望給予的工具要符合它自身的能力。但你怎麼知道那些能力是什麼?你要觀察、閱讀它的輸出、進行實驗。你要學會像 Agent 一樣看事情。
以下是在打造 Claude Code 的過程中,我們從觀察 Claude 身上學到的一些經驗。
改善引導與 AskUserQuestion 工具

在建立 AskUserQuestion 工具時,我們的目標是提升 Claude 提問的能力(通常稱為引導)。
雖然 Claude 可以直接用純文字提問,但我們發現回答這些問題感覺花費了不必要的時間。我們要如何降低這個摩擦,並提高使用者與 Claude 之間的通訊頻寬?
嘗試 #1 - 編輯 ExitPlanTool
我們首先嘗試在 ExitPlanTool 中加入一個參數,讓它能夠在計畫旁邊帶有一組問題。這是最容易實作的方式,但卻讓 Claude 感到困惑,因為我們同時要求它提供計畫以及關於計畫的問題。如果使用者的回答與計畫內容衝突怎麼辦?Claude 需要呼叫兩次 ExitPlanTool 嗎?我們需要另一種方法。
(更多關於我們為何建立 ExitPlanTool 的資訊,請參閱 我們關於提示快取的文章)
嘗試 #2 - 改變輸出格式
接著我們嘗試修改 Claude 的輸出指令,讓它使用一種稍微修改過的 Markdown 格式來提問。例如,我們可以要求它輸出一個帶有選項的條列式問題清單,然後我們可以解析並將該問題格式化為使用者介面。
雖然這是我們能做的最通用的改變,而且 Claude 似乎也還算擅長輸出這種格式,但這並不能保證。Claude 可能會附加額外的句子、省略選項,或使用完全不同的格式。
嘗試 #3 - AskUserQuestion 工具

最後,我們決定建立一個 Claude 可以在任何時候呼叫的工具,但特別提示它在計畫模式時這麼做。當工具觸發時,我們會顯示一個模態視窗來呈現問題,並阻擋 Agent 的迴圈,直到使用者回答。
這個工具讓我們能夠提示 Claude 產生結構化的輸出,並幫助我們確保 Claude 提供使用者多個選項。它也讓使用者能夠組合這個功能,例如在 Agent SDK 中呼叫它,或在技能中引用它。
最重要的是,Claude 似乎喜歡呼叫這個工具,而且我們發現它的輸出效果很好。即使是最好的設計工具,如果 Claude 不了解如何呼叫它,也無法發揮作用。
這就是 Claude Code 中引導功能的最終型態嗎?我們不確定。正如你在下一個例子中會看到的,對某個模型有效的做法,對另一個模型可能不是最好的。
隨著能力更新 - Tasks 與 Todos

當我們首次推出 Claude Code 時,我們意識到模型需要一個待辦事項清單來保持進度。待辦事項可以在開始時寫入,並在模型完成工作時勾選。為此,我們給了 Claude TodoWrite 工具,它可以寫入或更新待辦事項並顯示給使用者。
但即使如此,我們經常看到 Claude 忘記它該做什麼。為了因應,我們每 5 輪插入一次系統提醒,提醒 Claude 它的目標。
但隨著模型能力的提升,它們不僅不再需要被提醒待辦事項清單,甚至可能覺得它是一種限制。被發送待辦事項清單的提醒,讓 Claude 認為它必須堅持清單內容,而不是修改它。我們也看到 Opus 4.5 在使用子 Agent 方面變得更好,但子 Agent 要如何在共享的待辦事項清單上協調呢?
看到這一點,我們用 Task 工具取代了 TodoWrite(在此閱讀更多關於 Tasks 的資訊)。Todo 是關於讓模型保持進度,而 Task 則更側重於幫助 Agent 之間互相溝通。Task 可以包含依賴關係、跨子 Agent 分享更新,而且模型可以修改和刪除它們。
隨著模型能力提升,你曾經需要的工具現在可能反而限制了它們。不斷重新審視先前對於需要哪些工具的假設是很重要的。這也是為什麼最好只支援一小組能力概況相當相似的模型。
設計搜尋介面
對 Claude 來說,特別重要的一組工具是可以用來建立自身上下文的搜尋工具。
當 Claude Code 剛推出時,我們使用 RAG 向量資料庫來為 Claude 尋找上下文。雖然 RAG 功能強大且快速,但它需要索引和設定,而且在各種不同的環境中可能很脆弱。更重要的是,Claude 是「被給予」這個上下文,而不是自己找到上下文。
但如果 Claude 可以在網路上搜尋,為什麼不能在程式碼庫中搜尋呢?透過給 Claude 一個 Grep 工具,我們可以讓它自己搜尋檔案並建立上下文。
這是我們觀察到的一個模式:隨著 Claude 變得更聰明,如果給予正確的工具,它就越來越擅長建立自己的上下文。
當我們引入 Agent 技能時,我們正式化了漸進式揭露的概念,這讓 Agent 能夠透過探索逐步發現相關的上下文。
Claude 可以讀取技能檔案,而這些檔案又可以引用其他檔案,模型可以遞迴地讀取它們。事實上,技能的一個常見用途是為 Claude 增加更多搜尋能力,例如給它關於如何使用 API 或查詢資料庫的指令。
在一年多的時間裡,Claude 從幾乎無法建立自己的上下文,進化到能夠跨多層檔案進行巢狀搜尋,以找到它確切需要的上下文。
漸進式揭露現在是我們常用來新增功能而不增加工具的技術。
漸進式揭露 - Claude Code 指南 Agent
Claude Code 目前有大約 20 個工具,我們不斷問自己是否真的需要所有這些工具。新增一個工具的門檻很高,因為這會給模型多一個選項去思考。
例如,我們注意到 Claude 對如何使用 Claude Code 了解得不夠。如果你問它如何新增 MCP 或某個斜線指令是做什麼的,它無法回答。
我們可以把所有這些資訊都放在系統提示中,但考慮到使用者很少問這些問題,這會增加上下文腐化,並干擾 Claude Code 的主要工作:寫程式碼。
相反地,我們嘗試了一種漸進式揭露的形式。我們給了 Claude 一個指向其文件的連結,它可以在需要時載入並搜尋更多資訊。這方法有效,但我們發現 Claude 會載入大量結果到上下文中來尋找正確答案,而實際上你只需要那個答案。
所以我們建立了 Claude Code 指南子 Agent,當你問到關於 Claude Code 本身的問題時,Claude 會被提示呼叫這個子 Agent。這個子 Agent 有詳細的指令,說明如何有效地搜尋文件以及該回傳什麼。
雖然這還不完美(當你問它如何設定自己時,Claude 仍然會困惑),但已經比以前好多了!我們能夠在不增加工具的情況下,為 Claude 的行動空間增加新功能。
一門藝術,而非科學
如果你希望得到一套嚴格的規則來建立你的工具,很可惜這不是那樣的指南。為你的模型設計工具,既是科學也是藝術。它高度依賴於你使用的模型、Agent 的目標以及它所運作的環境。
經常實驗、閱讀你的輸出、嘗試新事物。像 Agent 一樣看事情。





