<-- mermaid -->

NewsPicksとABテスト基盤

はじめに

こんにちは!NewsPicks Business Growth のアダチ(@dikxs118)です。
NewsPicks Advent Calendar 2022 の最終日を担当させていただきます!
qiita.com

Business Growth ではLTVの最大化を目的として、様々な取り組みを行なっています。
その一つにABテストがあり、その実現方法として基本的には下記の二つを状況によって使い分けています。

  • 外部サービスである Braze
  • NewsPicksで独自に実装したABテスト基盤

本日は NewsPicksで独自に実装した ABテスト基盤について話していきたいと思います!

ABテストの流れ

ABテスト基盤の話に入る前に、ABテストの一連の流れをイメージしておきます。
大まかな流れは下記の通りです。

  1. ユーザーのログを送信する
    ユーザーの行動に沿ったログを仕込み、nginxに送信します
    バッチ処理により、nginxのaccessログをAmazon Redshiftに連携することで分析できるようにします

  2. ABテストの実装、ABテスト基盤の入稿
    ABテスト基盤に基づいて、データの入稿、必要に応じて実装を行います

  3. ログの収集
    定期的にAmazon Redshifitを確認して、ABテストの結果が効果的になるまでログを収集します

  4. 分析
    分析しやすい単位にテーブルを分割し、SQLにて分析を行います
    よく使うクエリは、リポジトリで管理、デプロイすることでクエリの保守性を上げています

これから話すは主に「2 .」にあたる部分ですね。

ABテスト基盤の仕組み

それでは、ABテスト基盤の仕組みを解説します!

まずはシーケンス図を見ていきます。基本的な流れは図の通りです。

シーケンス図

ユーザーがABテスト対象画面にアクセスすると、AllocationServiceにてABテストの各パターンを払い出します。
実際の払い出しロジックは UUIDUserIdで別のものを使っており、ABテストの特性によりどちらを選択するのかをDBで定義しています。 払い出しロジックについては、ここでは複雑になるので割愛します。

次にABテスト設定に必要なテーブルの主要なカラムを見ていきます。

設定カラム 内容
category ABテストごとに一意になる文字列、対応する実装をアプリケーションで実装する必要あり
start ABテスト開始日時
end ABテスト終了日時
allocate_type ユーザーグループの割り振り方
min_user_id テスト適用になる最小のuserId(NULLの場合は制限しない)
max_user_id テスト適用になる最大のuserId(NULLの場合は制限しない)
target_os テストの適用になるOS(IOS/ANDROID/ANY)
min_app_version テストの適用になる最小のアプリバージョン(NULLの場合は制限しない)
max_app_version テストの適用になる最大のアプリバージョン(NULLの場合は制限しない)
details テスト設定。必要なパターンを パイプ文字列で区切る

ABテストを新規のユーザーにあてるのか、既存のユーザーにあてるのか、
どのアプリバージョン、どのOSにあてるのかなどを詳細に設定することができます。

allocate_type について捕捉すると、 ABテストのユーザーグループの割り振り方は主に RANDOMID_DIVIDEDがあります。

ぞれぞれの使い分けは以下の通りです。

  • RAMDOM
    • 如何なる状態においても対象パターンをランダムに振り分ける
  • ID_DIVIDED
    • 画面間にて整合性が必要となる場合にその整合性を保証した状態で振り分ける(ex. ある画面でAパターンのユーザーは次の画面でBパターンを表示するなど)

この通りDBを設定することで、各カテゴリ毎に対象となるABパターンを対象となるユーザーにサーバーが計算し返してくれます。

様々なユースケースに対応する

さて、ここまでがベースとなるABテスト基盤ですが、その使用頻度が高まるにつれて様々な新しいユースケースが求められるようになってきました。 具体的には下記のようなものです。

  • 法人ユーザーに対してはABテストを行いたくない
  • 法人ユーザー以外でも特定のユーザーはABテストを行いたくない
  • 特定のユーザーに、特定のABテストの結果を返すように制御したい

ABテスト基盤は、日々ユースケースに合わせて刷新を行っていますが、
上記を受けてABテスト基盤の大幅なアップデートを行いました。

ドメインモデル図&ER図

特定のパターンを与えたい制御ユーザーを ControllerUser、特定のユーザー群をABテストから除外できるよう、ExcludedUserGroup,ExcludeUserとして定義しました。
法人ユーザーをABテストの対象にするかどうかはフラグで管理することで最小に工数でユースケースの実現を行いました。

何度も手の入るところなので、併せてテストの拡充、再モデリング、集約の切り出しなどを行ったことで保守性を上げることを意識できたのは良かったなと思っています。

管理画面のローコード化

ここまでが、ABテスト基盤の話ですが実際にそれぞれのデータをどのように入稿するのかについても、最後に触れておきます。
これまでのNewsPicksではABテスト基盤においては、直接DBのレコードを追加、修正することでそれぞれのデータを入稿していました。
それによって、ドメインの整合性を簡単に壊すことができ、DBをいじった直後からエラーが止まらない、時限でエラーが発生した、などの事故がよく起こっていました。

ABテスト実施者はどのようなドメインルールがあるのか完全に理解しているわけではないので、DBに誤った値を入れてしまうというのは容易に想像できることでした。

そこでAPIを通した更新しか認めないようにすることで、常に正しいドメイン、DBの状態を担保できるようにルールを敷きました。

ただ問題となるのはそのAPIをどう管理するのかです。

NewsPicks では独自の管理画面を持っていますが、その開発、保守コストが近年問題視されていました。
そこで管理画面をローコード化しようと、 BaseMachinaというSaaSを採用することにしました。

これはABテスト基盤に限った話ではなく、管理画面を作成、保守するのって正直辛いですよね。 最近では、管理画面のローコード化を行ってから、このコストが格段に減り非常に快適な管理画面ライフを送っています。

おわりに

ざっくりとですが、NewsPicksのABテスト基盤について解説させていただきました!
NewsPicksでは、既に300を超えるABテストがこの基盤を通して行われていて、常に数十のABテストが走っている状態です。

ABテストをすることで見えること、見えないこととありますが、様々なユースケースに沿ったABテストの実現を支えることで、 少しでもLTV向上に貢献に出来れば良いなと思っています。

それでは!!

Page top