Claude CodeとCursorを半年以上使ってきた。便利だが、「PoCは作れるけど本番には...」という感覚が拭えなかった。

その原因を分解してみた。

PoCで終わる3つの理由

1. コンテキストの断絶

AIは会話の文脈は理解するが、「プロジェクト全体の文脈」は理解しにくい。

  • なぜこのアーキテクチャなのか
  • 過去にどんな失敗があったか
  • チームの暗黙のルール

これらは毎回説明する必要がある。

2. エラーハンドリングの甘さ

AIが生成するコードは「正常系」に偏る。

// AI生成コードあるある
const data = await fetch('/api/articles').then(r => r.json());
// エラー時どうする?タイムアウトは?リトライは?

3. 一貫性の欠如

同じ機能を複数回依頼すると、毎回微妙に違うコードが出る。命名規則、エラー処理、ログ出力...全部バラバラ。

実用化に効く工夫

README.mdを「AIへの指示書」として書く

## Architecture Decisions

- State management: TanStack Query(Reduxは使わない)
- Styling: Tailwind CSS(CSS Modulesは使わない)
- Error handling: すべてのAPI呼び出しでtry-catchし、Sentryに送信

## Coding Conventions

- 関数名: camelCase、動詞から始める
- コンポーネント: PascalCase、1ファイル1エクスポート
- 型定義: interfaceではなくtypeを使う

CLAUDE.mdで明示的に制約を伝える

Claude Code用の設定ファイルで、やってほしくないことを明記する。

## Constraints

- 新しいライブラリを追加する前に確認を求めること
- テストは必ず書くこと
- console.logは使わず、専用のloggerを使うこと

小さく依頼する

「ユーザー認証機能を作って」ではなく:

  1. 「ログインフォームのUIを作って」
  2. 「認証APIを叩く関数を作って」
  3. 「認証状態を管理するContextを作って」

と分解する。レビューしやすく、手戻りも小さい。

AIに向いているタスク

  • ボイラープレートコード生成
  • 型定義の生成(OpenAPI → TypeScript)
  • テストケースの追加
  • リファクタリング(明確なルールがある場合)

AIに向いていないタスク

  • アーキテクチャ設計
  • パフォーマンスチューニング
  • セキュリティ要件の実装
  • レガシーコードの理解

おわり

AIコーディングを「魔法」ではなく「ツール」として捉えると、使いどころが見えてくる。PoCで終わらせないコツは、人間側の準備にある。