実験 : AIエージェントでの予測可能なアプリ開発

agent 利用者は既に近しい事をされていると思う。
自身で確証を得るために試した内容となる


# 概要
AIエージェントを活用してアプリを予測可能かつ再現的に構築するための試行プロセスについて記録する。
単にコードを生成させるのではなく、「仕様の揺らぎを排除したタスクリストの設計と制御」に主眼を置く。
LLM（大規模言語モデル）にタスク定義を与えることで、プロジェクト進行を段階的かつ安定的に制御する試みである。

実験対象として、ReactベースのシンプルなTODOアプリを開発対象とし、以下のAIエージェントを用いた：
- Windsurf
- Claude Code
- Codex




# なぜ「タスクリスト」なのか？
AIによるアプリ生成は、曖昧な指示や仕様の揺らぎに対して脆弱である。
この問題を回避するには、LLMが一貫して認識・処理できる形式でタスクを定義する必要があると考える

そのため、本プロジェクトでは以下の二段階を踏んでタスクを構築する：
- system.yaml にて、プロジェクトの背景・仕様・技術スタック・UI構成などを明記
- todos.yaml にて、MVP実装のための段階的・依存関係付きタスクリストを記述




# プロジェクト概要
作成：Reactを用いたシンプルなTODOアプリ
目的：AIがタスクリストに従い、段階的に機能を実装できるかを検証する
技術スタック :
- React
- Vite
- TailwindCSS
- TypeScript




# 要件記述（system.yaml）
まず、chatGPTなどに対して以下のような情報を与える

- アプリの目的・ユーザー像
- 技術スタック
- UI構成と画面遷移
- ディレクトリ構成の希望

この内容を膨らませ system.yamlに記述し、エージェントが参照可能な状態にした。


# task list の作成
chatGPT などへ以下のプロンプトを与えて task list を作成し、todos.yaml へ記述。 

```
システム要件(system.yaml)を元に MVP を作成するための詳細で段階的な計画を作成してください

- 計画立案
    - task は単位を小さくし漸進的に定義する
    - 端的な題名を記述する
    - task の内容を把握するための description を明確に記述する
    - 受け入れ条件を定義する
    - dependencies
        - 各 task には事前要件となる task を明記する
    - 自己テストを行うための linter, test を setup する工程を必ず付与する
        - ステップ毎にテスト, 検証可能である事
    - task の完了を把握するための status を持つ
- 計画の書き出し
    - todos.yaml へ書き出す
- 計画の作成目的
    - このタスク一覧は別の LLM agent によってソフトウェア開発に用いられる

- example: todos. yaml は以下の構造を持つ事

----
- id: '0.1'
  title: Git リポジトリを初期化
  description: プロジェクトルートに空の Git リポジトリを作成する。
  acceptance_criteria:
    - '`git status` がクリーンな初期コミットを示すこと'
  dependencies: []
  status: completed

- id: '0.2'
  title: Vite React‑TS プロジェクトをブートストラップ
  description: '`npm create vite@latest` でテンプレート `react-ts` を使用して生成し、開発サーバーが起動することを確認する。'
  acceptance_criteria:
    - '`npm run dev` で http://localhost:5173 にデフォルトページが表示される'
  dependencies:
    - '0.1'
  status: pending
----
```



# 生成された task list 
## 概要
```
# Todoアプリ構築フロー (React + TS + Zustand + Dexie)

## 0. プロジェクト初期設定
- [x] 0.1: Git リポジトリを初期化 (`git status`がクリーン)
- [x] 0.2: Vite React-TS プロジェクトを作成 (`npm create vite@latest`)
- [x] 0.3: ESLint (Airbnb-base) + Prettier を設定
- [x] 0.4: Tailwind CSS 導入
- [x] 0.5: 初期コミット作成 (`chore: baseline project setup`)

## 1. 型・ユーティリティ準備
- [x] 1.1: Todo 型定義（`id`, `title`, `done`, `createdAt`）
- [x] 1.2: `uuid()` ユーティリティ関数（`crypto.randomUUID`）

## 2. UI コンポーネント構築
- [x] 2.1: App シェル作成（ヘッダーとプレースホルダ一覧）
- [x] 2.2: TodoInput コンポーネント（入力 + 追加）
- [x] 2.3: TodoItem コンポーネント（トグル + 削除）
- [x] 2.4: TodoList コンポーネント（リスト描画 + 空状態）

## 3. 状態管理（Zustand）
- [x] 3.1: `useTodoStore` 実装（add/toggle/remove/load）
- [x] 3.2: UIとストア接続（追加 → リスト反映）

## 4. 永続化（Dexie + IndexedDB）
- [x] 4.1: Dexie セットアップ（`services/db.ts`）
- [x] 4.2: TodoRepository 実装（CRUD 抽象化）
- [x] 4.3: ストア ↔ リポジトリ同期（起動時ロード）

## 5. スタイリング
- [x] 5.1: 基本レイアウト調整（Tailwind）
- [x] 5.2: ダークモード対応

## 6. テスト・CI
- [x] 6.1: Jest + RTL 設定
- [x] 6.2: コンポーネント＆ロジック テスト（60%以上のカバレッジ）
- [x] 6.3: GitHub Actions CI（Lint + Test）

## 7. リリース準備
- [x] 7.1: 手動受入レビュー（オフラインCRUD確認）
- [x] 7.2: 本番ビルド確認 (`vite preview`)
- [x] 7.3: Git タグ `v0.1.0` を作成しリモートへプッシュ
```


