iT邦幫忙

2026 iThome 鐵人賽

DAY 6
0

上一篇最後留下了一個問題。

我們已經知道使用者真正想完成的 Job 是:

當我考慮購買一項商品時,我想要知道真實買家的想法,以便判斷這項商品是否真的符合我的需求。

但如果現在回到程式碼,還是會卡住。

因為「判斷商品是否符合需求」並不是一個可以直接觀察的事件。

程式看得到的是:使用者打開商品頁、閱讀評論、加入購物車、離開頁面、完成購買。至於他腦中是不是已經得到足夠資訊,程式本身不知道。

所以真正的問題是:

我們要怎麼把抽象的使用者成功,轉成可以觀察的東西?

這裡可以利用 Google 提出的 Goals-Signals-Metrics(GSM)

  • Goal:希望使用者得到什麼成果?
  • Signal:如果這個成果真的發生,外部應該出現什麼跡象?
  • Metric:怎麼把這個 Signal 定義成可以穩定計算的數字?

看起來只是三層,但真正容易出錯的地方,通常就在中間兩層。

Signal 不是 Event

回到聊天室的例子,我們的 Goal 已經很清楚:使用者能夠判斷商品是否適合自己。

那這個 Goal 成功時,可能出現什麼 Signal?

第一種可能是,使用者做出購買決策。

如果他最後買了,至少代表某種程度上已經完成判斷。但「沒有買」就很模糊:可能是判斷後決定不買,也可能只是因為資訊還是不夠,所以先離開。

第二種可能是,他調整候選商品。例如把某個商品加入購物車、移除其他候選,或停止繼續搜尋。

這比單純看聊天室使用量更接近原本的 Goal,但仍然可能因為價格、庫存或其他理由發生。

第三種可能是,直接問使用者:

目前的資訊是否已經足夠讓你做出購買判斷?

這個 Signal 很接近真正想知道的事情,但收集成本更高,也不可能每一次使用都問。

所以 Signal 並不是「找一個最接近的 Event 名稱」。

它比較像是在問:

如果 Goal 成功了,我有什麼理由相信它真的發生?

一個好的 Signal 通常同時希望有兩個特性。

第一,它要夠敏銳。Goal 發生時,這個 Signal 應該有高機率跟著出現。

第二,它要夠具體。Signal 出現時,不應該經常只是因為和 Goal 無關的其他原因。

這和工程上判斷監控訊號其實有點像。如果 Alert 永遠不響,就抓不到問題;如果任何小波動都響,又只會得到一堆 Noise。

產品 Signal 也一樣。

send_message 很容易收集,但對「完成購買判斷」既不夠敏銳,也不夠具體。直接問使用者是否已經取得足夠資訊,則更接近 Goal,只是成本高很多。

所以很多時候不會只靠一個 Signal,而是用幾個不同角度一起理解。

Metric 是把 Signal 寫成可重複計算的定義

找到 Signal 後,還不能直接開始畫圖。

例如我們說「使用者做出購買決策」是一個 Signal,接下來還要回答:

怎樣才算做出決策?

如果只是看 purchase_completed 的總數,流量變多時數字自然也會增加。

我們可能需要定義成:

看過商品頁的使用者中
24 小時內完成購買的比例

這裡已經多了幾個重要決定:

  • 分母是誰?
  • 觀察時間多久?
  • 同一個人多次購買怎麼算?
  • 哪些情況要排除?

這些才構成真正可以持續比較的 Metric。

同一個 Signal 也可能有不同的 Metric。

例如「取得足夠資訊」可以量:

回答「已經有足夠資訊」的比例

也可以量:

從第一次查看商品
到完成購買判斷所花的時間

前者比較直接,後者則可能更適合觀察產品是不是讓判斷過程變快。

怎樣判斷一個 Metric 選得好不好?

Metric 最麻煩的地方,是它永遠只是 Goal 的一個代理。

我們真正想改善的是使用者成功,不是讓某個數字看起來漂亮。

所以選 Metric 時,我覺得可以用幾個問題反過來檢查。

第一:

如果這個 Metric 變好,但使用者其實沒有更成功,我們還會覺得產品變好了嗎?

如果答案是否定的,這個 Metric 可能離 Goal 太遠。

例如把 chat_opened 當成功,只要把聊天室自動展開,數字就能大幅提升,但顯然沒有證明任何事情。

第二:

如果 Goal 真的改善,這個 Metric 有沒有機會在合理時間內反映出來?

太靠近表面的 Event 很容易變,但可能沒意義;太靠近長期 Outcome,又可能要等幾個月,而且期間受到很多其他因素影響。

例如 30_day_repeat_purchase 也許和產品價值很接近,但如果這次只是調整商品資訊,拿它當唯一 Metric 就會很難判斷。

第三:

這個數字變化時,有沒有可能只是流量、分母或使用者組成變了?

這也是為什麼 Rate 往往比 Count 更適合比較。

假設退款筆數從 1,000 變 1,500,不一定表示產品變差;如果同期訂單量翻倍,退款率反而可能下降。

有些情況甚至 Rate 還不夠。例如高單價商品和低單價商品的退款成本差很多,就可能要看 refund_cost / order 或其他更符合實際影響的定義。

最後還有一個很現實的問題:

這個 Metric 收不收得到?多久能知道?

直接詢問使用者通常比較接近真正的 Goal,但回覆率可能很低;使用行為比較容易收集,但往往只是 Proxy。

所以 Metric 很少有唯一正解。比較重要的是知道自己犧牲了什麼,以及這個數字可以支持多強的結論。

從 Metric 回到 Event

到這裡,Event Tracking 才真正有了方向。

假設我們最後決定觀察:

商品頁使用者中
24 小時內完成購買的比例

那至少需要可靠地知道:

view_product
purchase_completed

如果還想理解候選清單的變化,也可能需要:

posthog.capture('update_cart', {
    action: 'add_item',
    item_id
})

這和一開始直接對著 UI 找「哪裡可以埋 Event」的方向剛好相反。

我們是先從使用者想完成的 Goal 出發,找到能代表它的 Signal,再把 Signal 定義成 Metric,最後才知道程式碼裡需要留下哪些資料。

Goal
↓
Signal
↓
Metric
↓
Event / Property

這不代表每個功能都要正式寫一份 GSM 文件。

但當你開始不知道該追蹤什麼,或 Dashboard 已經塞滿一堆 Event 卻還是不知道使用者有沒有成功時,往回走這幾步通常很有用。

下一篇就從最後這一層繼續,看看實際做 Event Tracking 時,Event 和 Property 要怎麼設計,才不會很快又變成另一堆難以使用的資料。

參考資料


如果你願意花 30 秒留下回饋,我會用這些意見來調整後續文章:分享你的意見


上一篇
Day 5|讓使用者成功(上):JTBD / Job Story
下一篇
Day 7|把 Signal 寫進程式:Event Tracking
系列文
成為產品型工程師吧!從培養產品思維到 PostHog 數據實戰20
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言