広告

AIで126K行のAndroidアプリを作った—実際に機能したワークフロー

Dev.to / 2026/3/29

💬 オピニオンIdeas & Deep AnalysisTools & Practical Usage

要点

  • 著者は、AIコーディングの失敗の多くは、平易な英語プロンプトに対して本番投入可能なシステムコードを期待してしまうこと、そしてAIまわりの構造化されたエンジニアリングプロセスが欠けていることに起因すると主張している。
  • 安全性が重要な126,000行規模のAndroidアプリ(すべてAI生成)を構築したと述べており、単なるチャットによる反復プロンプトだけではなく、事前の設計(アーキテクチャ)と共有コンテキストを中心に据えたワークフローで進めた。
  • ワークフローは「Architecture before code (BMAD)」から始めることで、プロダクト要件ドキュメント、モジュールの境界/レイヤー、エラーハンドリングを定義するアーキテクチャドキュメント、そしてコーディング規約を標準化するプロジェクトコンテキストを作成する。
  • この1週間のアーキテクチャ策定フェーズにより、その後のAIとの会話で実際のシステムに適合するコードを生成できるようになり、そうでない場合に発生して膨大な手戻りを招く衝突が減ったと報告している。
  • さらに、リポジトリ直下の`CLAUDE.md`を「憲法(constitution)」として用意し、Claude Codeを通じてAIが毎回の会話開始時に一貫したプロジェクトルールを読み込めるようにする方法も示している。

AIコーディングツールを試している多くの開発者が、同じ壁にぶつかります。チャットを開いて「todoアプリを作って」と入力すると、見た目は正しく見える何かが返ってきます。そして、そのゴチャゴチャを直すのに3時間を費やします。次はもっと大きなプロジェクトで試しますが、もっと早く崩れます。最終的に、AIコーディングは誇大広告だと結論づけます。

私も同じ経験をしました。ですが、私はアプローチを変えました——ツールではなく、その周りのプロセスを。

4か月以上かけて、How Are You?! を作りました。これは、ひとりで暮らす高齢者を見守る安全性がクリティカルなAndroidアプリです。Kotlinの126,000行。144バージョン。130個のテストファイル。3つの言語。開始時点でKotlinの経験ゼロのソロ開発者です。コードベース全体はAIによって生成されました——私はKotlinを手書きで一度も書いていません。

この記事はアプリの話ではありません。ここまで可能にしたワークフローの話です。

なぜ多くの人がAIコーディングで失敗するのか

理由は2つです:

  1. 期待値が間違っている。 人々は「機能を平易な英語で説明すれば本番コードが出てくる」と期待します。これは関数なら成り立ちます。しかしシステムには成り立ちません。AIはエンジニアリングの代替ではなく、増幅器です。入力が曖昧なら、出力も曖昧になります。

  2. AIの周りに構造がない。 チャットを開いてプロンプトし、コードを受け取って貼り付け、またプロンプトします。アーキテクチャがありません。共有された文脈がありません。蓄積された知識がありません。毎回の会話は最初からゼロで始まります。

解決策は、より良いプロンプトではありません。AIを参加者として扱う、より良いエンジニアリングプロセスです。

ステップ1:コードの前にアーキテクチャ(BMAD)

コードを1行も書く前に、私は BMAD(AI支援開発のための構造化された手法)を使って、作りました:

  • プロダクト要件ドキュメント — アプリが何をするのか、誰のためのものか、制約は何か
  • アーキテクチャドキュメント — モジュール境界、レイヤの責務、エラーハンドリングのパターン、データフロー
  • プロジェクト文脈 — コーディング標準、命名規則、DO/DON'Tのリスト

これには約1週間かかりました。遅いと感じました。ですが、プロジェクト全体で最も価値のある1週間でした。

なぜでしょう? その後のAIとのすべての会話が、共有された土台の上に成り立ったからです。AIは「私のアプリがどんなものか」を当てずに済みました——知っていたのです。モジュール境界は定義されていました。エラーハンドリングは標準化されていました。システムが文書化されていたので、AIは実際のシステムに合うコードを生成できました。

アーキテクチャドキュメントがないと、AIは単体では正しく見えるコードを生成しますが、他のすべてと衝突します。その結果、機能を作る代わりに、矛盾した出力をマージする作業に時間を費やしてしまいます。

ステップ2:CLAUDE.md — 憲法

Claude Code は、会話の開始時に毎回、プロジェクトルートから CLAUDE.md ファイルを読み込みます。これは私のリポジトリで最も重要なファイルです。

私のものには以下が含まれています:

  • モジュール境界 — Gradleによって強制(どのモジュールが何をimportできるか)
  • コアのパターン(すべてのユースケースが Result<T> を返す、ViewModelは StateFlow を公開する(GlobalScope は使わない))
  • クリティカルなDON'T — 本番でのバグから生まれたルールを簡潔にまとめたもの
  • サブシステムのクイックリファレンス — 各領域(AlarmManager、センサー、AI、メール、請求、GPS、権限)ごとの詳細ルールへ誘導する表

