跳至主要內容

指南

線上實驗(A/B 測試)

你的離線比較說新版本更好。正式環境中的 A/B 測試向真實使用者提出同一個問題。你自己的路由器把單位(使用者或工作階段)隨機分到兩個組;oloproof experiment 讀取它的日誌,並用與其他所有規則相同的四種狀態作答。此方法已在聲明的條件下通過獨立稽核的准入:observed_until 是你對結果日誌擷取時刻的陳述,單位是獨立隨機分配的,任何單位的結果都不取決於另一單位所在的組,分配比例變動期間結果沒有漂移,且每次查看都讀取完整日誌。超出這些條件,答案不受保證。

日誌與宣告

兩個檔案,CSV 或 JSONL:一個分派日誌,每個單位一列(你宣告的單位欄位,以及 arm);一個結果日誌,包含單位及其 value。

experiment:
  name: checkout-v2
  unit: user
  allocation: {control: 0.5, treatment: 0.5}
  control: control
  treatment: treatment
  assignments: logs/assignments.csv
  outcomes: logs/outcomes.csv
  kind: rate
  rules:
    - {id: lift, kind: superiority}
    - {id: no-harm, kind: non_inferiority, margin: 0.01}
oloproof experiment experiment.yaml --policy release.yaml --json

kind: mean 接受一個宣告的 range: [low, high];direction: max 把較低視為較好。沒有結果列的已分派單位視為缺失,並在每一側以其最差值界定,除非 missing_outcome: zero 宣告沒有列即為零。為每個單位都記錄一列,包括零:只包含已轉換者的轉換日誌會把其他每個單位讀作缺失,答案將停留在 INSUFFICIENT_EVIDENCE。補零假設每個計入單位的結果窗口都已關閉;一小時前才分派的單位還沒有轉換,把它算作零會偏向轉換較快的那一組。宣告 outcome_window_hours、as_of 與 observed_until(擷取結果日誌的時間),並在分派日誌中加入 assigned_at 欄,則只計入窗口在 as_of 之前關閉的單位;缺少它們時,無論哪種監測方式,missing_outcome: zero 都會被拒絕。每個時間都要帶時區偏移或 Z 書寫(2026-10-11T00:00:00Z);兩者都沒有的時間會被拒絕。as_of 不得晚於 observed_until,兩者都不得在未來:擷取之後的結果不在日誌中。窗口決定問題:48 小時的窗口回答「48 小時內是否轉換」,因此它必須涵蓋你所指結果的延遲。單位 ID 在去除空白後按文字比較,42.0 讀作 42。結束代碼取最差規則的代碼:0 PASS,1 FAIL,3 INSUFFICIENT_EVIDENCE,4 MANUAL_REVIEW。

它先檢查什麼

  • 樣本比例。 各組的單位數與宣告的分配進行檢定(兩組用精確二項檢定,更多組用卡方,門檻 0.001)。不相符會讓每條規則變為 MANUAL_REVIEW:分流出錯代表各組不再可比,而更多同類資料也修復不了。在讀任何差值之前先找出原因(遺失使用者的重新導向、只作用於一個組的機器人過濾)。
  • 一個單位出現在兩個組。 分派發生了洩漏;每條規則讀作 MANUAL_REVIEW。
  • 一個單位有多筆結果列。 拒絕,因為同一使用者的事件並不獨立。宣告 aggregate: unit_mean,讓每個單位自己的平均值作為它的結果:此時答案關於平均使用者,而非平均事件。
  • 空組。 在有結果之前為 INSUFFICIENT_EVIDENCE。
  • 在 missing_outcome: zero 下,不對應任何已分派單位的結果列。 零依賴於連接,因此連接出錯會把真實單位讀作零;在 ID 一致之前,每條規則都為 MANUAL_REVIEW。在預設下,它們會被計數並排除在外。

它如何判定

每個組的平均值獲得 Oloproof 對單次執行已在使用的區間(比率用精確 Clopper-Pearson,其他情況用基於下注的有界平均),各占一半的誤差預算,差值由兩者相反的端點界定。它在任何樣本數下都成立,比教科書上的常態區間更寬。優效性規則在整個區間高於零時通過;不劣性規則在其下端不低於負的界限時通過。

monitoring: anytime 對兩個組都使用下注區間,無論你查看多頻繁、何時停止都成立。前提是每次查看都傳入截至那一刻的完整日誌:讀過之後,絕不要依時段刪除或篩選列。預設的 fixed 在你規劃的樣本數處讀取一次。

多個處理組

