👨‍🎓

AIを本気で使って分かった“現実と課題” 〜効率化の先にある、AIと共に成長するエンジニアリング〜

に公開

はじめに

先日、AIエージェントユーザー会(AIAU)の「AI Coding Meetup Aichi」に登壇させて頂きました。

https://aiau.connpass.com/event/369264/

本イベントは「実戦知」がテーマだったので、「あまり知られてない?AI の開発効率化」と「今僕自身が抱えてる課題と向き合い方」の二つについてお話ししました。

https://x.com/suna_gaku/status/1984486360364040306?s=46&t=JLHAI_qTC6GlGgAoZy6alw

ありがたいことに、素敵な感想や反響をいただきました反面、登壇時に上手く伝えられていない内容もあることが分かりました。
そのため、記事として補足しつつ再度投稿させて頂きました。

もし興味があれば、ご覧頂けると嬉しいです!

スライドは下記から確認できます!
https://speakerdeck.com/sunagaku/aiwoben-qi-deshi-tutefen-katuta-xian-shi-toke-ti-xiao-lu-hua-noxian-niaru-aitogong-nicheng-chang-suruenziniaringu

あまり知られてない?実践で見つけた効率化 5選

1. 作業タスクを分解し Git Worktree で並行開発

「Git Worktreeを使って、複数タスクを同時並行で進めよう」という話です。
僕自身は、「バックログタスクのブランチ」と「各種バグ修正のブランチ」を分ける、という運用をしています。

その結果、緊急対応や差し込みのタスクを別ブランチで対応できるので、今の作業をコミットしてブランチ切り替えて、終わったら元のブランチに戻して、みたいなのが不要になります。

Git Worktree に関しては、下記の記事が参考になります!
https://zenn.dev/hiraoku/articles/56f4f9ffc6d186

同一タスク内で、Git Worktree を活用する方法

並行開発は、基本的に「全く関係のないタスクで行う」のが主流です。コンフリクトを避けるためです。
しかし「最重要タスク」を集中して迅速に実装したい時もあると思います、その時に使える方法です。

僕は、下記の手順で実装しています。

  1. cc-sddを利用して、設計書や実装手順書を作成
  2. 作成された実装手順書に対して、大まかなタスクのカテゴリー分類を行う
    例えば 「型情報を定義するフェーズ」・「FeのUI作成部分」・「BeのAPI作成部分」に分ける。
    それにより、「同時並行で進められるタスク」を洗い出してまとめられます。
  3. 実装前に「各タスクで共通利用されるファイル」を予め作成する。そのブランチから各作業用ブランチを派生させる。
    これにより、共通利用のファイルが「それぞれの作業ブランチで独自実装されるのを防ぐ」ことが出来ます。
  4. 各タスク毎にブランチを作成し、実装を進める
    元々の設計書・実装タスクを共有しているので、「〇〇 の部分の実装をお願い」の指示の出し方を行います。
  5. 最後に、それぞれで実装させた内容を一つのPR用ブランチにマージ、動作確認してPR作成する

2. 独自のコード規約を作成してレビューさせる


AI にコードレビューさせる際は、「独自のコード規約」を作成出来ると精度が上がります。
例えば、「ディレクトリ構成やコンポーネントの書き方」などです。
AI のコードレビューを行う前に、上記の観点でレビューさせると、指摘事項を修正できてレビュー負荷が減ります。

以前Claude Code を利用してた時は、「サブエージェント」として「各コード規約専用のレビュワー」を作成していました。
コード規約のルールを一つずつファイルに切り出して、各コード規約のファイルに該当するサブエージェントを一つずつ作成してレビューさせていました。
その結果、Beのクリーンアーキテクチャチェックでは、「Repositoryを、直接コントローラーから呼ばない」などの指摘をしてくれています。

コード規約は コードレビュー時に随時追加

とはいえ、コード規約のメンテナンスは非常に手間がかかります。そこでオススメなのが、「AIのレビュー時に指摘・修正させた内容」を「その場で追加させる」です。
これで「初回は人が直すけど、二回目以降は防止できる」ことが出来ます。

