跳到主要內容

【2026 最新】MCP 工具搜尋怎麼做?Lazy Schema Loading 7 步實戰

最後更新: ·
MCP 工具搜尋與 Lazy Schema Loading 教學首圖,呈現搜尋卡、完整 Schema 與安全執行流程

MCP 工具搜尋最容易出現的浪費,不是 Agent 真的呼叫了太多工具,而是它還沒開始工作,Context(模型這一輪能閱讀的內容空間)就先被一整排工具說明塞滿。你接上一個 Jira、GitHub、資料庫與瀏覽器 server,每個工具又帶著完整 JSON Schema,Agent 像是每次進五金行都得先背完整本型錄,才准問「我要一支螺絲起子」。

2026 年 8 月 19 日,r/LLMDevs 一則開發者自報案例用刻意放大的單一 fixture 示範:217,316 bytes 的 tool-schema payload,被改寫成 5,062 bytes 的 discovery payload;作者以每 token 約四字元粗估,稱約從 54K 降到 1.3K tokens。這不是普遍節省率;原帖也沒有提供可供獨立重現的 fixture、模型版本與重複次數,但它把一個真問題照得很亮:模型需要先知道「哪個工具可能有用」,不必先吞下每個參數的百科全書。

這篇專為第一次做 Agent 系統的讀者寫。我不假設你懂 MCP SDK,會用白話帶你建立 search → inspect → execute 三階段代理層、保留權限與副作用資訊,再用固定任務 A/B Test 同時驗證 token、延遲與 wrong-tool failure。若你只使用 Claude Code,也會先看到更省事的內建路線,不必重造已經存在的能力。

Table of Contents

MCP 工具搜尋先說結論:先看索引卡,再借完整說明書

Lazy Schema Loading = Search(看索引卡)+ Inspect(展開完整 Schema)+ Execute(驗證後執行)。

把每個 MCP tool 想成倉庫裡的一台機器。搜尋卡只回答「它做什麼、需要哪些主要輸入、會不會改資料、需要什麼權限」;模型選中候選後,才展開完整 inputSchema;真正呼叫前,再用原始 schema 驗證參數並走權限與確認流程。小卡是目錄,不是執行契約。

  • Search:從短摘要找出 3~5 個候選,不讓模型讀完整目錄。
  • Inspect:只把選中候選的完整 schema 放進目前這段 Context。
  • Execute:用未裁切的 schema、目前身分與本地 policy 再驗一次,通過才呼叫 MCP server。
MCP 工具搜尋的 Search、Inspect、Execute 三階段 Lazy Schema Loading 流程圖
索引卡負責找路,完整 Schema 負責填參數,Policy Gate 負責決定能不能真的動手。

先別急著造 Proxy:Claude Code 已有內建 Tool Search

截至 2026 年 8 月 22 日,Claude Code 的 MCP 文件明載 Tool Search 預設啟用:啟動時載入工具名稱與 server instructions,完整定義等到需要時才載入。你可以先在 Claude Code 執行 /mcp 看各 server 與工具數,再用 /context檢查 Context 去向;若沒有相容性理由,第一步應是確認內建機制是否正常,而不是先加一層第三方 Proxy。

要做門檻式切換,可用 ENABLE_TOOL_SEARCH=auto:可延後的工具定義未達 Context window 10% 時先載入,達門檻後才延後;也能用 auto:5自訂百分比。Claude Agent SDK 文件同時提醒,工具少於約 10 個、schema 又小時,直接載入通常更快,因為搜尋會多一個 round trip。這正是為什麼本文的最後答案不是「一律 lazy」,而是「先量,再切」。

內建路線也有邊界:自訂 API host、雲端託管環境、模型相容性與組織設定都可能改變載入方式。不要從畫面感覺猜;依同一份官方頁面檢查實際設定,並把「完整工具是否被模型預載到初始 Context」列入 A/B trace。若你使用其他 client、自己做 Agent Harness,或需要跨多個 provider 統一搜尋,下面才是要動手的部分。

MCP 工具搜尋的底層:協定負責列工具,Harness 決定給模型看多少