## 実際の todos.yaml の一部
```
- id: '0.1'
  title: Git リポジトリを初期化
  completed: true
  description: プロジェクトルートに空の Git リポジトリを作成する。
  acceptance_criteria:
  - '`git status` がクリーンな初期コミットを示すこと'
  dependencies: []
- id: '0.2'
  title: Vite React-TS プロジェクトをブートストラップ
  completed: true
  description: '`npm create vite@latest` でテンプレート `react-ts` を使用して生成し、開発サーバーが起動することを確認する。'
  acceptance_criteria:
  - '`npm run dev` で http://localhost:5173 にデフォルトページが表示される'
  dependencies:
 - '0.1'
 - id: '0.3'
  completed: true
  title: ESLint と Prettier を設定
  description: Airbnb-base ESLint ルールと TypeScript 対応を追加し、Prettier と統合する。
  acceptance_criteria:
  - '`npm run lint` がエラーなしで完了'
  - '`npm run format` でコードが整形される'
  dependencies:
  - '0.2'
```


# AIエージェントとの連携結果
上述の system.yaml および todos.yaml をローカルディレクトリに配置し、各AIエージェント（Windsurf / Claude Code / Codex）に順次与えた。


## windsurf
- task への追従性がある事を確認  
- 使用方法に慣れず途中で断念


## claude
- CLAUDE.md へ上述の２ファイルを読み込むルールを記述する事で todo list への追従性がある事を確認
    - todo list に沿い task を順番に処理し逸脱は無かった
    - task へは追従するが、細かな指示を守らないケースが多い
    - 基本ルールとして branch を作成するルールを敷いたが無視した
    - todo list の complete status の変更を行わない事も多かった
- pit of death にはまる
    - react の無限リフレッシュに陥った際、自身では修正できずにハマった
    - 人間が調べて修正箇所を示すと解消
- cost 増大
    - project 初期化時に雛形ツールを使わずに自身で雛形を出力したようで 10$ 程無駄になった


## codex
- instruction.md へ上述の２ファイルを読み込むルールを記述する事で task への追従性がある事を確認
    - todo list に沿い task を順番に処理し逸脱は無かった
    - claude とは異なり細かなルールもある程度遵守する
    - bank dir に情報集積するルールを敷いていたが、ある程度適切に運用していた
    - todo list の complete status の付与を忘れるが, claude 程ではない
- agent からの提案
    - test の作成を後半に置いたが、先行して作成すべきでは? などの提案があった
- claude 同様に pit of death に落ちるケースもある
    - UI の dark mode / light mode の切り替えを搭載できずにループした
- cost
    - task を9割消化時で、20ドル 程度。
    - claude の様に莫大な出力を行うことはなかった 




# 所感と今後の課題
- claude、codex ともに細かな実装は異なるが、task の定義に従い近しい成果物を出力した。
    - タスクリストによる制御は、LLMの出力を意図から逸脱させないためのガイドレールとして機能した。 
    - さらに正確、詳細に小さな単位定義を行う事で再現性を向上させることが出来ると予測する。
    - agent は文脈が長くなると性能劣化するため、小さく task を保つメリットもある
    - 特に Codex は構造化タスクや指示に対し高い追従性を示した
- 一方で、受け入れ条件の自動検証や状態管理などには課題も残る
    - 現段階での agent では安定した成果物を作成するには人間のガイドがある程度必要である
    - agent がスタックした際などに文脈が失われる場合もある
- 失敗
    - project の雛形や最低限の構造は人間が用意した方が効率が良いとおもう
    - branch 作成のルールが遵守されなかった点は、task に必須条件として記述すると追従する可能性が高いと思う。全体的なプロンプトの改善も必要。



# codex の作成した簡易 todo UI
![2025_05_20.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/118627/93fdea52-2ee2-4703-9910-86ab7aae498e.gif)


試作のためリッチな UIや機能ではないので 20ドルは高額に思えてしまう。
chatGPT の UI 上で o3 はこの程度は作成できると思うが、linter、test、DB、css などの設定など多岐に渡り整備も行ったため妥当とも思える。