工具多到塞不進 Prompt:Agent 工具檢索(Tool Retrieval)實作課
今日主題:工具檢索(Tool Retrieval)
2026-10-23 | 資料來源:Anthropic、UC Berkeley、arXiv
10 月 4 日那篇談的是 Agent「怎麼呼叫工具」:strict schema、並行呼叫、BFCL 評測。但那篇文章留下一個沒碰的規模問題:當工具從 10 個變成 1,000 個、甚至 10,000 個,呼叫機制再漂亮也沒用——因為你連「把工具定義放進 prompt」這一步都做不到。
Anthropic 在 2025 年 11 月的 Advanced Tool Use 研究裡給了一個很具體的數字:一個接了 5 個 MCP server 的設定——GitHub 35 個工具、Slack 11 個、Sentry 5 個、Grafana 5 個、Splunk 2 個——光是工具定義就要吃掉約 55K tokens。Anthropic 內部甚至觀測到 134K tokens 的案例:對話還沒開始,context window 已經先被工具目錄佔掉一大塊。
這就是今天的主題:工具檢索(Tool Retrieval)。當工具多到塞不進 prompt,你需要一套獨立的機制,先幫 Agent「找到對的工具」,再談呼叫。
一、為什麼「全部塞進去」會壞掉
第一個壞掉的是 token 預算。每個 MCP 工具的定義(名稱、描述、JSON schema)大約 200–800 tokens,而且每一輪對話都要重付一次。Claude Code 的實測很有代表性:147 個工具的定義約 90K tokens,改用 ToolSearch 延遲載入後,固定開銷降到約 15K。
第二個壞掉的是選擇準確度。工具越多,名字長得越像:notification-send-user 和 notification-send-channel 只差一個字,模型在幾十個候選裡挑錯的機率直線上升。Anthropic 把這列為最常見的失敗模式:選錯工具、填錯參數。
第三個最值得警惕:Arcade.dev 拿 4,027 個工具實測 Anthropic 的 Tool Search,發現光是「正確的工具出現在搜尋結果裡」這一關,成功率就只有 56%(regex 模式)到 64%(BM25 模式)。注意,這還沒談模型會不會選對、參數填得對不對——純粹是檢索這一步,就已經掉了四成。
結論很清楚:工具檢索是個獨立的工程問題,必須和「呼叫工具」分開設計、分開評測。如圖一。
二、四種實作路線
路線一:語意檢索——Berkeley Gorilla
最早把這個問題做成系統的是 UC Berkeley 的 Gorilla(2023)。做法有三招:用 self-instruct 為每個 API 生成合成的使用者提問、做文件檢索、再用 Retrieval-Aware Training(RAT)微調模型。RAT 的想法很漂亮:檢索器本來就會出錯,所以訓練時就讓模型「意識到檢索結果可能是錯的」,學會交叉驗證。
他們還建了 APIBench(約 1,600 個 ML API),用 AST 子樹比對來評 functional correctness。結果:7B 的 LLaMA 加上檢索,在 API 呼叫準確度上打敗 GPT-4,參數幻覺錯誤也大幅降低。Gorilla 證明的第一件事:選工具可以拆成「先檢索、再決策」兩步,而且檢索那一步值得專門訓練。
路線二:分層路由——MCP-Zero
工具一多,連「一次掃完全部工具」都很貴。MCP-Zero 的做法是分層:先做 server 層過濾(這個任務需要哪個 domain 的 server),再在選中的 server 裡面做 tool 層排序。
關鍵的設計翻轉是「誰來發起檢索」:不是拿使用者問題去比對,而是讓 Agent 在執行中主動聲明「我現在缺什麼能力」,用結構化的工具請求(server domain 加上想做的操作)去觸發檢索。模型生成的請求比原始使用者輸入更貼近工具文件的語言,匹配準確度自然更高。而且檢索是迭代的:拿到工具後發現不夠用,Agent 可以修正請求再查一輪。
路線三:工具搜尋工具——Anthropic
2025 年 11 月,Anthropic 把這套做法做成平台級功能:Tool Search Tool。核心機制是 defer_loading——工具定義延遲載入,prompt 裡只放一個搜尋工具,Claude 需要時自己查,查到後再按需載入完整 schema。
官方數字:token 節省最高 85%,工具選擇準確率從 49% 提升到 74%(Opus 4)。Anthropic 的採用建議也很實在:工具定義超過約 10K tokens 就該用。Claude Code 的實作還補了一個細節:MCP 工具可以宣告 _meta['anthropic/alwaysLoad'] 讓核心工具常駐,而 ToolSearch 自己永不被 defer——搜尋機制本身是最後一道防線,不能被優化掉。
路線四:意圖查詢生成——Toollery(2026)
最新的解法來自 2026 年的 Toollery 論文。它的洞察是:檢索時真正該比對的不是「規格語言」(工具文件的寫法),而是「意圖語言」(使用者會怎麼描述這個需求)。所以它為每個 capability 預先生成一批 user-intent queries,檢索時同時比對意圖查詢和規格文件。
規模數字很驚人:在約 79K 個 skills 的測試裡,全量 prompt 需要約 43.1M tokens,而 Toollery 取 top-10 只要約 27.7K——差了三個數量級。Hit@1 從純規格檢索的 0.55(BM25)拉到 0.92(意圖加規格)。如圖二。
三、最小可跑骨架
不管選哪條路線,落地時都是同一個模式:給 Agent 一個 search_tools 工具,只回傳候選工具的完整定義。下面是一個三十行的骨架(sentence-transformers 做語意檢索):
from sentence_transformers import SentenceTransformer
class ToolRegistry:
def __init__(self, tools):
self.tools = {t["name"]: t for t in tools}
self.model = SentenceTransformer("all-MiniLM-L6-v2")
texts = [f"{t['name']}: {t['description']}" for t in tools]
self.emb = self.model.encode(texts, normalize_embeddings=True)
def search_tools(self, query: str, k: int = 5) -> list:
"""用自然語言描述需求,找回最相關的 k 個工具。
找不到就換關鍵字再查一次,不要猜工具名稱。"""
q = self.model.encode([query], normalize_embeddings=True)[0]
idx = (self.emb @ q).argsort()[::-1][:k]
names = list(self.tools)
return [self.tools[names[i]] for i in idx]
# Agent 系統提示詞的關鍵句:
# 「你有上千個工具可用,但一次只能看到搜尋結果。
# 先呼叫 search_tools 描述你的需求,拿到候選工具後再決定呼叫哪一個。」
重點在最後兩行提示詞:你必須明確告訴模型「不要猜工具名稱」。實務上很多選錯工具的案例,根因都是模型憑名字腦補出一個不存在的工具。
四、上生產環境的五個要點
第一,description 是檢索的命脈。寫「這個工具何時該用、何時不該用」,不要只寫功能。Toollery 的實驗證明:意圖語言的描述品質直接決定 Hit@1。
第二,核心工具常駐。搜尋工具本身、對話與推理的核心工具不要 defer,參考 Claude Code 的 alwaysLoad 機制。
第三,最小權限過濾。AWS Strands Agents 的 tool_filters 是很好的範本:生產環境只暴露該角色需要的工具。反面教材是「廚房水槽式」server:Atlassian Rovo 的 MCP server 一次註冊 70 多個工具,Agent 為了一個改 ticket 狀態的小任務,得先在一堆無關工具裡大海撈針。
第四,評測檢索本身。先量 recall@k 和 Hit@1,再談 agent 端到端成功率。Arcade 的 4,027 工具實測就是最好的提醒:檢索只有六成,後面做什麼優化都是沙上建塔。
第五,混合策略。BM25 吃精確名詞(工具名、專有名詞),語意檢索吃意圖描述,分層路由先縮小範圍。三者不互斥,生產環境通常是 BM25 加語意混合排序,外面再包一層 server 分層。
結論:選型建議
- 50 個工具以下:全部塞進 prompt,最簡單,別過度設計。
- 50–500 個:上 search_tools 加語意檢索,本文第三節的骨架就能跑。
- 500 個以上:分層路由或意圖查詢預生成,參考 MCP-Zero 與 Toollery。
- 生產環境:無論哪條路線,一律加最小權限過濾,並持續監控檢索命中率。
一句話收尾:工具檢索和工具呼叫是兩個問題。10 月 4 日那篇解決了後者,今天這篇解決前者。兩個都做好,Agent 才真的接得上現實世界那幾千個 API。
來源:
- Anthropic〈Introducing advanced tool use for Claude〉https://www.anthropic.com/research/advanced-tool-use
- Toollery: Scaling LLM Agents to Thousands of Skills and Tools https://arxiv.org/html/2609.22218v2
- Gorilla: Large Language Model Connected with Massive APIs https://arxiv.org/pdf/2305.15334
- Arcade〈Anthropic Tool Search Test: 4,000 Tools, 60% Success〉https://www.arcade.dev/blog/anthropic-tool-search-4000-tools-test/
- MCP-Zero:MCP tool discovery for autonomous LLM agents https://dev.to/portkey/mcp-tool-discovery-for-autonomous-llm-agents-3n3
- Strands Agents 工具過濾文件 https://strandsagents.com/docs/learning/give-your-agent-tools-using-mcp/
沒有留言:
張貼留言