前端開發 別再讓 Agent 猜按鈕:30 天打造並實測 Agent-ready 的 WebMCP 活動網站 · 第 9 / 30 篇

Day 09|網站該公開哪些 WebMCP Tool?從操作盤點到五支正式能力

2026 iThome 鐵人賽 WebMCP Day 9:安安~我是ChiYu~ 昨天才把 click_blue_search_button 請出 catalog,我差點又用同一套方法,把剩下的按鈕 全部包成 Tool。 我先把網站上看得到的操作列出來:展開篩選器、切換頁籤、查看詳情、收藏、關閉 dialo…

快速導覽 查看本文目錄

本文同步自 2026 iThome 鐵人賽原文 。完整系列可見 iThome 系列頁 。

安安~我是ChiYu~

昨天才把 click_blue_search_button 請出 catalog,我差點又用同一套方法,把剩下的按鈕 全部包成 Tool。

我先把網站上看得到的操作列出來:展開篩選器、切換頁籤、查看詳情、收藏、關閉 dialog、 送出報名、準備取消、確認取消。清單愈寫愈長,看起來很有進度,實際上比較像是在替 DOM 做戶口名簿。

昨天留下的 search_events 能成立,是因為「搜尋活動」本身就是使用者會提出的任務。至於 「展開篩選器」和「按下藍色按鈕」,只是目前這版 UI 完成任務的方式。把兩者混在一起, Agent 就得先學會網站的操作零件,再猜這些零件怎麼拼成使用者真正想做的事。

活動網站剛好很適合拿來做這次取捨。同一個產品裡有唯讀查詢、可以復原的收藏,也有會占用 名額的報名與影響既有權益的取消。它不需要硬塞付款、後台或第六支 Tool,就已經能讓我們 看見不同程度的風險。

Chrome 的 WebMCP 最佳實務 建議先規劃 Tool strategy,避免功能重疊,並在能力不再可用時解除註冊。每支 Tool 都會占用 Agent 的 context;規格沒有替 catalog 設定固定上限,不代表我們可以把所有按鈕都搬進去。

我把候選操作放進同一張矩陣,先看完整任務,再看它是否值得成為 Tool:

AgentReady Events 候選能力篩選矩陣

圖 1:保留的是使用者想完成的任務;淘汰的是目前 UI 恰好採用的操作步驟。

用五個問題判斷候選操作是否值得成為 Tool

使用者會說「幫我找台北的入門活動」,不會說「打開左側篩選器、選第三個下拉選單,再按 藍色按鈕」。後面那串只是這一版畫面的操作說明。

因此每個候選能力,我都先問下面五個問題:

判斷面向要問的問題
任務價值使用者能不能用一句自然語言要求這件事?
穩定性頁面改版或文案調整後,這項能力仍然成立嗎?
上下文必要的 route、ID、session 或狀態能明確驗證嗎?
副作用它會改資料、占名額或影響使用者權益嗎?
可復原性發生誤操作時,有 Undo、確認停點或補救方法嗎?

拿「關閉 dialog」和「收藏活動」相比就很清楚。前者只在特定畫面狀態下有意義,dialog 換個 版型,這支 Tool 可能立刻失業;後者有明確結果,也能讓使用者 Undo。兩顆都是按鈕,但只有 其中一顆承接了完整任務。

五支 Tool 分別承接查詢、收藏、報名與取消

篩選後,我把產品層的 catalog 收斂成五支 Tool:

Tool風險為什麼保留人類控制
search_eventsR0唯讀搜尋,有獨立活動清單結果同步更新到畫面
get_event_detailsR0接續搜尋結果,或讀取目前詳情 route列表頁沿用搜尋結果 ID;詳情頁使用 route context
save_eventR1收藏目前已顯示的活動,重複執行安全畫面顯示狀態並提供 Undo
prepare_event_registrationR2Agent 可替人準備表單,減少重填最終 POST 由人類按下
prepare_registration_cancellationR3Agent 可先整理取消對象與後果取消 mutation 由人類確認

