CLINEを使ったアジャイルに次ぐ第3の開発手法、ハイウェイモデルを考えた話
- 2025年03月05日 0:39 タイトルを変えました。CLINEの話ってことが初見でわからず。
最初に:この記事で書きたいことの概要
- 新しい開発モデル:ハイウェイモデル型開発を考えたい。
- 開発手法といえば、以下の二つが有名。
- ウォーターフォール
- アジャイル / スクラム
- ここに新たに、Cline/Claudeを使用したハイウェイモデル型開発手法を考えたい。
- ハイウェイについて知りたい人は、WFとアジャイルの部分を飛ばしてほしい。
以前の開発モデルについて
各開発モデルでは、具体的にビジネス上、作業を円滑に進め、プロジェクトを成功に導くような方法が歴史の上で考えられ、提案されている。
ウォーターフォールモデル
ウォーターフォールモデル(以下WF)というのは、水が滝を通じて下に流れ、上に遡らない様を表現している。
WFモデルでは、基本的に過去のことは蒸し返して議論したりはしないというルールがある。(守られるかは別だが)
WFモデルの最も重要視していることは、「リソースには限りがある」という点である。だからこそ、決めたことはその決めた時点に対して元に戻さない。という原則を敷いている。それがなければ無限にリソースをつぎ込むハメになるからだ。
この開発手法には、予算と計画を立てやすいという利点が存在する。なぜならリソースには明確な上限を設定するという前提で動くため、そのリソース内で動くため、できることが予測しやすい。
しかし、同時に限界が存在してしまうという原理的な欠点が存在する。リソース配分は最初に決定してしまうがゆえ、突然の変更や要望に応え辛いという欠点だ。この欠点を補強するために生まれた戦術がアジャイル方式と呼ばれるものだ。
アジャイル開発モデル
アジャイルはWFを補強するため、リソースを最適かつ柔軟に配分することで、より品質の高い成果物を作成するために生まれた手法と私は認識している。
そのためには、チームの要員は訓練されている必要があり、高い不確実性をいかにしてハンドリングしていくかが課題となる。
WFは計画とビジネスの不確実性を減らすという方向にアプローチしているのに対し、アジャイルでは高い不確実性を代償に理想的なリソース配分による高品質を実現するアプローチになる。
第3の開発モデル、ハイウェイモデル型開発
近年、生成AIの進化は目覚ましいものがあり、Claude3.7 sonnetなどのLLMが台頭し、それをバックエンドにエージェント型AIのCLINEなどが話題になっている。それらを最適に利用して開発する手法を、ハイウェイモデルとして、提案したい。
ハイウェイモデル型開発とは何か
私がハイウェイモデル型開発と名付けた理由は、CLINEやclaudeといったコード生成AIが、開発におけるハイウェイ'(高速道路)となっていることが由来である。私たちは基本的に徒歩でプロジェクトをあっちこっち歩いて、完成のゴールへ向かっていっているのだが、Claudeというハイウェイを、CLINEという車で運転して走ることで完成へ早く到着できる可能性があるという話をしたい。
ハイウェイモデル型開発の開発ルーチン
- 顧客の要求(本当に解決したい問題)は何かを定義する
- 1に沿って要件を暫定で決め、clineがいつでも読める資料としてmdで保存する
- 実装を行う
- 2に沿って実装を暫定で決め、ワンショットでCLINEにMVPを作成させる。
- また、2に沿ってテスト書き、TDDベースで実装をCLINEに行わせる。
- FBを顧客から受けたり、実装して使ってみて改めて判明した必要要件などを再度定義する
- 新たな要件をもとに定義書を修正する。
- 新たな要件をもとにTestを修正する。
- 3に戻り再度実装、以下のルールを守りながら3→4→3→4を満足いくまでハイウェイ走破を繰り返す。
- 必ず再実装させる。追加や修正は絶対にしない。(理由はのちほど記載)
- 巨大モノリスPJにしない。
- 各機能、抽象化することを目指す
- 1ファイルを必ず200行以下にするように分割する
- PJが大きくなれば、機能をmodule化して1回の再生成イテレーションを小さくする
- 1イテレーションは半日以内で再構築できるように再生成範囲を分割しておく。
- レビュー行為はなるべくしない。最初に作った(orそれから修正した)Testが通ればOKとするにとどめる。
- 納期が許すまで5を行い、品質を高める。
ハイウェイモデル型開発の利点・欠点
利点
- なるべくハイウェイを利用することで高速にプロダクト開発ができる
- ハイウェイ利用時、なるべく人間の手から離すことでしょうもないミスを減らせる
- 認識違いによる手戻り
- ディスコミュニケーション
- 心理的安全性の欠如による非効率的な開発
-
納期を動的に設定できる (めちゃめちゃ強い)
- 常にイテレーション成果物が完成品として出力されるため、いつでも提出できる状態を維持できる
- それでいてかつ、納期が許される限り品質を満遍なくひき上げられるため、納期がいつでも対応できる。
- PJに必要な人月工数が単純に少ない
- 人が必要じゃないので。
- WFよりも必要コストが少なく、アジャイルより不確実性が低い
- いいとこどりができる。
欠点
- API利用に対してかなりのお金がかかる(といっても人月に換算すれば激安だが)
- かなりの抽象化能力、ソフトウェアアーキテクチャに対する深い知見が必要
- ビジネス上、説得に必要な材料が大きい。
- AI任せのプロダクトでいかにして価値を産むかを深く考える必要がある。
- 人月商売との相性は悪い。作業時間≠価値であるため。
ハイウェイモデル型開発におけるビジネススキーム
ハイウェイモデルの欠点でも説明したが、このハイウェイモデルを使って開発するのが一般的な手法になった世界では、
作業時間は価値を産まなくなっていく。つまりそれは、現在の日本で通用している「人月商売ビジネスモデル」の崩壊を意味する。(当然、アジャイル/スクラムが出た時も同じ話題になったわけだが...)
人月スキームが廃れる理由
以下の理由が存在する
- ハイウェイをいかに利用できるかが差別化ポイントになっていくため。
- 100人の作業労働資源は1人のハイウェイドライバーに全て置き換わってしまうため。
- これがコモディティ化した時、お客様も単純な労働力にお金を払いたいと思わなくなるため。
- CLINE使えばコーディングできなくてもアプリ作れちゃうらしいやんけ!
- そうなった時にどうやって専門性の価値を認めさせるか考えるのは大事。
どうやって価値を産んでいくか
これは今後議論になっていくと思われるため、各自考えておく必要がある。最終的にはプロダクトが生み出す価値そのものが、ハイウェイ開発モデルにおける、価値提供の形になっていくと想像できる。
(具体例を出すとちょっと関係各所文句がつきそうな話題のため、今後勉強会とかで小出しにしていくつもり。)
CLINEの性能を活かす開発手法について
CLINEはそのままではうまく開発できない。なので、ハイウェイ開発モデルでも説明したが、以下のルールをもとに作成していくことが重要となる。それらの理由についても解説する。
- 要件定義書を作成する
- ここではclineに毎回打ち込むpromptをinstruction.mdなどに書き込むなど、指示書も同時に用意しておくことが望ましい。
- 実装は必ずワンショットで行うこと。
- つまり、生成するたびに0ベースで開発させることを意味する。
- 巨大なモノリスコードを生成させないようにドライブする
- イテレーション時間を短くする
- 論理的にレビューはしない。
以下の5点について、それぞれ解説する。
ルール1. 要件定義書を作成する
これは必ずリポジトリの中に作成するべきと考えている。チームに参画する場合もこの資料を元に開発に参加すれば、手違いも少なくなる上、CLINEにContextを伝える時にも、必要な資料や説明を一瞬で終えられることも利点として存在する。
また、gitベースで管理することにより、資料の差分を確認することが可能で、いつどこでなんの意思決定がされたかのログも残せる。(また、archiveファイルに議事録を残しておくのも有用である。)
ルール2. 実装は必ずワンショットで行う
LLMとしての原理的な限界
CLINE/Claudeは0ベースで作成することは得意だが、追加修正に弱い性質を持っている。なぜかというと、1つのContextで整合性をとることは簡単だが、Context外のことは考慮できないため、修正には範囲外のContextを取得する必要がある。そのため、CLINEが読まなければいけない資料を用意したり、読んでも整合性が取れなかったりする問題が発生する。
また、現状の開発Contextの共有は実際議事録mdや要件定義書mdを読ませることでも可能ではあるが、巨大PJであればあるほど、要件を含んだ仕様書はカオスになっていくため、1ファイル500行以上読むと現状力尽きてしまうCLINE/Claudeでは、うまく性能を発揮できないという特徴がある。
これはLLMにおける原理的な障壁であり、将来的にはハード/ソフト両面で今後様々改善されるとは期待できるが、現状ではLLMの原理的な障壁により厳しい状況である。
ただ、100行を早ければ1分程度で書いてしまうハイウェイがすでにあるのだから、LLMベースでわりかし正しいと思われるコードをワンショットで作らせた方が、辻褄があうコードを書いてくれる可能性が高く、安全性が高いと考えた。
ワンショットでできる範囲に制約する恩恵
また、追加修正を行い、コードを巨大化させることは、CLINEにとっても負担が大きく性能が落ちる要因でもあるが、同時に、ハイウェイドライバーたるユーザ側にも負担が大きいのである。
ユーザ側がContext Windowを広く持ち、修正箇所が演繹的に正しいコードであるかを判断するのは、まずユーザが正しいContextを脳内に正確な状態で持っている必要があり、忘却の性能が中途半端に高い性質を持っている我々人類にとってはかなりの無理難題なように思える。
ましてや、一つのtsファイルならまだしも、追加修正を行うということは複数にまたがるtsファイルを全て認識していることが必要であり、そこのレビューで時間を食っていては、ハイウェイドライブの意味がないのである。
そこで、ワンショットで生成できる範囲のコードだけを生成範囲としてハイウェイドライブすれば人間側が演繹的に良し悪しを判断するのに必要なContextの範囲も狭まり、判断が早くなる上、CLINE/Claudeにとっても、生成する範囲が少なければ少ないほど威力の高い生成をできるため、相乗効果としてよくなっていくと考えられる。
引き継ぎの恩恵
ワンショットで作るようにすると、引き継ぎの面でも恩恵を受けることができる。
ワンショットで作るということは、ある種冪等性のある開発スタイルを維持することになる。
それは、LLMにとっても都合がいいのはもちろんのこと、ハイウェイドライバーにとっても、事情を知ってなくても再生成できる仕組みが整っていることを意味する。これは開発PJにとっても以下のような非常に良い影響をもたらす。
- 開発者同士によるContext共有の会議が必要なくなる
- 認識や状態に依存しないため、ドライバーが変わっても対応可能
- もちろんハイウェイドライバーとしての前提認識は必要だが。
- CLINEに対する調教が不要
- 開発に必要なSeedというべき要素の確実な確保
- 不文律がなくなるため、新規ドライバーが参画しやすい
上記理由により、ワンショットで開発を行うことは必須と思った方が良い。もちろん、小さな修正であれば、再実装より修正を手でした方が良いことも当然あるので、ケースバイケースではあるが...
ワンショットのデメリット
以下のデメリットが存在するため、そこは柔軟に対応したい。
- 非常に小さな修正に再生成する場合、時間とToken代の無駄が大きい可能性がある。
- すでに運用を開始してしまっているプロダクトに対して毎回migration作業を行う必要が出る可能性がある。
- これに関してはmigrationスクリプトも用意しなければいけないため、コストは大きいかもしれない。
- しかし、migrationを前提に運用を組んでしまえば、この欠点も利点に変わる可能性は大いに存在する。
- 唐突に発生するレストア運用、本番障害の切り戻し対応、脆弱性対応に対して強力な強みにもなりうる。
1に関してはドライバに技量さえあれば簡単に回避できる。2に関しては、回避不可能な致命的な欠点といえばそう。ただし、migrationが毎回簡単にできるシステムを構築しておく、またはk8sよろしく、マイクロサービスアーキテクチャのようなものを構築しておくことは何も無駄なことはなく、本来やっておくべきことを強制されるため、ある意味利点として活きる可能性まである。
当然、dbの構造までreplaceすることは必ずしも必要があるわけではないのだが、migrationはすぐできる運用をしておく方がより望ましい。(その方が、データモデルに関してリスクを負う可能性が低くなり、初動も早くなる上、その必要コストが増えたとしてもその恩恵により、十分ペイするからである)
ルール3. 巨大なモノリスコードを生成させない
これはLLMが、原理的に長すぎるコードの構造理解ができないことに由来しており、巨大なコード(CLINE/Claudeの場合、400行以上のコード)を生成させないこともそうだが、何も分割されておらず、全て具体で固められたモノリスコードを生成させないことも大事である。
モノリスがなぜダメなのかというと、モノリスが生まれてしまうこと自体、大抵は具体実装で固められているからである。
モノリシックなコードがなぜダメなのか
まず長い。CLINEは読めはするが、500行以上読むと基本的に力尽きることが多い。人間も長いコードに弱いため、辛い思いをすることになる。また、雑然と整理されていないコードなことがほとんどであり、違和感にすぐに気づけないというところもやめた方が良いポイントである。
また、一番ダメな理由が、具体→抽象へエスカレすることの難しさがあるからだ。
抽象とは、一般に普遍的に広がるような、物理で語れば波のような性質を持ち、具体とは、反対に粒のような確定的な何かを持つものと私は考えている。
私が常に感じていることの一つに、基本的に仕事が早い人は、抽象で考えていることが多いように感じていることがある。具体は状態確定しているため、状態が確定しない抽象よりわかりやすいという利点はあるのだが、粒である具体から普遍的要素である抽象へのエスカレはかなり厳しいものがある。その一つの具体の外に考慮すべきことがたくさん存在するからだ。しかし逆は簡単なのである。すでに抽象は考慮されているからだ。
演繹的にこのコードが正しいのか正しくないのかを判断するのは完全な抽象であり、具体で固められたモノリスが本当に正しいのかは具体→抽象へのエスカレが必要となり、レビュー速度がかなり落ちてしまう問題が発生するのである。
→つまり、CLINEの性能の外に開発スピードのボトルネックを作ってしまうことになる。
競プロなどをやってる人や、普段から抽象で考えている人はこの感覚はわかるだろうと思う。(コーナーケースという具体から抽象を考えていると成績が伸びないのはそういうことだと思う。競プロはWAケースをいかに通すかという試合ではなく、最初からどう抽象を育てていくかというゲームだったりするらしい)
ルール4. イテレーション時間を短くする
イテレーションにかかる時間は常に短くなるようにハンドリングする必要がある。それは以下の理由が関係している。
- 1回のイテレーションが時間かかるような設計はそもそもハイウェイモデルと相性が悪い
- ハイウェイをうまく活用できてないということよりも、LLMが原理的に相性が悪いため。
- 人間が把握できるContext量が多くはないため。
- 仕様の抜け漏れに早く気づくため。
- 試して見て初めて悪手だと気づくということもあるため。
- 大きく動かないようにするため
- 小刻みに実験して動くことで手戻りを小さくすることも必要なので。
以上の理由から、イテレーションにかかる時間は短い方が良い
ルール5. 論理的にレビューはしない。
ハイウェイをうまく活用するためには、レビューはなるべくしないという原理のもとで、アーキテクチャで構成した方が良い可能性が高い。
なぜならば、人間がレビューをするという行為自体が、大きなオーバーヘッドとなり、全体のイテレーションスピードにも関わってくるということが挙げられる。
また同時に、人間がサクッとレビューできないようなコードを書かせてしまうこと自体が、何かがおかしくなっていることの前兆である場合が経験則的に多いと感じている。
人間がさらっと目grepして簡単に違和感に気づかないようなコードは、そもそも論として、かなり保守性が悪いコードであることが多い。つまり、アーキテクチャから抜本的に見直す必要がある可能性が高いと考えられる。
具体的には、
- Genericsなど、型の機能を活用していない
- interfaceとimplを分けていない
- コードがモノリスになっている
こういった状態のコードは、抽象化されていないという問題が共通して存在している。そういうコードはどういう状況を産むかというと、コードをパッと見た時の直感が働かないという経験を私自身がしている。
木を隠すなら森理論と等しく、型の機能を存分に活用していないコードは本当に演繹的に正しいコードなのかを論理的に考えにはかなりの体力が必要であり、また考えた先で違和感しか感じないことが多い。
そのため、CLINEの出力したコードに対して、本質的な設計ミスなのか、実装ミスなのか、コーナーケースによるパターン漏れなのか、パッとわからず、ちゃんと認識すべき違和感を、全て同じ違和感として受け取ってしまう問題がある。
一方で、型の機能をガチガチに使っていて、高度に抽象化されたコードは、基本的に概念としてすでに綺麗に構造化されており、整理されているため、本質的な違和感に気づきやすいという大きな利点がある。
わかりやすく具体的に説明すると、
- 本質的な設計ミス: interfaceや型実装に対して違和感がすぐ出る
- 実装のミス: implに対して違和感がすぐでる
- コーナーケースによるパターン漏れ: TDDベースで発見可能。またTest制作時に違和感に気づける。
という形だ。
以上5つが、CLINEの性能を活かす手法を解説した。
まとめ
- 第3の開発モデルとしてハイウェイモデル型開発を提案
- CLINE/Claudeなどの生成AIをハイウェイとして活用し、開発速度と品質を両立
- 社会インフラとしてハイウェイが出来上がったことにも由来する。
- ClaudeというハイウェイとCLINEという車を使い、どうやったら高速にPJを進められるかを考察
- 要件定義→実装→要件にフィードバック→再実装→...のサイクルを高速に回していくstyle
- 常に完成品として出力されるため、納期を動的に設定できる。
- WFよりも最適なコストで、アジャイルより不確実性が低い、いいとこどりの開発モデルを実現
- CLINEを活用するのに必要なドライバとしての原則を考案
- ドキュメント整理の原則
- 要件定義や議事録といった資料をCLINEに共有するためにmdで必ず保存すべし
- CLINEに読ませるために必要な資料であり、文書管理も楽になり一石二鳥となる。
- ワンショット実装の原則
- 追加修正は基本しない。再生成のみで実装を行う
- 整合性の高いコードを常に維持できる
- migrationを常に考える運用により、運用コストも下がる
- デグレの危険性があるため、TDDが重要になり、シナジーも生まれる。
- 巨大モノリス回避原則
- 200行以下の小さなファイル群に分割しないとLLMが読めない。
- 抽象化が強制されるため、設計として違和感に気づきやすい
- イテレーション短縮原則
- 設計ミスに早期に気づくために必要
- 完成までの時間を短くするためにも必要
- 前提をひっくり返すような無茶な要求にも簡単に対応できる。
- 論理的レビュー禁止の原則
- 常に再生成されるため、負荷のかかるレビューをしているとそこがボトルネックになりうる。
- 感覚で気づけるようにすることで、レビュー負荷を下げ、運用できるようにする。
- 自然と巨大モノリス回避原則が強制されるため、シナジーも生まれる。
- ドキュメント整理の原則
最後に:ハイウェイモデルの未来
ハイウェイモデルは、従来の「人月商売」ビジネスモデルを根底からひっくり返してしまうだろう。人月商売は続いていくだろうが、そのようなコスト度外視な商売では、ハイウェイモデルが一般化した世界に競争で勝てないと感じている。作業時間ではなく、プロダクトが生み出すビジネス的価値そのものが、エンジニアの報酬になっていく世界がそこにはある。
しかし、このモデルを実践するには、高い抽象化能力やソフトウェアアーキテクチャに対する深い知見が必要となる。
その見返りとして得られる開発効率と品質の向上は、ゲームチェンジャーになりうるが、同時に高い難易度を要求されると私は感じている。
怖いのが格差の問題で、ジュニアは永遠にこのまま取り残されてしまうのかと心配になっている。(当然私も例外ではないのだが...)しかし、今回考案した、CLINEによるハイウェイモデルは、高度な抽象化を強制するモデルであり、それらはどれも、CLINEを精度良く使用ためには必須である。
意識せずともCLINEを使って本番で使うプログラミングを行うならば、誰もがこのモデルを、この記事を通さずとも再発明できると考えている。
故に、ジュニアエンジニアが生き残っていく道は、ある種古典的な、TDDの開発手法や、抽象化を学ぶDDDやクリーンアーキテクチャをしっかりと学び、より専門家らしく、勉強に励み、手を動かすことしかないと感じている。
今後も有益な情報を発信していきたいので、面白いと思ったらいいね & シェアの方いただけると!!
Discussion