MCP 2026-07-28 tools 規格定義 server 透過 tools/list回傳完整工具定義,client 再用 tools/call執行;標準裡沒有 tools/searchtools/inspectdefer_loading。規格也明說,實作可採自己的互動介面;換句話說,MCP 解決「client 怎麼取得與呼叫工具」,而你的 Harness 決定「哪些資訊何時進模型 Context」。本文的 Search、Inspect、Execute 都是 host/adapter 內部 API,不是 MCP wire methods。

2026-07-28 的 tools/list支援分頁與 cache metadata,工具清單改變時也能配合 listChanged通知。這讓 Proxy 可以先把完整 catalog 存在模型看不到的記憶體或資料庫,再建立短卡索引。但 cache key 必須包含呼叫者身分與授權範圍:同一個 server 可依每次 request 帶的授權回傳不同工具,不能把管理員的 catalog 共用給一般使用者;工具集也不能因 connection 不同或前一個 request 的副作用而改變。因此 Lazy Loading 要發生在 host 到模型的 Context 層,不是先搜尋再偷偷改 server 的 tools/list

另一個關鍵是名稱碰撞。規格只要求同一個 server 內的 tool name 唯一,聚合多個 server 時可能都叫 search;server 自報的名稱也不適合拿來做安全識別。實作上請用「本地 server 設定 ID+tool name+schema digest」組成 action ID,而不是只存一個容易撞名的 search

一張可搜尋工具卡,最少要留下哪些欄位?

工具卡要短,但不能短到只剩漂亮名稱。下面是本文建議的應用層格式;它不是 MCP 官方 schema,而是你自己的 discovery contract。真正的 inputSchema仍完整保存在 catalog 裡。

{
  "action_id": "support-prod:tickets.create@sha256:8c4e…",
  "title": "建立客服單",
  "summary": "建立一張客服單並指派佇列",
  "intents": ["建立客服單", "升級客訴"],
  "required_inputs": ["subject", "body", "queue"],
  "risk": "write-reversible",
  "auth_scopes": ["tickets:write"],
  "confirmation": "required",
  "schema_digest": "8c4e…"
}
  • 辨識欄:action_idtitlesummary,讓搜尋與人類都能看懂。
  • 意圖欄:intents與常見別名,避免只靠精確字串。
  • 參數摘要:只列必要欄位名稱與用途,不複製整個巢狀 schema。
  • 風險欄:read/write、可逆性、外部世界、確認需求與 credential scope。
  • 完整性欄:schema_digest與 catalog version,確保 Inspect 與 Execute 看的是同一版。

MCP 的 ToolAnnotations schema提供 readOnlyHintdestructiveHintidempotentHintopenWorldHint,但規格明文要求:不可信 server 傳來的 annotations 不能直接決定工具使用。做風險卡時,把 annotations 當線索;本地 allowlist、實際 OAuth scope、工具名稱與操作類型可以提高風險等級,不能因一個自報的 readOnlyHint:true就自動放行。

MCP 工具搜尋的 7 步 Lazy Schema Loading 實作

Step 1|量出 Schema Tax,不先猜節省率

痛點:你看到 54K 就想直接套用 97.7%,但那是別人的單一壓力 fixture。解法:固定同一個 model、system prompt、使用者訊息與空輸出上限,做「完整 tools」與「只帶 discovery tools」兩次 token count。Anthropic 使用者可把相同 request 交給Token Counting endpoint,它會把 tools 納入計數;其他供應商則使用各自的 tokenizer/usage 欄位。記錄 catalog_bytesinput_tokens與 model ID,別用固定的 bytes ÷ 4 冒充所有 tokenizer。

Step 2|抓完整 Catalog,逐頁保存並做 Digest

痛點:只抓第一頁會讓搜尋靜悄悄漏工具。解法:透過你選用的 MCP SDK 走完 tools/list分頁,把每份原始 tool definition canonicalize 後計算 SHA-256。Catalog 要綁定 protocol version、server config ID、授權範圍與取得時間;收到清單變動事件或 freshness TTL 到期,就從第一頁重抓並原子替換對應 scope 的索引,不把多頁結果誤當永遠一致的 snapshot。

