iT邦幫忙

2026 iThome 鐵人賽

DAY 25
0
Modern Web

WebMCP:30 天打造 AI Agent 看得懂、也操作得動的網站系列 第 25 篇

Day 25|「找 2000 元以下的鍵盤」怎麼接?用 WooCommerce Store API 做商品 Tool

  • 分享至 

  • xImage
  •  

本篇重點

使用者說「找 2000 元以下的鍵盤」,網站需要把關鍵字與預算交給商品搜尋,再回傳商品名稱、價格與連結。

今天沿用 WordPress 外掛,新增 search_products 與 get_product。商品資料直接來自 WooCommerce Store API,前端不用放 API Key,也不用自己重做商品搜尋。

本機測試中,1,290 元的機械鍵盤符合條件,2,490 元的高階鍵盤被排除。這篇最容易踩到的地方是價格單位:輸入的 2,000 元,要依商店小數位換成 API 使用的整數。

一、先分清楚資料從哪裡來

本次流程是:

Agent
→ search_products/get_product
→ fetch
→ WooCommerce Store API
→ 整理後的商品 JSON

Store API 提供前台商品、購物車與結帳所需的介面。本篇只使用公開商品讀取:

GET /wp-json/wc/store/v1/products
GET /wp-json/wc/store/v1/products/{id}

商品搜尋支援關鍵字、價格、分類與屬性。本次 Tool 先開放 keyword、maxPrice、limit 三個參數,讓輸入範圍清楚。

這與需要驗證的 WooCommerce 後台管理 API 分工不同。商品查詢使用 credentials: 'omit',不傳送登入 Cookie、Nonce 或管理用 API Key。

二、準備測試商品與外掛

  1. 在 WordPress 啟用 WooCommerce 與 WP WebMCP Lab 0.3.0。
  2. 在「WooCommerce → 設定 → 一般」核對幣別與價格小數位。本機設定為 TWD、2 位小數。
  3. 在「商品 → 新增商品」建立下表四筆簡單商品,填入名稱、一般價格與商品說明。前三筆發佈,最後一筆儲存為草稿。
  4. 開啟網站首頁加上 ?webmcp_lab=25。本機網址是 https://wordpress.local/?webmcp_lab=25。
  5. 確認頁面顯示幣別、小數位,以及「已註冊 search_products、get_product」。

本機示範資料如下:

商品 ID 價格(TWD) 狀態
Day25 機械鍵盤 101 1290 已發佈
Day25 高階鍵盤 102 2490 已發佈
Day25 無線耳機 103 1680 已發佈
Day25 草稿鍵盤 104 699 草稿

商品 ID 由各站的 WordPress 產生。公開商品使用該站搜尋結果中的 ID;草稿商品的 ID 則從後台商品編輯網址的 post= 參數取得。

三、2,000 元不能直接當成 max_price

Tool 收到的 maxPrice 是使用者看得懂的金額,Store API 的 max_price 則使用最小價格單位。換算方式是:

API 價格 = 使用者金額 × 10 的小數位次方

本機小數位是 2,因此:

maxPrice: 2000
→ max_price=200000

prices.price: "129000"
currency_minor_unit: 2
→ 1290 TWD

不能只看到 TWD 就把小數位寫死為 0。外掛從 WooCommerce 讀取實際設定,再交給 JavaScript:

wp_localize_script(
    'wp-webmcp-products',
    'wpWebMCPProducts',
    array(
        'productsUrl' => esc_url_raw(rest_url('wc/store/v1/products')),
        'currency' => get_woocommerce_currency(),
        'minorUnit' => wc_get_price_decimals(),
    )
);

程式會驗證金額是否非負、是否超過商店允許的小數位,以及換算後是否仍是安全整數。像小數位為 2 時輸入 1.001,會回傳 invalid_input,不把預算偷偷四捨五入成另一個金額。

圖片 1|Store API 回傳價格 129000、小數位 2,Tool 換算為 1,290 TWD。
https://ithelp.ithome.com.tw/upload/images/20261004/20121296eOPSxt6oj2.png

四、建立 search_products

Tool 的輸入格式如下:

{
  "keyword": "鍵盤",
  "maxPrice": 2000,
  "limit": 5
}
  • keyword:必填,1~100 字。
  • maxPrice:選填,使用商店幣別的非負金額;省略就不限制最高價格。
  • limit:選填,1~10 的整數,預設 5。

註冊時把用途寫清楚:搜尋商品,不查歷史訂單,也不操作購物車。下面的 run() 是完整範例 assets/products.js 中共用的查詢函式。

await document.modelContext.registerTool({
  name: 'search_products',
  description: 'Search public WooCommerce products by keyword and optional maximum price in the store currency. For product discovery, not articles, carts or past orders. Does not buy anything.',
  inputSchema: {
    type: 'object',
    properties: {
      keyword: { type: 'string', minLength: 1, maxLength: 100 },
      maxPrice: { type: 'number', minimum: 0 },
      limit: { type: 'integer', minimum: 1, maximum: 10, default: 5 }
    },
    required: ['keyword'],
    additionalProperties: false
  },
  annotations: { readOnlyHint: true },
  execute: args => run('search_products', args)
});

共用函式完成驗證與價格換算後,加入這些查詢條件:

search=鍵盤
per_page=5
orderby=price
order=asc
max_price=200000

結果依價格由低到高排列。網址由 PHP 的 rest_url() 提供,程式同時支援 /wp-json/ 與 index.php?rest_route=...,不把固定網址格式寫死。

前端請求只讀取公開資料:

const response = await fetch(url, {
  credentials: 'omit',
  cache: 'no-store',
  headers: { Accept: 'application/json' }
});