這裡的 R0~R3 是本系列用來討論風險與人類停點的標籤,不是 WebMCP 官方認證等級。R0 是 唯讀操作,R1 會改變可復原狀態;到了 R2、R3,操作開始碰到名額或既有權益,Agent 能做的 事情就必須停在「準備完成」。

五支 Tool 最後組成三條 Journey:

搜尋 → 詳情 → 收藏
準備報名 → 人類送出
準備取消 → 人類確認

你會發現清單裡沒有 submit_registration,也沒有 cancel_registration。Agent 可以整理 資料、打開表單、說明影響,但最後一次 POST 或取消 mutation 必須留給人類。我刻意把這個 控制點留在人類手上。

這裡列的是整個產品允許出現的五個名稱,不代表每個頁面都會看見相同 Tool,也不代表 同名 Tool 在不同 route 一定使用同一份 input schema。真正公開給 Agent 的 active catalog, 仍要回到目前頁面與狀態判斷。

展開篩選器、切換頁籤與關閉 dialog 繼續留在人類 UI

有些操作對人類很好用,卻沒有必要升級成 Tool:

候選操作決定原因
展開篩選器不做 Tool只是搜尋流程中的版面步驟
切換「活動/我的報名」Tab不做 Toolroute 或導覽已能表達目的地
展開活動卡不做 Tool沒有獨立結果,改版後也可能消失
關閉確認 dialog不做 Tool應由人類決定保留或確認
直接送出報名禁止會建立名額與個人報名資料
直接取消報名禁止會影響既有權益,不應由 Agent 自行完成

「不做 Tool」不等於刪掉功能。人類 UI 繼續保留適合滑鼠、鍵盤與視覺判斷的互動;Agent 拿到的則是較穩定、能被驗證的任務介面。兩邊使用同一套產品能力,入口不必長得一模一樣。

把搜尋拆成五支 UI Tool,只會增加狀態與稽核噪音

如果我真的照按鈕做 catalog,一次搜尋可能會變成:

open_filter_panel
select_free_price
select_beginner_level
click_search_button
open_first_card

原本一次 search_events 能完成的工作,現在要連續呼叫五支 Tool。Agent 還得記住面板有沒有 打開、欄位是否已選取、第一張卡是不是剛才那一場。UI 只要換個排序,最後一步就可能打開 不同活動。

稽核紀錄也會跟著變模糊。一筆 search_events 很容易看懂使用者要求了什麼;五筆 UI 操作 只告訴我們 Agent 動過哪些零件,卻不一定說得清楚它想完成哪個任務。這種設計只是替 Browser Automation 的步驟換上 Tool 名稱,能力邊界並沒有因此變好。

產品只有五個 Tool 名稱,但每個 route 的 active catalog 不一樣

最終實作不是讓五支 Tool 每頁常駐,也不是搜尋完成後才臨時新增下一支 Tool。它採用的是 「產品名稱固定、目前 route 決定實際契約」:

Route/狀態目前公開的 Tool這一頁的契約
/eventssearch_events、get_event_details、save_event搜尋表單用 Declarative API;詳情 Tool 必須使用 search_events 回傳的 event_id;收藏只能使用剛顯示在頁面上的同一個 ID
/events/:eventIdget_event_details、save_event詳情 Tool 已綁定 route,只接受 {};收藏仍要沿用該活動 ID
/events/:eventId/registerprepare_event_registrationroute 提供活動 ID,Agent 只準備姓名與 Email;最後 POST 留給人類
/registrationsprepare_registration_cancellation有有效報名時才公開;只有一筆可用 {},有多筆時使用頁面提供的 registration_id
其他頁面或無可操作狀態無不因產品總共有五支 Tool,就硬把無關能力塞進目前頁面

/events 上的三支 Tool 會一起存在,是為了讓 Agent 能在同一頁完成 search_events → get_event_details → save_event。但一起存在不代表可以跳步: save_event 仍會檢查目前畫面顯示的活動是否和輸入 ID 相同。Agent 若沒有先取得並顯示詳情, 收藏就應該被拒絕。

