🚀

目指せ高付加価値!アジャイルにおけるフロー効率・リソース効率とは?徹底解説。

2022/11/07に公開

概要

みなさんは「フロー効率」や「リソース効率」という言葉を聞いたことはありますか?
最近、アジャイル開発やソフトウェア開発の文脈において、「リソース効率よりもフロー効率を重視すべき」といったニュアンスのコメントを見かける場合があります。このコメント自体は必ずしも間違いではないのですが、このコメントをふわっと解釈して、実態と異なる理解や説明が為されているのを見かけます。
そこで、この記事ではそうした誤解がなくなるようにフロー効率について説明をしていきます。

結局何をすればいいのか、端的に言うと

フロー効率の概念を踏まえて結局どうすればよいのか?という事ですが、簡単にまとめると以下のようになります。

  • ソフトウェアはデプロイされた時点から顧客に価値を提供するようになるので、他にしがらみが無ければフロー効率を上げた方がよい
  • アジャイル開発の文脈で、フロー効率とリソース効率は多くの場合トレードオフの関係にない
  • ただし、フロー効率を上げようとすると、そうでない場合に比べて追加タスクが発生する可能性はあり、リソース効率とは無関係にある種のトレードオフはある
  • 追加タスクの量は自動テストや自動デプロイで減らして、トレードオフをある程度は解消できる

最終的な結論としては、「リソース効率」に関する理解を除けば、一般的に言われていることとあまり変わりはありません。ただ、メカニズム・仕組みについて理解することで、実際の対応方針などが変わってくる可能性もあるので、仕組みへの理解を深める事に意味があると思っています。

記事の骨子

この記事で説明する内容の骨子をまとめました。

  • フロー効率・リソース効率という2つの効率の考え方において、それらが特にトレードオフ的になるのはリソースを増やす場面や作業量を減らす場面であること
  • アジャイル開発におけるリソースとは、多くの場面でタスクを消化する作業者を意味すること
    • 従って、普通の作業者は、意図的に遊びを入れない限りはフル稼働していること
  • そのため、アジャイル開発の文脈では、フロー効率とリソース効率の間のトレードオフはあまり発生しないこと
    • ただし、フロー効率を重視してデプロイサイクルを細かくすると、一括リリースよりも作業=タスク自体が増えること
    • これはリソース効率とは関係なく、フロー効率を重視した時にタスクが増えるという構造によるものであること
    • 従って、フロー効率を上げようとすると、デプロイサイクルを細かくするような仕組み(自動テスト、自動デプロイ等)である程度は対処ができ、それゆえ自動テストや自動デプロイが重要であること
  • 「全体のフロー効率」と「個々のタスクのフロー効率の平均」は異なること
    • 特に、リソース効率を保ったままフロー効率を上げる方法が存在すること
  • アジャイル開発におけるフロー効率を定義するには、リードタイムの定義が必要であること
    • つまり、具体的にいつの時点をタスクの発生として、いつの時点をタスクの完了とするかを定義する必要があること
  • 一方で、ソフトウェア開発の文脈では「タスクの発生」時点を普遍的に決められないこと
    • 例えば、タスクの発生タイミングは要望が上がった時か?要件定義時か?WBS作成時か?着手時か?
  • Four Keysにおいては、「変更のリードタイム」として「commit から本番環境稼働までの所要時間」を採用していること
    • これは、ざっくり (実装時間)/2 + リリース可能な状態から実際にデプロイされるまでの時間 を意味すること
    • つまり、タスクに着手するまでの待機時間は関係なく、着手してから実装完了するまでの時間(の半分)とデプロイまでの待機時間に分解されること
  • このFour Keysの変更のリードタイムについて、フロー効率を上げるというのは、特に開発完了からデプロイまでの時間を短くする事を意味していること
    • 従ってリソース効率とは関係がないこと
  • なぜフロー効率を上げた方がよいのかというと、次のようなことがある
    • Four Keysの有効性によって、少なくとも経験的には変更のリードタイムは短い方がよい傾向があること
    • 追加機能を早くデプロイできると、より多くの顧客に早期に価値を提供できること
      • 仮説検証が必要な場合にもデプロイを早くするのは有効であること

