「タイムバンク」におけるプロジェクトの立ち上げとMVP
田中裕一氏:みなさんこんばんは。田中といいます。メタップスという会社で「タイムバンク」というアプリの開発責任者をやっています。
このタイムバンクは去年の9月にローンチして、ちょうど8ヶ月ぐらいのプロダクトになっているんですが、ゼロから完全にスクラッチで立ち上げ等々をやってきました。
その立ち上げの時にどんな問題を抱えたのかというところと、チームワークをどうやって作っていったのか、あとはエンジニアの組織で起きがちな問題みたいなところを冒頭にお話しさせていただきます。
後半は、MVPという考え方をベースに、ユーザーに対してどのように機能を最速で提供していくか、という観点でやっていることについて、事例ベースでお話しできればと思っています
まずは自己紹介です。
経歴がまちまちで飛んでいますが、もともとは金融系をやっていました。COBOLなどをやっていて、そのあとに組み込み系でRTOSを組んでました。C++周りもさわりました。その後、ウェブ系に移りましてAdやSNS・ゲーム系にすこし携わって、ビッグデータやマシンラーニング系やった後、ベンダー系に移って、FinTechということでこのタイムバンクというサービスを作っています。
スキルセットもまちまちで飛んでいるのですが、フロントからインフラ周りまで、比較的どこも浅く触れます。深く触れるところとしてHadoop/Spark系やML系周りに触ることが多いです。見た目から「デザインも一緒にやってよ」ってよくお願いされるんですけど、デザインはぜんぜん無理です。
(会場笑)
Apache Sparkはご存知ですか? ビッグデータ、分散処理の環境で高速に処理するオープンソースのApacheの仕組みあるのですが、そちらで著書がいくつかあります。ぜひ興味があればお手にとってください。
Web記事もいくつか、ビッグデータ周りやマシンラーニングあたりで寄稿させてもらっています。こちらもぜひ読んでいただければと思います。
「タイムバンク」の現状
みなさん、タイムバンクというサービスをご存じの方はいらっしゃいますか?
(会場挙手)
知っているような知らないようなという感じですね。タイムバンクはざっくり説明するとFinTech系のサービスになっていまして、個人の空き時間を売買できる取引所です。
どういうサービスかというと、専門家と呼ばれるユーザーがタイムバンク上で時間を発行して、ファンの応援を受ける事ができる、また、その時間をユーザーどうしでやりとりできるというプラットフォームになります。
今日はシステム側の話なのであまりビジネスの話はしませんが、一応こういうサービスが背景にあることだけご認識いただければと思います。
今日は話するにあたって、システム周りの背景情報を先にお伝えできればと思います。立ち上げのタイミングはRubyオンリーでしたが、今はRubyとPythonとNode.jsでサーバサイドが動いております。これにiOSとAndroidのアプリがメインで、最近ようやくWeb系を作り始めたフェーズです。
インフラ的には完全にAWSの上に乗っかって、サービスが動いています。
チームは若干拡張していまして、現在5名くらいの人数+テンポラリーの方で開発してます。
プロジェクトの立ち上げとチームビルディング
ちょっと前置きが長かったですが、まずはプロジェクトの立ち上げとチームビルディングの話のお話ができればと思います。
「プロジェクトの立ち上げの際、あなたは理想のチームが作れる人脈・予算・期間を持っていますか? もしくは経営側からそういったリソースを割り当てられていますか?」という質問ですが、どうでしょうか? 「潤沢に資金・資産・人脈がある状態、スキルが揃っている状態で開発を始められていますか?」という質問になります。
もしこれイエスと、「周りのチームのスキルは完璧だし、予算も潤沢にあるし、期間もエンジニアの言うとおりにやらせてもらえるんだよ」という方は、あまり学びがないので20分間寝ておいていただいて問題ございません。
どのようなプロジェクトを立ち上げる際も、すべてがきちんと揃って立ち上げが行えるような開発状況にあることのほうが稀です。タイムバンクは、立ち上げの際にサーバサイド iOS・Androidのアプリが当初の開発要件として上がっていました。
エンジニアの技術的背景
まずスキルの背景を説明したいと思います。
開発メンバは当初非常に少ない人数で始まりまして、しかも外から入社したばかりのメンバも多かったです。また、開発要件が進むのに合わせて毎月人が増えていくスケールさせていく形になりました。
このように外部から人を雇ってプロジェクトを立ち上げる際、得意な言語がそれぞれ違ったり、「自分はこういう新しい技術にチャレンジしたいんだ」というようにやりたい方向が違ったり。あとは経験、やったことのある業種がバラバラという状況よく発生します。
さらにレイヤーの違いによるスキルの差異。僕はどちらかというとミドル寄りのサーバサイドのエンジニアになります。それ以外にも、インフラ寄りミドル寄り。AWSの設定、Ansibleなどを書いていらっしゃったり、ミドルウェアにもカリカリにチューニング入れられるような方がいたり、「サーバサイドも組めるけど、どっちかというとJSが得意なんです」というような方もいます。
レイヤーの違いによるスキル差異やバックグラウンドによるスキル差異をチームの立ち上げの際は考慮する必要があります、タイムバンクのチームも、正義の違いというか、持っている背景で「こっちのほうがいいんじゃないか?」という議論をよくやりました。
あとは背景職の違いですね。ここがよく揉めるところなのですが、「いいシステムってなんですか?」という問に対して、バックグラウンドによってなにを重視してどういう状態がよいのかがけっこう違うという問題がありました。
とくにAdtech・ゲーム・Web系は、システムに対してスケーラビリティや開発速度を重視しがちで、「スケーラビリティが取れる仕組みになっていないのはシステムとしては失格だ」という考え方にどうしてもなってしまいます。また、オープンソース系の方は、後々にそのような拡張が可能かであったり、どのように安定性を持たせて開発を進めていくかというところを重視します。バックグラウンドがガチガチな金融系の方は、「そもそも仕様がちゃんとないと作ってられないよ」というふうに、チームの立ち上げタイミングではよく揉めます。
対話&対話&対話
最初の頃は、どうしても作業の量が多いし、とりあえずリリースを進めなきゃということで、比較的同じ目標に向かえることが多かったですが、やはりどこでもあると思いますが、プロジェクトが進んでくると第一次マサカリ戦争が勃発します。「とりあえずそのPull RequestはありえないのでCloseしました」ということも起こりました。
また、稼働も高く状況もシビアになってきて、そして思ったとおりにものが作れていないと、こういったプルリク、コメント、クローズ、change requireが飛んできたりします。
開発を進めていく中で、それぞれが重視している事や、開発のフロー、当たり前だと思っている事の違いなんかが出てくるわけですね。そんな中で新しい機能をどんどん開発してくために、我々はコミュニケーション・対話をチームとして重視してました。
お互いに正義の違いがあるのはわかったと。どういうことをやりたいのかもちゃんと話していきましょうね、と。ただ、我々はエンジニアチームとして「どこに目線を合わせて、なにをチームとして重視するんだっけ?」ということをくりかえし話しました。
ここには対話&対話&対話と書いていますが、基本的に、チームの立ち上げ時、バックグラウンドやスキルがきちんと揃った人間を揃えるのは不可能であったり、そもそもモチベーションや目的意識もバラバラな状態で、教科書どおりにアジャイルの要素だけをとりいれればプロジェクトが進むのかというと、そんなことはありません。ですので、まずは対話をしましょうと。
我々が今どんな状態にあって、なにをチームとして重視して、どこを目指すのか。つまり、私たちはプロフェッショナルなのか日曜プログラマなのかというところをきちんと話しました。
「僕たちタイムバンクというサービスを作るために、これを市場に出して市場のユーザーに受け入れてもらうために、こういう新しいサービスをもってチャレンジするために入ったんだよね」というところで、エンジニアリングとサービスのバランスについて我々がどう思っているか、目線合わせに沢山の時間を使いました。
我々はあくまでサービスをユーザーに使ってもらうために、より早くサービス・新しい機能を市場に出して、市場に評価されていきましょう、という目線合わせを行ったあとに、「たくさんのチャレンジをしていくためにリリースサイクルってどうやったら速くなっていきますか? どのようにプログラムを組むとリリースサイクルは速くなるんでしたっけ?」「サービスの継続性の担保って今我々やらなきゃいけないところなんでしたっけ?」といったようなところで、「まずは何からコミットをしましょうか?」というところをかなり時間をかけてやりました。
重視したことと、諦めたこと
とくに重要視したことは合意の方向性です。これは今でも意見が違った際に「僕たちこれでなにを実現したかったんだっけ?」という話をよくやっています。
まず、エンジニアがなすべきことをフェーズを分けて考えます。最初に100パーセントのものを作ることを求めたところで書けないし、書き方がそもそも違う。例えば「C2まで求めるか? C1のレベルを求めるのか? C0のレベルを求めるのか?」みたいなところもバックグラウンドでぜんぜん違うので、「とりあえずリリースを最優先しましょう。できあがったものを優先していきましょう」というのが、ありがちですが、最初の合意になっていました。
具体例をあげると、Unitに関してまず完全に諦めましょうと。そもそも書く・書かないでコミットまでの時間やスパンが作っている人によってバラバラになってしまったこと、書き方があまりにも違いすぎて、Unitを書いてもUnitの意味をなさない状態にありました。
Rubyなのでバリデーションはわりとみんな書くんですが、バリデーションまわりのUnitだけを書いてもあまり意味がなくて。そういった意味でUnitは諦めました。代わりに結合や機能テストである程度初期のリリースに関してはカバーしましょうというかたちで、Unitは諦めています。
いったん「MVCぐらいはみんな意識するよね」というなかで、意識はするが書き方の微妙な部分は個々の判断でプルリクに特にコメント(change request)つける事もあまりしないかたちに当初しました。 書き方が微妙な部分というのは、「Railsのお作法にそもそも則っているか?」みたいなところがどうしてもRails屋さんは気になってしまいますが、「でも今のタイミングでは我々の生産性にあまり貢献しないよね」ということで諦めてもらっています。
インフラのスケーラビリティも部分的に諦めました。これは立ち上げのスピード感というところと、インフラでとくにAWSのバックエンドをきっちり持った方が、当初はチームにいない、コード化する時間がもったいない、ここは考えてもしょうがないし、調べるほどの時間もなかったのでいったん諦めてもらいました。
ドキュメンテーションのルール
ただ、諦めなかったところとして、新しい体験を最速でユーザーに届けるために必要なものを準備しましょうということで、デプロイフロー、リリースフローだけは最初からきっちり作っておきました。ボタン1個押せばとりあえずリポジトリからデプロイまで持っていけるというところは、必ず担保し続けています。
デプロイ周りに関しては、わからない人がいるなら時間をかけても教育しようということで、最初からこの2つは担保しています。
仕様書の体裁や粒度も諦めましたが、チケットは最低限書いていきましょう。どういう体裁でもいいし、どの粒度でもいいので、なにをやったかということと、いつなにが発生してそれを誰が処理したのかはやってました。
1日30分の対面コミュニケーションを義務化
赤字の部分は特に重視した部分です。1日30分の対面のコミュニケーションを義務にしました。エンジニアはよくSlackやチャットツールに閉じこもりがちなんですが、「30分必ずビジネス側・エンジニア側問わずコミュニケーションをするのが仕事です」というかたちにしています。あと、リモートワークいったんNGにしました。リリースからだいたい2〜3ヶ月くらいはこのかたちで進めてました。
その後、プロモーションや広告を打ち始める時期に少しやり方を変えています。基本的にUnitに関してはこのタイミングぐらいから書き始めましょうと。その認識合わせのためにチーム内の勉強会を必ず週に1時間とるようにしました。
そのなかで「どのように書きましょうか」「どこまで書いたらプルリクってだすんだっけ?」ということをきちんと話し合いました。「お金に絡む部分は必ず書いてください」ということに、これぐらいのタイミングからかえてきました。「ただ、リリース優先のためにスキップすることはあります」ということは納得していただいていました。
今はまだリリース最優先でやっています。これはサービス自体がまだリリースしたい事が多く、まだ安定期に入っていないことが主な理由です。
新規部分に関しては、チームの育成も含めてやってきたところもあり「新規部分に関してはUnitをきちんと書きましょうよ」「MVCきちんと書きましょうよ。まさかControllerにビジネスロジック入ってないですよね?」ということを最近極力やるようになってきてます
「明らかにおかしいものに関しては、どう直してほしいかを記述した上でapproveまではかけてください」という状態でやっています。あと、マイクロサービス化も進めています。また、最近は週1でリモートワークの日を作れるようになってきました。
プロジェクトに対してコミットしつつも、エンジニアとしてきちんと成長できるような環境を作ることを主眼に置いてやっています。他にもいくつか課題ありますが、これは細かい話なので次にいきます。
現在のリリース頻度
そんな感じでチームビルディングをやってきて、現在は、だいたい1日に1〜2回ぐらいの頻度で本番プロダクションのリリースをかけています。アプリが絡む大型のリリースも約週1〜2、fixを含めると多い時に週3回ほど本番リリースをかけています。
開発のラインは2本+αベースで設計していまして、サーバ1名、iOS1名、Android1名で1機能を2本。+α部分はhotfixやイベントの作成、あとは後ほど出てきますが、オズの魔法使い役を設けています。
Web系だとわりと当たり前なリリースサイクルですが、はじめはこの状態に持っていくまでにいろいろな課題があり、ようやく最近ここまで持ってこれるようになりました。ここまでが、チームビルディングのお話です。
「MVP」と「オズの魔法使い」とは何か?
それでは、MVPのお話ができればと持っています。オズの魔法使いの前に、MVPをみなさんご存じですか?「検証可能な必要最低限のプロダクト」のことです。
実際のユーザーに提供して、それがユーザーに利用されるまでは、そのサービスを実装してよかったかどうかはただの仮説です。提供者の都合のよい思い込みであるから、まずはユーザーに必要最低限の機能を提供して、そのフィードバックを得て仮説検証を行って、サービスを適宜調整することで余計な開発コストの削減、プロダクトマーケットフィットを目指す手法をMVPと呼ぶそうです。
「オズの魔法使い」もその手法の1つになっていまして。タイムバンクでは一部意図してオズの魔法使いとスモークテストを行っています。
オズの魔法使いとはどんな手法なのかですが、本来システム化されているように見えるプロダクトを、実際は生身の人間が手動で操作することで、初期開発費用や期間を大幅に削減してシステム化のリスクを回避する手法になります。要は人が後ろでがんばっている状態です。タイムバンクでは意図的にこの状態を作り出している部分があります。
そもそもタイムバンクのような少人数開発のリスクどこにあるのかということで、横軸に時間、縦軸にコストを置きました。
(開発の)時間が増えれば増えるほどどんどん開発コストは上がっていきます。このギャップが開発チームにとってリスクとして乗ってきます。つまり、一生懸命時間をかけて作ったサービスが、ユーザーにとって本当に重要な機能だったのかは実際に使われるまではわからず、開発に時間をかければかけるほどリスクが高くなっていくというのが、基本的なタイムバンクの開発の考え方になっています。
MVPが解決する課題
MVPはどのようにその問題を解決していくのか? MVPでは、まずは簡単な機能をリリースして、ユーザーに使ってもらってユーザーに体験してもらって、そこでKPIが跳ねる(ユーザーにより利用される)のであればその機能を拡張したり、ピボットしてより高機能なもの、もしくは次の機能を開発するなど、適宜市場にフィットが可能になることでリスクを小さく抑える開発手法です。
どんな時にMVPで検証しているのか、こちらは例です。
このような要件を例としてみていきましょう。「ユーザーの売り注文に対して、買い注文の絶対数が少ない」。これはデータから見えている事実です。「ユーザーの買い控えになっているのではないか?」。これは仮説1ですね。「市場全体の価値が上昇することで、セカンドバイの心理障壁が薄れるのではないか?」。これが仮説2です。
そういった要件があったときになにを検証するのか? 「買い注文に対してランキングを作成して上位者にインセンティブを付与することで、ユーザーの買い注文が増えるはず」。これが検証1ですね。「市場全体の価値が上昇するはず」。これも検証2です。「心理的な障壁がきちんと薄れているか?」。これが検証3です。
では、これらを検証するために必要なもの。「ランキングをちゃんと表示するページ必要だよね、ユーザーを参加させる導線必要だよね、ランキング計算するバッチ必要だよね、イベント期間管理するテーブル必要だよね」といった形で検証に必要な機能をだしていきます。
通常2〜3週間ぐらいあればうまくイベント設計してできるんじゃないかという工数なのですが、ユーザーに体験してもらうことを重視して、こういったかたちでオズの魔法使いを作っています。
「まず検証可能かどうか? 測定可能かどうか?」「そもそも改善したかどうかって比較対象のデータ持っているか?」。「短期的に検証可能な項目かどうか?」をよく意識しています。
それをもとに、例えば「ユーザーの買い注文が増えるかどうか?」を検証できるか考えます。これはDBを漁れば一発で取れるので検証可能ですよね。「市場全体の価値が上昇するか?」。これもDBに入っている情報なので検証可能です。
最後に「心理的な障壁が薄れるか?」。こうした検証不可能な定性的なものに関しては、定性から定量化が必要になります。そもそもどうやって定量化するのかの議論から始まり、計測の仕方やデータの取得の仕方をディスカッションしていく必要があるのですが、こういった作業には非常に時間かかります。
検証可能なようにディスカッションして定量化を行うということがそもそもコストなので、定量化が難しい項目は一旦脇に置いておいて、評価可能な項目があるのであればとりあえず開発進めています。
こうしたディスカッションというのは最も工数が重たい作業です。新たな軸、心理的表現を探るパターンは、だいたい途中で意味消失するか限定的な解釈が可能になる程度なので、「工数に対して初期ではなかなか効果が見込めませんよ。だから避けるのもありですよ」ということで、検証項目をバサッと切ってしまうのも1つの手です。
必須のとそうでないものを切り分ける
MVP(最低限検証するため)において、赤字で書いてあるのが必須の部分です。
これがないとそもそもユーザーがたどり着けないとか、データが格納できないので、赤は必須で必要です。
青字はランキングを計算するバッチです。例えば「これってバッチ化する必要そもそもありましたっけ?」ということで、誰かが2時間に1回SQLを叩くことで対応可能になるかもしれません。少し極端な例ですが、これをやることで1日リリースのタイミングが速くできるのであればリリースして、早くユーザーに体験してもらいましょうというかたちでやってます。
緑の部分は「最初からこれって必要でしたっけ?」という機能です。「そもそも流行るかどうかわからないイベントのために管理画面って作る必要ありましたっけ?」ということで、「これもエンジニアが手作業で叩いたらこれできますよね?」というものは実装の優先順位を落として、後ほど実装することにしています。
こうした切り分けをすることで、もともと2週間ぐらいかかると言われていたことがだいたい1週間弱で収まります。開催中に実装可能なもの、あとで間に合えばよいものに関してはあとにする。検証を待ってから実装すればよいものに関しては検証を待ってから実装するという切り分けにしています。
青と緑の部分を例に、手でやっても問題ないものに関しては極力手でやる。オズの魔法使いをきちんと作ってその人に運用してもらいながら、横で開発もガリガリやって、とりあえず早くイベントを出してしまう。ユーザーがそのイベントに対してどう反応したか早く検証して、検証してOKだったら続きの開発を入れていく。管理機能を作ってそれを定常イベントを機能として実装して回していく、というやり方がスタートアップで開発リソースが限られている場合には有用な手法になると思います。
失敗したと思っているケースです。
これもあくまで架空の例ですが、先ほどのすでに定常化したイベントに対して、インセンティブを変更してみたいと。ここを変更すると影響度合いが大きいので、イベントの終了後まとめて付与するように直したのですが、その結果、「バグですか?」という不具合報告が大量にあがってくるようになってしまいます。
オズの魔法使い化する場合、今まで動いているものを変更かける場合、ユーザー体験を損ねるものは、最小限の検証可能なプロダクトの失敗例だと思っています。
ユーザーも開発者もプロダクトオーナーもプラスになる
まとめです。MVPを上手く使えば、プロダクトオーナーはどんどんリリースができてうれしいです。開発エンジニアも、作らなくてもよいところに関しては作らない。どんどん検証を取って、いらないものは速攻で捨てるようになるので開発工数が減ります。ユーザーも、新しくいろんな体験ができるのはプラスです。
ただ、ユーザー体験を損ねるもの、ユーザーを度外視してしまうようなMVPの使い方には注意しましょうというのが学びです。
ものすごく駆け足になってしまいましたが、チームの立ち上げフェーズは、やはりチームワークです。先ほども話がありましたが、対話をベースに自分たちがどういうポジションにいるのか、自分たちがどんな状態にあるのかをみんなが認識した上で、それをもって我々は何をやっていくのかという対話がとても重要です。
2つ目。スタートアップをやるにあたって、MVP、「直近必要ないものは開発しない。手で行えるものは手で行う」という判断の仕方も、大幅に工数を削減するうえで有効じゃないかと思い、ご紹介させていただきました。
ちょっと長くなりましたが、僕の話は以上になります。ご清聴ありがとうございました。
(会場拍手)