WebMCP 最容易被誤用的方式,就是把每個 UI 元件一比一轉成 Tool。網站有 50 個按鈕,就註冊 50 個 Tools;技術上很完整,模型面前卻變成一大堆語意重疊選項。
官方 WebMCP Tool Design 指南也強調從使用者目標、對話流程與狀態轉換來設計 Tools,而不是從 DOM 元件清單開始。
今天以一個有 14 種 UI 元件與操作的電商頁面為例,先挑出「找商品到準備結帳」這條流程,再設計 5 個 Goal-oriented Tools。收藏等其他目標不在本次 Demo 範圍內,並不是把所有網站功能硬塞進五個 Tool。
假設商品頁有:
搜尋框
類別下拉
價格篩選
排序
上一頁
下一頁
商品卡片
查看詳情
尺寸下拉
數量 +
數量 -
加入購物車
收藏
結帳
如果直接照 UI 做:
set_search_text
select_category
set_max_price
change_sort
click_next_page
open_product_card
select_size
increase_quantity
add_button_click
...
Agent 的任務會變成:
我應該先
set_search_text還是select_category?價格篩選完是不是要click_apply_filter?
這種設計容易讓 Agent 仍然需要規劃每個介面操作,未必能降低推理負擔。是否改善任務成功率,還需要實際測試,不能只看 Tool 數量。
📸 圖片 1|從低階 UI 操作,轉向使用者目標
使用者真正會說:
幫我找 2000 元以下的黑色外套。
看看第二件有哪些尺寸。
幫我加 M 號一件到購物車。
購物車現在有哪些東西?
準備結帳。
所以 Tools 可以收斂成:
search_products
get_product
add_to_cart
get_cart
prepare_checkout
UI 細節由網站自己處理。本日 Demo 註冊這五個 Tool,讓網頁表單與 Tool 共用商品、尺寸與購物車邏輯。
商品與購物車都是本地模擬資料,重新整理會清空購物車;prepare_checkout 只產生預覽,不會建立訂單或扣款。
📸 圖片 2|Inspector 中的五個 Goal-oriented Tools
以「2000 元以下的黑色外套」為例,search_products 接受的是搜尋條件:
{"keyword":"外套","color":"黑色","maxPrice":2000}
在 Inspector 執行後,Demo 回傳兩筆商品:第一件是 ID 101 的輕量黑色外套,售價 NT$1,490;第二件是 ID 102 的防風黑色外套,售價 NT$1,890。
呼叫端不需要先填搜尋框、再選顏色、再調整價格。這些條件一起交給搜尋邏輯處理,Tool 的完成條件就是回傳符合條件的候選商品。
📸 圖片 3|search_products 一次處理關鍵字、顏色與價格條件
使用者接著說「看看第二件有哪些尺寸」,這裡的「第二件」要從剛才的結果取得,不能把序號 2 當成商品 ID。本次搜尋的第二件是 102,因此 get_product 的輸入為:
{"productId":102}
商品詳情會提供 M、L 尺寸,對應的 variationId 分別為 102-M、102-L。要加入 M 號一件,就把商品與尺寸的識別值交給 add_to_cart:
{"productId":102,"variationId":"102-M","quantity":1}
加入後,Tool 回傳更新後的購物車:數量 1、小計 NT$1,890。再用空物件 {} 呼叫 get_cart,便能查看目前內容,不會增加數量。
這裡要留意:add_to_cart 是累加操作,每成功呼叫一次就再加入指定數量。它和 Day14 的收藏不同,重試前應先核對購物車,正式系統也要另外處理防止重複加入的機制。
最後以 {} 呼叫 prepare_checkout。它直接使用目前購物車,不再接受另一組商品、數量或價格。
本例會得到小計 NT$1,890、運費 NT$60、總額 NT$1,950,並回傳 status: preview_ready 與 simulated: true。若購物車為空,則回傳 empty_cart;購物車變更後,畫面上的舊預覽會清除,需要重新準備結帳。
📸 圖片 4|依購物車內容產生結帳預覽,總額為 NT$1,950
這條流程驗證的是五個 Tool 能否傳遞正確資料、完成各自的目標。圖片 3、4 是 Inspector 手動呼叫的結果;若要評估 Agent 是否能從自然語言選對 Tool,仍需另外跑完整對話並檢查實際呼叫紀錄。
兩個極端都不好。
click_plus
click_minus
open_dropdown
select_option
缺點:Agent 需要大量步驟與狀態推理。
buy_everything_user_wants
缺點:
我比較喜歡每個 Tool 對應一個可清楚驗收的使用者目標/狀態轉換。
例如:
search_products
輸入:查詢條件
輸出:候選商品
業務資料副作用:無(Demo 會更新畫面上的搜尋結果)
add_to_cart
輸入:productId / variationId / quantity
輸出:更新後 cart summary
副作用:修改購物車
Chrome 官方 Build Tools 指南提供一個很好用的方法:先模擬完整對話,再問每一輪需要什麼資訊、什麼 Action、什麼 Tool。
例如:
User:
幫我找 2000 元以下的黑色外套。
Agent needs:
→ 商品搜尋
Tool:
→ search_products
Agent:
找到輕量黑色外套與防風黑色外套,你想先看哪一件?
User:
看第二件有哪些尺寸。
Tool:
→ get_product
User:
加 M 號一件到購物車。
Tool:
→ add_to_cart
從 Conversation 反推 Tools,比從 Route List 反推自然很多。這段是對話設計示例;實際測試時,要依 Agent 當次列出的商品順序解讀「第二件」,並使用 get_product 回傳的尺寸 ID。
不要看到這篇就走另一個極端,只留一個:
commerce_agent_tool
然後 schema 裡放:
{
"action": "search|get|add|remove|checkout|..."
}
這會讓單一 Tool 變成隱藏版 RPC Router,Description、風險、參數全部混在一起。
尤其:
search_products
和:
confirm_checkout
風險完全不同,不應塞同一個 Tool。這裡的 confirm_checkout 是沿用 Day15 的高風險操作例子;本日 Demo 只到 prepare_checkout,不包含真正執行訂單的 Tool。
每新增一個 Tool,我會問:
1. 使用者會用一句自然語言描述這個目標嗎?
2. Tool 的完成條件能不能明確驗收?
3. 它和其他 Tool 的用途是否高度重疊?
4. 它是否把不同風險等級的操作混在一起?
5. 如果 UI 大改版,這個 Tool 的語意還成立嗎?
第五題非常好用。
如果 Tool 叫:
click_blue_checkout_button
UI 改版就失去意義。
如果叫:
prepare_checkout
即使整個畫面重做,使用者目標還是一樣。