📝

〜AI駆動開発で個人開発するなら、設計をしろ〜 バイブコーディングでのレビュー負荷を低減する方法

に公開

はじめに

https://zenn.dev/sunagaku/articles/e06100e505a2f0

この記事は、上記の記事の続編です!

AI駆動開発(Vibe Coding)で個人アプリを開発する際、「コードレビュー」がボトルネックとなり、開発効率が落ちていました。

そのため、バイブコーディングをする前に、「設計」をがっつりして、レビューの負荷を減らし開発効率を上げていこう、という内容です。

なぜ設計をしないと、レビューの負荷が増えるか?

レビュー時の観点が複数生じ、同時に確認することになる

AIのコードレビューに大きい負荷がかかる理由は、

  1. コードが冗長ではないか?もっと良い書き方はないか?
  2. コードのロジックは問題ないか?
  3. そもそも設計は問題ないのか?

上記3つの観点を「同時に確認しようとする」からだと考えています。

どこからコードを読むか?処理の流れは問題ないか?を確認しつつ、一つ一つの処理は問題ないか?のロジックの中身を見て、その上でリファクタリングできないか?も考えています。

この時点で、かなりのマルチタスクです…

もちろん、業務でのレビューも同様の事象は起きていますが、人が作成したコードは「動作確認や実装に問題がない」など「一定の質は担保される」ので、AIのコードほど負荷が大きくないと思います。

レビュー後の修正の手戻りが増える

AIに修正させた後にレビューし、さらに修正させてレビューして、という負のループに陥ります...

例えば、Aクラスのxxxメソッド、yyy メソッドのレビューをしていました。
その後、Bクラスをレビューした際、クラス分けに問題があったとします。
そのため、新たなCクラスを作成し、各種ロジックも修正しました。その際に、既にレビューしたAクラスにも、変更が影響しました。

ロジックが変わってなければ、そこまで問題ではありませんが、もし変更されている場合、再度レビューが必要になり…というのが何回も頻発します。その度に疲弊していきます😭

設計をせずにバイブコーディングをすると?

「ライブラリ側」か「アプリ側」か、で原因切り分けが出来ない

ライブラリ選定などの話です。

前回の記事にも共通しますが、Aiが作ったコードのデバッグは、負荷がかかります。
また、AIに作成させたコードは、ベストプラクティスではない場合が多いです。そのため、エラーが発生した際、「ライブラリーにその機能が無い」のか、「使い方が間違えている」のかが判断できません。

そのため、設計の一環として行う「ライブラリ選定」は、「ライブラリの使い方」・「できること・できないこと」を理解しておかないと、手戻りが発生する可能性があります。

技術的負債が高速で溜まっていく

「今後、どんな機能を追加していきたいか?」
もし次に作る機能が決まっているなら、その機能を追加しやすい形で実装できてるか?

この視点が設計に含まれてないと、技術的負債となる可能性は、かなり高いです。
新規機能追加時に、既存機能に無理やり追加する形になるので、「コードの可読性が低下」し「デグデが起きやすく」なり、大きな泥団子が一瞬で完成します。

最近だと、AIは開発スピードを上げるが、その分技術的負債が貯まるスピードも高速化する、という話もあります。これは、初めの設計を念入りに行わなかったため、強引な機能追加を行い続けた結果だと思います。

技術的負債は、下記の記事がとても参考になります!簡単にお伝えすると、「認知負荷の高いコード」です。
https://zenn.dev/nyaomaru/articles/technical-debt-basics

これらの背景を踏まえると、「先に設計をする」ことで、レビュー時に「設計には問題がない」ことを担保できるので、コードを読む負荷が減り、修正の手戻りも減らせると考えています。

また、設計されていないコードのレビュー時にはかなりの負荷と時間がかかるので、最初から自分たちで設計を行う場合と比較しても、トータルの作業負担はさほど変わらないというのが実感です。

なぜ、「一旦作らせ、それを修正する」ではダメか?

とはいえ、過去の僕はこう感じていました、

「設計考えるのめんどくさい、一旦作らせてから修正すればいい」
「Claude Code Max契約してるから、元取らないと」

結局、AIに簡単な要件を伝え、コードを作らせて、レビューしつつ修正させて…
ただこの場合、以下の事象が発生するため、好ましくないと考えています。

修正後にデッドコードが残る

既に経験済みだと思いますが、「今の実装と互換性を持たせる」として、修正させた内容が別パターンとして新規実装されることがあります。その結果、修正前のコードは残ります…

その後、レビュー時に、大量のデッドコードに目を通し、「なぜこのコードが残っているのか?」を考えていく必要があります...

そのため、レビューするコード自体を減らすためにも、AIへの修正回数は出来る限り少なくするのが、重要です。

実装が複雑になればなるだけバグる

コードは「シンプルに保つ」ことが大切です。

AIに修正させた場合、先述の通りデッドコードが増えたり、ロジックを新規追加して対応することが多いので、必然的に実装も複雑になりがちです。

「KISS(Keep It Simple Stupid)の原則」を大切にする上でも、大きい修正は避けたいです。

https://qiita.com/7_zidan_/items/4311cc49b263ec625bd0

何を設計すればいいか?

では何を設計すればいいか?
大きく分けて、下記の三つです。

  • 利用するライブラリや技術
  • クラス構成と大まかな処理の流れ
  • テーブル設計

