フロー効率性とリソース効率性について(QCDのトレードオフなんて本当は無かったんだ)
最新版
本ポストをXP祭り2017で発表したので、補足を含め要点のみを抽出してリライトしております。
本ポストはプロダクト開発における特定の文脈によるものなのですべてがそうだとは言っていませんのであしからず。バイモーダル戦略でいうところのSoE領域*1であり、学びによる改善サイクルをガンガン回していくようなモデル・フェーズを対象としております。TPSやLEANを現場で実践してる方々には今更なお話かと思いますが、DevOpsやアジャイル、リーンスタートアップを実践していく上で何周かしてまた原点の理解すると深みがますというかようやく、「ちょっとだけリーンわかる」ようになったので自分用のメモになります。
共通の価値観としての「リードタイム」
SoEライクな開発をしていると、仮説を立案し、そのための仮説を実証するための機能を実装し、リリースして計測、そして学びを得て仮説を補正する(別の案を試す)というサイクルをくるくる回すことになるかと思います。このようなときに開発チームとして目指すところは学びの回数を最大化することなのは自明かと思います。そしてそのサイクル短くする、すなわちサイクル効率性を高めることが必要になります。サイクル効率には仮説の質等も影響も与えますが、今回はエンジニアが直接結果をコントロールしやすいサイクルタイム、言い換えるならば、学びまでのリードタイムを軸に考えていきます。またスコープは学ぶまでのリードタイムであるため、Build部分のみにフォーカスするのではなく、Build-Measure-Learnの1回転をスコープとします。 例えば、コードレビューで手戻りが頻発すればリードタイムが伸びますし、受け入れテストで受け入れられなければやりなおしになるのでリードタイムが伸びます。様々な活動は結果的にリードタイムに跳ね返ります。
すごくラフですが以下のような開発プロセスのバリューストリームマッピングを例にします。LTはリードタイムを表しています。リードタイムとはプロセスが作業を受け付けてから、下流のプロセスに渡すまでの時間になります。PTはプロセスタイムで、作業者がひとつの作業項目を完了するのにかかる時間です。そして実際に価値が作り込まれているのがこのプロセスタイムになります。実際のところは[PT = Value Add Time(VAT) + ムダ ]であり、 本当に価値を作っている時間はその一部になります。赤い部分が上記のBuild-Measure-LeanサイクルのBuild部分に相当します。エンジニアが直接結果をコントロールしやすい部分です。
フロー効率性とリソース効率性の話
あえて極端な例。A機能、B機能、C機能の実装それぞれ15人日かかる場合。
- リソース効率性パラダイム(図の上側レーン) 複数のことを同時にやるとプロダクトが届くまでのリードタイムが長くなる。ただし、みんなに仕事が割り振られるためリソースの稼働率は高くなる。
- フロー効率性パラダイム(図の下側レーン) 逆に、同時にやることを一つにすると、プロダクトが届くまでのリードタイムは短くなる。ただし、全員が同じことをやる場合、どうしても一時的に、手持ちがなくなる人が出て来るためリソースの稼働率は下がる。図ではCも3Weekのリードタイムで出してるが実際は、4週目とかにズレこむ感覚。でも、ABCのリードタイムのトータルでは上側レーンよりは圧倒的に少ない。
これはどちらが正解というわけではないです。この2つはQCDのようによくあるトレードオフの関係にあります。大規模開発のように大量のものを一括でドン!とリリースするような文脈だと、上記のリソース効率のパラダイムになります。そんな中でフロー効率性を高めるようなペアプログラミングを実施したいと提案しても、(リソース)効率落ちるだろと言われ却下されることは多いのではないでしょうか。逆にフロー効率性を高めて、学びまでのリードタイムを最小化しようとしているときに、偉い人が出てきて「リリース物は全部承認印が必要だ、だが、時間はあまりないので一括で見るからまとめて持ってきなさい」とかいわれると現場はフロー効率性を高めようとしているのにリソース効率性のノイズが入り、現場からはヘイトが高まるのではないでしょうか。
ポイントとしては、タスクやデータ、物事の流れに着目し、それがうまく流れているかをカイゼンしていくことが大事です。
そして、一般的には、フロー効率性の目線で現場の課題を可視化していき、フロー効率性を高めると結果的にリソース効率性における課題も表出化され改善されることが多いです。ベースはフロー効率性を高める目線で活動しつつ、制約が現れたときにそれをコントロールの対象とするか、前提とおくかは重要(制約理論)です。ここらへんはThis is Lean*2とかに詳しくは書いてあります。
QCDのトレードオフなんて本当は無かったんだ
SoEライクな開発の座組において、QCDとScopeは「学びまでのリードタイム」という軸で見ると以下の意味を持つ。結論から言うとリードタイムという観点だとQCD全部大事。品質は悪いと基本的に手戻りを生むので速度に跳ね返る。手戻ってる時間は学びをうまない時間。品質を下げるという判断は学びの速度低下を許容するとこと。
- Quality:低下するとリードタイムを悪化させる(=品質下げるという選択肢がそもそも無い:固定)
- プロセス品質下げると手順ミス等により手戻りが発生しデリバリへのリードタイムが長くなる
- 内部品質さげるとバグの発生、コードレビューの指摘、技術的負債による実装の複雑さなどにより手戻りや速度低下を招き、デリバリへのリードタイムが長くなる
- 外部品質さげるとUXバグをうみ、本来検証したいことが検証できず学びまでのリードタイムが長くなる。障害発生により、それの対応に終われリソースが枯渇し本来やるべきことの足かせになり、リードタイムが長くなる
- 利用時の品質さげると、カスタマーサポートが頻発しその対応に組織のパワーが持って行かれリードタイムが長くなる
- Cost:大抵人件費でありチーム体制は頻繁に増減はない(固定)
- コストはエンジニアリングの場合、大抵、人件費に跳ね返るが体制は基本的には固定であり頻繁に上下するものでないので固定になるケースが多い。
- 学びまでのリードタイムの人件費と見るのであれば、少ないにこしたことはない。結果的にコストはリードタイムそのもの。
- Delivery:出来るだけ短縮したい(伸ばさない、短縮すべき対象)
- リードタイムそのもの
- Scope:一度にやる量を決めることでリードタイムが結果的に変わってくる
- 大きくする(大きなバッチ)と、リソース効率性のバイアスがかかるため、一括でリリースは出来るが、デリバリまでのリードタイムは増える(前述の図の上側レーン)
- 小さくする(1個流し)と、フロー効率性のバイアスがかかるため、小出しにはなるがデリバリまでのリードタイムは小さくなる(前述の図の下側レーン)
QCDは調整ネジではなく、リソース効率性とフロー効率性が調整のネジ
この文脈においてQCDは基本的に変数ではなく、ほぼ定数として扱うことになる。全部大事。そして、デリバリは早ければはやいほどいい。そこで調整ネジというか変数になってくるのがScopeで、一度に開発する(同時にリリースされる)対象の量とサイズがそれにあたる。それにより、リードタイムが上下する。 調整ネジとは言え、学びへのリードタイムを短くしたいので、フロー効率性を高める選択をしたほうがよいのが本音。
チームが一度に行うタスク量が多い/サイズが大きい場合
一度に開発する量が多い/サイズが大きいと、並行作業が発生する。チームメンバは担当する機能が割り当てられ、それぞれ別々の機能の開発をする。つまり、この時点で、チームは前述の以下の図の上側レーンを選択したことになる。例えば、プロダクトオーナーから起案された機能要望がとてつもなく大きいとかがこれにあたる。エンジニアは本能的に下記図で上側レーンのようにリードタイムが増えることを感じ、「もっと分割できないですか?」「必要最小限にできないですか?」ときいたりするが、「これ全部必要です。」といわれることが経験上あるはず。しかしながら、これに対して「エンジニアチームの生産性が悪い」「なかなかリリースされない」みたいな意見がでたりもする。この状況を作り上げている「1つ」の要因はバッチサイズの大きさである。しかし、これはチームがそうなることを選んだのである。POやプロダクトマネージャーはチームに大きな塊を渡した時点で、渡した側も何が起きるか、どういう選択をしたのかを把握しておく必要がある。
This is Leanの P21にはリソース効率性に振り切っている状況を以下のような図で説明されている。1つのリソースにフォーカスして、そのリソースが与えられる稼働を100% になるように複数のフローユニット(タスク)に分割する。
部分的にリソース効率性が求められる場合はある
- どうしても一括でまとめて処理しないとならない場合
チームが一度に行うタスク量が少ない/サイズが小さい場合
一度に開発する量が少なく、サイズが小さい場合、チームは1つのことにフォーカスできる。例えば1つの機能を全員で実装する。すると複数の機能を全員で実装していた場合よりも、とある1つの機能は学びまでのリードタイムが短くなる。下記図の通りである。また、チームへ渡される要件のスコープが小さければ小さいほど、チームの見積もりの確度は高まる。更に、チームは自分たちの本来の適正な生産性で作業を実施できるようになる。
This is Leanの P21には以下のような図で説明されている。1つのフローユニット(機能)にフォーカスして、その1つのフローユニットが受けられるリソース時間を最大化する。
フロー効率性を向上させるプラクティスや事例
- カンバン(トヨタ生産方式)
- ペアプログラミング
- 二人で1つのことをするため、二人で別々のことをするよりも流れるものの数が半分&品質が上がる(副次効果で引き継ぎが不要になり、結果的に誰でもどんな作業もプル出来るようになる。こちらもフロー効率性に寄与する。)
- モブプログラミング
- Github-Flow & Feature Flagのコラボ
- FeatureFlagを仕込んだプルリクのMasterマージで本番環境への自動デプロイ
- 断片でのプッシュが可能になり、プルリクが小さくなる
- 流れるもののサイズを小さくする効果(フロー効率性)
- 対してGit-FlowはReleaseブランチが若干一括処理でありリソース効率性がある。
- 継続的ビルド&テスト&インテグレーション
- フィードバックループの短サイクル化
- 早く間違いに気づく
- 手戻りの最小化
- マルチタスクをやめる
- カンバンのWIP制限の話と同義
- バリューストリームマップ
- バリューストリームマップにて、プロセスタイムとリードタイムを可視化。ムダを特定しフローを改善。
- クロスファンクショナルチーム
- 他組織とのやりとりは基本的にバッチ処理になりがちであり、引き継ぎのムダが発生する。それの排除。
- フルスタックエンジニア
- クロスファンクショナルチームの人バージョン。1人で全部できれば待ちのムダが省ける。フルスタックはある文脈では(笑)とされるが非常にフロー効率性が高い。
- etc
まとめ
仮説検証型でプロダクト開発を行う場合、学びまでのリードタイムを如何に短くするかが重要であるのはもう自明ではあり、目指す方向は「一個流し」(フロー効率性:高)である。しかしながら「目指す」のであり「目的」ではないのがポイント。フロー効率性の極値である「一個流し」を目指すことで様々なムダが浮き彫りになり、それを解消していくと、結果的にリソース効率性も高まるのである。
- フロー効率性(流す量を減らす)をあげると、ライン上にタスクまちの人が増えて、何もしない人がうまれる。(リソース効率性悪化)
- リソース効率性(流す量を増やす)をあげると、ライン上に人まちのタスクが増えて、リードタイムが増える。(フロー効率性悪化)
エンジニアリングに読み替えると、チームに渡される玉の量とサイズの大きさと、それを全員で一個を倒しに行くのか、ばらばらにそれぞれのタスクをこなすのか。一般的にプロダクト開発においてプロジェクトマネジメント上QCDが調整ネジに扱われるが、SoEな文脈においてはフロー効率性とリソース効率性( チームに渡される玉の量とサイズの大きさ )を調整ネジにすべき。従来の鉄板(だと誤解されていた)だった品質すてて速度あげようは 品質は劣化すれば手戻りが発生するだけで、結局はリードタイムの増加に跳ね返る のでやめましょう。
結果的に、カンバンやスクラムがWIP制限だのプル型だのいっている理由やスコープで調整軸にするというあたりまえの話に結局戻ってしまったが、一周回って?基本を理解できたのでよかった。
*1:以下でバイモーダル戦略やSoE/SoRについて触れています i2key.hateblo.jp
*3: カンバン仕事術 http://amzn.to/2rfmwHUamzn.to