AIへの取り組み Vol.2
ウォーターフォール型のAI駆動開発
はじめに
生成AIが登場した当初は、チャットで質問をしたり、コードの一部を書いてもらったりと、「AIと対話しながら作業を進める」という使い方が中心でした。
その後、AIがコードやファイルを読み取り、自ら複数の作業を進めるAIエージェントが登場したことで、AIの使い方も大きく変わってきました。コードを書く一部分だけではなく、要求整理や設計、実装、テストまで含めて、開発工程そのものをAIと一緒に進められるようになってきています。
そこで今回は、「マイコン上で動くアプリケーションの評価ツール」開発のプロジェクトでウォーターフォール型の開発工程をベースに、
- 要求分析
- 基本設計
- 詳細設計
- 実装
- テスト
- レビュー
- ドキュメント作成
といった各工程でAIを活用し、前工程の成果物を次工程へ引き継ぎながら開発を進めたので、その内容を紹介します。
対象とした評価ツールのシステムは、大きく次の3つから構成されています。
- 利用者が実際に操作するWindowsのフロントエンドアプリケーション
- 実機(マイコンボード)上で動作するファームウェアアプリケーション
- 地図や更新ファイル等の配信物やAPIの提供と認可を行うサーバーアプリケーション
このうちソフトウェアの更新機能や地図描画機能などの「サーバー連携機能」を中心に、各開発工程でAIをどのように活用したかを紹介します。
AI駆動開発とは、AIを補助ツールとして少し使うだけでなく、要求分析・設計・実装・テスト・レビュー・ドキュメント作成まで、開発工程全体にAIを組み込む進め方です。
ウォーターフォールとは、要求分析、設計、実装、テストといった工程を順番に進め、前工程の成果物を次工程の入力として引き継いでいく開発手法です。
AIと対話しながら、雰囲気(Vibe)や試行錯誤を重視してコードを書く「Vibe Coding」と呼ばれる開発手法もありますが、今回は対話だけで開発を進めるのではなく、ウォーターフォール型の工程をベースに、各工程の成果物を次の工程へ引き継ぎながら開発を進めました。本記事では、その進め方をご紹介します。
要求分析
AI駆動開発の最初のステップとして、チーム内で考えている
- 実現したい機能
- 解決したい課題
- 開発の目的
をヒアリングし、AIを活用しながらソフトウェア要求を整理しました。
ヒアリングした内容は、AIを使って似た要望をまとめたり、曖昧な部分や追加で確認が必要な点を洗い出したりしながら整理しました。整理した内容は、大きく2種類に分けました。
要求仕様書
内容が明確になっており、仕様として確定できるものを記載します。
確認項目一覧
次のような、まだ判断が必要なものを記載します。
- 実現方法が決まっていないもの
- 複数の実現案が存在するもの
- 松・竹・梅のように段階的な選択肢があるもの
- 関係者への追加確認が必要なもの
確認項目一覧をもとに話し合いや相談を行い、決まった内容を要求仕様書へ反映します。
この流れを繰り返していくことで、曖昧な項目や抜け漏れを減らしながら要求を具体化していきました。
AIは要求を整理したり、確認すべき点を洗い出したりする役割を担いますが、最終的な仕様や方針についてはチームで確認して決定しました。
設計工程
設計工程では、要求仕様書をAIに読み込ませ、その内容を前提として
- システム構成
- 技術スタックの選定
- 各機能の役割
などを整理しながら基本設計を行いました。
次に、作成した基本設計書をAIに読み込ませ、
- API仕様書
- テーブル定義仕様書
- 処理シーケンス
などを含む詳細設計書を作成しました。
前工程の成果物を次工程の入力として利用することで、要求仕様書、基本設計書、詳細設計書の内容につながりを持たせながら、段階的に設計を具体化していくことができました。
また、AIに参照させる前提条件や確定事項を文書として明示することで、
- コンテキスト不足によるハルシネーション
- 要求仕様と矛盾する設計
- 基本設計と詳細設計の不整合
- AIによる独自解釈
を減らすことができた点も、この進め方の利点でした。AIが生成した設計案については、そのまま採用するのではなく、人が要求との整合性や技術的な実現性をレビューしました。不足している内容や実際の環境に合わない部分には修正や補足を加え、設計書へ反映することで、設計内容を効率的に整理しました。
実装工程
実装工程では、詳細設計書をAIに読み込ませ、その内容を前提としてコードを生成しました。要求仕様書、基本設計書、詳細設計書と段階的に整理してきた内容を、実装時の入力コンテキストとして引き継いでおり、設計上の前提や確定事項があらかじめ文書化されていたため、設計方針から外れた実装や、AIによる独自の解釈が入り込む余地を減らせました。
ソースファイルを変更したタイミングやAIエージェントが作業を終えたタイミングで単体試験と静的解析を走らせ、コード変更によるデグレード(既存機能の劣化)が起きていないかを確認し、不具合の混入を減らす工夫を行いました。一例ですが、以下のようなHooksで制御が可能です。

