Skip to content

03 · 給它手:工具怎麼設計 ​

模型本身什麼也做不了。它能幹的每一件事,都來自你給的工具。所以工具這一層完全由你控制——也意味著它幹錯的事,多半也是你給的工具設計得不好。

工具呼叫是怎麼回事 ​

一句話:模型只負責"提出要調什麼",真正執行的是你的程式。

text
① 你告訴模型:手上有這幾個工具,各自能幹嘛、要傳什麼參數
② 模型判斷:這一步該調 search_docs,參數是 {"query": "定價"}
③ 你的程式執行:真的去搜
④ 結果塞回上下文:模型看到搜尋結果
⑤ 模型繼續判斷下一步

第 ② 步就是 Function Calling。注意第 ③ 步——執行權在你手上,這是你能設邊界的物理基礎(05 章)。

工具描述就是它的說明書 ​

模型靠什麼決定調哪個工具?靠工具的名字和描述。 這跟 Skill 的 description 是完全一樣的機制——寫不好,它就選錯、或者根本不選。

一個工具的定義通常包含三樣:

作用寫不好會怎樣
名字標識起名含糊(get_data),它分不清幾個工具的差別
描述決定它什麼時候調這個最關鍵。糊了就亂調或不調
參數說明每個參數是什麼、什麼格式糊了它就亂傳,或者漏傳

對照 ​

text
❌ 名字:search
   描述:搜尋。
   參數:query(字串)

它不知道搜的是什麼、搜到的是哪個範圍、query 該寫關鍵詞還是自然語言。

text
✅ 名字:search_internal_docs
   描述:在公司內部文件庫中做全文檢索,返回最多 10 條匹配片段及其文件標題和連結。
        用於查詢內部規範、流程說明、歷史方案。**不能搜到公開網頁**——
        需要公開資訊時用 search_web。
   參數:
     query(字串):檢索關鍵詞,用空格分隔,不要寫成完整句子。
                     例:"報銷 差旅 標準"
     limit(整數,可選):返回條數,預設 10,最大 50

三處改進:說清返回什麼、說清不能幹什麼並指向替代工具、參數給了格式和例子。

寫工具描述時,把Skill 篇 04 章那一整套原封不動搬過來:

  • 既寫"做什麼",也寫"什麼時候用";
  • 工具多的時候加排除條款("公開資訊用 search_web");
  • 用具體的詞,別用抽象的詞;
  • 參數給例子,比給類型有用。

工具描述和 Skill description 是同一件事的兩個位置。

工具設計的五條規矩 ​

一、一個工具一件事 ​

text
❌ 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 章)。

text
❌ 返回:整個網頁的 HTML
✅ 返回:頁面標題 + 正文純文本(截斷到 2000 字)+ 原始 URL
       截斷時註明"(已截斷,完整內容見 URL)"

但也別精簡過頭——它得能判斷"這次呼叫成功了沒有、要不要換個方式再試"。返回一個空字串,它不知道是沒找到還是出錯了。

四、錯誤要說人話 ​

工具報錯時,返回的資訊是給模型看的,目的是讓它知道下一步該怎麼辦:

text
❌ Error: 400
✅ 錯誤:query 參數不能為空。請提供檢索關鍵詞後重試。

❌ Error: not found
✅ 未找到匹配文件。建議:換更寬的關鍵詞,或改用 search_web 查公開資訊。

第二種寫法裡那句"建議",能直接省掉它兩三圈瞎試。

五、危險的動作,工具層面就攔住 ​

別指望靠提示詞說"不要刪檔案"。 提示詞是軟約束,工具是硬約束:

  • 不想讓它刪,就別給 delete_file 這個工具;
  • 必須給,就讓這個工具返回一個待確認的動作,而不是真的執行——由人點頭之後再執行。

這是本章最重要的一條

提示詞裡的"不許做 X",和"根本沒有做 X 的工具",是兩種完全不同強度的東西。

能靠不給工具解決的,就不要靠說服解決。

常見的一組工具 ​

大多數 Agent 的工具集是這幾類的組合:

類別例子風險
讀搜尋、讀檔案、查資料庫、讀網頁低。主要風險是讀到不該讀的(05 章)
寫寫檔案、建記錄、發訊息中。要能撤回,或者要人確認
刪 / 改刪除、覆蓋、更新狀態高。預設不給,或者必須人確認
執行跑命令、跑程式碼、調外部 API最高。必須沙箱 + 白名單
對外發郵件、發訊息、提交表單、支付最高。一律人工確認,無例外

設計工具集時先做一次分類:把你打算給的工具按上面五類擺一遍。

"高"和"最高"那兩類,逐個問一句:"這個真的必須給它嗎?"

多數時候答案是:這一步可以由人來做,或者可以讓 Agent 只產出一個"待執行清單",由人批次執行。

一個折中做法:先產出計劃,再執行 ​

對付高風險動作,有個很實用的模式:

text
Agent 不直接執行危險動作,而是產出一份「計劃檔案」:
  - 要刪哪幾個檔案
  - 要發哪幾條訊息,發給誰,內容是什麼

人看一遍這份計劃 → 確認 → 由程式按計劃批次執行

好處:Agent 的自主性保住了(它自己想清楚該幹什麼),風險也控住了(真正的動作由人點頭)。而且計劃是文本,好看、好改、好留檔。

這跟 Workflow 篇 07 章"把要判斷的和已經沒問題的分開列"是同一個思路。

下一步 ​

04 · MCP:一個統一的插頭 —— 工具從哪兒來,以及怎麼不用每接一個系統就寫一遍。

一份講通用概念的入門手冊 · 不綁定任何一家模型或工具 · 例子可直接照抄