"体系的" に開発サイクルを回して "効果的" に学びを得るには

会員事業部エンジニアの新井( @SpicyCoffee66 )です。 Splatoon2 で各ルール S+1 以上になるため日々奮闘中のところに MHW が発売されました。 加えて最近ぷよぷよを始めたので、どう考えてもいろいろ計算が合わなくなってきました。

本日おこなわれた Cookpad TechConf 2018 では「クックパッドの "体系的" サービス開発」と題し、社内でどのような点に気をつけて開発サイクルが回されているかをお話しさせていただきました。 動画・発表資料は後日アップロードされる予定ですので、よろしければ合わせてご覧ください。 今回は、TechConf 2018 での発表内容から、BML ループの運用について、多少の補足や要約を交えながら書きたいと思います。

サービス開発は難しい

まず前提として、サービス開発は難しいです。 その難しさの大部分は、以下の2つの要因からきています。

  • 到達するべきサービスのゴールが明確でない
  • サービスの今いる地点が明確でない

到達するべきサービスのゴールが明確でない

サービス開発においては、ユーザーさんの持つ欲求や、抱えている課題を解決することがゴールとなります。 しかし、この欲求や課題は、ユーザーさん本人を含めて、誰にもわからないことがほとんどです。 また、仮に一度この欲求を捉えたとしても、その後時間とともに変化してしまうことが一般的です。

私たちが何もしなくても、ユーザーさんの使うデバイスはガラケーからスマートフォン、タブレットへと移り変わっていくでしょうし、 個々人のライフステージに関しても、独身だったユーザーさんが結婚し、子どもを持つようになるなど、多くの変化が起こり得ます。 このような状況のもとでは、ユーザーさんが抱えている欲求も、常に変化し続けると考えるほうが理にかなっています。

サービスの今いる地点が明確でない

得てしてサービス開発者は、自分のサービスを正しく理解できていないことがほとんどです。 サービスの価値はこうだ!コアとなる機能はこれだ!と信じていても、 実際にユーザーさんに使ってもらっているところを見てみると、想像と全く違う使われ方をしていた、なんてことは日常茶飯事でしょう。

学びのサイクル

前述したような状況の中でサービス開発に取り組むためには、自分たちの仮説をユーザーさんにぶつけ、その結果からフィードバックを得ることで新たな仮説を立てるという作業を繰り返す必要があります。 そうるすことで、目指すべきゴールや、サービスの今いる地点を確認しながら前に進んでいくわけです。 この「自分たちの仮説をユーザーさんにぶつけ、その結果からフィードバックを得ることで新たな仮説を立てる」という行為を、開発サイクルや学びのサイクルと呼んでいます。

BML ループ

学びのサイクルを実現するフレームワークに、BML ループと呼ばれるものがあります。 これは、リーン・スタートアップの中で提唱されているフレームワークで、以下の 3 フェーズから成ります。

  1. 仮説からプロダクトを作成する Build
  2. プロダクトをリリースしユーザーの利用状況を計測する Measure
  3. 得られたデータから知見を抽出し、新たな仮説を構築する Learn

f:id:spicycoffee:20180210144116p:plain

これらのフェーズの頭文字を取って BML ループと呼ばれているわけです。 このループを数多く回しながら、その都度学びを得ていくのがサービス開発では重要になってきます。

よくある失敗とその対策

しかしながら、サービス開発ではサイクルを回しながら学びを得るのが重要であるということがわかったところで、実際に BML ループを回そうとすると大抵の場合どこかのフェーズで失敗します。 具体的には、各フェーズで

  • Build
    • プロダクトが不必要に大きくなって実装に時間がかかる
    • 検証したい仮説と完成したプロダクトの機能が噛み合っていない
    • そもそも仮説に考慮漏れがある
  • Measure
    • いざ計測しようとするとログが埋まっていない
    • 複数の A/B テストが衝突して計測結果に影響が出る
    • 集計 SQL に間違いがあり、最悪の場合それに気がつかない
  • Learn
    • 出てきた数字をどう解釈すればいいかイマイチわからない
    • 数字は動いたがその原因がわからない、再現性が取れない
    • 得られた知見が属人的になる、あるいは闇に消える

といったような失敗がよく起こります。