Step 3|把完整 Schema 蒸餾成「短而不瞎」的卡片

痛點:只保留 tool name,模型會把 ticket.searchticket.createticket.delete混在一起。解法:由程式抽出名稱、描述、required fields,再疊上人工維護的 intent aliases 與本地 risk policy。卡片設硬上限前,先驗證最長名稱、權限與風險欄不會被截掉;需要縮短時,優先刪例句,不刪副作用。

Step 4|Search 回傳候選,不替模型偷做決定

痛點:模糊意圖可能同時命中三個工具。解法:結合 lexical search(關鍵字)與 semantic search(語意),回傳有穩定 tie-break 的 top-k 卡片;分數接近時保留多個候選,讓模型根據使用者目標挑選,或要求補充問題。搜尋 trace 至少保存 query、候選 action IDs、scores、選中項與拒絕原因。

Step 5|Inspect 完整 Schema,生成參數後再做 JSON Schema 驗證

痛點:卡片看得懂意圖,卻沒有 enum、格式、巢狀條件與 $ref解法:選中工具後,以 action ID 取回 digest 相同的完整 schema,才讓模型填 arguments;執行端再用支援該 draft 與 $ref解析的 validator 檢查,預設禁止從網路抓外部 reference,無法解析就 fail closed,並限制 schema 深度與驗證時間。schema digest 漂移就中止這次提案、重新 Inspect,不能拿舊卡配新工具。

Step 6|把 Policy Gate 放在 Execute 前面

痛點:「選對工具」不等於「有權執行」。解法:用目前使用者、connector、OAuth scope、環境與 arguments 做授權;寫入、刪除、付款、對外傳送與 unknown risk 類別顯示工具、目標與參數,取得人類確認後才送出。MCP 規格也建議應用程式清楚顯示暴露給模型的工具、呼叫指示與操作確認。

Step 7|把 Execute 收據寫進 Trace,讓錯選可以回放

痛點:只看最終回答,找不到是搜尋、選擇、填參數、授權還是 server 執行出錯。解法:每次留下 query → candidates → inspected_digest → proposed_args → validation → policy_decision → tool_result事件鏈。這和Agent Observability的思路相同:先把黑盒拆成可定位的階段,回歸測試才知道哪一段退步。

完整走一次:從「幫客戶處理重複扣款」到安全呼叫

假設 catalog 裡有 payments.searchtickets.createpayments.refundpayments.delete_record。使用者只說:「幫這位客戶處理重複扣款。」Search 不應直接猜退款,而是回傳搜尋交易、建立客服單與退款三張卡;刪除紀錄因意圖較遠,只保留在低順位。

  1. Agent 先選 payments.search查兩筆交易,這是 read 類操作。
  2. 結果確認其中一筆重複後,Search 再找到 payments.refund
  3. Inspect 展開退款工具的完整 schema,發現需要 payment_idamountreason與 idempotency key。
  4. Validator 確認 amount 格式與 enum;Policy Gate 檢查 refund:write scope,並把目標交易與金額顯示給使用者確認。
  5. Execute 成功後保存 server result 與 request ID;相同 idempotency key 的重試不會被 Agent 自行換掉。

這個例子的重要處,不是少看了幾個 tokens,而是高風險細節在真正需要時完整回來。如果 Search 卡把「退款」與「刪除交易紀錄」壓成同一個「處理付款」摘要,token 省得再多也是失敗。

語言無關 Pseudocode:把三階段接起來

catalog = buildCatalog(mcpClient.listToolsAllPages(), authScope)
cards   = catalog.map(makeSearchCard)

hits   = search(cards, userIntent, topK = 5)
choice = model.choose(hits)
tool   = catalog.get(choice.actionId)

assert sha256(canonicalJson(tool.definition)) == choice.schemaDigest
args = model.fill(tool.inputSchema)
jsonSchemaValidate(args, tool.inputSchema)

decision = policy.authorize(identity, tool, args)
if decision.requiresConfirmation:
    user.confirm(tool.title, args)

result = mcpClient.callTool(tool.name, args)
trace.append(hits, tool.digest, args, decision, result)