宣告 treatments: [b, c] 來取代 treatment:,並為每條規則指定它所比較的處理組(treatment: b)。m 個組中每個組的區間取 1 - alpha/m,因此由聯集界,每個處理組減去對照組同時被涵蓋:每個處理組一條規則,各一項主張,整個族一起成立。每個區間都比兩組時更寬,因為每個組都要為其他組付出代價。有多個處理組時,報告在通過每條點名它們的規則的處理組中點名最佳者,並說明它是否與其他每個通過的處理組分開:每個差值由同一組同時區間界定,不含零。並列者保持宣告的順序,從不分開。樣本比例檢查已經讀取每個組。聯合保證涵蓋的是一個實驗檔案中的各組:把處理組拆分到多個檔案就放棄了它。

比率指標

點擊率是點擊數除以工作階段數,而一個有很多工作階段的使用者並不是很多個獨立使用者。在每個單位一列上宣告該比率,並給出每個單位的值都落在其中的範圍:

  ratio: {numerator: clicks, denominator: sessions, numerator_range: [0, 50], denominator_range: [1, 50]}
  aggregate: unit_sum   # only if a unit has several rows: they are added

估計目標是每個組的平均分子除以其平均分母。兩個平均值都由已認可的區間界定,各占其應得的誤差預算份額,比率則透過對它們的端點相除得到,因此在任何樣本數下都成立,不依賴常態近似。區間觸及零的分母不給出區間。超出其範圍的值是一個點名該單位的設定錯誤,絕不截斷。Delta 方法的區間通常更窄,顯示在旁邊,從不判定。

測試之前的共變量

一個與測試前量測之物(上個月的支出、上週的工作階段)相關的結果,在去掉它之後波動更小。提供每個單位在測試前的值,以及一個在讀取本測試結果之前就已固定的係數:

  covariate: {values: logs/pre_period.csv, range: [0, 500], theta_from: logs/history.csv}

判定的結果是 Y - theta (X - c)。theta 要麼是宣告的(theta:,可選 center:,預設為範圍的中點),要麼在測試之前某個時段的歷史檔案上擬合(covariate 與 outcome 欄),絕不在本測試自己的結果上擬合。由於 X 是在分派之前量測的,並且哪些單位有 X 也是在分派之前就確定的,調整後的差值有相同的估計目標。檔案中沒有值的單位不做調整。一個有效的調整仍可能比不調整更寬,因為調整後結果的範圍更寬,所以報告同時顯示兩個區間並說明哪個更窄;它不宣稱任何節省。

新奇與干擾,只做顯示

novelty: {exposure_column: exposed_at, time_column: at, days: 7} 從分派日誌讀取每個單位的首次曝光,從每筆結果列讀取其時間,並顯示曝光後前 days 天與之後的差值。一個已判定的早期差值,配上一個未判定或相反的後期差值,會被標為「可能是新奇效應」。這種拆分從不判定規則:在某個時段沒有列的單位被排除在該時段之外,而不是以最壞情況界定。它每列取一個結果,不接受比率或共變量。

cluster_column: team 統計持有多個組單位的團隊,並詢問一個單位的結果是否可能依賴另一個單位所在的組。如果可能,請按團隊隨機化,並把它宣告為單位。

多個處理組、比率和共變量已於 2026 年 11 月 3 日經獨立稽核及其確認認可,條件與兩組相同。

離線與線上

指定離線比較及其指標(offline_comparison: <id>,offline_metric: pass_rate),答案會回報兩個已判定的方向是否一致。這只做回報,從不判定任何事:不一致是去檢查測試集的理由,而不是對發布的裁決。

陷阱

  • 中途偷看。 每天讀取固定期限的測試並在好日子停下,會放大虛假的勝利。請規劃樣本數,或宣告 monitoring: anytime。
  • 新奇與學習。 使用者會對任何新東西做出反應,然後趨於平穩。第一週的提升可能消退;執行夠長的時間以涵蓋你的使用者週期,並宣告 novelty: 以查看拆分。
  • 干擾。 區間假設一個單位的結果不依賴另一個單位所在的組。共享庫存、交易市集、社交功能或被一個組預熱的快取都會打破這一點;此時請按更大的單位(一個地區、一個團隊)隨機化,並宣告 cluster_column: 以查看各叢集混合的程度。
  • 分流變化下的漂移。 區間假設分配在測試期間保持不變,或在分配變化時結果沒有漂移。從 10% 逐步提高到 50%,或在一個工作日與一個週末先 90/10 後 10/90,會讓每組對各時段的加權不同,並把時間效應混入差值;樣本比例檢查讀取的是彙總計數,看不到這一點。請保持分流固定,或只根據逐步提高之後的時段做決定。
  • 更換單位。 用同一單位隨機化與分析。隨機化使用者卻把工作階段當作獨立計數,會錯誤地收窄區間。

這無法告訴你的

  • 結果是否適用於測試時間窗、地區或流量之外的使用者。
  • 關於測試前未宣告的指標的任何事;事後選擇的指標只是描述。
  • 你的路由器是否真的做了隨機化:樣本比例檢查能發現大的故障,發現不了細微的。
  • 未通過的處理組中哪個最好:只有通過的處理組才排名。分層分配和輪換(switchback)設計尚未建置。