Pinterest A/B 測試平臺構(gòu)建的解決方案
A/B測試、灰度發(fā)布是精益產(chǎn)品增長最常見的實踐,除了掌握方法,一個高效的工具也是開展實驗的基礎(chǔ),譯文即為Pinterest A/B測試平臺搭建的整體概述,讓你對這樣一個平臺的構(gòu)建會有大體的認(rèn)識。如果你是非技術(shù)人員也可移至文末,看滴滴出行在數(shù)據(jù)驅(qū)動平臺搭建以及A/B測試、灰度發(fā)布方面的真實案例。
以下為譯文,有編輯:
作為一個數(shù)據(jù)驅(qū)動的公司,我們總是會基于實驗去指導(dǎo)產(chǎn)品設(shè)計和功能開發(fā),在過去一段時間,我們跑了大概有1000個實驗,并且每天都在增加,不斷增長的實驗量以及產(chǎn)生的海量數(shù)據(jù),驅(qū)使我們需要有一個穩(wěn)定的、精準(zhǔn)的、簡單易用的平臺來支撐增長團隊的使用需求,為了排除實驗過程中的一些共性問題,我們開發(fā)了一個操作更加輕量、支持跨平臺協(xié)同以及一些精簡的API接口來滿足A/B測試過程中可能要面對的復(fù)雜問題。
在搭建這樣一個平臺的時候我們優(yōu)先考慮了以下需求:
- 配置實時:我快速響應(yīng)實驗需求,能夠隨時關(guān)閉或啟動實驗,而不需要在代碼層面做更改,特別是需要修復(fù)網(wǎng)站的事件
- 操作輕量:實驗設(shè)置要像啟用一個功能那樣簡單,當(dāng)然,也要能規(guī)避一些預(yù)先能想到的錯誤操作
- 學(xué)習(xí)成本低:使用者不需要因為平臺的不同而學(xué)習(xí)新的實驗方法論
- 易于分析:為了能夠更好的輔助決策,我們構(gòu)建了一個新的并且易用的分析看板
- 擴展性強:我們需要這樣一套系統(tǒng)能支持線上和線下實驗數(shù)據(jù)的處理
一、流程優(yōu)化
Pinterest的實驗都遵循一套通用的方法論:
- 提出假設(shè)。并且針對假設(shè)提出一些驗證的猜想;
- 篩選實驗用戶群。創(chuàng)建用戶組、禁用組、通過過濾器修改組;
- 分發(fā)變量給實驗用戶,并記錄實驗結(jié)果。
在我們以前的框架下,這些變量的配置都是通過修改代碼的方式,然而,我們希望把這些變量的控制能夠在前端界面組織起來,在可配置的框架下,獨立于代碼做些變量控制。
實驗過程中有些共性的問題,比如語法錯誤、不均勻的用戶分組、組用戶重疊或者實驗流程不規(guī)范,我們也主動地在輸入框預(yù)設(shè)了一些查詢字段,盡可能的減少了手動輸入造成的錯誤,如圖2,跑一個實驗通常就是幾個點擊這樣簡單。
為了讓任何人能夠?qū)崟r地、便捷地進(jìn)行實驗配置,我們在內(nèi)部的系統(tǒng)中以串行隊列的方式存儲了所有的實驗設(shè)置,并且在幾秒內(nèi)同步至我們每個實驗系統(tǒng)的主機上,一個典型的配置文件有如下幾個內(nèi)容:
{“holiday_special”:{“group_ranges”: {
“enabled”: {“percent”:?5.0,?“ranges”: [0,?49]},
“hold_out”: {“percent”:?5.0,?“ranges”: [50,?99]}
},
“key”:?“holiday_special”,
“global filter”: user_country(‘US’),
“overwrite_filter”: {“enabled”: is_employee()},
“unauth_exp”:?0,
“version”:?1
}
}
配置和代碼分離最大的好處是提升了我們的實驗效率,這意味著變量的控制效率高了,比如實驗組需要增加流量不需要在代碼層面做調(diào)整,極大的釋放了實驗的部署時間,加快了迭代速度特別是原先有緊急需求的時候。
二、質(zhì)量保證
1、代碼監(jiān)測
實驗很簡單但能影響數(shù)以百萬計的用戶,所以對實驗工具的操作和結(jié)果的準(zhǔn)確性都提出了很高的要求。執(zhí)行實驗的系統(tǒng)還內(nèi)置了一個review工具,他會為每個實驗加載一段review的代碼。如圖3顯示的就是一個掛起的更改,這個時候可以修改組范圍和篩選條件。
2、人工監(jiān)測
對于很多實驗,我們有一個由平臺開發(fā)人員、使用者、數(shù)據(jù)科學(xué)家組成的小助手(helper)團隊,幾乎每一次變動都會要求一個helper去嚴(yán)格的檢查方案設(shè)計、實驗假設(shè)、關(guān)鍵結(jié)果、觸發(fā)邏輯、篩選設(shè)置、組驗證以及相關(guān)文檔。這樣的過程強加在平臺上就使得每一次變動都必須有一個小助手輔助(監(jiān)督)。當(dāng)然了,我們也有常規(guī)的helper培訓(xùn)計劃以確保每個團隊至少有一個人可以做監(jiān)督人。一個實驗通常會關(guān)聯(lián)到代碼的改變,把對照組和實驗組的信息嵌入到?jīng)Q策邏輯中,我們會要求實驗操作人員通過Pull Request按鈕增加一個Pull Request鏈接。
使用者可以在前端直接復(fù)制一個之前的實驗(如圖1),然后粘貼到如圖5的測試區(qū)域內(nèi),在這個區(qū)域內(nèi)的改動不會影響正式環(huán)境下的實驗,并且那個執(zhí)行復(fù)制操作的用戶才能夠訪問
三、API接口支持
API接口用來支撐前端發(fā)送來的一些實驗配置請求,以下提供了兩個關(guān)鍵的方法:
def get_group(self, experiment_name)def activate_experiment(self, experiment_name)
特別說明一下,get_group方法將會返回被調(diào)用者定向了的組名,進(jìn)一步來說,其實是基于實驗信息計算了這個群組的哈希值(hash value),這個方法不會形成任何副面影響,另一方面,調(diào)用activate_experiment 給系統(tǒng)發(fā)送一條日志消息輔助了分析結(jié)果的產(chǎn)出,這兩個方法基本覆蓋了大部分的使用場景,并且被經(jīng)常應(yīng)用在以下環(huán)境下:
# Get the experiment group given experiment name and gatekeeper object, without actually triggering the experiment.group = gk.get_group(“example_experiment_name”)
# Activate/trigger experiment. It will return experiment group if any.
group = gk.activate_experiment(“example_experiment_name”)
# Application code showing treatment based on group.
if group in [‘enabled’, ’employees’]:
# behavior for enabled group
pass
else:
# behavior for control group
pass
上述代碼所示中的gatekeeper object是用戶/會話/元數(shù)據(jù)信息封裝的,除了python庫,我們有一個單獨的JVM(Scala and Java)庫來面向JS和移動端(Android和iOS)做支持 。
實驗平臺從邏輯上可以劃分成三部分:配置平臺、一組API接口和分析模塊兒。
數(shù)據(jù)流向說明:
- 配置平臺將用戶在前端界面上的操作保留在實驗數(shù)據(jù)庫,這些信息將會定期通過串行的方式并且顆粒度足夠細(xì)的上傳到每一個服務(wù)器;
- 實驗分析人員通過前端界面和調(diào)用API的方式去配置實驗邏輯,比如實驗類型設(shè)定、組篩選等;
- 實驗產(chǎn)生的各種日志通過我們內(nèi)部的Singer service上傳至Kafka,分析模塊兒將通過用戶定義的數(shù)據(jù)指標(biāo)生成實驗結(jié)果并且把他們同步到看板 。
原文作者:Shuo Xiang
原文地址:https://engineering.pinterest.com/blog/building-pinterest’s-ab-testing-platform
譯者:GrowthHub(微信公眾號:growthhub)
本文由 @GrowthHub 翻譯發(fā)布于人人都是產(chǎn)品經(jīng)理。未經(jīng)許可,禁止轉(zhuǎn)載。
- 目前還沒評論,等你發(fā)揮!