以上がこの記事の内容の骨子です。ただし、本文の中で示される順番が少し前後する場合があります。
それでは、詳しく説明していきましょう。

フロー効率・リソース効率の定義とトレードオフの仕組み

前提

適宜発生するタスクを、1人以上の人が処理していくような状況について考えます。
タスクを処理する人の事をリソースと呼びます。
各リソースは適宜タスクに割り当てられ、タスクは時間を経て消化されていきます。
タスクが発生してから、そのタスクが着手されて完全に消化されるまでの時間をリードタイムと言います。
ここでは、このように時間をかけて決まったリソースでタスクを消化していくようなモデルについて考察します。

より沢山のタスクを、より短いリードタイムでこなせることが効率の良さという事になりますが、タスクとリードタイムそれぞれの観点で別の効率を定義できます。それがリソース効率とフロー効率です。

今後この記事では、添付のような図でタスクと所要時間を表現します。

図のオレンジの箱が、一つのタスクを表現しています。タスクの実施にかかる所要時間を横幅で表現しています。これは一つのタスクの場合で、今後の図には複数のタスクが出現する場合があります。

フロー効率とは

あるモデルにおいて、各タスクの作業量をリードタイムで割った値をフロー効率といいます。
例えば、実作業時間が2時間のタスクについて、タスクの発生から完了までにかかる時間が4時間であったとすれば、そのタスクのフロー効率は2/4=1/2です。先程の図では、作業量が2、所要時間が2でフロー効率は1という事になっていました。次に示す図では、フロー効率は1/2=50%となります。

リソース効率とは

あるモデルにおいて、各リソースが単位時間に処理できるタスクの平均量のことをリソース効率といいます。
特に、あるリソースについて【稼働しているときは常に同じ作業速度で作業をする】と仮定すると、リソースの稼働率、つまりリソースがタスクに取り組んでいる時間と一致します。
例えば、勤務時間が8時間の人がうち4時間作業していたとすれば、リソース効率は4/8=1/2です。
※この1/2という値を見てむむむ?と思った方、ぜひ続きをお読みください。

例1)1人がタスクを処理するときの、フロー効率とリソース効率の比較

ここで、簡単なモデルとして、1人の人が、時系列的に発生するタスクを処理していく場合について考察します。
tを時刻として、t=0の時点でタスクが2つ存在していて、以降t=1で1つ、t=2でもう1つ、t=3でさらに1つ、...とタスクが1つずつ増えていくものとします。
Aさんは、このタスクを発生した順番に処理することにしました。この様子を図で表現すると次のようになります。

t=0の時点ではタスク0とタスク1が存在していますが、同時に2つのタスクには着手ができないので、Aさんはタスク0から順番に処理していきます。そうすると、これらのタスクはすべて発生してから一定の待ち時間を経て処理される事になるので、各タスクのフロー効率は常に1/2=50%になります。
また、全体のフロー効率というものを、(作業時間の合計)/(所要時間の合計)と考えると、全体のフロー効率もまた50%になります。ここで、タスク0には待ち時間がないので、実際には50%より高くなるのでは?という考えもあるのですが、処理するタスクの量が増えればこの誤差の部分は無視できるため、全体のフロー効率は50%と考えて差し支えありません。

さて、このとき、同じモデルを少し違った図で整理してみます。今はタスクを一つの行として整理していたのですが、リソースを一つの行として整理し直すと、次のような図を描くことができます。

リソース効率は、この図でいうとオレンジ色の領域の密度となります。Aさんには暇な時間は全く無いので、この場合のリソース効率は100%です。
このように、フロー効率とリソース効率は、同じモデルに対してタスクに注目して定義したものか、リソースに注目して定義したものか、という違いを持つ"効率"になっています。

ちなみに、いまはリソースに注目した図についてもオレンジ色でAさんの作業を塗り分けしましたが、この図だけを見るときは以下のような塗り分けの方が理解が進むかもしれません。

