AI×アジャイル開発探検記#1 仕様化・文章化・ルール化で見えてきたこと

1. はじめに
私たちがジョインしているプロジェクトでは、Cursorを使って開発を進めています。
これまで設計や調査・レビューなどでAIを使うことはありましたが、コーディングの大半をAIに任せるのは初めてでした。
正直、ワクワクよりも「本当にうまくいくのか?」という不安のほうが大きかったです。
- どうすればAIに仕様を守らせられるのか?
- コードの品質をどう担保すればいいのか?
- テストや設計の整合性は維持できるのか?
不安を抱えたままでは進められないと思い、社内の有志で「AI駆動開発の品質保証を考える会」という雑談会を開きました。
話すうちに、AIとうまく付き合うためのいくつかのヒントや指針が見えてきました。
このシリーズ (AI×アジャイル開発の手探り実践) では、その指針をもとに、実際のスプリントの中で試してきた工夫や気づきを少しずつまとめていきます。
今回はその 第1回として、「仕様化・文章化・ルール化の実践と、それを進める中で見えてきたこと」を紹介します。
2. 雑談会で見えた「AIとうまくやるための3つのコツ」
雑談会では、AIを試したメンバーからいろんな課題が出ました。
- 存在しない関数を呼び出すテストを生成してしまう
- 一見通っているように見えるが、意味のない“嘘のテスト”を書いてしまう
- 一度に大きなタスクを渡すと、途中で文脈を失う
こうして見えてきたのは、AIへの私たちの伝え方の問題でした。
AIは曖昧な指示に忠実に従います。結果として、指示の曖昧さがそのままコードに現れます。
雑談会を通じて、下記のような基本ルールを設けると開発しやすそうだと感じました。
- タスクを大きくしすぎない
- 不明瞭な指示を与えない
- 仕様を明確に定義する
これらを意識するようになって、Cursorを使った開発への不安が少しずつ軽減されていきました。
「AIに何をどう伝えれば理解してもらえるか」を考えることが、結果的にチーム全体の思考整理にもつながっていきました。
3. 見えてきた指針を、実際の開発に落とし込む
この雑談会で得たヒントをきっかけに、実際のアジャイル開発にAIを組み込みながら、試行錯誤を重ねていきました。
ここからは、開発の中で直面した課題と、そのときの取り組みを紹介します。
3-1. Issueテンプレートを設計し、AIに十分な情報を渡す
背景
AIにはIssue内容を与えてコーディングさせていましたが、AIに実装計画を出してもらおうとしたときに、背景情報や前提条件が足りず、出力が安定しないことが多くありました。
アクション
テンプレートを設計して「ユーザーストーリー」「背景情報」「やらないこと」「補足情報」を必須項目に追加しました。
さらに、Issue内容を基にCursorにGherkin形式(Given–When–Then)の受け入れ基準を生成させ、
それを人間がレビューして確定するようにしました。
結果・学び
AIの出力が安定し、仕様の抜け漏れも減りました。
またチーム全体で「AIに説明できるか?」を基準にIssueを書くようになり、自然と粒度の揃った課題管理ができるようになりました。
Gherkin形式の受け入れ基準の例
Feature: ユーザー登録機能
Scenario: 新規ユーザーが正常に登録できる
Given ユーザーが登録画面にアクセスしている
When ユーザーが有効なメールアドレスとパスワードを入力する
And 「登録」ボタンをクリックする
Then アカウントが作成される
And 自動的にログイン状態になる
And 登録完了メッセージが表示される
Scenario: 既に登録済みのメールアドレスで登録しようとした場合
Given "test@example.com" というメールアドレスが既に登録されている
When ユーザーが同じメールアドレスで登録しようとする
Then エラーメッセージ「このメールアドレスは既に使用されています」が表示される
And アカウントは作成されない
3-2. READMEとcursorrulesを整備し、AIに開発方針を伝える
背景
Cursorで実験的にコーディングを行った際、出力のたびに異なるアーキテクチャやテスト設計が提示されることがありました。このままでは一貫性のないシステムが構築される懸念がありました。
アクション
READMEとProject Rulesを段階的に整備し、AIと人間が同じ前提を共有できるようにしました。ChatGPTとの議論を踏まえ、「AIが参照すべき文脈」を明示的に文書化しました。
役割分担を明確化:
- README.md:チームの意図と開発方針を定義(アーキテクチャ指針、テスト戦略、Definition of Doneなど)
- .cursor/rules (Project Rules):AIが従うべき具体的な指示を定義(AIへの依頼フォーマット、禁止事項、コード生成時の必須要件など)
モノレポ構造に対応するため、ルート・backend・frontendそれぞれにProject Rulesを定義し、作業対象に応じて適切なルールが適用されるようにしました。
backend/README.md(抜粋)
## 🧩 アーキテクチャ指針
本システムは、**疎結合でテストしやすい構成**を重視しています。
### 原則
- **API や Service 層から boto3 を直接呼ばない**
→ 永続化は必ず Repository を経由します。
- **例外設計は 3階層で分離**
- `DomainError`(業務ルール違反)
- `ApplicationError`(ユースケース例外)
- `InfrastructureError`(外部API・DynamoDB障害)
## 🧭 開発方針
### テスト駆動開発(TDD)
- **必ず t_wada(和田卓人)氏の推奨する方法**で進める。
- Red → Green → Refactor のサイクルを厳守。
### テスト戦略
- **pytest** を用いて自動テストを実行。
- ユニットテスト:Service層を中心にモック化。
- 統合テスト:DynamoDB(moto / LocalStack)を利用。
.cursor/rules/backend.mdc(抜粋)
# Tests
- すべての機能追加・変更は **TDD(Red→Green→Refactor)** で行う。
- pytest を使用し、ユニットテストでは Repository をモック化。
- 統合テストでは moto または LocalStack を使用。
# Architecture
- 層構造:API/Router → Service/UseCase → Repository(Interface) → Infrastructure(boto3 Adapter)
- **禁止**:API / Service 層から boto3 の直接呼び出し。
- **Repositoryパターンを必須**:DynamoDBアクセスは Repository 経由とする。
# AI Usage (How to Ask AI)
- AI に依頼する際は以下の4点を明確にする:
1. 対象(どのファイル/関数か)
2. 目的(何を実現したいか)
3. 受入条件(どんなテストが通れば完了か)
4. 出力範囲(どこまで編集してよいか)
テスト戦略の明確化
特に重要なのは*テスト戦略を明確に定義することです。AIはテストコードを生成する際に、どのような方針で、どういった観点のテストを書けばよいかが明確でないと、過剰なテストを生成したり、逆に不足したりします。
Frontendでは、Kent C. Doddsの「Testing Trophy」モデルを採用し、各テストレイヤー(Unit、Integration、E2E)の役割と優先順位を明確にしました。
また、テスト件数の目安や制約、カバレッジ目標を設定し、AIがテストを生成する際の判断基準を提供しました。
これらの戦略をREADMEと`.cursorrules`に記載し、AIがテストを生成する際に必ず参照するようにしました。また、テスト生成前に既存のテスト状況を確認し、制約を超える場合は人間に判断を促すよう指示しています。これにより、AIは「どの観点でテストを書くべきか」「どの程度のテスト量が適切か」を理解し、一貫性のあるテストコードを生成できるようになりました。
結果・学び
AIの出力がチーム方針に沿うようになり、テスト戦略や命名規則の一貫性が向上しました。特に、テスト戦略を詳細に定義したことで、AIが生成するテストコードの質と量が適切になり、過剰なテスト生成やテスト不足を防げるようになりました**。
READMEとルールファイルは、人間とAIの両方にとっての設計書として機能するようになりました。特にテスト生成やリファクタリングといった「AIフレンドリーな領域」では、チーム全体での再現性が大幅に向上しました。
3-3. DoDを定義し、品質担保を"仕組み化"する
背景
AIを使うことで、1つの機能を半日程度で完成させられるようになりました。しかし、コードレビューがこの速度に追いつかず、品質担保が開発速度に取り残されるリスクがありました。
アクション
DoD(Definition of Done)を定義し、品質担保の一部を明文化しました。カバレッジ閾値(Line/Branch 70%)を自動テストとCIチェックに組み込み、人間が確認すべき項目を明確にしました。
DoDの例:
- 受入基準を満たしている
- 静的検証を通過している(Linterと型チェックが警告・エラーゼロ)
- テストが通過している(カバレッジ基準 Lines≥70% / Branches≥70%)
- ビルドとデプロイが成功している
- ドキュメントが最新化されている
- セキュリティ・秘匿情報の取り扱いが適切
GitLab CI/CDのテストステージで、Lint、型チェック、テスト、ビルド検証を自動実行し、すべてのチェックが通過しない限りマージできない仕組みを構築しました。
結果・学び
DoDは今までの案件でも定義していましたが、AIがコードを書く場合は、明確なDoDの存在がより効果を発揮すると感じました。
人間がコードを書く場合、DoDは「チェックリスト」として機能し、開発者の自主性に依存した運用になりがちです。一方、AIがコードを生成する場合、DoDをREADMEや`.cursorrules`に明記することで、AIがコード生成時に品質基準を参照できます。さらに、DoDをCI/CDに組み込むことで、品質基準を満たしていないコードは物理的にマージできなくなり、自動的に品質が担保されます。
Lint、型チェック、テスト、ビルド検証などをCIで自動実行することで、レビューでは「コードの正しさ」よりも「設計意図」や「影響範囲」に集中できるようになりました。
3-4. コミット/MR をAIに生成させ、手間なく必要情報を記録する
背景
MRを人が書いていた頃は、内容にばらつきがあり、
レビュー時に「結局この変更は何?」と聞き返す場面が多くありました。
アクション
Cursorにgit diffを解析させて、コミットメッセージとMR本文をAIに生成させる運用に変更しました。
結果・学び
MR作成時間が数分から数秒になり、説明の粒度が一定化しました。
また、コミットメッセージに必要な情報が記載されるようになり、人間が履歴を読みやすくなったのはもちろん、Cursorの精度向上にもつながっています。
4. おわりに
今回は、今まさに走り続けているプロジェクトでの取り組みについて共有させていただきました。
AI駆動開発を実践する中で強く感じたことは、「AIに説明できるチケットは、人間にも分かりやすい」ということです。
ユーザーストーリーや受け入れ基準が明確で、「この開発でどんな価値を生み出すのか」が整理されているチケットなら、AIに任せても比較的スムーズに成果が出せます。
一方で、実現したいことが不明瞭だったり、受入基準が曖昧なチケットだと、AIは人間にとって斜め上な実装を行なってしまいます。
AIに伝わるように考えることは、自分たちが何を生み出したいのかしっかり考えるきっかけにもなっていると感じます。
今後も実践を続け、プロジェクトに区切りがついた際に、その結果や学びを改めて共有できればと思います。
この記事が「うちでも試してみようか」と思うきっかけになれば嬉しいです。
