AIを使った開発が、当たり前になりました。
最初は、コーディングを任せる道具でした。いまでは仕様を考え、コードを書き、テストし、フィードバックを受けるところまで一緒に進みます。プロダクト開発のパートナー、と呼んでもよいでしょう。
一つだけ文句があります。
楽な仕事から先に取られました。残ったのは、判断が重く、頭を使い、失敗すれば責任までついてくる仕事です。便利になったはずなのに、なぜか人間の仕事は難しくなりました。
それでも、悪くありません。AIとプロダクトを作る知見が少しずつ溜まってきたので、現在の進め方を書き残します。
まず、仕様を詰めてもらう
コードを書く前に、AIへ仕様を問い詰めてもらいます。
以前は、複数人で会話しながら要望を整理していました。いまも、人との対話が出発点であることは変わりません。まずクライアントや関係者から話を聞く。その内容をAIへ渡し、決め切れていない部分を洗い出します。
この工程では、grill-me というスキルを使っています。計画や設計に対して質問を重ね、判断の枝を一つずつ明らかにするためのスキルです。
検討する範囲は広く取ります。
- イベントストーミングとドメインモデル
- 集約の境界と状態遷移
- アーキテクチャと外部システム
- ディシジョンテーブルと権限
- エラー、回復条件、エラーコード
- 未決の論点とユーザーストーリー
- 正常系だけでなく、境界値と失敗時の振る舞い
例を増やすだけでは足りません。どこから挙動が変わるのか。誰が、どの条件で、何を許されるのか。境界を明確にすると、あとで実装を頼んだときのずれが減ります。
鍋の底が見えるまで煮詰める。ただし、焦がさない。よい火加減で、何度も。
仕様は対話のために使う
整理した内容はMiroなどへ書き出し、クライアントや関係者と確認します。そこで得たフィードバックを、もう一度AIへ渡す。再び質問し、直し、議論する。その繰り返しです。
MVPの輪郭が見えたら、作業をGitHub Issuesへ分けます。原則は、一つのIssueに一つのPull Request。バックエンドなら、差分が200行前後に収まる大きさを一つの目安にしています。
200行は品質を保証する数字ではありません。フロントエンドはマークアップだけでも膨らみますし、生成ファイルが混ざる場合もあります。大切なのは、変更の目的を一つに絞り、人が短い時間で意図と影響を確認できることです。
最後に残る仕様はコードである
仕様書を作ること自体が目的ではありません。資料は、ゴールを共有し、MVPを短い期間で作るために使います。実装が進めば、最終的な振る舞いを決めるのはコードとテストです。
自然言語には曖昧さがあります。その余白から、感情や文化が生まれる。私は、そこが好きです。けれど、権限や課金、状態遷移の境界に、解釈の余地は残したくありません。
だからプログラミング言語は強い。少なくとも、実行される振る舞いについては、自然言語より厳密です。
新しい開発手法を発明したいわけではありません。これまでのプロダクト開発で培われた実践を、AIという強力な相手と、速く反復する。それが目的です。
Issueを実装してもらう
仕様が固まったら、実装は驚くほど単純です。Issue番号を渡し、Pull Requestを作ってもらいます。
人間の時間は、レビュー、リファクタリング、ドキュメントの整備へ寄せます。コードを書く量は減りました。ただし、コードを読む量は減りません。むしろ増えました。
レビューの基準をリポジトリへ置く
レビューにはGitHub Copilot code reviewを使っています。リポジトリ全体の規則は .github/copilot-instructions.md に置き、アーキテクチャ、テスト、セキュリティ、命名など、毎回確認してほしい観点を短く書きます。
指示は、長ければよいものではありません。曖昧な理想論より、検査できる規則を置く。GitHubのドキュメントにもあるとおり、AIによるレビューは非決定的で、すべての指示へ毎回同じように従うとは限りません。補助線として使い、最終判断は別に持ちます。
保守もワークフローへ入れる
.github/workflows では、Pull Requestの作成時にADRが必要な変更かを確認します。定期実行のワークフローでは、静的解析やテストだけでは拾えない改善候補を洗い出し、Issueとして残します。
狙いは、人間が思い出さなくても、品質を保つための問いが定期的に現れる状態です。ドキュメントが古くなれば、AIも古い前提でコードを書きます。コードと資料を一緒に更新する仕組みは、次の実装の質にも効いてきます。
自動化できる工程は増えました。それでも、すべてを自動でマージするつもりはありません。Pull Requestごとに人が差分を読み、ブラウザで動作を確かめます。認証、権限、課金、データ破壊につながる変更は、さらに慎重に扱います。
ここがボトルネックです。
けれど、AIを中心に据えるのではなく、AIと開発すると考えれば、自然な境界でもあります。人間は意図と体験を判断する。AIは探索、実装、反復を速める。得意な仕事を分ければよいのです。
そのためにも、Pull Requestは小さく保ちます。小さな差分は、AIのためではありません。読む人のためです。
人間の仕事は、まだ残る
AIと人間では、得意なことが違います。その違いは、よいと思っています。
AIは、決まった範囲を速く探索し、疲れずに反復できます。人間は、何を作るかを選び、曖昧な要望の裏側を読み、体験として正しいかを判断します。責任を引き受けるのも、いまのところ人間です。
まあ、こんな感じです。
一緒に作れるのは楽しい。ただ、楽な仕事を取られ、面倒でつらい仕事をきれいに残されたことだけは、まだ少し悲しく思っています。