もちろん、Agent.md に追記する方法でもある程度はできますが、肥大化するとうまく動かなくなります。
そのため、「実装にそこまで影響はないけど、最後には修正させたい」内容は、個別のコード規約にまとめた上で、最後に一気に修正させればいい、という考えです。

また、コード規約はある程度整備できれば、リファクタリングも容易になります。

3. AI に任せる ≠ 最短


「細かい調整や実装」 は、AI に任せずに人がやる方が早い場合があります。
というのも「プロンプト入力時間やコード生成時間を加味すると、完成までの時間がかなりかかる」ためです。
細かい調整は、何度も会話してニュアンスを伝える必要があり、プロンプトを工夫する必要も出てきます。Codex は応答時間が長いので、この影響が顕著に出ます。

また、AI のコードを最終的にレビューするのであれば、「後から読むのか、今から読むのか」の違いなので、早めに読めると試行錯誤の時間は短縮できるのかな?と思います。

4. 何も分かってないタスクは任せない


AI に任せるタスクは、ざっくりでも実装のイメージが出来ていると、実装がスムーズにいくと思います。目安としては「チュートリアルや初期設定」の理解ができてる、です。

AI は、「設定自体のミス」を検知しにくいです。もし正しいドキュメント見れてなければ、ハルシネーションで一生正解に辿りつけないです。また仮に動いたとしても、コードは試行錯誤した後のスパゲッティーコードで、デグレしやすくなります。

また、実装の全体像や概要がわかっていれば、AI に指示させる時にも効率的に正確に指示できます。
例えば、「エラーログだと、ここら辺の値おかしいから、注意して見て」と言えます。
しかしここが無いと、「迷宮入りして永遠に直らない」 が起こります。

これらを考えると、「0 -> 1 のタスク」は、人が積極的に入れるといいかな?と思っています。
「ライブラリの初期設定や、サンプルコードが動くこと」を確認し、その上で「そのコードを水平展開させる」が、結果的に早いと思っています。

5. AIとのペアプロタスクは 1つに絞る


「人の脳は、PC とは違う」 と最近痛感しています。

  • PC: 非同期処理を挟めば、タスクが止まったら次に処理するやつを実行して、みたいな仕組みを作れる
  • 人: タスクの切り替えを行うたびに疲れていき、どんどん疲労が溜まっていく

「認知的切り替えコスト」という、目の前のタスクから別のタスクへと注意や行動を切り替える際には、「負荷」や「非効率」が生じる、という考えがあります。
この「認知的切り替えコスト」が、上記の方法だと大量発生しているのかな?と思います。

そのため、「タスクの切り替え」を最大限減らすのが、重要だとと考えています。

タスクのフェーズに合わせて、同時並行で進めるタスクを管理する

ここで、僕が実践している「タスク管理方法」について、お伝えします。
まず前提を共有すると、開発のタスクには「2つのフェーズがある」と考えています。

  • AI が主導するフェーズ(コーディング・簡単な動作確認・Lint チェック)
  • 人が主導するフェーズ(最終調整や動作確認)

AI が主導するフェーズの場合は、人が見る必要はありません。逆に人が主導するフェーズの場合は、積極的に人が介入する必要があります。
この時に、「人が主導するフェーズ のタスク」は 1つだけに絞りつつ、「AI が主導するフェーズ のタスク」は同時並行で進める、という進め方をしています。

また、この時に 「AI が主導するフェーズ」 での完成度をどれだけ高められるか?が重要になります。
そのため、事前に「kiro や cc-sdd」や 各種ツールのプランモードを利用して、具体的な設計まで押さえておく。あるいはコード規約や動作確認の仕組み、TDDなどを用いて、実装の質を高めることが重要かな、と思います。

AI駆動開発を進めて感じた現実と課題

1. AI を使うと 成長実感が得られない


AI を利用すると、スピードも上がり快適に開発できます。また設計書を作成することで実装のブレも少なく、修正ゼロでマージ出来ることもあります。