ただ、今回の場合は2つの図の間でオレンジ色の意味を統一した方がわかりやすいかと思い、そのままにしました。

例2)Bさんの場合

同じく最初にタスクが2つ存在して、その後1つずつ増えていくモデルで、今度はBさんがタスクを処理する場合について考えてみます。Bさんは、なんと最初に存在するタスク0に全く着手せず、代わりにタスク1、タスク2、タスク3、...を進めていくような作業の進め方をします。
これを図式化すると、以下のようになります。

実際にはこのようなタスクの進め方は許されない可能性もありますが、このタスクの進め方には面白い点があります。それは、タスク0以外のすべてのタスクのフロー効率が100%になり、かつリソース効率は100%のままで、しかし全体のフロー効率は50%のままである、ということです。
なんと、タスクの処理の仕方を変えるだけで、個々のタスクのフロー効率はこのように変化してしまいました。タスク0を無視できるとすれば、すべてのタスクのフロー効率が100%になり、ある意味で非常に効率的なタスク処理という事になります。

実際にこのようなやり方ができるかはタスク0の性質によるでしょうが、私はかつてAさんのような仕事の仕方に近い状態になってしまい、「一つ最初に失敗してしまっただけで、連鎖的に後続のすべてのタスクが遅延して、顧客からずっと不満に思われ続ける」という現象を経験したことがあります。私の場合は、このタスクはシステムのリリースでした。システムのリリースが色々な事情によりずれこんでしまい、お客様の評価が下がるのですが、後続の機能リリースもずっとずれ込んでしまうため、その報告をする度にお客様は不機嫌そうな顔をするのです。Aさんのように、最初にずれてしまった状態を仕切り直しできないと、永遠にフロー効率が悪くなり、それによって評価も下がり続ける。この継続的な評価の下がりが、「最初に1つ余分なタスクが存在する」というだけで発生するのはとてもおもしろいです。
また、現在はBさんのような状況によく出くわします。急ぎのタスクが発生した時に、発生した順番にタスクに対応するのではなくて、優先度の高いタスクは発生と同時に処理して、優先度の低いタスクは空いた時間で対応するというようなタスク消化戦略です。これは現場で必要になったので取り入れた戦略ですが、数理的にこのような裏付けができるとは思いませんでした。

さて、話を戻すと、このようにリソース効率は100%を維持したままでフロー効率を変えることができてしまいます。ただし、当然ですがそうでない場合もあります。

例3)コールセンターのフロー効率とリソース効率

コールセンターでお客様の電話をさばく仕組みも、多数のタスクを複数人で処理する仕組みとして捉えることができ、従ってフロー効率とリソース効率の概念を考えることができます。簡単のため、お客様の電話はすべて一度の電話で解決するもの、従って折返し電話などは発生しないものとしましょう。
この例におけるフロー効率については、お客様が電話をかけて、待ち時間があって、オペレーターにつながって話をして、要件が終わるという一連の時間から算出ができます。つまり、一つの電話の中で
フロー効率=(応答中の時間)/(オペレーターが出るのを待つ時間+応答中の時間)
です。
一方、リソース効率は、あるオペレーターがお客様から電話がかかってくるのを待つ時間と、応答中の時間から算出できます。つまり、一人のオペレーターについて
リソース効率=(応答中の時間)/(電話がかかってくるのを待つ時間+応答中の時間)
という事になります。

この例において、顧客満足度を上げようと思うと、フロー効率を上げる(待ち時間を短くする)ことが必要で、そうするとリソース量を増やすことになります。というのは、もしオペレーターの人数が十分にお客様を捌ける数であったとしても、お客様が偶然一時的に集中してしまった場合には、そのお客様には待ち時間が発生してしまうからです。お客様が集中した時にも待ち時間なく捌けるようにするためには、当然ですが、単に定常的にお客様を捌ける数よりも多くのオペレーターが待機する事になります。そうすると、一人のオペレーターが電話に出ていない時間も長くなるので、リソース効率は下がるという事になります。
逆に、(定常的にお客様を捌ける範囲で)リソース量を少なくすれば、混雑したときには待ち時間がすごく長くなる可能性もありますが、リソース効率的には効率よく捌ける事になります。

