私たちのチームが生産性をあげた取り組み

どうも、スペースマーケットでエンジニアリングマネージャーをしている人です。

みなさん開発してますか？
エンジニアですから…してますよね！？（煽り）

最近私たちのチームでいくつか取り組みをしてみたのですがどんどん生産性が上がっているのでそのお話をしたいと思います。
これで皆さんのチームも良くなるかは分かりませんが、参考にしていただければと思います。

※こちらの記事はZennのPublicationにも投稿しています。ご了承ください。

## チームの課題を見つける
まずはチームの課題を見つけるところから始めました。
何をするにもチームの生産性を上げるためにはその中での課題を見つける必要があります。

ちょうど3月に新たなEMが誕生したので、チームを分割し2つのチームに分かれました。

そのタイミングで改めて新しいメンバーの課題点を洗い出してみました。

弊社ではFindy Team+を導入しております。

Findy Team+を使い直近半年のデータからどんなところに課題がありそうか。
そこからどのようにしていくかを考えてみます。
今回はいくつかの観点で見る指標を決めています。

- アウトプット量
  - デプロイ頻度
  - プルリクエスト作成数
  - コーディング延べ日数
- アウトプットの質
  - 1プルリクエストごとの変更行数
  - 1プルリクエストごとの変更ファイル数
- サイクルタイム
  - コミットからオープン
  - オープンからレビュー
  - レビューからアプルーブ
  - アプルーブからマージ
- リードタイム
  - 変更のリードタイム
  - 自分が最初のレビューをするまでの平均時間

アウトプット量はどのくらい開発にコミットできているかという観点で選んでいます。
それに対してどのくらいの質でアウトプットできているかという観点で変更行数やファイル数も見ています。
またそのアウトプットを出すためにどのくらいのサイクルタイムだったりリードタイムがかかっているかを見ています。

組織によっては見るべき指標は異なると思います。
まずは確認できるすべての数値を見て課題を洗い出すというのも一つの手です。

### 半年のデータ推移
まずは過去半年のデータを月間ベースで確認しました（実際のデータをお見せはできませんが）。
半年推移で見ると以下のようなことがわかりました。

- 一人当たりのプルリクエスト作成数が概ね10件を下回る
- 変更行数は概ね300行から500行の間
- コミットからオープン、レビューからアプルーブまでの開発サイクルタイムが他の指標に比べて長い
- 自分が最初のレビューをするまでに半日〜下手すると2日程度日が空いている

一旦このような状態であることが分かりました。

特に「自分が最初のレビューをするまでの平均時間」に課題を感じました。
データとしてみると他の時間が10時間を超えていたりするため、時間という軸ではあまり大きく見えません。
が、実態としてレビューするまでに4時間かかっていたら、1日の稼働時間に対して半日も時間がかかっているということです。
1プルリクエストに対して半日も時間がかかっていると
「レビューが返ってくるの時間がかかるから一通り実装が終わったらレビューに出そう」
という思想が働いてしまうことが分かります。

実は一番筋が悪いポイントだと思っています。
レビューが返ってこないと1プルリクエスト単位での変更行数が増えます。
変更行数が増えるとレビューがコストになります。
レビューがコストになると「あとで見ればいいや」という考えが広まった状態になります。
全てが悪循環なわけです。

また、これだけにとどまらずレビューで手戻りがあった場合も変更箇所が多いために直す範囲が広がります。
私もよくやるのですが、変更行数が多いと1度のレビューで全てコメントを上げるのは難しいです。
「まず根本的にここがまずいから直してもらおう、残りのコメントは今しても変更されるだろうからまた仕上がったタイミングでチェックすれば良いか」
といった形でそのレビューが2回以上の往復をする前提で考えていたりします。
また、そもそもですが変更行数が増えれば増えるほど認知の限界を超えてしまうのでそのレビューが正しいかも検証が難しくなります。

こうなってくるとレビューが正しく機能しなくなっていきます。
組織に「レビューがコストになっている」という雰囲気を生み出さないためにもここの改革は必要になると考えています。

### 組織全体との比較
次に組織全体との比較をしてみます。
1チームあたりの推移を全体の平均と比較することでどこに課題を見出すべきかわかってくるはずです。
この分析の中では以下のような課題が見つかりました。

