今まで何回か触れたとおり、最近新しいサービスを作っています。私と村澤(彼のブログ記事は以下のリンクを参照)の2人でやっているのですが、担当分野が異なるので、私の担当部分に関してはほぼ個人開発みたいになっています。
そこでどのような開発方法をやっているかを簡単に説明します。(社外の人だけでなく、社内でも興味のある方向けに書いています。)
概要
大まかには以下の通りです。
- 複数のタスクを並行して作業する(最大3つ)
- 大元となる仕様は自分で書いて、タスクの詳細化と実装の大半は生成 AI に任せる
- 生成 AI が作業をしている間に、他のタスクの作業をする
次項以降、まずはやり方を説明して、その後に考察等を記載します。
複数タスクを並行して作業する方法
Git ブランチ初期設定
git worktree コマンドを使います。恥ずかしながら今まで使った事がなかったのですが、今回使ってみました。ブランチ運用の概要としては以下の通りです。
- タスクは最大3つなので、worktree は最初に3個作っておく
- 基準となるディレクトリは常に
mainレポジトリの最新にしておく
手順ですが、事前準備は以下の通りです。
# git clone して、それをまず基準のディレクトリとする
git clone <url> proj-a
cd proj-a
# feature/task1 ブランチ用の worktree を作成。
git worktree add ../proj-a-t1 -b feature/task1 main
# 2, 3 についても同様。
git worktree add ../proj-a-t2 -b feature/task2 main
git worktree add ../proj-a-t3 -b feature/task3 main
# 一覧は以下のコマンドで確認できます。
git worktree list
ここで ../proj-a-t1 は feature/task1 用に作りましたが、feature/task1 が完成して main にマージされても ../proj-a-t1 は削除せずに使い回します。
Git ブランチ運用
proj-a-t1 で作業する例です。
cd ../proj-a-t1
# この辺は通常通り行います。
git add
git commit
git push origin feature/task1
# main に新たな変更が加わったので、rebase したい。
cd ../proj-a
git pull # 基準のディレクトリに main の最新を取り込む
cd ../proj-a-t1
git rebase main
# PR レビュー中に task4 をやりたいので、proj-a-t1 は feature/task4 のために使い回す。
git checkout -b feature/task4 main # 最新の main から feature/task4 を作成
git add
git commit
git push origin feature/task4 # WIP
# PR レビューを経て、feature/task1 が main にマージされました。
cd ../proj-a
git pull # 基準のディレクトリに main の最新を取り込む
# proj-a-t1 で feature/task4 の作業を再開
cd ../proj-a-t1
Docker Compose の注意点
proj-a-t1, proj-a-t2, proj-a-t3 ディレクトリそれぞれで Docker Compose を使って環境を立ち上げる際に、以下が被ることがあります。
- コンテナ名
- ポート
後者に関しては、以前村澤が以下のブログ記事を書きましたのでご参照ください。
[Docker Compose] そのポート公開、本当に必要? – もばらぶエンジニアブログ
前者ですが、 compose.yml で container_name を指定していると、複数ディレクトリで起動したときにコンテナ名が被って起動できません。 container_name の行を削除するのが一番簡単です。
services:
proj-a-postgres:
container_name: proj-a-postgres # ここで固定の名前になっている
image: postgres:16.2-alpine3.18
ターミナル
私は macOS ですが、Windows でも同様に出来ると思います。私のやり方としては、
- worktree (
proj-a-t1等)毎にターミナルウィンドウを1つ立ち上げる - 各ターミナル内で
tmuxを使う
IDE
これも単純で、 worktree 毎に IDE のウィンドウを起動しています。私は JetBrains の IDE を使う事が大半です。
生成 AI に実装を任せる方法
巷で言われるドキュメント駆動開発のようなものです。
流れ
- 自分で大元となる仕様、サブタスクの一覧などを Markdown で記載する
- コーディングエージェント(Claude Code や Codex CLI) に変な所・曖昧な所はないか、もっとよいタスク分割はないかを提案してもらう
- それを元に大元の仕様を確定する
- コーディングエージェントにサブタスクの仕様書を Markdown で書いてもらう
- それを見て以下を行う
- 分からない所は質問
- 意図していない部分は修正依頼
- 大体、「ここはどうしますか」みたいな質問がファイルの中に記載されているので、それに回答する
- サブタスクの仕様書も確定したら、各サブタスク毎にコーディングエージェントに実装を依頼する
Spec Kit も使ってみたのですが、まだピンとこなかったので、今のところはコーディングエージェント(Claude Code や Codex CLI)のみを使っています。
ディレクトリ構成
まだ試行錯誤中ですが、以下の通りです。
- /docs/ : 仕様書等を入れるディレクトリ
- dev/ : コーディングエージェント向けのディレクトリ(今考えるともう少し良い名前に変えたい)
- issueNN-add-foo-feature/ : GitHub の issue 単位でディレクトリ作成
- 00-master-spec.md : 「流れ」の1で作成する大元の仕様書ファイル
- MM-some-subtask.md : サブタスクの仕様書(サブタスク毎に作成)
- issueNN-add-foo-feature/ : GitHub の issue 単位でディレクトリ作成
- dev/ : コーディングエージェント向けのディレクトリ(今考えるともう少し良い名前に変えたい)
大元の仕様書に含めている内容
このくらいの簡単な内容を書いています。
- Background: なぜこのタスクをやるのかという背景の説明
- Goal: このタスクで達成したいこと
- Out of Scope: このタスクのスコープ外のこと
- Rough Implementation Plan (Sub tasks): サブタスクをリスト形式で
生成 AI がよしなに色々補足・肉付けしてくれるので、最初から完璧な物を書こうとしなくても良いです。
補足・考察等
生成 AI の作業中は何をするか
最初の方に書いたとおり、生成 AI が何か作業している間はぼーっと画面の前で待っていないで、別のタスクをします。
元々は、その時間に飲み物を飲んだり軽い運動とかをしていたのですが、一日中コーヒーを飲んだり運動し続けるわけにもいかないので、結局だらだらネットを見たりという悪い習慣が出来ていました。
今回の開発方法によって複数のタスクを並行して作業するようになり、AI を待つ間にだらだらする時間は確実に減ったと思います。
コンテキストスイッチの問題
コンピューター(CPU)はコンテキストスイッチのコストは低いですが、人間は複数のタスクを並行して実行すると効率が落ちます。特にタスクを切り替えた直後は、切り替え後のタスクの情報を思い出したりしなければいけないので効率が低いです。
個人的な対応方法は以下の通りです。
- 3つのタスクを全く別の同じくらい負荷の高いタスクにするのではなく、関連するタスクにする
- 例えば、Aというタスクのサブタスク1, 2, 3を同時に行うようにする、など
- 3つのタスクのうち1つは軽いタスクを混ぜる
- 例: タスクAサブタスク1の実装、タスクAサブタスク2の実装、ウェブサイトのタスクA関連ページの更新、の3つを同時に行う、など
- タスク切り替え後にそのタスクのことをすぐ思い出せるように、必要な事はドキュメントにしっかり書いていく
- 今回の方法であれば、サブタスクの仕様も Markdown で書いてあるので、その点でも有用です
とはいえ、人によって複数のタスクを並行して実行する人が苦手な人もいると思います。そういう人は、実装系のタスクの合間にお客様からのメールや同僚からのメッセージに返信する、今やっているタスクで不明な点をネットで調べる、などして時間を使うのが良いと思います。
私はマルチタスクは割と得意な方だとは思いますが、3つで十分かなと思います。というか、環境は3つ用意していますが、実際には2つだけ並行作業して残りの1つは使っていない時間も多いです。1つのサブタスクを AI が実装する時間は5〜10分前後が多いので、2並列でも待ち時間はほぼ発生することはありません。
使っている AI エージェント
この項は全て個人の感想です。
Claude Code をしばらくメインで使っていたのですが、最近は Codex をメインに使っています。面倒くさがり屋な性格のため、CLAUDE.md をあまり頑張って育てたりしていなかったのもあるかもしれませんが、最近はいまいち思ったようなコードが出てこない気がします。Codex は、それほど細かく指示しなくても割と期待通りの動作をしてくれます。
例えば、他の人のネット記事とかを見ると「曖昧な点は実装前に全て質問する」とかの細かい指示を CLAUDE.md や AGENTS.md に記載している例も見ます。当然効果はあると思いますが、現実の仕事だと、出来る人間ならうまくバランスを取って、必要なところは質問して自分で判断すべき所は自分で判断して進めると思います。コーディングエージェントも同様に、あまり事細かく指示をしなくてもプロフェッショナルな仕事をしてくれた方が助かります。
大元の仕様書を作成する能力
生成 AI に実装させる方法は、結局いかに最初の仕様書をしっかり作るかが大事です。生成 AI の発展によって、ソフトウェア開発の業務で人間が行うべき事の抽象度が上がったという事です。
ただ、「しっかり」というのは、なかなか言語化が難しいところではありますが、詳細に記載すれば良いというわけでは無いように思えます。要点を押さえておけば詳細は AI が肉付けしてくれますので。具体的な例を出すと、エラー処理などは、特殊な要件が無い限りはそこまで細かく書かなくても AI が定番の一般的なエラー処理の仕様を書いてくれます。逆に、そのシステム・業務固有の話・要件はそれなりに細かく説明する必要があります。
では、そうした仕様書を作成する能力はどのように身につくのでしょうか。大雑把には
- 論理的な文章を作成する能力
- 業務要件等を把握して整理する能力
に大別できると思います。そして、両方とも座学は重要だと思いますが、業務における経験も重要だと思います。前者はソフトウェア開発以外の業務からも身につけることが出来ますが、後者に関してはソフトウェア開発の現場から得る部分が多いと思います。
今後
どこまで自動化するか
ここ最近見たネットの記事で、Claude Code のメイン開発者だったかが、ブラウザのテストやバグ修正なども自動化し、AI エージェントも最大で(確か)15並列動かしている、みたいな実例も見ました。ある程度参考になる部分もありつつ、一般人にはそのまま適用できない部分もあるので、自分の頭で考えて試行錯誤するのも大事だと思っています。
とりあえず以下は取り入れていこうと思っています。
- 要件からテストを自動生成する
- テストが通るような実装を自動生成する
UI の確認とかもある程度自動化は出来ると思いますが、完全に自動化するのは直感としてなんか怖い気がするので、当面は行わないかと思います。
育成の問題
世間で良く言われるとおり、こうした AI 主導のワークフローはある程度経験豊富なエンジニアでないとなかなか機能しませんが、現時点でそうした経験が少ないエンジニアをどうやって育てていけば良いのでしょうか。
これに関しても色んな意見が出ていますが、現時点での私の意見は以下の通りです。
- 短期〜中期: エンジニアは二極化して、上級開発者は少数選抜育成型になる
- 自衛隊員(防衛大卒 vs. 普通の隊員)みたいなイメージ
- 長期: AI の発達によって、実務経験的も AI が提供するシミュレーション的なものによってある程度は獲得できるようになる
- 門戸は広く開かれているが、個人の適性・努力などによって差がつく
- つまり現在とそこまで変わらなくなる
最後に
生成 AI がソフトウェア開発を大きく変えています。(同じような事をブログ等で何回書いたか覚えていません。)人間がある程度の仕様を作成し、生成 AI に仕様の詳細化・実装を依頼することで、開発の時間を短縮できます。また、生成 AI が作業している間に別のタスクにも取りかかることで、さらに効率を上げることが出来ます。
ただ、こうしたワークフローは、経験豊富な上級開発者が仕様を適切に仕様書に落とし込む事が出来ないと機能しません。そして、そうした上級開発者をどうやって育成していくかは、世間のみんなが苦労・試行錯誤しているところだと思いますし、私としてもまだ確たる結論は出せていません。
今後も試行錯誤しながら自分の、そしてチームの業務を改善していきたいと考えています。