そのファイル内のすべてのルールは、「一度だけそれを破った結果、何かが壊れた」から存在します。プロジェクトとともにファイルは成長します。

重要な洞察はこれです:CLAUDE.mdは、一度きりの学びを恒久的な制約に変える。 AIは、そこに置いたルールを忘れません。私は忘れがちです。

ステップ3:開始/停止コマンドによる“生きた”ドキュメント

私は、開発セッションの前後を必ず挟むために、カスタムのスラッシュコマンドを作りました:

/howareyou-start — デベロッパーブリーフィング、クリティカルなルール、リリースノート、現在のバージョンを読み込みます。AIは、私が最初のプロンプトを書いた時点で、すべてを読み取ります。所要30秒で、以前私が犯していたミスの80%を防いでくれます。

/howareyou-stop — リリースノートを更新し、古いエントリをアーカイブし、あらたな学びがあれば CRITICAL_DON'T.md を更新し、デベロッパーブリーフィングを更新し、バージョンを上げ、コミットしてプッシュします。

ドキュメントは決して古くなりません。更新することが、リリースプロセスの一部であり、別タスクではないからです。私はドキュメントを手作業で更新しません。AIが、出荷作業の一部としてやってくれます。

これにより、フライホイールが回ります:より良いドキュメント -> より良いAI出力 -> バグが減る -> 学びが記録される -> より良いドキュメント。

ステップ4:具体的な技術仕様

新しい機能が必要になったとき、私は「旅行検知を追加して」とは言いません。BMADの技術仕様(tech spec)ワークフローを使って、次を明確に指定するドキュメントを作ります:

  • 正確な状態機械(HOME -> DAY_1 -> TRAVELING -> TRIP_ENDED)
  • データベーススキーマの変更(テーブル名、カラム型、インデックス)
  • どの既存クラスが影響を受け、どうなるか
  • エッジケースとエラーハンドリング
  • 書くべきテスト

仕様書は2〜5ページです。BMADのガイド付き会話で書くのに30分かかります。実装中のAIとの往復を何時間も節約し、「生成されたけど要件に合わない」という問題をなくします。

ルール:仕様書で十分に正確に機能を説明できないなら、私はそれを作る準備ができていません。まず(これもAIと一緒に)ブレインストーミングし、次に仕様化し、その後に作ります。

ステップ5:ブレインストーミングセッション

私はBMADのブレインストーミングをあらゆることに使います——コードだけでなく、価格戦略、UXの判断、マーケティング施策、SMS通知をサポートするかそれともメールに固執するか、といったことにもです。

パターンはこうです:セッションを開き、問題を説明し、AIに自分の前提を突かせます。議事録(トランスクリプト)を残します。私の最高のアーキテクチャ判断のいくつかは、AIがまだ考えていなかったエッジケースを指摘してくれたブレインストーミングセッションから生まれました。

ステップ6:毎週実行する自動監査

私のアプリは、AndroidのOEMが投入してくる電池殺し(Samsung、Xiaomi、Honor、OPPO——彼らはバックグラウンドアプリをそれぞれ別のやり方で殺します)に耐えなければなりません。これらのOEMは、互換性レイヤを壊しうるアップデートを絶えず出します。

私は2つの監査コマンドを作りました:

/howareyou-oem-audit — ウェブ上で最近のOEMの変更履歴エントリと破壊的変更を探し、その後、影響を受ける領域を私のコードベースからスキャンして、修正案を提案します。

/howareyou-gps-audit — GPSとロケーションAPIの変更(FusedLocationProviderの更新、OEMのGPS電力管理の変更)について同様に実行します。

/howareyou-full-audit — 両方を並列に実行し、優先順位付きのアクションプランを含む統合レポートを作ります。

私は毎週これらを実行しています。ユーザーに届く前に、壊れる変更を見つけてきました——たとえば、SamsungがOTAアップデート後にバッテリー最適化の除外をサイレントにリセットすること、Honorがwakelockタグのホワイトリスト挙動を変更すること、Googleが位置情報APIのパラメータを非推奨にすることなどです。

こういうことは、人間の開発者なら手作業で探すだけでも何時間もかかってしまう類のものです。AIは数分でそれをやり、見つけた内容を直接私のソースコードに対応づけます。

ステップ7:ワンコマンドでの公開

/howareyou-build-test    → signed release AABをビルド
/howareyou-publish-testingMode  → Google Playのinternal + closed testingにアップロード

「コードが準備できた」から「テスターが更新を受け取った」までを5分以内で実現し、ターミナルから離れる必要もありません。ブラウザも、Play Consoleのクリック操作も不要です。

ステップ8:インフラ監視

返却形式: {"translated": "翻訳されたHTML"}