今回担当した機能は、利用者が操作する画面や実機への書き込みを担うフロントエンドと、配信物の提供や認可を担うサーバーの両方にまたがっていました。
通常であれば担当者や作業工程を分けて進める範囲ですが、今回は時間的な制約から、フロントエンドとサーバーの実装を並行して進めました。この進め方が可能だったのは、詳細設計の段階でAPI仕様やデータ構造を確定し、両方の実装から参照できる共通文書を用意していたためです。
フロントエンド側とサーバー側の各AIセッションでは、この共通仕様書を参照先として利用しました。各リポジトリの既存コードやプロジェクト固有のルールも参照させ、別々のセッションで並行して作業しながらも、同じ前提とそれぞれのリポジトリ固有の実装方針に基づいて実装を進められるようになりました。
繰り返し作業のスキル化
開発を進める中で、同じ形式の作業をAIへ繰り返し依頼する場面がありました。毎回の対話で同じ条件や手順を説明していると、
- 指示の一部が抜ける
- 成果物の粒度が変わる
- 書式が変わる
- セッションごとに判断基準が変わる
といった問題が発生します。そこで、繰り返し発生する作業については、
- 必要な入力情報
- 確認する観点
- 作業手順
- 出力形式
をあらかじめ定義し、個別のAIスキルとして登録しました。
スキル名を指定して呼び出すことで、セッションが変わった場合でも、同じ手順と基準で処理できるようにしました。
今回はプロジェクト固有のスキルではなく、様々なプロジェクトで使える汎用的なスキルを紹介します。
一つ目は、Jiraへのコメント作成を支援するスキルです。Jiraの運用では、実施した作業、調査結果、発生した課題、対応内容、残っている確認事項などを記録します。記載する観点や書式はある程度決まっていますが、作業内容を整理して文章にするには一定の手間がかかる課題がありました。

そこで、作業の経過や実施内容を入力すると、Jiraのコメントとして必要な情報を整理し、投稿文の候補を生成するスキルを登録しました。あわせて、Jiraのチケットに記載された課題や依頼内容を読み取り、対応すべきアクション、確認が必要な点、作業の優先事項を整理するスキルも用意しました。
これにより、記録内容の粒度や書式を揃えながら、対応漏れや確認事項の見落としを減らせるようになりました。ただし、生成された内容をそのまま投稿するのではなく、実際の作業内容やチケットの意図と合っているかを人が確認し、必要に応じて修正したうえでJiraへ反映しています。
二つ目は、コミットメッセージの生成です。プロジェクトでは、変更種別を示す接頭辞、要約の文字数、本文の書式など、コミットメッセージの記述ルールが決まっています。そこで、「/commit-message」を呼び出すとGitの差分を確認し、これらのルールと実際の変更内容に沿った候補を作成する手順として登録しました。

