iT邦幫忙

2026 iThome 鐵人賽

DAY 17
0
Modern Web

網站終於會說話:30 天實作並驗證 Agent-ready 的 WebMCP 活動網站系列 第 17

Day 17|Tool 回太少做不完,回太多又把內部資料倒給 Agent

  • 分享至 

  • xImage
  •  

安安~我是ChiYu~

昨天的 get_event_details 終於不用再猜 current,可以從目前頁面找到正確活動。照理說,
接下來只要把資料交給 Agent,讓它整理完就收工。

結果我一看 Tool result,新的問題馬上排隊進場:到底要回多少?

只回一句「找到活動」,Tool 看起來執行成功,Agent 卻回答不了地點、時間與剩餘名額;直接把
server 物件整包倒出去,又會把內部欄位、儲存結構與不受信任內容一起送進模型。

所以今天不加新 Tool。我把「太少、太多、剛好夠用」三種 payload 放在一起,看每個欄位到底
有沒有工作。

今天沿用同一版詳情頁,只調整回傳契約

今天沒有新的程式里程碑。若昨天已經切到 v3-day-15,就留在同一版;單篇閱讀時可以執行:

git switch --detach v3-day-15

昨天驗證的是 Tool 怎麼找到目前活動,今天則檢查它找到資料後應該公開什麼。先固定 route 與
handler,才不會把「資料邊界」和新功能混在同一次修改裡。

三種 Tool result 契約比較

圖 1:左邊太省,無法完成任務;中間直接暴露內部物件;右邊只留下公開回答、下一步與 UI 同步需要的資料。

第一種:只回「找到活動」,execution 成功但任務沒完成

最短版本可以只有:

{
  "message": "找到活動"
}

這份 result 說明 handler 有跑完,卻回答不了使用者剛才問的名稱、場地、時間與剩餘名額。
下一步若要收藏,Agent 也拿不到合法的 opaque ID。

它很像餐廳叫號只喊「餐點好了」,卻沒說是哪一桌。訊息沒有錯,但現場沒有人知道下一步
該做什麼。

Result 的目標不是證明程式執行過,而是提供完成目前任務所需的資料。

第二種:直接回 server 物件,省下 mapping,也公開了內部結構

另一個極端是 API 查到什麼,Tool 就回什麼:

{
  "event": {
    "...": "資料庫欄位、內部旗標與尚未整理的內容"
  }
}

少寫一層 mapping 當下很舒服,代價是 server 儲存格式直接變成 Agent 契約。之後資料表改名、
內部狀態拆欄位,模型看到的 payload 也跟著變動。

更麻煩的是,像 internalOwnerId、私人輸入、stack trace、內部錯誤或尚未整理的活動文案,
可能在沒人要求的情況下進入模型 context。

Tool result 是模型的輸入面。資料多不會自動變可靠,只會讓真正要回答的欄位埋得更深,也
擴大隱私、相容性與 Prompt Injection 的風險。

第三種:從任務反推真正需要公開的欄位

我最後把 result 收斂成公開的 EventDetail,再補上執行狀態、下一步 guidance 與 UI 座標:

{
  "ok": true,
  "code": "SUCCESS",
  "data": {
    "event": {
      "id": "evt-webmcp-intro",
      "title": "WebMCP 入門工作坊",
      "summary": "從語意 HTML 到第一個網站 Tool。",
      "startsAt": "2027-01-23T10:00:00+08:00",
      "endsAt": "2027-01-23T12:00:00+08:00",
      "location": "taipei",
      "venue": "台北前端共學空間",
      "price": "free",
      "level": "beginner",
      "remainingCapacity": 8,
      "registrationDeadline": "2027-01-21T23:59:59+08:00",
      "state": "open"
    }
  },
  "guidance": {
    "availableActions": ["save_event"],
    "currentTarget": {
      "kind": "event",
      "id": "evt-webmcp-intro"
    },
    "requiresHumanConfirmation": false
  },
  "uiUpdated": true,
  "stateVersion": 2
}

先說清楚:這個 ok / code / data / guidance / uiUpdated / stateVersion envelope 是
AgentReady Events 為了統一驗收而定義的專案契約,不是 WebMCP 規範要求的固定 JSON
格式。其他網站可以採用不同 shape,重點是成功、錯誤、下一步與可見狀態要能被一致判讀。