しかし「スキルアップができてるのか?」という不安も抱えるようになりました。
AIを使うと、その提案に対して「Yes or No」しか言えなくなります。それ以外に存在していたかもしれない「ベストプラクティス」を知る機会が訪れにくくなります。

実装自体はできている、AI も他の方よりは多少上手く使いこなせる。でも AI が上手くできなかった時に、ちゃんと作れるか?など「自分自身のスキル」として自信を持てていませんでした。

また、「バイブコーディングが上手い」 ≠ 「高いスキルを持っている」とも感じました。
自分自身の経験としては、バイブコーディングで作ると、「技術力として何が得られたか?」を振り返った時にほとんど思い出せなかった、という経験があります。ここから 「AI に指示を出すのが上手なだけで、技術力の証明にはならない」という問題も存在してしまうのかな?と思います。

2. 現場で起きている問題


また、日本の現場だと「ジュニアエンジニアの採用を少なくしよう」という流れがあります。
この事象が起こった経緯は、下記だと思います。

  1. ジュニアエンジニアが、AI を利用して PR を大量に作る
  2. シニアエンジニアがレビューで疲弊している
  3. シニアエンジニアを雇って、その人にAIを使って開発してもらった方がいい

3. なぜシニアが疲弊するのか?


上記の経緯を考えた時に、問題は「PRの数だけでは無い」と感じるようになりました。
僕は、今インターン生のマネジメントをしているのと、僕自身もプレイヤーなので、「コードや設計の意図・背景が読み取りにくい」事象が増えたことが原因だと考えています。

例えば、「ここがエラーの原因みたいだけど、なぜそのコードにしたの?」と聞くと、「AI が出力したからです」となる場合、「なぜそのコードなのか?」の背景情報がありません。
もちろんこの返答は、僕やインターン生は行わないように気をつけてはいますが、とはいえ「意図」の部分が弱くなっているのは事実です。

また、設計を決める時にも「上手く動いたから」でそのまま決定されている人も多いと思います。

その結果、シニアエンジニアが、実装内容や要件を加味した上で「コードの設計意図を読み取る」・「その設計が正しいかどうかを一から判断する」の二つを行っていると思います。これは「自分で一から作る」よりも大変なタスクです。

また、コードの意図や背景を確認すれば、そのエンジニアの力量や今の理解度も測れますが、AIに作らせただけだと上手く把握できないので、任せられるタスクの範囲も見極めにくいです。

4. 古典が語る最適な開発とは?


エンジニアの「名著」と呼ばれる本の中に、「達人プログラマー」という本があります。この本には、「エンジニアの姿勢や実装時の注意点・心構え」など、重要な原則が書かれています。

その中に「本能に耳を傾けながらプログラミングをする」・「偶発的プログラミングを避ける」の二つが記載されていました。

「本能に耳を傾けながらプログラミングをする」は、プログラミングをしている時に、「なぜ冗長なコードになる」や「設計したけどピンとこない、違和感がある」時は、一度机から離れて深呼吸して、最適な設計を考え直そう、と言う教えです。

「偶発的プログラミングを避ける」は、「なぜか動いているコードは危険」という考え方で、修正を入れていたらある時急に動かなくなって、そのままシステムを全部捨てることになる、と言う事象を避けるべき、と言う教えです。

バイブコーディングだと、これらは意識しにくいなと思いました。

  • AI がが言ってるから問題ない だと、「実装時の違和感」は感じにくい
  • コードの意図を理解してないから、「なぜ動いているか?」を理解しにくい

昔と今では前提条件が違うのも事実です、しかし先ほどの現場で生じている問題は、これらの原則が守られてないから発生しているのではないか、とも感じています。

5. ジュニアエンジニアの宿命


では、ジュニアエンジニアはどうすればいいのでしょうか...
今、ジュニアエンジニアは、「アウトプット」で評価されます。
「PRを出していない」と、仕事は無事に進んでいるか?何か問題は起きてないか?と不安になります。なので、しばらくは「成果量」が求められると思いますし、そのため生産性の向上も必要です。

