はじめに
ChatGPT、Claude Code、Gemini。
今は誰でもAIを使って簡単にアプリを作れる時代になりました。とても便利な世の中になり、Googleでも「ソースコードの半分はすでにAIが書いている」と言っています。こういう話を聞くとこれからは「自分で手を動かして、実装していくことがなくなっていくのだろう」と思っています。個人的にはそうなるだろうと思いつつも、そうなってほしくない気持ちもあります。理由は単純で、私は「自分で実装すること」が好きだからです。
しかし現実には、仕事でも趣味でも AIを使うのが当たり前になりつつある。
そこで今回は、
AIに“自分の楽しさを奪わせない”ための使い方
を実際に検証してみました。
AIが「やりすぎ」と感じる瞬間
私はこれまで、Copilot(従来のオートコンプリート系)くらいであれば快適に使えていました。
理由は明確で、自分で考えたコードを高速に補完してくれる「高精度な予測変換」 のように感じられたからです。
しかし、v0 や Claude Code のような 全部コード生成してくれるタイプは、正直こう感じます。
「なんか知らんが動くものができてしまった」
自分で実装する部分が減る=楽しさが減る 1 、という構図になっていました。
解決策:AIを“開発者の雑務担当”として働かせる
そこで考えたのが次の方針です。
実装は自分が楽しむ。
AIにはその周りの作業(テスト・Lint・QA・レビューなど)を丸ごと任せる。
今回はGitHub CopilotのAgentモードを使って、開発者のCopilotに徹しさせてみました。
Agent モードは、.github/copilot-instructions.md に指示を書いておけば、そのタスクを自律的に実行してくれます。
私は今回、以下のタスクをプロンプトにしてみました:
- テストコードの作成
- テストコードの実行
- lintの実行
- Chrome DevTools MCPでの簡単な動作確認
- デザインレビュー
- コードレビュー
- レポートの作成
検証用に作ったミニアプリ
題材として、個人的に欲しかったのもあり、技術ブログ集約サイトを作りました。
技術ブログをユーザごとに登録して、一括検索できるシンプルなサービスです。使い方としては、ログイン後、画面上部にある「記事を追加」ボタンをクリックするとダイアログが表示されます。そのダイアログに記事タイトル、URL、タグを設定して追加するだけで自分の記事一覧に追加されて表示されるシンプルなアプリです。
技術構成は以下の通りです:
- フロントエンド:Nuxt、Vue
- DB:Neon DB
- UIライブラリ:Nuxt UI
- テスト:Vitest、Playwright
- 簡単な認証あり
- デプロイ:vercel
今回のアプリ実装の方針としては、次のスタイルで検証していきます。
- アプリ本体の実装は 自分で書く
- 周辺作業は 全部Copilot Agentにやらせる
実際にCopilot Agentにやらせたこと
というわけで具体的な挙動を見ていきましょう。GitHub Copilotのモデルとしては「Claude Sonnet 4.5」を使用しています。今回与えた指示書は以下です:
# 指示書
あなた(Copilot)は**テスター**です。
私は開発者であり、**コードを書くことを楽しむ**人間です。
したがって、**私の楽しみを奪う(=コードの実装や修正を勝手に行う)ことは絶対に許しません**。
あなたができることは、以下のテスト関連作業のみに限定されます。
あなたはコードを「書く」のではなく、「テストコードの作成、確認・検証・報告」する役割を担います。
---
## あなたが行えること
### 1. テストコード作成
- プロジェクト内のディレクトリを探索して対応するテストコードが `tests`ディレクトリにない場合は、`Vitest` 形式の**単体テストコード**を作成してください。
- 目的は**仕様確認**と**既存コードの動作検証**です。
- テストケースは以下を意識して設計してください。
- 正常系・異常系の両方を網羅する
- テスト名は `describe` / `it` ブロックで明確に意図を示す
- Mock や Stub は必要最低限にとどめ、挙動確認に焦点を当てる
- `@testing-library/vue` ライブラリを使用する。
- テストコードを保存する場所は、`tests` ディレクトリを作成し、その中に同じディレクトリ構造の場所に `*.spec.ts` として保存する
- 対象の関数・モジュール・コンポーネントは、ls コマンドで探索して特定する
- 開発者も意図せずに非同期処理が張っていることがあるので、findBy 系のメソッドを多用してください
> ❌ 実装コードそのものを修正・改善しようとしてはいけません。
> ✅ テストコードで「どうあるべきか」を表現してください。
> テストの設定は, vitest.config.mts に記載されています。
> コンポーネントのテストの実装例は tests/app/components/ui/UiButton.spec.ts を参照してください。
> 不足しているソースコードに対する不足ファイルをすべて作成してください。
---
### 2. 単体テスト実行 (`npm run test`)
- コマンド:
```bash
npm run test
```
上記を実行した結果を報告してください。
以下の情報を含めて出力を要約してください。
- 失敗したテスト名
- エラーメッセージ
- スタックトレースの要点
可能であれば、失敗原因の推測(※修正提案は禁止)
✅ 例:
「should calculate total price correctly テストが失敗しました。NaN が返されています。引数の型に不整合がある可能性があります。」
### 3. Lint チェック (npm run lint)
コマンド:
```bash
npm run lint
```
検出された Lint エラーを一覧形式で報告してください。
- ファイルパス
- 行番号
- エラー内容(ルール名含む)
Lint 修正はあなたの仕事ではありません。
指摘のみを行ってください。
### 4. Chrome Devtools MCP を用いたブラウザ検証
`http://localhost:3000` をブラウザで開き、コンソールエラー・警告・表示崩れを報告してください。
次の点を確認してください:
- JavaScript コンソールにエラーが出ていないか
- ネットワークリクエストに失敗がないか
- レイアウトが崩れていないか
- 問題が見つかった場合は、再現手順とエラー内容を簡潔に報告します。
- ソースコードの内容を読んで、適当な操作をしてください。
- 操作をした場合は、その内容を`tests/e2e/`ディレクトリに保存してください。
### 5. デザインレビュー
私のデザインセンスはあまり良くないので、デザインレビューを行ってください。
- 配色、レイアウト、タイポグラフィ、ユーザビリティの観点から評価してください。
- 改善点や提案があれば具体的に指摘してください。
- デザインに関してだけは、CSS ファイルを作成することを許します。
- tailwindcss を使用している前提で提案してください。
- 特に nuxt UI を用いて実装しています
### 6. コードレビュー
私が作成したコードをレビューしてください。コードの量が多い場合は、分割してレビューを行います。
- 可読性、保守性、パフォーマンス、セキュリティの観点からコードを評価してください。
- 問題点や改善点を具体的に指摘してください。
- ただし、コードの修正案を提示することは禁止です。
### 7. レポートの作成
- 上記の各タスクの結果をまとめたレポートを作成してください。
- test-report-YYYYMMDD-HHMMSS.md という名前で保存してください。
- review ディレクトリに保存してください。
### 禁止事項
- コード(実装・リファクタリング・最適化など)を書き換えること
- 新しい関数・モジュール・クラスを提案または追加すること
- 仕様を勝手に変更すること
- コードの「修正案」を提示すること(修正は私の仕事です)
実行
事前指示は勝手に読み込んでくれるので「役目を果たせ」だけ入力します。

