跳到主要內容

工具搜索

當會話中附加了許多 MCP 服務器或非核心插件工具時,它們的 JSON Schema 會在每一輪對話中佔用上下文窗口的相當大一部分——即使其中只有少數幾個與用戶的實際請求相關。

工具搜索(Tool Search) 是 Hermes 針對該問題提供的可選漸進式披露層。激活後,模型可見的工具數組中的 MCP 和插件工具將被三個橋接工具取代,模型會按需加載每個特定工具的 Schema。

內置的 Hermes 工具從不延遲加載

構成 Hermes 核心能力集的工具(terminalread_filewrite_filepatchsearch_filestodomemorybrowser_*web_searchweb_extractclarifyexecute_codedelegate_tasksession_searchsend_message 以及 _HERMES_CORE_TOOLS 中的其餘工具)始終直接加載。只有 MCP 工具和非核心插件工具才有資格被延遲加載。

工作原理

當工具搜索在某一輪對話中激活時,模型會看到三個新工具來替代被延遲加載的工具:

tool_search(query, limit?)     — search the deferred-tool catalog
tool_describe(name) — load the full schema for one tool
tool_call(name, arguments) — invoke a deferred tool

典型的交互流程如下:

Model: tool_search("create a github issue")
→ { matches: [{ name: "mcp_github_create_issue", ... }, ...] }
Model: tool_describe("mcp_github_create_issue")
→ { parameters: { type: "object", properties: { ... } } }
Model: tool_call("mcp_github_create_issue", { title: "...", body: "..." })
→ { ok: true, issue_number: 42 }

當模型調用 tool_call 時,Hermes 會解包橋接層,並像模型直接調用底層工具一樣分派該工具。預工具調用鉤子、防護欄、審批提示和後工具調用鉤子都針對真實工具名稱運行,而不是針對 tool_call。CLI 和網關中的活動反饋也會進行解包,因此你看到的是底層工具,而非橋接工具。

何時激活?

默認情況下,工具搜索以 auto 模式運行:僅當可延遲加載的工具 Schema 將佔用當前模型上下文窗口至少 10% 時才會激活。低於該閾值時,工具數組的組裝是純透傳的,不會產生任何開銷。

每次構建工具數組時都會重新評估此決策,因此:

  • 僅有少量 MCP 工具且使用長上下文模型的會話永遠不會激活工具搜索。
  • 附加了許多 MCP 服務器(通常超過 15 個工具)的會話開始激活它。
  • 在會話中途移除 MCP 服務器後,下一次組裝時會正確恢復為直接暴露模式。

配置

tools:
tool_search:
enabled: auto # auto (default), on, or off
threshold_pct: 10 # percentage of context — only used in auto mode
search_default_limit: 5
max_search_limit: 20
默認值含義
enabledautoauto 在超過閾值時激活;on 只要存在至少一個可延遲加載的工具就始終激活;off 完全禁用。
threshold_pct10auto 模式啟動時的上下文長度百分比。範圍 0–100。
search_default_limit5當模型調用 tool_search 而未指定 limit 時返回的結果數量。
max_search_limit20模型可以通過 limit 請求的硬性上限。範圍 1–50。

你也可以切換傳統的布爾值形式:

tools:
tool_search: true # equivalent to {enabled: auto}

何時不使用

工具搜索用固定的每輪 Token 成本(三個橋接工具 Schema,約 300 個 Token)以及至少一次額外的往返交互(搜索 → 描述 → 調用)來換取延遲加載 Schema 所節省的空間。當你擁有大量工具但每輪只使用少數幾個時,這是一個明顯的優勢;但當你的工具總數很少時,這反而會成為開銷。

auto 默認值會自動為你處理這種情況。如果你無條件設置 enabled: on,預計在小型工具集上每輪對話會有輕微的額外成本。

無法避免的權衡

這些權衡源於提示緩存完整性不變量——它們是任何漸進式披露設計固有的,並非此實現特有:

  • 冷啟動工具需要額外的一次往返交互。 模型首次需要某個延遲加載的工具時,需要花費一到兩次額外的模型調用來查找並加載其 Schema。靜態側節省的 Token 是真實的,但部分成本會在運行時償還。
  • 延遲加載的 Schema 無法享受緩存收益。 加載後的 tool_describe 結果會進入對話歷史(因此在後續輪次中確實會被緩存),但它永遠無法受益於系統提示前綴緩存。
  • 依賴於模型質量。 工具搜索假設模型能夠為其想要的工具編寫合理的搜索查詢。較小的模型在這方面表現較差;Anthropic 發佈的數據(Opus 4 在使用與不使用工具搜索時的準確率從 49% 提升到 74%)顯示了其優勢,但也表明仍有約 26 個百分點的準確率損失源於檢索失敗。
  • 工具集編輯會使緩存失效。 在會話中途添加或移除工具會改變橋接工具的描述(其中包括延遲加載工具的數量)和目錄,從而導致提示緩存失效。這與任何工具集編輯面臨的權衡相同。

實現細節

  • 檢索: 對分詞後的工具名稱 + 描述 + 參數名稱執行 BM25 算法。當 BM25 未返回任何正分數命中結果時,回退到對工具名稱的字面子串匹配,從而防止零 IDF 退化情況(例如,在目錄中每個工具名稱都包含 "github" 的情況下搜索 "github")。
  • 目錄在多輪對話中無狀態。 每次組裝時都會從當前的工具定義列表重新構建目錄——不使用基於會話鍵的 Map。這避免了一類 bug,即存儲的目錄與實時工具註冊表不同步。
  • 目錄的作用域限定於會話的工具集。 tool_searchtool_describetool_call 只能查看和調用會話實際被授予權限的工具。限制為工具集子集的子代理(subagent)、看板工作器(kanban worker)或網關節點(gateway session)無法使用該橋接來發現或調用該子集之外的工具——延遲目錄是會話自身啟用/禁用工具集的可延遲切片,而非整個進程註冊表。
  • 無 JS 沙箱。 Hermes 使用更簡單的“結構化工具”模式(將搜索/描述/調用作為普通函數)。其他一些實現提供的 JS 沙箱“代碼模式”具有較大的攻擊面;我們跳過它。

另請參閱

  • tools/tool_search.py — 實現代碼
  • tests/tools/test_tool_search.py — 迴歸測試套件
  • 原始實現 PR 中的 openclaw-tool-search-report PDF,其中包含塑造該設計的研究內容