f:id:spicycoffee:20180210144443p:plainf:id:spicycoffee:20180210144447p:plainf:id:spicycoffee:20180210144451p:plain

※ 巷にあふれる失敗例

このような失敗をなるべく減らすために、社内では 「最初に BML ループ全体を設計する」 ということが意識されています。 そうすることで「手戻りの防止」や「効率的な学び」を実現することが可能になります。

最初にサイクル全体を設計する

手戻りの防止

BML ループを、Build が終わってから Measure、Measure が終わってから Learn といったように、逐次的に実行した場合、大きな手戻りに繋がる可能性があります。

たとえば、Build が終わって Measure のフェーズに入ったタイミングで、ログが取れてないなかったことが発覚した場合、もう一度 Build のフェーズに立ち返ることになります。 Learn のフェーズに入って知見を抽出しようとしたタイミングで、数字の解釈がよくわからないといった状況に陥ってしまうと、もはや手戻りをすることすら難しく、何の学びも得られないままサイクルを回し終えてしまうこともありえます。

しかし、よく考えると、前のフェーズが終わらなくても、次のフェーズで何をやるかについては考えることが可能です。 むしろ、BML ループ自体を一つのプロジェクトと考えると、各フェーズを前から順番に実行していくようなやり方よりも、 最初に全体を設計することが自然に思えてきます。 BML ループにおいて、最初に全体を設計するというのは、仮説が立った段階で、各フェーズで必要になりそうなことを明確にしておくことになります。 実際にサイクルを回しだす前に、各フェーズでの要件を明確にした上で、それに沿って Build・Measure・Learn と施策を進めていくことで、手戻りの原因となりうる事故を事前に察知 し、それを防ぐことが可能になるのです。

効率的な学び

最初にサイクル全体を設計することは、効率的に学びを得るためにも必要なことです。 "学び" は定義しにくい概念ではありますが、その一つの重要な要素として、 サービスに対する理解と現実とのギャップ があげられます。

これをもう少し具体化すると、サービスに対する理解は、今のサービスに対して施策を打ったときの、施策結果に対する予想と考えることができます。 それに対応する現実は、実際に施策を打った結果です。 この2つを比較することで、思ったより結果が良かった/悪かったといった事実が出てきます。 その事実について「それはなぜか?」という点を考えることで、自分たちがサービスに対して抱いている理解のズレ・勘違いが明確になり、それが大きな学びになるのです。

f:id:spicycoffee:20180210144500p:plain

したがって、サービスに対する理解を事前に固めておくことは非常に重要なことになります。 今のサービスに施策を打ったとき、ユーザーさんはどのような体験をして、その結果どういう指標がどのくらい動きそうかということを事前に予想しておくことが大事なのです。 これはすなわち、事前に Measure や Learn のフェーズで出てくる結果について、考えを巡らせておくことになります。 こういった観点からも、実際にサイクルを回しだす前に、先のフェーズの設計をおこなっておくことが重要になってきます。

各フェーズの設計

この節では、BML ループの各フェーズについて、何を設計すればよいのか、つまりは、具体的にどのようなことを事前に決定しておけばよいのかについて書いていきます。

Build の設計

Build の設計では、以下のようなことを決定・確認しておきます。 とはいっても、このフェーズは仮説立案から距離が近いため、特に意識せずとも施策立案の段階で合わせてやっていることも多いでしょう。

  • 絶対に検証したい仮説の明確化
  • 検証背景の整理
  • 検証内容・注意点などの整理

Measure の設計

Measure の設計では以下の様なことを決定・確認しておきます。

  • 計測手法
    • A/B テストでいいのか?
    • A/B テストでいいとして、全ユーザーを対象にしてもいいのか?
  • KPI
    • 施策をどういう数字で評価するのか
    • 他に影響を与える指標はないか?
  • ログの確認、SQL の実行
    • 取りたいデータに必要なログは、現在集計されているか?
    • SQL を叩いた結果が概ね正しそうか?

特に KPI 周りの設計については注意が必要です。 指標というのはそれ単体で存在することは珍しく、大抵は相反する指標、影響を与え合う指標が同時に存在します。 これらの指標を見落としてしまうと、たとえば

TOP ページにプロトタイプとして会員登録の導線を置いたら、ある程度の会員登録が認められた
→ この施策を採用してプロダクトにリリースした
→ しばらく経ってみると、別のページ(検索結果ページ等)からの会員登録数が減っていた

