03 · 給它手:工具怎麼設計
模型本身什麼也做不了。它能幹的每一件事,都來自你給的工具。所以工具這一層完全由你控制——也意味著它幹錯的事,多半也是你給的工具設計得不好。
工具呼叫是怎麼回事
一句話:模型只負責"提出要調什麼",真正執行的是你的程式。
① 你告訴模型:手上有這幾個工具,各自能幹嘛、要傳什麼參數
② 模型判斷:這一步該調 search_docs,參數是 {"query": "定價"}
③ 你的程式執行:真的去搜
④ 結果塞回上下文:模型看到搜尋結果
⑤ 模型繼續判斷下一步第 ② 步就是 Function Calling。注意第 ③ 步——執行權在你手上,這是你能設邊界的物理基礎(05 章)。
工具描述就是它的說明書
模型靠什麼決定調哪個工具?靠工具的名字和描述。 這跟 Skill 的 description 是完全一樣的機制——寫不好,它就選錯、或者根本不選。
一個工具的定義通常包含三樣:
| 作用 | 寫不好會怎樣 | |
|---|---|---|
| 名字 | 標識 | 起名含糊(get_data),它分不清幾個工具的差別 |
| 描述 | 決定它什麼時候調這個 | 最關鍵。糊了就亂調或不調 |
| 參數說明 | 每個參數是什麼、什麼格式 | 糊了它就亂傳,或者漏傳 |
對照
❌ 名字:search
描述:搜尋。
參數:query(字串)它不知道搜的是什麼、搜到的是哪個範圍、query 該寫關鍵詞還是自然語言。
✅ 名字:search_internal_docs
描述:在公司內部文件庫中做全文檢索,返回最多 10 條匹配片段及其文件標題和連結。
用於查詢內部規範、流程說明、歷史方案。**不能搜到公開網頁**——
需要公開資訊時用 search_web。
參數:
query(字串):檢索關鍵詞,用空格分隔,不要寫成完整句子。
例:"報銷 差旅 標準"
limit(整數,可選):返回條數,預設 10,最大 50三處改進:說清返回什麼、說清不能幹什麼並指向替代工具、參數給了格式和例子。
寫工具描述時,把Skill 篇 04 章那一整套原封不動搬過來:
- 既寫"做什麼",也寫"什麼時候用";
- 工具多的時候加排除條款("公開資訊用 search_web");
- 用具體的詞,別用抽象的詞;
- 參數給例子,比給類型有用。
工具描述和 Skill description 是同一件事的兩個位置。
工具設計的五條規矩
一、一個工具一件事
❌ manage_file(action, path, content) action 可以是 read / write / delete / move
✅ read_file(path)
write_file(path, content)
delete_file(path)拆開的三個理由:它選錯的機率低;你能對 delete 單獨加確認(05 章);日誌裡一眼看出它幹了什麼。
那個 action 參數版本,日誌裡全是 manage_file,你得點進去看參數才知道它是讀還是刪。
二、數量控制在十幾個以內
工具太多有兩個問題:每個的描述都要常駐上下文,幾十個工具就是不小的開銷;而且選擇困難——相似的工具一多,它選錯的機率明顯上升。
超過二十個,考慮分組:按任務階段給不同的工具集,或者用一個"目錄型"工具讓它先查有哪些工具可用。
三、返回結果要精簡,但要夠判斷
工具返回的東西會原樣進上下文。一個返回整頁 HTML 的工具,幾圈就能把桌子佔滿(07 章)。
❌ 返回:整個網頁的 HTML
✅ 返回:頁面標題 + 正文純文本(截斷到 2000 字)+ 原始 URL
截斷時註明"(已截斷,完整內容見 URL)"但也別精簡過頭——它得能判斷"這次呼叫成功了沒有、要不要換個方式再試"。返回一個空字串,它不知道是沒找到還是出錯了。
四、錯誤要說人話
工具報錯時,返回的資訊是給模型看的,目的是讓它知道下一步該怎麼辦:
❌ Error: 400
✅ 錯誤:query 參數不能為空。請提供檢索關鍵詞後重試。
❌ Error: not found
✅ 未找到匹配文件。建議:換更寬的關鍵詞,或改用 search_web 查公開資訊。第二種寫法裡那句"建議",能直接省掉它兩三圈瞎試。
五、危險的動作,工具層面就攔住
別指望靠提示詞說"不要刪檔案"。 提示詞是軟約束,工具是硬約束:
- 不想讓它刪,就別給
delete_file這個工具; - 必須給,就讓這個工具返回一個待確認的動作,而不是真的執行——由人點頭之後再執行。
這是本章最重要的一條
提示詞裡的"不許做 X",和"根本沒有做 X 的工具",是兩種完全不同強度的東西。
能靠不給工具解決的,就不要靠說服解決。
常見的一組工具
大多數 Agent 的工具集是這幾類的組合:
| 類別 | 例子 | 風險 |
|---|---|---|
| 讀 | 搜尋、讀檔案、查資料庫、讀網頁 | 低。主要風險是讀到不該讀的(05 章) |
| 寫 | 寫檔案、建記錄、發訊息 | 中。要能撤回,或者要人確認 |
| 刪 / 改 | 刪除、覆蓋、更新狀態 | 高。預設不給,或者必須人確認 |
| 執行 | 跑命令、跑程式碼、調外部 API | 最高。必須沙箱 + 白名單 |
| 對外 | 發郵件、發訊息、提交表單、支付 | 最高。一律人工確認,無例外 |
設計工具集時先做一次分類:把你打算給的工具按上面五類擺一遍。
"高"和"最高"那兩類,逐個問一句:"這個真的必須給它嗎?"
多數時候答案是:這一步可以由人來做,或者可以讓 Agent 只產出一個"待執行清單",由人批次執行。
一個折中做法:先產出計劃,再執行
對付高風險動作,有個很實用的模式:
Agent 不直接執行危險動作,而是產出一份「計劃檔案」:
- 要刪哪幾個檔案
- 要發哪幾條訊息,發給誰,內容是什麼
人看一遍這份計劃 → 確認 → 由程式按計劃批次執行好處:Agent 的自主性保住了(它自己想清楚該幹什麼),風險也控住了(真正的動作由人點頭)。而且計劃是文本,好看、好改、好留檔。
這跟 Workflow 篇 07 章"把要判斷的和已經沒問題的分開列"是同一個思路。
下一步
04 · MCP:一個統一的插頭 —— 工具從哪兒來,以及怎麼不用每接一個系統就寫一遍。