LLMへの移譲レベルを段階的に上げて、開発生産性を最大化する

はじめに

こんにちは!カイポケコネクトの開発推進チームでエンジニアをしている@_kimusonです。

私たちのチームは、ストリームアラインドチーム*1の生産性向上をミッションに持つチームで、その文脈で生成AIの活用にも取り組んでいます。

LLMを使った開発が当たり前になってきて、実際に生産性が上がる側面を実感している一方で、できることが多すぎるが故に夢が広がりつつも、現実では壁も多くて難しいポイントが多いのも事実です。人間の作業がボトルネックになってしまい、思ったほど生産性が上がらないという課題にもぶつかります。

このエントリでは、生産性向上をゴールに、AIをどう活用していくのが良いかの整理と、私たちのチームで実際にどういうコンセプトでAI活用を進めているのかを紹介したいと思います。

LLMへの移譲レベルを定義する

AIエージェントを活用して仕事をするということは、仕事の一部をLLMに権限移譲するということです。

したがってLLMとの責務の境界を明確に意識しておくと良いだろうなと思っています。

ここでは、チーム開発でよく使われるDelegation Poker *2 の移譲レベルの分類を借りて、人間とAIエージェント間の責務の移譲レベルを分類してみます。

よくあるLLMの利活用シーンと対応する移譲レベルは下記のように対応します:

流れ 移譲レベル 主体
ChatGPTに設計について相談し、自分で実装 Consult 人間
Copilotの補完を使いながら、自分で実装 Consult 人間
細かい指示を出しながらエージェントが実装。Driver がエージェントなモブプロ Agree 人間 & LLM
LLM にチケットを渡してPRまで作ってもらう Inquire LLM
LLM にチケットを渡してPRを作ってもらい、LLMによるレビューでマージまで完結 Delegate LLM

ConsultレベルではあくまでLLMに相談をするだけなので主体は常にわれわれ人間です。AgreeレベルになることでLLMも共同で責務を持ちますが、われわれ人間も一緒に作業をすることになります。

この辺りまでの活用が現実的に多く行われている・採用されやすい移譲レベルだと思います。

そこからさらに移譲レベルを上げていくと

  • 最終レビューはするけどタスクの主体はLLMに移譲されているInquireレベル
  • さらにはわれわれ人間による承認さえ不要なDelegateレベル

に到達することなります。

移譲レベルがなぜ重要か

まず大前提として、コーディングを初めとしてタスクの作業時間はわれわれ人間よりLLMの方が圧倒的に早いです。物理的な速度もそうですし、LLMは並列で作業を進めることも可能です。

生産性を上げるには、ボトルネックを解消していくことが大切であり、作業がLLMのほうが高速だからこそ移譲レベルを上げていくことでボトルネックが解消し、移り変わっていきます。

  • Consult / Agree レベル: 人間の作業時間がボトルネック
    • 人間が必ずつきっきりで作業する必要があるため
  • Inquire レベル: 人間の認知負荷がボトルネック
    • 人間が変更内容を認知し、責任を持ってマージする必要があるため
  • Delegate レベル: 人間のチケット生成速度がボトルネック
    • 理論上すべてがDelegateなら、お金が許す限り24時間開発を進められるが、チケットの方が足りなくなるはず

つまり、生産性を上げるには、LLMへの移譲レベルをいかに上げていくかがポイントになりそうです。

移譲レベルをどう上げていくか

アウトプット(アウトカムではない)の生産性だけを考えた場合、理想論で言うと、人間はボトルネックにしかならないのですべてのタスクをDelegateレベルで進めるのがベストです。

とはいえ、現実的には

  • クオリティコントロール
  • 方向性の維持
  • アウトカムにならない

といった側面を考えると、すべてを丸投げするのは無理があります(できたらシンギュラリティですね)。