テストコードの作成
ちょっと工夫したところ
- Nuxtだとフォルダ内にあるファイルを勝手に実行ファイルと解釈するので、testsフォルダを完全に別で作成しています
- ソースコードと一対一対応で、テストコードを作成してほしかったので事前にソースコードを探索するようにさせています
- 指定したライブラリを使ってくれないところはテストコードの例を指定して読み込ませました
結果
一度にすべてのテストコードを作成はしてもらえませんでしたが、毎回5ファイルぐらいは作成してくれました。ほかのステップにもいえることですが、今回AI利用方針は何回実行しても基本的に問題ないものなので、何度も実行してすべてのテストファイルを作成するといったことを行えました。
テストコードの実行
ただ実行するだけなので、問題なく実行してくれます。注意点としては実行させるときに、Vitestのwatchモードで実行してしまうと、AIがプロセス完了待ちが発生してしまいます。
肝心の結果ですが、今回はほぼ通りました2。よく落ちるのは非同期処理待ちが正しくできていないケースが大半でした。

Lintチェック
こちらも基本的には実行させるだけです。工夫している点としては、ESLintだと実行が遅いので Oxlintを採用しています。
Lintエラーを発生させるものの大半は前工程でAIが生成したテストファイルでしたが、そもそもテストファイルをLint対象にするのかで変わってくるかと思います。
ブラウザ検証(Chrome DevTools MCP)
今回はGoogle Chrome Devtools MCPを使用してみました。作成したアプリには認証があったので、シナリオを指定せずともログイン操作、未ログインでのアクセスなどのシナリオを実行ごとにランダムに行ってくれたので軽いモンキーテスト感覚でした。またスクショも自動取得し、後続のデザインレビューの材料として利用することができます。
デザインレビュー
趣味開発だと個人的にはあまり気が進まないデザインに関してレビューをさせてみました。AIに画面のスクリーンショットを渡したうえでレビューさせると:
- 配色
- レイアウト
- アクセシビリティ
など、毎回異なる観点で指摘してくれました。以下が実際のレビュー内容です。(aria-が不足しているなどは耳が痛いですね...)
## 5. デザインレビュー
### 全体評価: ⭐⭐⭐☆☆ (3/5)
スクリーンショットとコードから評価しました。
### 配色
#### 現状
- **背景**: ダークブルー系(`#1a2332`程度)
- **テキスト**: 白
- **アクセント**: 緑(`#10b981`)
- **入力フィールド**: 暗い背景に白テキスト
#### 評価
- ✅ ダークモードで統一感がある
- ⚠️ コントラストは良好だが、アクセントカラーが限定的
- ⚠️ エラー表示(赤)以外の色彩が少ない
#### 改善提案
```css
/* 推奨カラーパレット */
--primary: #10b981; /* 緑 - アクション */
--secondary: #3b82f6; /* 青 - 情報 */
--accent: #8b5cf6; /* 紫 - 強調 */
--warning: #f59e0b; /* オレンジ - 警告 */
--danger: #ef4444; /* 赤 - エラー */
--background: #0f172a; /* 濃紺 - 背景 */
--surface: #1e293b; /* 中間 - カード */
```
### レイアウト
#### 評価
- ✅ シンプルで分かりやすい
- ✅ フォームが中央寄せで読みやすい
- ⚠️ スペーシングがやや詰まっている印象
- ⚠️ レスポンシブデザインの確認が必要
#### 改善提案
```vue
```
### タイポグラフィ
#### 評価
- ✅ 読みやすいフォントサイズ
- ⚠️ 見出しとボディテキストの差別化が弱い
- ⚠️ フォントファミリーが明示されていない
#### 改善提案
```css
```
### ユーザビリティ
#### 良い点
- ✅ フォームが直感的
- ✅ エラーメッセージが分かりやすい位置に表示
- ✅ ボタンが十分な大きさ
#### 改善点
1. **パスワード表示切り替え**: パスワードフィールドに目のアイコンを追加
2. **ローディング状態**: ボタンクリック時のローディング表示
3. **キーボードナビゲーション**: Enter キーでログイン可能にする
4. **フォーカスインジケーター**: よりはっきりしたフォーカス表示
#### 実装例
```vue
```
### アクセシビリティ
#### 改善が必要な点
- ⚠️ フォームラベルが`placeholder`のみ(`label`タグが必要)
- ⚠️ エラーメッセージとフォームの関連付けが弱い
- ⚠️ `aria-label`や`aria-describedby`の使用が不足
コードレビュー
最後にコードレビューです。今回は趣味開発&勢いで作成しているので自分でも色々な指摘があると思って作っています。
個人的には今回サボって実装していないエラーハンドリングとローディングを指摘してくれたので、効果があると感じました。また最後のステップでコードレビューをさせたので、今までのデザインレビューやLintエラーの観点を踏まえられた多様な指摘ができていそうと感じました。
## 6. コードレビュー
### 可読性: ⭐⭐⭐⭐☆ (4/5)
#### 良い点
- ✅ Composition API を適切に使用
- ✅ TypeScript の型定義が明確
- ✅ コンポーネント分割が適切
- ✅ ディレクトリ構造が整理されている
#### 改善点
1. **コメントの追加**: 複雑なロジック部分にコメントを追加
2. **マジックナンバー**: `60 * 30`などを定数化
3. **変数名**: より明示的な命名(例:`isFailure` → `hasLoginError`)
### 保守性: ⭐⭐⭐☆☆ (3/5)
#### 良い点
- ✅ コンポーネントが再利用可能
- ✅ Store を使用した状態管理
- ✅ ユーティリティ関数の分離
#### 問題点
1. **`server/api/signup/index.post.ts:12`**
```typescript
if (!body.password !== !body.confirmPassword) {
```
⚠️ **重大なバグ**: この条件は常に`false`になります
**修正が必要**:
```typescript
if (body.password !== body.confirmPassword) {
```
2. **エラーハンドリングの不統一**
- API クライアントで`throw new Error`を使用
- 一部で適切なエラーハンドリングが不足
3. **ハードコードされた値**
```typescript
maxAge: 60 * 30 // 30分
```
定数化を推奨:
```typescript
const SESSION_MAX_AGE = 30 * 60 // 30分(秒単位)
```
### パフォーマンス: ⭐⭐⭐⭐☆ (4/5)
#### 良い点
- ✅ `computed`を使用した効率的な再計算
- ✅ 不要な再レンダリングを回避
- ✅ 非同期処理の適切な使用
#### 改善の余地
1. **記事一覧の最適化**: 大量のデータに対する仮想スクロール
2. **画像の遅延読み込み**: `loading="lazy"`の追加
3. **キャッシュ戦略**: API レスポンスのキャッシング
### セキュリティ: ⭐⭐⭐☆☆ (3/5)
#### 良い点
- ✅ パスワードのハッシュ化
- ✅ `httpOnly` Cookie の使用
- ✅ セッション管理の実装
#### **重大な問題**
1. **平文でのパスワード送信**
- HTTPS 必須(現在 HTTP 使用)
- クライアント側でのハッシュ化も検討
2. **CSRF トークンの不在**
- POST/PUT/DELETE リクエストに CSRF 対策が必要
3. **レート制限の不在**
- ログイン試行の制限がない
- ブルートフォース攻撃に脆弱
4. **セッション固定攻撃への対策不足**
- ログイン後にセッション ID を再生成すべき
5. **XSS 対策**
- 入力値のサニタイズが不十分な箇所がある可能性
- `v-html`の使用は避ける
#### 推奨対応
```typescript
```
### 依存関係管理
#### 確認事項
- ✅ `package.json`に適切な依存関係
- ⚠️ セキュリティ脆弱性チェックが必要: `npm audit`
---
## 7. 総合評価と優先度付き改善提案
### 🔴 最優先(セキュリティ・バグ)
1. **サインアップのパスワード検証バグを修正** (server/api/signup/index.post.ts:12)
```typescript
// 修正前
if (!body.password !== !body.confirmPassword)
// 修正後
if (body.password !== body.confirmPassword)
```
2. **HTTPS 化**
- 本番環境では必ず HTTPS を使用
3. **レート制限の実装**
- ログインエンドポイントへのブルートフォース攻撃対策
### 🟡 高優先(品質改善)
4. **Lint エラーの修正**
- 未使用変数の削除または`_`プレフィックス追加
5. **テストの安定化**
- 失敗している 5 テストケースの修正
- 非同期処理のタイミング問題の解決
6. **エラーハンドリングの統一**
- 一貫したエラー処理パターンの導入
### 🟢 中優先(UX 向上)
7. **ローディング状態の表示**
- ボタンクリック時のフィードバック
8. **パスワード表示切り替え機能**
- ユーザビリティ向上
9. **キーボードナビゲーション**
- Enter キーでのフォーム送信
### 🔵 低優先(改善)
10. **デザインの洗練**
- 配色バリエーションの追加
- スペーシングの調整
11. **アクセシビリティの向上**
- ARIA ラベルの追加
- 適切な HTML 要素の使用
12. **パフォーマンス最適化**
- 画像の遅延読み込み
- 仮想スクロールの検討
---
## 8. まとめ
### 現状評価
| 項目 | 評価 | コメント |
| -------------------- | --------- | ---------------------------------- |
| **テストカバレッジ** | ⭐⭐⭐⭐☆ | API 層は良好、UI 層で改善の余地 |
| **コード品質** | ⭐⭐⭐⭐☆ | 全体的に良好、一部バグあり |
| **セキュリティ** | ⭐⭐⭐☆☆ | 基本的な対策はあるが改善必要 |
| **デザイン** | ⭐⭐⭐☆☆ | シンプルで使いやすいが改善の余地 |
| **保守性** | ⭐⭐⭐⭐☆ | 良好な構造、ドキュメント追加で向上 |
レポート作成
実行したタスクのすべてを Markdown にまとめさせて保存するステップです。今までのmarkdownがこのレポートの一部となっています。振り返り用のドキュメントとして十分実用的なので、保存は必須です。
総括:このアプローチは“アリ”か?
良かった点
アーキテクチャの勉強になる
自分で実装していると、どういうアーキテクチャにするかを一から考える必要がありますが、レビューされる頻度が高いので、修正しやすいと感じました
フレームワーク依存度が下がる
ソースコードを生成させると、特に指定しなかったらReactが使われるみたいな現象があると思いますがテストやLint系などの補助ツールは多くのフレームワークに対応しているので、幅広く使えると思いました
出力コンテキストが少ない
従量課金制のLLMだと大半のコストのネックが出力によるものです。ちゃんと比較はしていませんが、出力を最低限に抑えているので、全部生成させるよりはコストが減ると思います
とりあえず実行させておける
生成するのがテストコードだけなので、自分が開発中の時にとりあえず実行して後でレポートを読むといったことができます。また実行させるたびに観点が変わることがあるので多角的にレビューを受けることができます。
微妙だった点
AI生成のテストコードは完全に信用はできない
テストコードの生成は完全AI生成なので、自分のコードが間違っているのか、テストコードが間違っているのかといった議論が発生しやすいと思います。ただテストコードレビューをすれば十分に抑えられると思います。
趣味範囲の規模なら問題なさそうだが、大規模だと?
今回の検証はかなり小規模なアプリなので、大規模になっても対応できるのか気になります。