這段刻意省略了 transport reconnect、protocol negotiation、分頁錯誤、timeout、rate limit、$ref遠端資源政策與 secret redaction;它只能當架構骨架。Production 請讓正式 MCP SDK 處理 wire protocol,並依規格的 security considerations補上 schema 驗證、結果驗證、逾時、稽核與人類確認。

怎麼驗收 MCP 工具搜尋:固定任務 A/B Test

不要只比第一輪 token。A 組讓 Agent 一開始看完整 tool definitions;B 組只看 discovery 介面,選中後才 Inspect。兩組使用同一批任務、相同 model、prompt、temperature、授權、server snapshot 與起始資料,交錯執行並保留所有失敗。若你已讀過MCP vs CLI A/B Test,這次只是把變因收窄成「完整載入 vs Lazy Schema Loading」。

MCP 工具搜尋 A/B Test 指標卡,涵蓋 Token、延遲、正確率與 wrong-tool failure
這是驗收儀表板範本,不是 AlphaLab 已跑出的結果;先守住任務正確率與高風險錯選,再比較 token 與延遲。
  • Context 成本:首輪 input tokens、整個 task 的 uncached/cached input,以及 catalog bytes。
  • 速度:到第一次正確工具提案的時間、到任務完成的時間、Search 額外 round trips。
  • 選擇品質:top-1/top-k 命中、需要澄清的比例、search miss、錯選工具。
  • 參數品質:schema-valid rate、缺少 required field、enum/format 錯誤與重試次數。
  • 安全品質:未授權提案、危險工具未確認、同名 tool collision、stale digest 與副作用重複。
  • 任務品質:最終完成率與人工介入;只有同等或更好的任務品質,token 節省才有意義。

先用唯讀與可重置測試環境跑,再加入「搜尋同義詞」「三個近似工具」「tool name 相同但 server 不同」「schema 更新」「權限較低使用者」與「破壞性工具混在候選」等對抗題。想把這套評測擴成回歸門,可接著讀AI Evals 實作指南Agent Harness 動手做

7 個最常踩的坑

  1. 把 bytes 當 tokens:不同 tokenizer 與內容形狀會改變結果;用實際 model 的 token counter。
  2. 卡片刪掉風險欄:required inputs 可以晚點看,副作用與確認需求不能消失。
  3. 只驗證 tool name:多 server 可能同名;action ID 必須綁本地 server identity 與 schema digest。
  4. 共享錯誤 Catalog:工具集合可能依授權而變;cache key 必須含 subject/scope。
  5. 相信 server annotations:它們是提示,不是安全證明;本地 policy 才是放行者。
  6. 只測正常問法:近義詞、錯字、模糊意圖與高風險近鄰才會暴露 wrong-tool failure。
  7. 以為 schema 小了,result 也會小:Lazy Schema Loading 處理工具定義;大型查詢結果仍要分頁、摘要與設定輸出上限。

現成實作可以怎麼參考?

若你的 client 沒有內建 discovery,可閱讀開源的mcp-tool-search:它用 proxy 預掃 backend servers,對模型暴露搜尋、取 schema、呼叫與列 server 四個工具。README 的 85~96% 是專案自報估算,表格範圍也不完全一致,不能當成通用 benchmark。這個專案採靜態 catalog,工具或設定改變後要重建;實際 backend transport、credential 與版本相容性都要先驗證。真正可移植的是「catalog 留在代理層、模型按需取 schema」的結構,不是安裝後必然省下某個百分比。

如果你在 Anthropic API 自建工具層,Tool Search API已提供供應商特定的 defer_loadingtool_reference機制;deferred definitions 每次仍要放進 API request 的 top-level tools,只是不進模型的初始 Context。若你做跨 provider Harness,就把本文的卡片與 policy contract 放在自己的 gateway,再由各 provider adapter 轉成對方接受的格式;這是可攜架構,不是 drop-in wire compatibility。先理解AI Agent Harness 是什麼,會更容易看懂這層為何不屬於模型本身。

常見問題(FAQ)

Q1:Claude Code 使用者需要自己架 MCP Tool Search 嗎?