同名的 get_event_details 也有兩種明確契約。列表頁需要 event_id;詳情頁則由 route 綁定目前活動,只接受空物件。這比在同一份 schema 裡把 event_id 寫成選填,再期待模型 判斷何時該省略更容易測,也少了一個傳入 null 的模糊空間。

專案再用 APPROVED_TOOL_NAMES 凍結產品層的五個正式名稱,測試也明確拒絕加入第六支 finalization Tool。包含 catalog 與相關契約的聚焦測試共 11 項通過,但這份結果仍是 E2 harness:它證明程式與契約一致,還不能替真實 Chrome 宣布發現成功。

今天,我沒有替網站增加任何新功能,反而把候選清單刪到只剩五支。刪完之後,每支 Tool 都能回答「使用者到底想完成什麼」,不同 route 的 input 與狀態前提也有了清楚位置。

紙上的 catalog 已經定案,下一個問題很直接:Chrome 看得到嗎?明天我會安裝 WebMCP Inspector、啟用 testing flag,先從一片空白的側邊面板開始查起。

讀完了!你覺得這篇如何?

你的回饋會決定下一篇要寫什麼。

還有疑問

Learning path

別再讓 Agent 猜按鈕:30 天打造並實測 Agent-ready 的 WebMCP 活動網站

這篇是系列中的第 9 / 30 篇。可以順著列表補完整脈絡,也可以直接跳到需要的段落。

  1. 01 Day 01|網站真的會被 Agent 使用嗎?我先丟了一句自然語言
  2. 02 Day 02|換到全新資料夾後,網站還能不能跑?
  3. 03 Day 03|先別急著做 Tool,我把活動網站自己走了一遍
  4. 04 Day 04|按鈕只多包一層,哪種 Playwright Locator 撐得住?
  5. 05 Day 05|只改按鈕四個字,Playwright 為什麼停在 click 以前?
  6. 06 Day 06|Playwright、REST API、MCP 與 WebMCP,各自負責哪一段?
  7. 07 Day 07|Agent 偶爾答對還不夠,我先出二十道測試題
  8. 08 Day 08|WebMCP Tool 該怎麼設計?把「點按鈕」改成「搜尋活動」
  9. 09 Day 09|網站該公開哪些 WebMCP Tool?從操作盤點到五支正式能力 目前閱讀
  10. 10 Day 10|Inspector 裝好了,為什麼 Tool 面板還是一片空白?
  11. 11 Day 11|什麼是 Declarative API?讓 HTML 表單成為 WebMCP Tool
  12. 12 Day 12|Tool 註冊完還不算完成:離開 route 後誰把它收回來?
  13. 13 Day 13|第一次按下 Inspector 的 Send,先被 Gemini 429 擋在門外
  14. 14 Day 14|五支 Tool 不再往外長:把產品範圍寫成會亮紅燈的契約
  15. 15 Day 15|讓人類與 Agent 共用同一套活動搜尋規則
  16. 16 Day 16|Agent 怎麼知道「我現在看的活動」是哪一場?
  17. 17 Day 17|Tool 回太少做不完,回太多又把內部資料倒給 Agent
  18. 18 Day 18|活動服務暫時失敗時,Agent 應該重試還是停下來?
  19. 19 Day 19|同一場活動收藏兩次,網站為什麼只能留下同一筆?
  20. 20 Day 20|表單填好了,為什麼這次報名仍然不能算通過?
  21. 21 Day 21|一句「這個我不要了」,Agent 到底敢不敢直接取消?
  22. 22 Day 22|五支 Tool 如何共用同一套規則,串成三條完整流程?
  23. 23 Day 23|在問 Agent 聰不聰明前,先證明網站沒有壞
  24. 24 Day 24|活動摘要叫 Agent 洩漏祕密,它會把這句話當資料還是命令?
  25. 25 Day 25|localhost 成功不算交付:怎麼證明公開網址跑的是同一份程式?
  26. 26 Day 26|把自然語言送進公開站,Agent 真的會自己選對 Tool 嗎?
  27. 27 Day 27|寫入型 Tool 怎麼驗收?把 Trace、Network、UI 與 Server 狀態放在一起看
  28. 28 Day 28|Agent 選錯、傳錯或答錯時,怎麼知道問題卡在哪一層?
  29. 29 Day 29|把網站交給 Agent 前,我最後會檢查哪十件事?
  30. 30 Day 30|網站終於會說話:做完五支 Tool 後,我學到什麼?