- プルリクエストは全体と比較してかなりビハインドしている
- レビューからアプルーブまでの時間がかなりかかっている

プルリクエストはかなりビハインドしていることが分かりました。
組織全体が平均値で出されているので概ね自分たちのチームがここの数値を下げている可能性が高いです。
量が出せてない理由は2つです。

- 1プルリクエストあたりが大きすぎる
- 純粋に開発にコミットできていない

実際のところ2023年12月からQAを担当しているメンバーがいてこの期間は開発にコミットできていません。
メンバー自体もプルリクエスト作成数で目標を持っていたメンバーもいましたが、テストにコミットしているため目標値を調整していました。
ある程度加味はすべきだと思います。
しかし、テストしているから開発できませんでは本質的に組織全体としてリリースを増やしていきたい（＝開発速度をあげていきたい）という課題を解決できているとは思えません。
また、まだまだスキルを伸ばしていけるメンバーがコードを書くというところにコミットできていないのも問題です。
もちろんテストという領域もできるようになって欲しいですが、今回で一通り経験できたという点も踏まえてよりコードを書いて成長してほしいというのがマネージャー心というものです。

また、レビューからアプルーブまでの時間がかなりかかっていることもわかりました。
この場合考えられるのは下記です。

- レビューしてもらえるまでに時間がかかってしまっている
- 手戻りが多く発生していてコメント修正に時間がかかっている

1つ目は先ほど書いた通りレビューするまでの時間がだいぶ長いのでそこに課題があることはわかっています。
もう1つも結局のところ1プルリクエストあたりの修正量が多く、その分手戻りの修正に時間がかかっているのだろうというのが想像できます。
この点は改善の余地がありそうです。

他にもいくつか考えるべきポイントもあると思いますが、まずは個々の改善をしていくことを目標に取り組む方が良さそうです。

## 目標の設定
さて、課題がいくつか見つかったので目標を考えます。
定量的な数値目標としてここの達成をゴールにしてみます。
今回立てた定量的な目標は以下の指標としました。

- 1人あたりのプルリクエスト作成数
- 1プルリクエストあたりの平均変更行数
- 1プルリクエストあたりのサイクルタイムのうち下記2つの指標
  - コミットからオープン
  - レビューからアプルーブ
- 自分が最初のレビューをするまでの平均時間

実際の数値はここでは書きませんがこの5つの指標を追うことを目標にしました。

### 1人あたりのプルリクエスト作成数
こちらは言うまでもなくコードを書くと言うことにコミットして欲しいと言う期待値を込めました。
一旦目標値は組織全体の数値を基準にしてみました。
私たちのチームが目標達成することで平均値は上がりますが、まずは直近半年の平均値を目指すと言うところにおいています。

またプルリクエスト作成数は個人レベルでは目標を持たせないようにしています。
これは開発のフェーズによってはテストをしたり、設計をしたり、インフラの環境を作ったりとGithubで計測できること以外のこともする可能性があるためです。
しかしそれでもコードを書くと言うところにコミットしていかなければチームの生産性は上がりません。
なので、まずはチーム全体の1人あたりの数値を持ってもらうことにしています。
このようにすればいろんな役割の帽子に被り変えて活躍できます。
もちろんですがそれぞれで数値を持ちたい！と言う方にはその数値を持たせています。

### 1プルリクエストあたりの平均変更行数
こちらは読んで字の如くです。
そもそも組織全体の方が変更行数は大きいですが、変更行数が小さいけどプルリクエストが作れていないというのがチームの状態なので、より小さくしてプルリクエストを作るというところから始めてもらっています。

### 1プルリクエストあたりのサイクルタイム
こちらは2つの指標に絞りました。
コミットからオープンは要は1つの開発をどれだけローカルで蓄えているかと言う話なので、これをもっと早くプルリクエストという形で成果物をあげて欲しいためピックアップしています。
レビューからアプルーブは手戻りを少なくしていこうという期待値を込めています。

### 自分が最初のレビューをするまでの平均時間
こちらは先ほど散々話したところです。
正直1日以上かけているのはだいぶ問題があるので、半日以下を目指してもらいます。