この例の場合には、フロー効率とリソース効率の間にトレードオフが存在することになり、そのトレードオフはリソースの増減によってもたらされるという事になります。
ちなみに、一般論として、リソースの増減の代わりに単位時間あたりに消化される作業量を増減させることができる場合には、それを増減させることでも同様のトレードオフが生まれます。この例で言えば、お客様が電話をかける総量が減ると、相対的にリソースを増やしたのと同じような状態になるので、フロー効率とリソース効率の間に同様のトレードオフが発生するということです(電話がかかってこなくなると、オペレーターが働く量は減るので)。

アジャイル開発の文脈では、リソースや単位時間あたりに消化される作業量は変わらない

さて、ではアジャイル開発の文脈では、この例1・2と例3のどちらがシチュエーションとして近いでしょうか?
答えを述べてしまうと、例1・2の方です。というのは、アジャイル開発におけるリソース=開発者について、電話の待ち時間と同じような意味での待機時間というのは存在しなくて、常に何らかの作業やタスクは実施している状態にあるのが自然だからです。もちろん、休憩などの時間はあるでしょうが、それはどんな作業にも付随する休憩なので普通にタスクをこなすために必要な時間であって、電話オペレーターのようなタスク待ち(電話待ち)による本質的な待ち時間が発生することは基本的にありません。
同様に、コールセンターの設計論のように、開発者を増やした時に「タスク待ちによって」リソース効率が下がるのかというと、そうでもないでしょう。発生するタスクの量が少ない場合にはそういった事もあり得るでしょうが、アジャイル開発の現場でそのようなことは稀であると思います。
そのため、アジャイル開発の文脈で「フロー効率を求めるのはリソース効率とのトレードオフになる」というのは間違いであり、リソース効率は関係ないです。

ただし、フロー効率を高めようとする事でテストやデプロイなどのタスクがより多く発生して、それによって「リソース効率は変わらないが、作業が増える」という形でのトレードオフが発生する場合はあります。そうすると、例えば人件費などは増える可能性があるので、そのような現象を持って漠然と「フロー効率を上げることで、得られる"成果"に対してリソース効率が悪くなる」といった解釈をしてしまう場合があります。"成果"に対してコストが増える可能性があるというのはそのとおりですが、それはリソース効率の問題ではなくて、作業が増える事による問題です。そのため、実際に打つべき対策も「リソース効率を高める」という事ではなくて「追加される作業を減らす」というような対策になります。例えば、自動テストや自動デプロイを充実させる、ということです。これはリソース効率を高める手段ではなく、デプロイを細かくしてフロー効率を高める際に発生する作業を減らす(あるいは機械に対応させる)手段です。

以上、ここまででフロー効率・リソース効率とトレードオフの構造について説明しました。
しかし、まだアジャイル開発におけるフロー効率について十分に解説できていません。というのは、実はアジャイル開発におけるリードタイムの待ち時間は、実装前ではなく実装後であるという事についての説明ができていないからです。上記の例1・2と例3で比較すれば、例1・2の方がまだ実態に近いのですが、しかしアジャイル開発の場合は待ち時間が後ろにあるという事と、デプロイしてはじめて価値が生じるために、実装後にデプロイしていない状態は価値を放棄している状態と同じという事が構造的に異なるので、以降で詳しく説明します。

アジャイル開発におけるフロー効率の定義

フロー効率と対になるリードタイムは何なのか・リードタイムの構造

アジャイル開発において、リソースを開発者とするなら、リソース効率は開発者の稼働率(原則として作業時間の100%、休憩等は作業に含める)として定義ができます。では、フロー効率を定義することはできるのでしょうか?
実は、ソフトウェア開発一般で通用する唯一無二のフロー効率の定義、のようなものはありません。というのは、フロー効率を定義するにはタスクの発生と完了を定義する必要がありますが、その発生は具体的にいつのタイミングとすべきか、非常に難しいからです。
それは、要求が発生したタイミングでしょうか?要件定義が完了したタイミングでしょうか?それとも、WBSを作ったりタスクとして定義されたタイミングでしょうか?はたまた、作業に着手したタイミングでしょうか?
そこで、ここでは現実に機能している指標値である Four Keysを参考にしてみます。これが絶対的な定義という事ではないですが、これを元に考察する事が大外れではないであろう、ということです。