Further reading

Day 30|網站終於會說話:做完五支 Tool 後,我學到什麼? 封面圖 2026-09-30 Day 30|網站終於會說話:做完五支 Tool 後,我學到什麼? Day 29|把網站交給 Agent 前,我最後會檢查哪十件事? 封面圖 2026-09-29 Day 29|把網站交給 Agent 前,我最後會檢查哪十件事? Day 28|Agent 選錯、傳錯或答錯時,怎麼知道問題卡在哪一層? 封面圖 2026-09-28 Day 28|Agent 選錯、傳錯或答錯時,怎麼知道問題卡在哪一層?

留言討論

用 GitHub 帳號留言,留言會同步到這個 Blog 的 GitHub Discussions。

閱讀導覽

約 6 分鐘

本文目錄

本篇所在系列 · 第 9 / 30 篇

別再讓 Agent 猜按鈕:30 天打造並實測 Agent-ready 的 WebMCP 活動網站

  1. Day 01|網站真的會被 Agent 使用嗎?我先丟了一句自然語言
  2. Day 02|換到全新資料夾後,網站還能不能跑?
  3. Day 03|先別急著做 Tool,我把活動網站自己走了一遍
  4. Day 04|按鈕只多包一層,哪種 Playwright Locator 撐得住?
  5. Day 05|只改按鈕四個字,Playwright 為什麼停在 click 以前?
  6. Day 06|Playwright、REST API、MCP 與 WebMCP,各自負責哪一段?
  7. Day 07|Agent 偶爾答對還不夠,我先出二十道測試題
  8. Day 08|WebMCP Tool 該怎麼設計?把「點按鈕」改成「搜尋活動」
  9. Day 09|網站該公開哪些 WebMCP Tool?從操作盤點到五支正式能力
  10. Day 10|Inspector 裝好了,為什麼 Tool 面板還是一片空白?
  11. Day 11|什麼是 Declarative API?讓 HTML 表單成為 WebMCP Tool
  12. Day 12|Tool 註冊完還不算完成:離開 route 後誰把它收回來?
  13. Day 13|第一次按下 Inspector 的 Send,先被 Gemini 429 擋在門外
  14. Day 14|五支 Tool 不再往外長:把產品範圍寫成會亮紅燈的契約
  15. Day 15|讓人類與 Agent 共用同一套活動搜尋規則
  16. Day 16|Agent 怎麼知道「我現在看的活動」是哪一場?
  17. Day 17|Tool 回太少做不完,回太多又把內部資料倒給 Agent
  18. Day 18|活動服務暫時失敗時,Agent 應該重試還是停下來?
  19. Day 19|同一場活動收藏兩次,網站為什麼只能留下同一筆?
  20. Day 20|表單填好了,為什麼這次報名仍然不能算通過?
  21. Day 21|一句「這個我不要了」,Agent 到底敢不敢直接取消?
  22. Day 22|五支 Tool 如何共用同一套規則,串成三條完整流程?
  23. Day 23|在問 Agent 聰不聰明前,先證明網站沒有壞
  24. Day 24|活動摘要叫 Agent 洩漏祕密,它會把這句話當資料還是命令?
  25. Day 25|localhost 成功不算交付:怎麼證明公開網址跑的是同一份程式?
  26. Day 26|把自然語言送進公開站,Agent 真的會自己選對 Tool 嗎?
  27. Day 27|寫入型 Tool 怎麼驗收?把 Trace、Network、UI 與 Server 狀態放在一起看
  28. Day 28|Agent 選錯、傳錯或答錯時,怎麼知道問題卡在哪一層?
  29. Day 29|把網站交給 Agent 前,我最後會檢查哪十件事?
  30. Day 30|網站終於會說話:做完五支 Tool 後,我學到什麼?
看完整系列 30 篇