## 生産性をあげるための取り組み
さていくつか目標を立てましたが「じゃあこれに向けて頑張りましょう！」で数値が上がるのであれば誰も困りません。
実際にどんな取り組みをしていくか方向性を考えてそこに取り組んでいかなければいけません。

そこでどんなことに取り組みを行ったのか紹介できればと思います。

### バックログリファインメント中により実装の具体の話を深掘りし実現方式への解像度を高める

*期待する数値：1プルリクエストあたりのサイクルタイム*

突然ですが弊社ではスクラムを取り入れています。
毎週火曜日は終日スクラムイベントを行い、その中でバックログリファインメントも行います。

バックログリファインメントではおおよその見積もりを決めるストーリーポイントも入れています。

実はここが課題ではないかと考えたというのが一番の大きな部分です。
これまでのチームではリードエンジニアがいたのでそこの話に合わせてポイントを入れていた可能性があります。

「このプロダクトバックログアイテム、よくわからないけどあの人が言っているしそうなんだろう」

という形で納得感のない状態で見積もりをしていたということです。
実際メンバーに聞いてみたらそのようなことも何度かあったと聞いています。
まずはこの状態を解決していきます。

リードエンジニアであれば概要レベルの話でも実装イメージは固まっているはずでここまでする必要はありません。
しかしリードエンジニアだけではないので、私たちはリファインメントを行う際により詳細の話まで行うことにしました。
Figjamなどの可視化できるものを使い、どのようにデータが流れるのか、どのように処理を行うのか、そこで気をつけるべきポイントなどを議論するようにしています。
また、その時点でユーザーストーリーやAC（Acceptance Criteria）に不足があればそのタイミングで見直しも行います。
そうすることで開発に入る前の段階で何をすればいいか明確になります。
開発に入る前で解像度が高くなれば、そのあとのプランニングでもタスクは小さくできますし、タスクが小さくできているということは迷わずにコードを書けるということです。

そうすると「コミットからオープン」というプルリクエストを立てるまでの時間は短くなります。
また大前提を全員で認識合わせできているため、レビューで手戻りもなくなります。
その結果「レビューからアプルーブ」までの時間も改善するはずです。
そのためこの取り組みを行うことでサイクルタイムは全般的に改善することが分かります。

### 1タスクチケットは1プルリクエスト単位で作成する

*期待する数値：1人あたりのプルリクエスト作成数 / 1プルリクエストあたりの平均変更行数*

弊社ではJIRAでチケット管理をしています。
プロダクトバックログアイテムを作ったあとスプリントプランニングの場でプロダクトバックログアイテムをより詳細にしていきます。
実はここにも課題があります。

これまではよく「実装」というチケットを切られることが多くありました。
実はこのチケットがあることでタスクが終わらない原因を作っています。

実装というチケットがあった時2人のエンジニアがいました。
1人はリードエンジニア、1人はジュニアのエンジニアです。
リードエンジニアなら「実装ということはここのACがこうだからこことここをこうすれば良いな」ということを考えながら実装できます。
反対にジュニアのエンジニアは「何から手をつければ良いんだろう」という状態に陥ることが多いはずです。
最初は分かるところからやっていくのですが、次第にどうしたら良いかわからなくなりなかなか成果物が出せないという状態に陥ると思います。
悪循環ですね。

また実装という単語のままだとチケットを作った人、またそのチケットを作る際その場にいた人なら文脈はわかりますが、そこにいなかった人には伝わりません。
「このチケットはあの人が進めていますが今日休みなので明日確認しましょうか」
というやりとりを朝会の中でしていませんか？
その人が例えば流行りの感染症でもう数日休まなきゃいけないとなったらそのタスクはなかなか終わらなくなります。
これは非常に不健全な状態で、誰でもチケットを取れる状態にしておくことが理想です。

ということで1タスクチケットを1プルリクエスト単位にします。
1プルリクエスト単位は1つの関心ごとの変更を行なったプルリクエストのことです。
例えばユーザー登録機能を作るというプロダクトバックログアイテムに対しては、

- フォームを作る
- フォームの内容をSubmitする
- エンドポイントのIF部分を実装しモックのレスポンスを返すようにする
- 入力内容のバリデーションを追加する
- リクエストされた値を基にデータベースへユーザー登録できるようにする
- 画面から一連の動作を実行できるかテストを行う