もちろん、他にも詳細に書ける所は、書きましょう。
これから、「なぜ設計しておくべきか」と「設計時の注意点・観点」についてお伝えします。

利用するライブラリや技術

ここを設計しないと、「そのライブラリメンテされてない」・「そのライブラリじゃ機能要件満たせない」が頻発します。

基本的に、AIが拾ってくるデータは最新情報でないです。過去の情報を元に判断してます。
そのため、インストールした瞬間から「Deprecatedだったライブラリ」を利用して、「即座にリプレース」という事象が一瞬で来ます…笑。

それを避けるためにも、利用するライブラリや技術は、私たちが考えましょう。

また、ジュニアエンジニアにとっては、各ライブラリの特徴やメリットデメリットの比較など、トレードオフの考えなどを学ぶ、いい経験になります。
勉強だと思い、積極的に考えるといいと思います。(僕自身への自戒の念も含めてます笑)

クラス構成と大まかな処理の流れ

ここは、絶対に設計したほうが良いです。
ここを設計すると、レビュー時の負荷が減ります。レビュー時に「問題無くデータが処理されてるか?」だけ見れば良くなります。

もしバグが生じても、処理の流れが分かっていると「修正する箇所(クラス)を特定しやすい」ため、簡単に対応できます。
また、既に「全体像を把握してる」ことから、心理的なハードルも下がります。

反対に、全体像やクラス構成を把握できてないと、「どのような処理があり、どのクラスでバグが生じてるか?」を一から調べることになります。ここの負荷を軽減できます。

余談ですが、フロントエンドの開発時は、どんな画面構成にして、どのようにコンポーネント分割し、どのファイルにコンポーネントを入れるか、を伝えておくと、生成されるコードの質が上がる印象です。

テーブル設計

複雑な機能の作成時は、「テーブル設計」が一番の手戻りの原因になります。

仮に、AIに機能要件を正しく伝えられなかった場合、作成されるテーブルには不備があります。この事象は、たびたび発生します。

その結果、失敗したからもう一回作り直すことになります。この作り直す工数を考えると、先に設計しておけば手戻りが少なくなる、という話です。

ただ「作る中で、他にもカラムが必要だと分かった」場合もあります。それは、随時追加して問題ないです。

一番もったいないことは、見当違いのテーブル設計をしていたことで、今回作らせた実装全てを捨てることになり、流用するものが何もない、という状態です。

これを避けるためにも、テーブル設計も私たちが行いましょう。

設計・レビューに関するベストプラクティス

大きな修正を何回も行うなら、作り直す

  • なんとか完成はしたけど、デッドコードが多くレビューできない。
  • 小さな修正ですら、バグが頻発する。

上記に当てはまったら、「1から作り直す方が早い」可能性があります。

ただ、この時にコツがあります。AIに「今の実装の大まかな設計書」を作成させることです。

クラスのインターフェースやデータ処理の流れ、テーブル設計などを出力してもらい、私たちで一部手直しした上、それを再度AIに渡して作り直してもらいます。

すると、詳細な設計の指示をAIに出せるので、生成コードの質がかなり担保されます。また全体の設計は把握できてる状態なので、レビューの負荷を軽減し、かつ不要なデッドコードも作られにくくなります。

Planモードで、実装計画を作成する

もし複雑な実装を依頼するときは、ぜひ行いましょう。

設計書の内容が正しく伝わっている、とは限りません。

そのため、Planモードを使い、実装計画書を作らせることで、「正しく認識しているか?」のチェックができると、手戻りが少なくなります。

動作確認をレビュー前に必ず行う

動作確認は、徹底させましょう。

動作確認を徹底させると、「修正させたことでロジックが変わり、今までのレビューが水の泡に…」をかなりの割合で減らせます。

僕は、Webアプリを作成しているので、PlayWrightMCPを使い、AIにE2Eテストを行わせて「関連ページの挙動に問題ないか?もしバグっていたら修正して」と指示しています。
完全に動作が問題ないところまで確認して貰った上で、レビューに移っています。

AIにリファクタリングさせる

重複コードを可能な限り減らせると、レビューが楽になります。

既存のファイルとかディレクトリの情報を渡し、その構造に合わせた形でリファクタリングをさせます。
例えば、「DBとアクセスする処理は、Repositoryディレクトリにクラスを作成してそれを呼び出して」などです。

これにより、コード自体の量が減り、かつ呼び出し元も簡潔になることで、レビュー負荷が減ります。

レビュー前に、実装した計画書を作成させる

レビュー前に、実装の全体像を把握するため、AIに実装した内容を出力させましょう。

ざっくりとしたデータの流れやクラスを知れると、各コードの意図や意味に対する理解度が変わります。

「今回の実装した内容をmd形式で出力して」などの指示をすると、出力してもらえます。

終わりに

設計は、一見遠回りに見えますが、レビュー負荷を軽減して開発効率を上げるには、有効な方法だと考えています!

他にも、もっと良い進め方が沢山あると思います、ぜひ工夫してる点をコメント欄で教えていただきたいです!


次回、「~~ AI駆動開発で学びを最大化する方法 ~~ あれ、僕は何も成長してない…からの脱却」編でお会いしましょう!

Discussion