システムテストへの展開
関数やクラス単位の動作については、実装工程で単体試験としてコード化し、継続的に実行しています。一方、利用者の操作や複数のコンポーネントをまたぐシステムテストについては、試験項目の管理や更新を効率化するための仕組みを現在整備しています。
具体的には、試験項目をMarkdownで管理し、実施用のExcel試験書を生成する構成としています。
試験項目をMarkdownで管理する
試験項目は、
- 各画面
- 接続・切断
- ログ保存
- ファームウェア更新
など、機能ごとにMarkdownファイルを分けて管理します。
Markdownには、
- 前提条件
- 操作内容
- 確認方法
- 評価基準
などを記載します。
一方、次のような
- 試験結果
- 確認者
- 確認日
- 確認バージョン
- 備考
などの実施記録は、Excel生成時に記入欄として追加する想定です。
Markdown形式で管理することで、試験項目の変更内容をGitの差分として確認でき、Merge Request上でレビューしやすくなります。
また、AIから試験項目を追加・修正する場合にも、Excelのセルや書式を直接操作するより、構造化されたテキストとして扱えるため変更を反映しやすくなります。
AIに与えるコンテキストを絞る
試験項目を機能単位でファイル分割することには、差分レビューのしやすさに加えて、もう一つ目的があります。
AIに与えるコンテキストの範囲を、対象機能に応じて制御するためです。
例えば、ファームウェア更新の試験項目を作成する場合には、
- ファームウェア更新に対応するMarkdownファイル
- 関連する設計書
- 関連するソースコード
- 操作マニュアル
だけをAIに参照させます。
作業対象に応じて入力する情報を絞ることで、リポジトリ全体を読み込ませる場合と比較してトークン使用量を抑えられます。
さらに、関係のない画面や別の更新方式の情報が混ざることを防げます。

ファームウェア更新の場合、
- 更新確認ボタンの活性制御
- 更新有無の判定
- 更新ファイルのダウンロード
- ハッシュ値の照合
- 実機への書き込み
- 書き込み失敗時の再実行
- 更新後のバージョン確認
といった一連の利用シナリオに沿って、試験項目が不足していないかをAIに検討させやすくなります。
また、試験項目と操作マニュアルを比較することで、試験に必要な操作手順、注意事項、エラー発生時の対応などがマニュアルに記載されているかを確認し、マニュアル側の不足項目の洗い出しにも活用する予定です。
評価作業者には、Markdownから生成したExcel試験書を渡し、試験結果をExcelへ直接記入してもらう運用を想定しています。試験項目の更新と試験結果の記録を分けることで、試験仕様の差分確認やレビューを行いやすくしながら、従来のプロジェクトと同様のフォーマットで試験運用もできます。将来的には、試験実施や結果記録の一部についても自動化を検討しています。
現時点では仕組みを整備している段階ですが、試験項目をAIが追加・修正しやすい形式で管理し、対象機能に応じて参照するコンテキストを絞ることで、システムテスト仕様書の作成や更新を効率化できると考えています。
まとめ
今回の取り組みを通じて、AI駆動開発では、AIに自由に生成させるだけでなく、前提となる文書や作業手順、テストなどをあらかじめ整えておくことが重要だと分かりました。
生成AIは、要求の整理、設計案の作成、コード生成、文章作成など、正解が一つに定まらない作業を柔軟に進められる一方で、同じ指示を与えても出力が変わることがあります。そのため、開発の前提や確定事項は要求仕様書や設計書として固定し、繰り返し発生する作業はAIスキルとして手順化しました。さらに、生成されたコードについては単体試験や静的解析を機械的に実行し、その結果に基づいて妥当性を確認しました。
このように、検討やアイデアの生成にはAIの「確率論的な性質」を活用し、仕様の確定、作業手順、品質確認には文書・ルール・テストといった「決定論的な仕組み」を用いました。AIの出力の揺らぎをなくそうとするのではなく、揺らぎがあっても開発の品質や一貫性を保てるように、工程全体を設計する考え方で取り組みました。
AIによる柔軟な生成と、決定論的な仕組みを適切に組み合わせることで、開発速度を高めながら、要求から実装までの一貫性や成果物の品質を保ちやすくなりました。AIにすべての判断を委ねるのではなく、AIに任せる部分と、人や仕組みによって確実に確認する部分を設計することが、AI駆動開発では重要だと感じました。これは、クラウド開発から組み込みまで、あらゆるソフトウェア開発に共通する設計の考え方だといえます。
クラウド開発においても、AIに任せる工程と自動化・テストによって担保する工程を整理しながら、より効率的で再現性の高い開発プロセスを構築していきたいと考えています。