といったあたりでしょうか。
チームによってここの粒度は違うと思います。
もっと小さくても良いと思いますが概ねこのようにチケットが作られると思います。
実装という大きなチケットではなくなったので、複数人で作業分担もできますしこの単位でプルリクエストを出してもらえれば比較的小さい変更行数でレビューができるようになります。

もちろん小さくしたからプルリクエストも増えます。
それが本質的なのかというのは議論すべきです。
当然組織全体としてそのような取り組みをしていないので、これでやったら目標値が低いのでは？と思うくらいですが、まずはベースを作るために組織全体と同じ数値にしています。
この取り組みをしていき基準値を上げていくことでより開発が早くなっていくと考えています。

### プルリクエストは他のタスクより最優先でレビューを行う

*期待する数値：自分が最初にレビューするまでの平均時間*

上の2つの取り組みをしていくとそもそものプルリクエストが小さくなっていきます。
そうするとどうでしょう。
レビュー自体にかかる時間も下がっていくはずです。
1000行のプルリクエストには1時間もかかりますが、10行の修正をレビューするのに5分も時間はいらないはずです。
そのため優先的にレビューをしていこうというのが今回の取り組みです。

レビューが早く帰ってくると次のタスクに取り掛かる前、少しお手洗いに行って戻ってきたらもう返信が来ている状態です。
コンテキストをスイッチしなくて済みます。
修正があったとしても変更量も限りなく小さいのですぐに直してすぐにレビューをもらえます。

要はこれレビューと言っていますが、早くフィードバックをもらおうねという話です。
よくある仕事術の100%を目指すより60%でまずはフィードバックもらおうというのと一緒です。
小さい変更量であれば100%にするのも容易です。
1000行を100%に持っていくのはすごく時間がかかりますが、10行そこらであれば大してかからないという話です。

当然最優先と言っていますが会議中だったりタスクを進めている最中は難しいこともあると思います。
しかし1タスクチケット自体が小さくなっている、会議だって長くても1、2時間で切れ目が来るはずです。
なのでこれまで半日以上かかっていたレビューが1、2時間程度、これだけでも半分の時間です。
もっと早くすればより開発の速度が早くなっていきます。

依頼した側も依頼された側も、レビューがコストではないと感じるようになってくればより心理的な安全性も担保されていきます。

このように良い循環をつくるために3つの取り組みをしていこうとチームで決めました。

## 取り組みの結果
それじゃあどうなったかというとまだ期間は短いですが実際にすぐ効果が出ました。
特にプルリクエスト作成数は大幅に改善し組織全体の数値と同じくらいに改善しています。

上記はあくまで定量的な面での計測ですが、実際にメンバーから上がってきた声もやってよかったという声ばかりです。

「これまでレビューで手戻りが多くなかなかタスクを完了にできなかったが、最近は1日に複数のチケットを進められるようになって楽しくなってきた」
「レビューがすぐ返ってくる、しかも修正もほぼなし、あってもちょっとだけの修正でLGTMをもらえるのでタスクを進めやすい」
「チームの数値もそうだが個人単位でも見違えるほど色んな数値が改善していて達成感を感じられている」
「これまでは自分が関わってないタスクは取りづらく、チームでやっている感があまり感じられないという場面もあった。最近はどのバックログも実装イメージがついていてタスクも小さくなっているので終わらない時は手を挙げて取れるようになった」
「他の人がどんなところで困っているのか分かって手伝える機会が増えた」

など声があがっています。
マネージャーから見ても以下の点で変化を感じられることが多いです。

- スキルごとに得意不得意があってアプリケーション全体が不透明だったメンバーの解像度が上がっている
- 数日動かないまま放置されているタスクがなくなった
  - 基本1日で複数チケットが動く状態になった
  - 反対に動かないとそこに対して声掛けがされるようになった
- タスクの協業が増えた
- バックログ自体も小さくする動きが増えてきた

## さいごに
まだまだ初めて3、4週間程度なので今後もさらに改善していくと思うと非常に私たちのチームは楽しみに感じています。
もちろんチームの状態に応じて取り組むべき内容は異なると思いますがみなさんのチーム、組織の参考になれば幸いです。