現実的には、開発タスクの中で移譲レベルを上げやすいタスクを移譲していき、手離れさせた時間でエンジニアがより難しい問題にAgree/Consultレベルで協業することで生産性を高める のが良いと思っています。

より具体的には

  1. 主要なエンジニアのタスクを分類する
  2. 丸投げビリティ *3 を評価し、どのタスクをどの移譲レベルに持っていけるか評価する
  3. DelegateやInquireレベルに移せるタスクを移譲していく

という流れで方針を作っています。

丸投げビリティという指標

LLMに丸投げしやすいタスクを定性的にでも評価できないと、どのタスクを移譲すべきか判断しづらいです。

個人的には、以下のような観点で評価できそうだと考えています。

最悪壊れても良いか

ワークフロー設計でアウトプットを安定させるのは前提としても、LLMなので(まあ人間でも同じですが)一定のミスは許容せざるを得ません。それがどの程度許容できるかという観点です。

例えば、CIの設定ならまあ壊れるときもあるよね、という許容度があると思います。一方で、本番機能のコアロジックだとそうはいきません。

LLMでどれだけ期待値ラインに近いアウトプットを出せるか

ふわっとしていますが、そもそもある程度見て「よし!」となるアウトプットが出づらいなら最初からAgreeでやれば良い、という話です。

個人的にLLMが解けるかはコンテキストがすべてだと思っています。暗黙知でコンテキストに含められない、デカすぎて含められない、といった制約がなければ、情報の集め方やワークフロー設計を適切にチューニングすればある程度どうとでもなる気はします。

チーム内での相対的な指標としてはStorypointが使えるかもしれません。ただし、Storypointはチーム固有の基準なので、丸投げビリティの評価には定性的な観点も併せて考慮する必要があります。

その作業内容が自動化されることでどれだけ嬉しいか

一般的な自動化と同じ観点です。例えば年1でしか発生しないタスクに適用していきますか?という話ですね。コマンドの整備などにもコストがかかりますから。

私たちはこの考え方で評価をしていますが、「どういうタスクがLLMに丸投げできるか」の評価が行えていれば手段はなんでも良いと思っています。

例えば下記の記事では「生成されたコードを自分が読んでいない割合」が基準になるという考え方が紹介されています。読んでない=すでに移譲されている、ということなので丸投げできるよね、という話で、こういったシンプルな考え方もアリだなと思います。

移譲レベルの上げ方

タスクごとの移譲レベルの評価ができたら、あとは実際にLLMの責務を増やしていく必要があるので少し具体に踏み込んで、実際にどうやって移譲レベルを上げていくのかを紹介します。

Agree から Inquire へ

LLMへの移譲レベルを上げる=LLMに移譲する責務を増やす=コンテキスト分解が必須、というのがAgreeからInquireへの移行のキモだと思っています。

コンテキストウィンドウの物理的なサイズももちろんありますが、それ以上に複数のことをやらせるとわかりやすく性能が落ちます。

つまり、LLMでも単一責任の原則が重要であり、複数の責務を持たせるならオーケストレーションが前提になります。

エージェントが別のプロンプト(=責務)を持つエージェントを呼び出せる必要があります。Claude CodeはTaskツールとサブエージェントによってこれをサポートしているので、サブエージェントとコマンドを作成してみました。

作業イメージとしてはこんな感じです:

  • エンジニア: /inquire_xxx <チケットURL> の実装をして
  • Claude Code(Orchestrator)
    • use: オーケストレーションスキル
    • Claude Code(context-collector): 情報収集
    • Claude Code(architect): 設計
    • Claude Code(engineer): TDD実装
    • Claude Code(reviewer): レビュー×N
    • Claude Code(pr-creator): PR作成 & CIチェック
    • Claude Code(QA): 動作検証
    • → レポート

単一の責務を持つエージェントが協業することで質の高いアウトプットは出やすくなりますが、手離れする以上、期待と異なる場合に止めることができないので渡せる難易度に限界はあります。

Inquire から Delegate へ