這份 payload 中,每組資料都有明確工作:

資料 用途
data.event 回答名稱、日期、地點、費用、程度、名額與開放狀態
event.id 交給後續 Tool,避免 Agent 自行發明目標 ID
guidance 說明目前目標、可接續動作與是否需要人類確認
uiUpdated 回報這次執行是否同步更新可見畫面
stateVersion 讓後續流程知道狀態是否已換版

日期保留時區,避免 Agent 自己猜活動所在地;remainingCapacity、截止時間與 state 放在
一起,才足以描述目前是否還能報名。

guidance.availableActions 也不是替 Agent 開一條新權限。它只能列出產品 catalog 已存在的
下一步;真正能不能執行,仍要重新查看目前 route、schema 與 server 狀態。

Result 要能回答三個問題

欄位收斂後,我用三個問題重新檢查:

  1. 現在問的問題能回答嗎?
    名稱、時間、場地、費用、程度與名額都能直接對回公開資料。
  2. 下一步需要的識別資訊有嗎?
    後續 Tool 使用同一個 opaque ID,不讓模型猜 currentevent-1
  3. 畫面與狀態有沒有座標?
    uiUpdatedstateVersion 讓呼叫端知道這次結果是否已反映在可見介面。

反過來,沒有參與這三項工作的欄位,就不應該因為「反正已經查到了」一起塞進 result。

Result 正確,Agent 最後還是可能答錯

做到這裡,很容易看到 unit test 通過,就宣布「Agent 已經會回答」。中間其實還隔著一層。

一次 Inspector 紀錄要拆成兩段:

Tool result 是否符合契約
→ AI result 是否忠實使用這些欄位

假設 Tool 明明回了 venueremainingCapacity,最後回答卻漏掉名額,問題在 grounding 或
回答整理;如果 Tool result 根本沒有 venue,就不能怪模型沒報地點,更不能期待它自行補值。

昨天的 SEL-02 trace 正好能重播這項核對。Agent 最後回答中的活動名稱、日期、場地與剩餘
8 名,都能逐項回到 Tool result,沒有靠模型常識補資料。

但今天沒有把那份舊 trace 改寫成新的 invocation。Payload shape 與 direct tests 是 E1/E2
契約證據;Inspector trace 才能說明真實 Agent 如何使用 result。兩者可以一起判讀,不能混成
同一種證據。

uiUpdated: true 不是一張萬能證書

get_event_details 成功後,實作會先呼叫 show(event) 更新可見內容,再回傳
uiUpdated: true 與新的 stateVersion。Direct test 也會檢查 show 是否收到同一份活動。

不過,這個欄位仍只是 result 的狀態回報。DOM 是否真的顯示正確、鍵盤與螢幕閱讀器能否使用,
仍要交給 browser test 或實際畫面驗收。把 true 寫進 JSON,不會讓瀏覽器因為感動而自動
更新。

私人輸入與內部錯誤不進公開 result

正式 payload 不包含:

  • session cookie、CSRF token 與 user ID;
  • Email 等私人輸入;
  • stack trace、SQL 與內部錯誤物件;
  • 整頁 HTML 或資料庫 entity;
  • 與目前任務無關的內部旗標。

欄位應該從使用者問題與下一步反推,而不是拿後端物件當菜單整份照抄。活動公開文案若會進入
模型,也仍要當成不受信任內容,不能因為它來自自己的網站就直接升格成系統指令。

今天把成功 result 收到一個能回答、能接續,也能回頭核對的範圍。明天換失敗 result 上場:
輸入錯誤、查無資料與服務暫時中斷若全部只回一句「發生錯誤」,Agent 根本不知道該修正、
停止,還是稍後重試。到時我會故意把活動 API 弄壞一次,看契約能不能把它安全帶回來。


上一篇
Day 16|Agent 怎麼知道「我現在看的活動」是哪一場?
下一篇
Day 18|活動服務暫時失敗時,Agent 應該重試還是停下來?
系列文
網站終於會說話:30 天實作並驗證 Agent-ready 的 WebMCP 活動網站23
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言