一方で、コードの質を上げなければ、全体から見ると逆効果になります。

  • シニアエンジニアのレビューがボトルネックになる
  • ソースコードの品質低下により、機能修正に時間かかるようになる

つまり、「質を担保したり高める工夫」をした上で、かつ「生産性も上げる」必要があると思います。

しかし、コードの質とは何でしょうか?このAI時代でどうすれば成長できるでしょうか?

3. 「一人前になるために」 AIとどう向き合うべきか?

エンジニアが求められるスキルは?


ただ、「コードの質を上げる」の答えは、「すでに出ている」と思っています。

そもそも現場で出ている問題は、

  • ジュニアエンジニアが出したコードの量が増える
  • 意図が汲み取りにくくて、適切かどうかの判断がしにくいPRが増えている。

の二つです。

これを裏返すと、シニアエンジニアにとっての「いい品質」は、「レビュワーに負荷をかけさせない」コードと言えます。

  • レビュワーがコードの意図を知りたいと思った時に「ちゃんと質問を打ち返せる」
  • 実装時に感じていた懸念や、技術負債になりそうだと感じたことを共有できる
  • 他に検討していた代替案なども共有して、レビュワーが判断したりレビュイーの理解度を測れるようにする

これらの「シニアエンジニア・レビュワーが求めていること・聞きたいこと」を答えられるようなコードを作ればいい、ということです。

これらのコードを作るにはどうしたらいいか?
3つの方法があると考えているので、共有させて頂きます。

1. 設計を説明できるようになる


一つ目は、「設計を説明できるようになる」です。
「その設計にした背景」を、自分の言葉で語れるようになれるとベストだと思います。

  • 機能要件に対して、なぜこの設計がいいのか、どうして他の設計ではダメなのか?
  • 「今のプロジェクトが重視してる要件」を満たせているのか?

などです。
必要であれば、他の設計案も準備しておいて、それぞれのメリットデメリットも把握できるといいと思います。

もちろん、そのタスクの緊急度や重要度によっても変わるのですが、これらの準備をすることで、エンジニアとしての設計スキルも上がるのでオススメです。

2. コードを説明できるようになる


二つ目は、「設計を説明できるようになる」です。

もちろん、全てのコードの変更意図を説明する必要はないです。TailWind のクラスの書き順などは、重要ではありません。

しかし、重要な業務に関わるような内容なら、周りの人にも説明できるようにできるといいと思います。
また、変更意図や予想される影響範囲などを理解して共有すると、レビュワーは助かります。
細かくてかつ全部見ないといけない領域は大変なので、「めんどくさくて手間だけど必要な情報」は、一通り用意しておけるとベストです。

また、懸念事項等があれば、合わせて質問するのもいいと思います。

3. 設計の学習を継続的に行う


三つ目は、「設計の勉強を継続して行う」です。
大前提「知らないことを指摘するのは難しい」です。いくらAI のコードをレビューしたとしても、「コード実装の落とし穴」を理解していないと、問題点に気づけないです。

もちろん、今後のAIの進化で、この前提が変わるかもしれないですし、今のAIが出す設計も基本的には問題ないことが多いです。

ただ、現在はまだ不備がある場合もあるので、より良い設計をAIと共に作る上で、エンジニア自身のスキルも向上させる必要があります。

設計を勉強する時は、ただ「そういう設計方法がある」だけで終わらせないのが大切です。

  • なぜその設計が必要なのか?
  • 設計を適用するとどんなメリットがあるか、逆にデメリットは何が生じるのか?

目の前のAIが生成したコードに対して評価しながら、より良い設計はないか?を考えられると、他にも応用が効くスキルが身につけられます。意識してみてください!

おわりに

今回、初めてオフライン登壇をさせて頂いたのですが、素敵なスタッフさんや会場のおかげでとても楽しく、かつ学びの多い時間を過ごさせて頂きました、本当にありがとうございました。

他にも様々な効率化の方法や考え方があると思います、ぜひ教えて頂きたいです!

Discussion