はじめに
ClaudeCodeを使って、これまでにいくつかのWebアプリケーションを開発しました。
最初は「AIにプロンプトを投げれば完璧なアプリができる」と期待していましたが、現実は全く違いました。
むしろ、PM(プロジェクトマネージャー)としてのスキルが試される場面ばかりでした。
この記事では、ClaudeCodeでの開発を通じて学んだ「PM的な思考」について共有します。
前提: 私の経歴、開発環境
- 役職: ネット銀行のバックエンドエンジニア
- 経験: 元SIer → 金融系システム開発
- 資格: 国家資格キャリアコンサルタント、IT系資格多数
- 使用ツール: ClaudeCode, VSCode, Cline
- 技術スタック: Next.js 14, TypeScript, Supabase, Claude API
ClaudeCodeの「幻想」と「現実」
幻想: AIに丸投げすればOK
開発者: 「XX系コミュニティアプリを作ってください」
ClaudeCode: 「承知しました!」
→ 完璧なアプリが完成!
こんなに甘くありません。
現実: 様々な問題が発生
実際に遭遇した問題:
-
想定外の実装
- 期待と違うUIが生成される
- 不要な機能が追加される
- エラーハンドリングが不十分
-
コスト意識の欠如
- 無料APIで十分なのに有償APIを提案
- ClaudeAPIを提案されたが、GoogleAIStudioAPI(無料)で十分
-
品質のバラツキ
- セキュリティ考慮が不十分
- テストケースが不足
- エッジケースへの対応漏れ
-
トラブル時の対応
- エラー原因の特定が困難。エラー解決を丸投げでは解決できないことがある。
- 複数の問題が絡み合う
- 発生したエラーに対する根本的な対応ではなく、その場しのぎの対応を行うことにより、全体の品質が悪化
-エラー発生後のタイムアウト時間を伸ばす対応を行い、根本的にエラーを発生させないような対応を行わなかった。
→ PMとしての判断・指示が必須
PM的に考えるべき7つのこと
1. アーキテクチャ選定は自分で判断する
失敗例
悪いプロンプト:
AIによる分析機能を実装してください。
結果:
- Claude API(有償)を提案される
問題点:
AIは最新・高品質なAPIを優先して提案するが、コスト面を考慮しない。
改善後
良いプロンプト:
音声認識機能を実装してください。
【必須要件】
- 選択可能なAPIをいくつか選定すること。有償API、無料APIの機能面のメリット/デメリット、コスト面を比較結果を整理すること。(その結果を持って、判断は人間がやる)
- ブラウザのネイティブ機能で実現すること
【理由】
- コストは可能な限り抑えたい
結果:
- GoogleAIStudioAPI(無料)
学び
✅ 無料/有料の選択肢を事前に調査
✅ プロンプトで明示的に指定
✅ コスト試算を自分でする
✅ 段階的アプローチ(MVP → 高度な機能)
2. 要件定義は詳細に、曖昧さを排除
失敗例
悪いプロンプト:
XX登録画面を作ってください。
結果:
- 想定と全く違うレイアウト
- 必要な機能が不足
- 不要な機能が追加される
改善後
良いプロンプト:
XX登録画面を実装してください。
【レイアウト】
- 2カラムレイアウト
- 左側(30%): クライアント情報パネル
- 名前、年齢、職業
- アイコン/アバター
- 右側(70%): 入力用UI
- メッセージ履歴(スクロール可能)
- 入力フォーム(テキストエリア + 送信ボタン)
【UI/UX要件】
- レスポンシブ対応(モバイル: 1カラム)
- メッセージは自動スクロール(最新が常に表示)
- Enterキーで送信、Shift+Enterで改行
- 送信中はボタンを無効化
【エラーハンドリング】
- ネットワークエラー: 赤いトーストで表示
- バリデーションエラー: 入力欄の下に赤文字
- タイムアウト: 30秒でエラー
【参考デザイン】
LINE や ChatGPT のようなチャットUIをイメージ
結果:
- 期待通りのUIが生成される
- エラーハンドリングも完備
- 手戻りが最小限
学び
✅ ワイヤーフレームを言語化
✅ 具体的な画面遷移・操作を明示
✅ エラーケースも詳細に指定
✅ 参考デザインを提示
3. 段階的に進める(アジャイル的アプローチ)
失敗例
悪いプロンプト:
涙活アプリの全機能を実装してください:
- 認証
- 投稿機能
- コメント機能
- いいね機能
- 通知機能
- プロフィール編集
- 検索機能
結果:
- エラーだらけ
- どこが原因か特定できない
- デバッグに数日かかる
改善後
Phase 1: 認証のみ
まずは認証機能だけを実装してください。
- Supabase Authを使用
- メールアドレス + パスワード
- ログイン/サインアップページ
- エラーハンドリング
他の機能は一切実装しないでください。
完璧に動作確認してから、次のフェーズに進みます。
Phase 2: 基本的な投稿機能
認証が完璧に動作しました。
次は投稿機能を実装してください。
- 投稿フォーム(テキストのみ)
- 投稿一覧表示
- 自分の投稿のみ編集・削除可能
Phase 3: コメント機能
投稿機能が完璧に動作しました。
次はコメント機能を追加してください。
(以下詳細...)
学び
✅ MVPから始める
✅ 1機能ずつ実装・検証
✅ 動作確認してから次へ
✅ 問題の切り分けが容易
✅ 手戻りコストの削減
4. テストケースを明示的に指示
失敗例
悪いプロンプト:
投稿機能を実装してください。
結果:
- 正常系は動作するが...
- 空の投稿ができてしまう
- 文字数制限がない
- ネットワークエラー時に固まる
改善後
良いプロンプト:
投稿機能を実装してください。
【テストケース】
必ず以下の全てのケースに対応してください:
正常系:
- 通常の投稿(100文字)
- 最小文字数(10文字)
- 最大文字数(3000文字)
異常系:
- 空の投稿 → エラーメッセージ「10文字以上入力してください」
- 10文字未満 → 同上
- 3000文字超 → エラーメッセージ「3000文字以内で入力してください」
- ネットワークエラー → トースト表示「投稿に失敗しました。もう一度お試しください」
- タイムアウト → 同上
- 認証切れ → ログインページにリダイレクト
【バリデーション】
- クライアント側とサーバー側の両方で実装
- zodを使用した型安全なバリデーション
結果:
- 全てのエッジケースに対応
- ユーザーフレンドリーなエラー表示
- 本番環境でも安心
学び
✅ 正常系だけでなく異常系も必須
✅ バリデーションを明示
✅ エラーハンドリングを徹底
✅ ユーザー体験を考慮
5. セキュリティは明示的に指示、確認必須
失敗例
悪いプロンプト:
Claude APIを使った分析機能を実装してください。
結果:
// ❌ 最悪のコード
const ANTHROPIC_API_KEY = "sk-ant-xxxxx"; // ハードコード!
export async function analyzeText(text: string) {
const response = await fetch("https://api.anthropic.com/v1/messages", {
headers: {
"x-api-key": ANTHROPIC_API_KEY, // クライアントに露出!
},
// ...
});
}
問題:
- APIキーがクライアントコードに露出
- GitHub にpush したら世界中に公開
- 不正利用で高額請求の恐れ
改善後
良いプロンプト:
Claude APIを使った分析機能を実装してください。
【セキュリティ要件(必須)】
1. APIキーの管理:
- 必ず環境変数(ANTHROPIC_API_KEY)を使用
- クライアント側では一切使用しない
- Next.js API Routesで実装
2. 認証・認可:
- ログインユーザーのみ利用可能
- Supabase Authで認証確認
- ユーザーは自分のデータのみアクセス可
3. Supabase RLS:
- Row Level Securityポリシーを適切に設定
- ユーザーは自分のデータのみ読み書き可能
4. その他:
- XSS対策(入力のサニタイズ)
- CSRF対策
- レート制限の実装
【実装場所】
- app/api/analyze/route.ts(API Route)
- クライアントからはfetchで呼び出し
結果:
// ✅ 正しいコード
// app/api/analyze/route.ts
import Anthropic from "@anthropic-ai/sdk";
const anthropic = new Anthropic({
apiKey: process.env.ANTHROPIC_API_KEY, // 環境変数
});
export async function POST(request: Request) {
// 認証確認
const supabase = createServerClient();
const { data: { user } } = await supabase.auth.getUser();
if (!user) {
return new Response("Unauthorized", { status: 401 });
}
// レート制限
// ... 省略
const { text } = await request.json();
// バリデーション
if (!text || text.length < 10) {
return new Response("Invalid input", { status: 400 });
}
const response = await anthropic.messages.create({
model: "claude-sonnet-4-20250514",
max_tokens: 1000,
messages: [{ role: "user", content: text }],
});
return Response.json(response);
}
学び
✅ セキュリティ要件を必ず明示
✅ 実装後に自分で確認
✅ 環境変数、RLS、認証は必須三種の神器
✅ クライアント側にAPIキーは絶対NG
6. コード品質をレビュー(Claude Opusを活用)
問題: ClaudeCodeが生成したコードの品質にバラツキ
生成されるコードには以下の問題がある場合も:
- 型安全性が不十分
- パフォーマンスが悪い
- 保守性が低い
- ベストプラクティスに反する
解決策: Claude Opusでレビュー
Opusへのプロンプト:
以下のコードをレビューしてください。
【レビュー観点】
1. 型安全性:
- any型の使用
- 型推論の適切さ
- 型定義の不足
2. パフォーマンス:
- 不要な再レンダリング
- メモ化の必要性
- 非効率なループ
3. 保守性:
- 命名規則
- コンポーネントの分割
- コメントの必要性
4. セキュリティ:
- 脆弱性の有無
- ベストプラクティスとの乖離
5. Next.js 14のベストプラクティス:
- Server Components vs Client Components
- 適切なデータフェッチ方法
- キャッシング戦略
【コード】
```typescript
// ここに生成されたコードを貼り付け
優先順位をつけて、具体的な改善案を提示してください。
**Opusの回答例:**
【重大な問題】
-
型安全性の欠如(優先度: 高)
問題: user.name が any型
改善:
interface User {
name: string;
email: string;
} -
パフォーマンス問題(優先度: 高)
問題: useEffectで毎回API呼び出し
改善: useSWRまたはReact Queryを使用
【推奨改善】
3. 命名規則(優先度: 中)
問題: getData という曖昧な関数名
改善: fetchUserProfile に変更
(以下省略)
#### 学び
✅ **生成コードをそのまま信用しない**
✅ **Opusでレビューさせる**
✅ **優先度をつけて改善**
✅ **ベストプラクティスを学ぶ機会**
---
### 7. トラブル時の切り分けと原因分析
#### よくあるトラブル
1. **エラーが出るが原因不明**
2. **複数の問題が絡み合っている**
3. **ClaudeCodeだけでは解決できない**
#### 解決プロセス
**Step 1: 情報収集**
- エラーログを全て確認
- ネットワークタブ(DevTools)を確認
- コンソールのwarningも確認
- Supabaseのログを確認
**Step 2: Opusに原因分析を依頼**
**プロンプト:**
以下のエラーが発生しています。
原因と解決策を分析してください。
【エラーログ】
Error: Failed to fetch
at fetchData (page.tsx:45)
...
【状況】
- Supabase からデータ取得時に発生
- ローカル環境では動作する
- Vercel 本番環境でのみ発生
- 認証は成功している
【確認済み】
- 環境変数は正しく設定されている
- Supabase RLSポリシーは設定済み
- APIエンドポイントは正しい
【コード】
// 該当部分のコードを貼り付け
考えられる原因を優先順位をつけて提示し、
それぞれの検証方法と解決策を提案してください。
**Opusの回答例:**
【最も可能性が高い原因】
-
CORSの問題(可能性: 80%)
Vercel本番環境とSupabaseのドメインが異なるため検証方法:
- ブラウザのコンソールでCORSエラーを確認
解決策:
- Supabaseの設定で許可ドメインを追加
- next.config.jsでheadersを設定
-
環境変数の参照ミス(可能性: 15%)
NEXT_PUBLIC_ プレフィックスの有無検証方法:
- console.log(process.env.NEXT_PUBLIC_SUPABASE_URL)
解決策:
- クライアント側で使う環境変数には必ず NEXT_PUBLIC_ を付ける
-
タイムアウト(可能性: 5%)
本番環境のネットワークが遅い解決策:
- fetchにtimeoutを設定
**Step 3: 優先順位順に検証**
原因1から順に検証し、解決していく。
#### 学び
✅ **エラーログを丁寧に読む**
✅ **環境の違いに注目**
✅ **Opusに分析を依頼**
✅ **優先順位をつけて検証**
✅ **1つずつ潰していく**
---
## ClaudeCodeとの正しい付き合い方
### AIは「優秀な部下」であって「完璧な神」ではない
**優秀な部下の特徴:**
- 指示が明確なら高いパフォーマンス
- 曖昧な指示では期待外れの結果
- レビューと修正が必要
- 学習と改善のサイクル
**PM(あなた)の役割:**
- 明確な要件定義
- アーキテクチャ判断
- 優先順位付け
- 品質管理
- リスク管理
### PM的思考チェックリスト
開発前に確認すべき項目:
```markdown
## 要件定義
- [ ] 機能要件は具体的か?
- [ ] UI/UXは詳細に記述したか?
- [ ] エラーケースを想定したか?
## アーキテクチャ
- [ ] 無料/有料の選択肢を調査したか?
- [ ] コスト試算をしたか?
- [ ] スケーラビリティを考慮したか?
## セキュリティ
- [ ] APIキーの管理方法を指示したか?
- [ ] 認証・認可を実装するか?
- [ ] RLSポリシーを設定するか?
## 品質管理
- [ ] テストケースを明示したか?
- [ ] レビュープロセスを決めたか?
- [ ] ベストプラクティスに沿っているか?
## リスク管理
- [ ] トラブル時の対応を考えたか?
- [ ] 段階的なアプローチを取るか?
- [ ] ロールバック方法を確認したか?
副次的な効果: PM能力の向上
この開発経験を通じて、以下のPMスキルが向上しました:
1. 要件定義力
- 曖昧さを排除する重要性
- ステークホルダーの期待を言語化
- エッジケースの想定
2. アーキテクチャ判断力
- 技術選定の基準
- コストと品質のトレードオフ
- 将来の拡張性の考慮
3. リスク管理能力
- 問題の予測と対策
- 段階的アプローチ
- トラブル時の切り分け
4. コミュニケーション力
- 明確な指示の出し方
- フィードバックの仕方
- レビューの観点
5. 品質管理意識
- テストケースの網羅性
- セキュリティの重要性
- 保守性への配慮
→ 本業の業務にも直結して役立っています
キャリアコンサルタントとしての視点から(筆者はキャリコンの資格も持ってます)
国家資格キャリアコンサルタントとしての視点でも、この経験は非常に価値があります。
AI時代に求められるスキル
従来:
- プログラミングスキル
- フレームワークの知識
- アルゴリズムの理解
AI時代:
- 要件定義力(AIに何を作らせるか)
- 判断力(AIの提案を評価)
- レビュー力(品質を担保)
- 問題解決力(トラブル対応)
→ まさにPM的なスキルが重要に
エンジニアのキャリア戦略
AI時代のエンジニアは:
- コーディングはAIに任せられる部分が増える
- 設計・判断・レビューなどの高度な部分に注力
- PM的な思考が競争優位性になる
この開発経験は、キャリアアップの材料になります。
まとめ
ClaudeCodeは強力なツールですが、「丸投げ」では成功しません。
必要なのは:
- ✅ アーキテクチャ選定(コスト意識)
- ✅ 詳細な要件定義(曖昧さの排除)
- ✅ 段階的アプローチ(アジャイル)
- ✅ テストケースの明示(品質担保)
- ✅ セキュリティの徹底(必須要件)
- ✅ コードレビュー(Opus活用)
- ✅ トラブル対応(分析と優先順位)
PM的な思考が、AI開発の成否を分けます。
AI時代こそ、人間の判断力が重要
AIは道具です。
使いこなすのは人間です。
その「使いこなし」にPM的思考が不可欠だと、
4つのアプリ開発を通じて痛感しました。
開発したアプリ
涙活アプリ
メンタルヘルスケアを支援するアプリ。泣けるコンテンツの紹介、感情の記録、コミュニティ機能を提供。
https://ruikatsu-app.vercel.app/
参考情報
- ClaudeCode: https://docs.claude.com/en/docs/claude-code
- Anthropic API: https://docs.anthropic.com/
- Next.js 14: https://nextjs.org/docs
- Supabase: https://supabase.com/docs
最後に
これからAI開発を始める方、ClaudeCodeを使っている方の参考になれば幸いです。
質問やフィードバックがあれば、コメント欄でお気軽にどうぞ。
一緒にAI時代を生き抜きましょう!
タグ提案:
#ClaudeCode #AI開発 #プロジェクトマネジメント #Next.js #個人開発 #プロンプトエンジニアリング