といったような事故が発生します。 このような事例を防ぐために、予め関連する指標としてどのようなものがありそうかリストアップしておくことが必要です。

Learn の設計

Learn の設計では以下の様なことを決定・確認しておきます。

  • 指標の解釈
    • この数値が高くてこの数値が低いときは、ユーザーさんはどのような体験をしているのだろうか?
  • 結果の想定
    • 測定指標がどのくらいの数字になったら施策を採用するか
    • そこまではいかなくても、どのくらいの数字になったら再度議論するか

この2つの項目について事前に考えておくことを、社内では「成功のイメージを共有する」といったような言葉で表現することが多いです。 施策が成功したときに、ユーザーさんがどのような体験をして、その結果どういった指標がどの程度まで上がっているだろうか といったことを事前に想定しておきます。 そうすることで、結果から意味のある知見を抽出しやすくなりますし、効果の薄い施策を採用してしまう可能性も減らすことができます。

まとめ

上述したように開発サイクルを回していくやり方は、既に当たり前の方法となっています。 しかし、当たり前の方法だからこそ、自分たちの中で注意するポイントをしっかりと定めて運用することで、より大きな効果を期待することができます。 組織の特性や置かれている状況によって、注意するポイントは変わってくると思いますが、一つのベースとして、この記事がみなさんの参考になれば幸いです。

/* */ @import "/css/theme/report/report.css"; /* */ /* */ body{ background-image: url('https://cdn-ak.f.st-hatena.com/images/fotolife/c/cookpadtech/20140527/20140527163350.png'); background-repeat: repeat-x; background-color:transparent; background-attachment: scroll; background-position: left top;} /* */ body{ border-top: 3px solid orange; color: #3c3c3c; font-family: 'Helvetica Neue', Helvetica, 'ヒラギノ角ゴ Pro W3', 'Hiragino Kaku Gothic Pro', Meiryo, Osaka, 'MS Pゴシック', sans-serif; line-height: 1.8; font-size: 16px; } a { text-decoration: underline; color: #693e1c; } a:hover { color: #80400e; text-decoration: underline; } .entry-title a{ color: rgb(176, 108, 28); cursor: auto; display: inline; font-family: 'Helvetica Neue', Helvetica, 'ヒラギノ角ゴ Pro W3', 'Hiragino Kaku Gothic Pro', Meiryo, Osaka, 'MS Pゴシック', sans-serif; font-size: 30px; font-weight: bold; height: auto; line-height: 40.5px; text-decoration: underline solid rgb(176, 108, 28); width: auto; line-height: 1.35; } .date a { color: #9b8b6c; font-size: 14px; text-decoration: none; font-weight: normal; } .urllist-title-link { font-size: 14px; } /* Recent Entries */ .recent-entries a{ color: #693e1c; } .recent-entries a:visited { color: #4d2200; text-decoration: none; } .hatena-module-recent-entries li { padding-bottom: 8px; border-bottom-width: 0px; } /*Widget*/ .hatena-module-body li { list-style-type: circle; } .hatena-module-body a{ text-decoration: none; } .hatena-module-body a:hover{ text-decoration: underline; } /* Widget name */ .hatena-module-title, .hatena-module-title a{ color: #b06c1c; margin-top: 20px; margin-bottom: 7px; } /* work frame*/ #container { width: 970px; text-align: center; margin: 0 auto; background: transparent; padding: 0 30px; } #wrapper { float: left; overflow: hidden; width: 660px; } #box2 { width: 240px; float: right; font-size: 14px; word-wrap: break-word; } /*#blog-title-inner{*/ /*margin-top: 3px;*/ /*height: 125px;*/ /*background-position: left 0px;*/ /*}*/ /*.header-image-only #blog-title-inner {*/ /*background-repeat: no-repeat;*/ /*position: relative;*/ /*height: 200px;*/ /*display: none;*/ /*}*/ /*#blog-title {*/ /*margin-top: 3px;*/ /*height: 125px;*/ /*background-image: url('https://cdn-ak.f.st-hatena.com/images/fotolife/c/cookpadtech/20140527/20140527172848.png');*/ /*background-repeat: no-repeat;*/ /*background-position: left 0px;*/ /*}*/