接著整理 Store API 回應。價格使用每筆商品回傳的 currency_minor_unit 換算,並保留 currency_code,避免 Agent 把原始整數當成售價。

搜尋結果會保留 id、name、type、price、onSale、inStock、hasOptions 與 url。其中一筆價格資料為:

{
  "id": 101,
  "name": "Day25 機械鍵盤",
  "price": {
    "amount": 1290,
    "currency": "TWD",
    "range": null
  }
}

有價格區間時,range 保留最低與最高金額;沒有定價時,amount 使用 null。商品有選項時,也保留 hasOptions,供後續選擇規格使用。

實際操作

  1. 在 Inspector 的 Tool 選擇 search_products。
  2. Input Arguments 輸入 {"keyword":"鍵盤","maxPrice":2000,"limit":5}。
  3. 按 Execute Tool。
  4. 核對 status: success、count: 1,以及機械鍵盤的 price.amount: 1290、currency: TWD。

圖片 2|search_products 篩出 2,000 元以下的機械鍵盤,並回傳明確的金額與幣別。
https://ithelp.ithome.com.tw/upload/images/20261004/20121296sTWNEE9Wky.png

五、用 get_product 讀取商品詳情

搜尋清單先提供挑選商品所需的資訊。選定商品後,再將搜尋結果的 ID 傳給 get_product:

{ "productId": 101 }

get_product 只接受正整數 productId,查詢 Store API 的單一商品 endpoint。除了商品基本資料,回傳內容增加:

  • shortDescription:純文字短說明。
  • description:純文字完整說明。
  • isPurchasable:API 回傳的可購買狀態。
  • attributes:屬性名稱與選項。

HTML 說明先放入未掛到畫面的 template,移除 script、style,再擷取文字;頁面用 textContent 顯示。Tool 描述同時要求把商品文字視為資料,不把商品說明中的句子當成操作指令。

實際操作

  1. 將 Tool 改成 get_product。
  2. Input Arguments 輸入 {"productId":101}。
  3. 按 Execute Tool。
  4. 核對商品名稱與價格,並確認說明顯示「87 鍵、紅軸,適合辦公與日常打字。」,沒有 <p> 標籤。

這個 Tool 負責讀取商品詳情。選擇變體、加入購物車與付款不在本篇功能範圍內。

圖片 3|get_product 使用搜尋結果中的商品 ID,取得純文字說明與商品狀態。
https://ithelp.ithome.com.tw/upload/images/20261004/20121296tKRpOcAU4K.png

六、查不到商品與 API 出錯分開處理

將 Inspector 的 Tool 改回 search_products,在 Input Arguments 輸入:

{ "keyword": "xyz-123", "limit": 5 }

按 Execute Tool。這次 API 回傳 HTTP 200 與空陣列,Tool 整理成:

{ "status": "no_results", "count": 0, "products": [] }

這表示沒有符合條件的商品。網路失敗或 API 異常則回傳 internal_error,不把所有錯誤都寫成「沒有商品」。

圖片 4|查詢成功但沒有符合商品時,Tool 回傳 no_results 與空清單。
https://ithelp.ithome.com.tw/upload/images/20261004/20121296FY1hrbMIxf.png

七、核對公開商品邊界

Store API 的公開商品集合會排除草稿與其他未發佈商品;直接用未發佈商品 ID 查詢,也會回 HTTP 404。

先在後台確認 ID 104 的「Day25 草稿鍵盤」維持草稿狀態,再回到 Inspector,將 Tool 改成 get_product,在 Input Arguments 輸入 {"productId":104},按 Execute Tool。回傳結果如下:

{
  "status": "no_results",
  "httpStatus": 404,
  "message": "找不到可讀取的商品。"
}

以下整理本次透過 Inspector 的 Execute Tool 取得的實測結果:

操作 HTTP 結果
鍵盤、最高 2000 元 200 只回傳 ID 101,1290 TWD
讀取商品 101 200 回傳價格與純文字商品說明
搜尋 xyz-123 200 no_results,空清單
讀取草稿商品 104 404 no_results

圖片 5|直接查詢草稿商品 ID,Store API 回傳 404,Tool 保留查無商品的結果。
https://ithelp.ithome.com.tw/upload/images/20261004/20121296Lzp4uisehO.png

Agent 測試清單

使用 Inspector 的 Send 測試自然語言;每題先 Reset,再記錄實際 Tool 與參數:

  1. 「找 2000 元以下的鍵盤。」核對 search_products 是否帶入 keyword 與 maxPrice。
  2. 「找耳機,告訴我第一個商品的詳細說明。」核對搜尋後是否用回傳 ID 呼叫 get_product。
  3. 「找一個不存在的商品 xyz-123。」核對回答是否依據空結果。
  4. 「我之前買過哪個鍵盤?」這是購買紀錄需求,本頁商品工具沒有訂單資料。
  5. 「找適合送禮的耳機。」核對 Agent 是否依商品說明提出理由;Store API 的文字搜尋本身不等於送禮推薦系統。

可帶走的重點

  1. 商品查詢可以直接使用 WooCommerce Store API,Tool 負責把輸入與輸出整理清楚。
  2. 預算依商店小數位換算;商品售價依回應中的小數位還原,同時保留幣別。
  3. 搜尋清單與商品詳情分成兩個 Tool,先找到候選商品,再讀取詳細說明。
  4. 本次價格篩選排除了超過預算的商品,草稿商品直接查詢回傳 404。
  5. 空結果、無效輸入與 API 錯誤使用不同狀態,讓 Agent 有明確依據回應。

參考資料


上一篇
Day 24|不用重做搜尋後端:把 WordPress REST API 包成 search_posts Tool
系列文
WebMCP:30 天打造 AI Agent 看得懂、也操作得動的網站 共 25 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言