Gemini APIキーのローテーションのために、私は6つのGoogle Cloudプロジェクトを使っています(各プロジェクトが無料リクエスト/日10K — 合計60K)。物事は壊れます。請求が無効化されます。キーが期限切れになります。

/howareyou-monitor — 6つのシャードすべてをチェックし、健全なもの、失敗したもの、そしてその理由を報告します。

/howareyou-fix-billing — 無効化されたシャードを共有の請求アカウントに自動で再接続します。

これらは開発タスクではありません。同じターミナルからコードを書きつつ、運用として対応しています。

Step 9: 2つ目のモデルで行うコードレビュー

機能を実装した後、BMADの敵対的レビューのワークフローでコードレビューを実行します。すべてのレビューで3〜10個の特定の問題を見つけるように設定されています — 「良さそうです」とは決して言いません。次を確認します:

  • アーキテクチャ準拠(モジュール境界は守られているか?)
  • テストカバレッジ(エッジケースはテストされているか?)
  • セキュリティ(ハードコードされたキーはないか? SQLインジェクション? XSS?)
  • パフォーマンス(不要なアロケーション? インデックスの欠落?)
  • プロジェクトのパターンとの一貫性

これにより、何時間もコードを見つめているせいで見落とすようなことが見つかります。敵対的な前提づけが重要です — 常に承認されるレビューは役に立ちません。

Step 10: 生きたドキュメントとして学びを残す

すべての本番バグが、CRITICAL_DONTS.md のルールになります。このファイルはサブシステムごとに整理されています:

  • AlarmManager: setAlarmClock() は1日3回以上呼ばない(Honorフラグを尊重)
  • Sensor: 常にFIFOをフラッシュし、古い読み取り値を破棄する(Honorがタイムスタンプをリベースすることを尊重)
  • Email: 受信者ごとに送信し、バッチ処理しない(Resendの配信追跡が壊れる)
  • GPS: 優先度のフォールバック全チェーンを使い、単一の getCurrentLocation() の呼び出しを信頼しない

このファイルには50以上のルールがあります。各ルールには(追加された時点の)バージョン番号と、その重要性の根拠(なぜ大事なのか)があります。AIは /howareyou-start コマンドで、毎回のセッション開始時にこのファイルを読み込みます。

このワークフローの中で最も過小評価されている部分です。多くの開発者は学びを頭の中にだけ置きます。頭は忘れます。ファイルは忘れません。

毎日のワークフロー

典型的な開発日がどのようなものかを示します:

  1. /howareyou-start — AIがすべてのコンテキストを読み込む(30秒)
  2. タスクを説明 — それが機能なら技術仕様で、修正ならバグの説明で
  3. AIが実装 — 私が差分をレビューし、テストを実行
  4. 反復 — 通常1〜3ラウンド
  5. /howareyou-stop — ドキュメント更新、バージョンを更新、コミット、プッシュ
  6. /howareyou-publish-testingMode — テスターがアップデートを受け取る

このフローで、私は1日に複数のバージョンをリリースします。急いでいるからではありません。「コードが動く」から「テスターが使える」までのオーバーヘッドがほぼゼロだからです。

これは何か(NOT)

  • これは「ノーコード」ではありません。言語が分かっているなら、必要に応じて確認し、修正する価値があります。時間があれば、必要な小さな修正は減っていくはずです。アーキテクチャを理解し、設計判断を行うのは常に良いことです。
  • これは楽ではありません。このワークフローを構築するのに数か月かかりました。ドキュメントは充実しています。
  • これは魔法ではありません。AIは間違えます。違いは、間違いがユーザーによって見つかるのではなく、プロセス(テスト、レビュー、ルール、監査)によって見つかることです。

数字

  • 126,000行 のKotlin(398ファイルにわたって)
  • 45,000行 のテスト(130ファイルにわたって)
  • 144バージョン リリース
  • 3言語(英語、ブルガリア語、ドイツ語)
  • 50+の本番学び が CRITICAL_DONTS.md に記録
  • 14か月(Kotlinの経験ゼロから、Google Playの本番アプリまで)
  • 9つのカスタムコマンド(開発ライフサイクル全体を自動化)
  • 0行 のKotlinを、私が手で手書きした

まとめ

AIのコーディングツールは、魔法のコード生成器ではありません。エンジニアリングのプロセスに対するフォースマルチプライヤーです。あなたのプロセスが「チャットを開く→プロンプトを打つ→最善を祈る」なら、失望するでしょう。

一方で、あなたのプロセスが「アーキテクチャをドキュメント化し、ルールを定義し、ライフサイクルを自動化し、すべての学びを記録し、敵対的にすべてをレビューする」なら — AIは不合理なほど効果的になります。

投資先は、より良いプロンプトではなく、より良いエンジニアリングです。

このアプリは How Are You?! — 高齢の親のためのAIセーフティ監視です。近日リリースします。ここで説明したコードのワークフローでは Claude CodeBMAD を使います。どちらも私が日々使っているツールで、本気でおすすめします。

広告