上一篇最後留下了一個問題。
我們已經知道使用者真正想完成的 Job 是:
當我考慮購買一項商品時,我想要知道真實買家的想法,以便判斷這項商品是否真的符合我的需求。
但如果現在回到程式碼,還是會卡住。
因為「判斷商品是否符合需求」並不是一個可以直接觀察的事件。
程式看得到的是:使用者打開商品頁、閱讀評論、加入購物車、離開頁面、完成購買。至於他腦中是不是已經得到足夠資訊,程式本身不知道。
所以真正的問題是:
我們要怎麼把抽象的使用者成功,轉成可以觀察的東西?
這裡可以利用 Google 提出的 Goals-Signals-Metrics(GSM)。
看起來只是三層,但真正容易出錯的地方,通常就在中間兩層。
回到聊天室的例子,我們的 Goal 已經很清楚:使用者能夠判斷商品是否適合自己。
那這個 Goal 成功時,可能出現什麼 Signal?
第一種可能是,使用者做出購買決策。
如果他最後買了,至少代表某種程度上已經完成判斷。但「沒有買」就很模糊:可能是判斷後決定不買,也可能只是因為資訊還是不夠,所以先離開。
第二種可能是,他調整候選商品。例如把某個商品加入購物車、移除其他候選,或停止繼續搜尋。
這比單純看聊天室使用量更接近原本的 Goal,但仍然可能因為價格、庫存或其他理由發生。
第三種可能是,直接問使用者:
目前的資訊是否已經足夠讓你做出購買判斷?
這個 Signal 很接近真正想知道的事情,但收集成本更高,也不可能每一次使用都問。
所以 Signal 並不是「找一個最接近的 Event 名稱」。
它比較像是在問:
如果 Goal 成功了,我有什麼理由相信它真的發生?
一個好的 Signal 通常同時希望有兩個特性。
第一,它要夠敏銳。Goal 發生時,這個 Signal 應該有高機率跟著出現。
第二,它要夠具體。Signal 出現時,不應該經常只是因為和 Goal 無關的其他原因。
這和工程上判斷監控訊號其實有點像。如果 Alert 永遠不響,就抓不到問題;如果任何小波動都響,又只會得到一堆 Noise。
產品 Signal 也一樣。
send_message 很容易收集,但對「完成購買判斷」既不夠敏銳,也不夠具體。直接問使用者是否已經取得足夠資訊,則更接近 Goal,只是成本高很多。
所以很多時候不會只靠一個 Signal,而是用幾個不同角度一起理解。
找到 Signal 後,還不能直接開始畫圖。
例如我們說「使用者做出購買決策」是一個 Signal,接下來還要回答:
怎樣才算做出決策?
如果只是看 purchase_completed 的總數,流量變多時數字自然也會增加。
我們可能需要定義成:
看過商品頁的使用者中
24 小時內完成購買的比例
這裡已經多了幾個重要決定:
這些才構成真正可以持續比較的 Metric。
同一個 Signal 也可能有不同的 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 很少有唯一正解。比較重要的是知道自己犧牲了什麼,以及這個數字可以支持多強的結論。
到這裡,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 秒留下回饋,我會用這些意見來調整後續文章:分享你的意見