Inquire時点で実装面は移譲されているので、Delegateへの壁は大きく2つあります。

  • GitHubにおけるマージブロックをどう適切なタスクでのみ回避するのか
  • AIレビューでどう品質保証するか

前者は、Delegateレベルで移譲できる対象のソースコードに対してCODEOWNERSでオーナーをもたせることでエージェントによるレビュー及び承認・マージを行うことができます。

後者は、「エンジニアがコードレビューで担保している内容」を言語化する必要があります。加えてタスクごとに観点が異なるはず(機能実装とCIの管理では観点ぜんぜん違いますよね)なので、タスクごとに個別で考える必要があります。

例: Renovate の Delegate 化

直近ありがたみが大きそうで取り組んでいるのがRenovateの手離れです。 下記は実際には運用されていない叩きですが、例えば1例としてこういった確認及びLLMによるオートマージが考えられます。

  • 0.x以外のpatchバージョンは変更内容をざっと読んで問題なければカジュアルにApprove
  • minor updateや0.xアップデートはClaude CodeにBreaking Changesを中心に影響範囲を調査してもらい、影響がないかを確認
    • 影響なし → Approve
    • 影響あり → Inquireレベルで修正を行ってもらい、エンジニアのレビューにフォールバック
  • Majorなどでもパッケージごとのルールで制御
    • Majorはデフォルトでは慎重に扱う
    • 例えば開発環境で使うパッケージはpnpm buildが通ればOKとか、グループごとに確認すべき内容を言語化。通っていればマージまでOK
    • アプリで使うパッケージでも、例えば副作用のないdate-fnsやes-toolkit等はCI通過を持って問題なしとできそう

こんな感じの確認がClaude Codeによって行われれば、Approve & マージして良いのではないか、という考え方です。

ここはチームでの合意形成がタスクごとに必要となります。例えばRenovateは上記のようなガイドラインを持ってマージOKとしてよいか、といった議論ですね。

並列で Inquire 以上のタスクを行う仕組み

Inquireレベルでゴリゴリのタスクを進めるのには一定の仕組みが必要です。

現状は私の開発マシンで1つのworktreeをClaude Code用に割り当て、手前味噌ですが私が作っている d-kimuson/claude-code-viewer *4のスケジューラ機能(cron式にマッチする時間で自動でメッセージ送信)を使うことで完全に手離れしたところで軽いタスクを実行しています。

LLM タスクのリファインメント

  • 上記で挙げた丸投げビリティ(定量的にはStorypoint、定性的にはACの充実度や内容)を言語化し、LLM自身に「やるべきタスク」「やらないべきタスク」を分類させる
  • Claude Codeに実施させるべきかの最終チェックは一応したいので分類された情報をみて、承認したチケットをQueueに積む

自動実行

  • Queueから定期的にチケットを取り出してinquireレベルでClaude Codeを実行

まとめ

LLMへの移譲レベルを整理し、私たちが現在取り組んでいるLLMによる開発生産性向上の考え方を紹介しました。

移譲レベル(Consult / Agree / Inquire / Delegate)を意識的に設計することで、エンジニアは本当に難しい問題・楽しめる問題に集中できるはずです。

実際に判断基準をより正確に言語化したり、一部のタスクをDelegateに移していくところはまだまだ私たちも取り組んでいる最中であり、チームでの合意形成を大事にしながら進めていきたいと思っています。

*1:チームトポロジーで紹介されているチームの分類の1つで、ドメインに沿って継続的にプロダクト開発を行うチームがこれに該当します。

*2:Management 3.0 で紹介されている管理者からチームへ権限移譲をするためのゲームです。権限を7つのレベルに分類し、移譲レベルの期待値をすり合わせます。この記事では人間からAIへの権限移譲の度合いを分類するために利用しています。

*3:タスクをLLMに移譲しやすいかどうかを評価する指標。造語です

*4:Claude CodeのGUIクライアント