さて、Four Keysの中には、次のような指標値があります。

変更のリードタイム - commit から本番環境稼働までの所要時間

この「変更のリードタイム」を、フロー効率の定義に用いる事にしたいと思いますが、この値は非常に示唆に富む値です。というのは、このリードタイムにおいては、commitまでの待ち時間は考慮外となっていて、commitされてからの値だけが対象となっているからです。
一般には、1つのcommitだけで直ちにデプロイされるとは限らず、commitから本番環境稼働までには、別のcommitが含まれることになります。例えば5のcommitで1つのPRを構成してデプロイする事を考えると、
1番目のコミットについてのリードタイム=2番目の実装時間+3番目の実装時間+...+5番目の実装時間+5番目の実装後の純粋なデプロイ完了までの時間
という事になり、1番目のコミットについてのリードタイムは少なからず実装の時間を含むことになります。これらの平均を取ると、ざっくりと

1つのPRについての平均リードタイム = (実装時間の平均)/2 + 実装後の純粋なデプロイ完了までの時間

という近似ができ、これまでに考察した例におけるリードタイムとは対象的に、実装が完了してから待ち時間があって、最終的にタスクとして完了する、というような構造となっています。

この場合には、フロー効率は

((実装時間の平均)/2) / ((実装時間の平均)/2 + 実装後の純粋なデプロイ完了までの時間)

と考えられます。このフロー効率を高めるというのは、実装後の純粋なデプロイ完了までの時間を短縮するということです。これは当然ですがリソース効率とは関係ありません。

なぜフロー効率を上げるべきなのか

ここまで、アジャイル開発におけるフロー効率の持つ性質と実態について解説しましたが、フロー効率を上げるべき理由については説明しませんでした。
今更ですが、なぜフロー効率を上げるべきなのか、という事を述べます。

まずひとつは、身も蓋もないですが、Four Keysでそれが指標として挙げられているから、です。
つまり、理論的な事とは無関係に、様々な分析の結果として開発の高パフォーマンスと相関性の高いデータとしての裏付けがあるので、フロー効率を上げるべきという事があります。

もうひとつ、定性的な説明をするとすれば、ソフトウェアの実際の価値はデプロイ/リリースまでは生じないので、機能実装が完了してからリリースされるまでの間は単にその価値を放棄しているのと同じ状態になっており、早くリリースすることでその状態を脱して価値を増やせるからです。
(これは広く一般に言われている事と同じかと思います)

まとめ

この記事では、アジャイル開発におけるフロー効率について、その考え方を説明しました。
「それで結局何をしないといけないのか」という事については、冒頭にまとめたとおりで

  • ソフトウェアはデプロイされた時点から顧客に価値を提供するようになるので、他にしがらみが無ければフロー効率を上げた方がよい
  • アジャイル開発の文脈で、フロー効率とリソース効率は多くの場合トレードオフの関係にない
  • ただし、フロー効率を上げようとすると、そうでない場合に比べて追加タスクが発生する可能性はあり、リソース効率とは無関係にある種のトレードオフはある
  • 追加タスクの量は自動テストや自動デプロイで減らして、トレードオフをある程度は解消できる

という事になります。あまり居ないかもしれませんが、私のようにフロー効率とリソース効率のトレードオフってなんだ?このシチュエーションで本当に発生するのか?といった"どうでもいい"事で悩まれた方には、役に立つ記事になったのではないかと思います。
もしお気づきの点があれば、ぜひお気軽にコメントください。私としては、必ずしもうまく書ききれていないと思う部分もあり、また説明や定義もオリジナルな部分があるので、間違いがあればブラッシュアップしていければと思っています。

Discussion