先不用。目前 Claude Code 預設延後 MCP schema、按需搜尋;先用 /mcp/context與 trace 確認你的 host/model/設定走的是 Tool Search。只有需要跨 client 統一 catalog、特殊搜尋或自訂 policy 時,再評估 Proxy。

Q2:MCP 規格會強迫模型每輪讀完整 schema 嗎?

不一定。MCP 規格定義 client 與 server 的列出/呼叫契約,也允許實作採不同互動方式;完整 schema 是否被送進模型 Context,是 client/Harness 的設計。

Q3:54K 降到 1.3K,代表我也能省 97.7% 嗎?

不能這樣推。那是作者刻意放大的單一 schema fixture,token 還是用 bytes 粗估。你的結果由工具數、schema 長度、卡片欄位、tokenizer、cache 與每個任務實際 Inspect 幾個工具決定。

Q4:只做 Search,不做 Inspect 可以嗎?

不適合一般有參數的工具。搜尋卡負責候選召回,enum、條件、格式、巢狀欄位與 $ref仍要靠完整 schema;高風險操作更應在填參數前展開。

Q5:MCP ToolAnnotations 可以直接當權限規則嗎?

不能單獨使用。規格把它們定義為 hints,並要求不可信來源不能主導 tool-use decision。權限要回到本地 policy、實際 credential scope、使用者身分、目標與參數。

Q6:有 Prompt Cache,還需要 Lazy Schema Loading 嗎?

看你的瓶頸。Cache 可能降低重複前綴的計費或計算,但 schema 仍占可用 Context,也可能影響選擇品質;Anthropic 文件另指出 deferred tools 不進初始 prompt prefix,可保留既有 prompt cache。用同任務量 token、延遲與正確率再決定。

Q7:這會一起縮小大型 Tool Result 嗎?

不會自動縮小。本文處理的是工具定義的載入時機;結果內容要另外做 server-side pagination、欄位選擇、摘要、artifact storage 或 output budget。

Q8:什麼時候不值得導入?

工具少、schema 小、每輪幾乎都會用到時。此時 Search 的額外 round trip 可能比省下的 Context 更昂貴。保留完整載入當 control arm,讓數據而不是架構潮流做決定。

給新手的 5 個重點

  1. 先確認 client 是否已有 Tool Search;Claude Code 目前已有內建路線。
  2. Lazy Schema Loading 的核心是「索引卡 → 完整契約 → 受控執行」,不是把 schema 永久刪掉。
  3. 風險、權限、確認需求與 schema digest 必須跟著卡片走。
  4. A/B Test 先守任務完成率、wrong-tool 與副作用,再看 token。
  5. 工具很少時保留 upfront loading;工具越多、每次用得越少,按需載入才越有機會划算。

想把這個 gateway 做成可維護的 Agent 系統,可從 AlphaLab 的AI 課程建立完整學習路線;若眼前目標只是控制 Context,先讀Claude 省 token 實戰,把 schema、tool result、history 與 cache 分開量。

結語:別讓 Agent 背著整本型錄找一支螺絲起子

現在回到那句錨點:Lazy Schema Loading = 先看索引卡,再借完整說明書,最後才動手。它的價值不只是少幾個 tokens,而是把工具發現、參數理解與安全執行拆成三個能分別量測、分別失敗、分別修正的階段。

今天就挑一個固定任務:先跑完整 catalog baseline,再跑 lazy arm;同時記下 input tokens、首次正確工具提案時間、最終完成、schema validation、wrong-tool 與 policy decision。若 B 組只省 Context 卻更常選錯工具,就先修卡片與搜尋;若品質守住,再把更多 server 移進按需載入。這才是把 54K 的驚嘆號,變成你自己系統裡可重跑的工程決策。

ALPHALAB 社群

有問題?來 Telegram 聊

和 Terry、編輯、其他網友一起討論這篇文章。提問、分享觀點,回覆更即時。

加入 Telegram 討論

📩 訂閱 AlphaLab 電子報

每週最多三封:一封 Weekly 週報與最多兩封關鍵 Alpha Signal。

我們不會 spam,隨時可退訂。