Claude Codeで本番用AIプラットフォームを30日で構築:その真実の物語
火曜日の午前2時、課金システムがユーザーに2倍の料金を請求していることに気づきました。そのバグは本番環境で6時間も放置されていました。その日の午後、Claude Codeが支払い照合ロジックを生成し、私はそれをレビューし、テストし、デプロイしました。コードは完璧に見えました。すべてのテストに合格していました。しかし、根本的に壊れていたのです。
これは、AIコーディングアシスタントを使って、274のAPIルート、46のデータベースモデル、10万行以上のコードを持つ LemonData を構築した物語です。よくある「AIがいかに生産性を高めるか」という美化された話ではありません。失敗や午前3時のデバッグセッション、そしてAI支援開発が本当に良いアイデアなのか疑問を抱いた瞬間を含んだ、現実の物語です。
AI支援開発の理想と現実
AIコーディングアシスタントの売り文句は魅力的です。欲しいものを説明すれば、AIがそれを書き、人間がレビューしてデプロイする。理論上、一人の開発者がチーム全体の仕事をこなせるようになります。
実際はどうだったか?最初の2週間は素晴らしいものでした。Claude Codeは私のコードベースを理解し、完全な機能を生成し、ファイル間をまたいでリファクタリングを行いました。これまでのキャリアでかつてないほどの速さでデプロイしていました。次々と課題を解決していくドーパミンは中毒性がありました。
しかし、次第に亀裂が見え始めました。
同じ関数が3つの異なるファイルに、わずかに異なる実装で現れました。設定値がランダムな場所にハードコードされていました。パッケージ間で型定義が矛盾していました。コードベースは急速に拡大していましたが、同時に「動いてはいるが、なぜ動いているのか分からない」コードの迷路になりつつありました。
そして、あの課金バグです。Claudeは、一見完璧に理にかなった照合関数を生成しました。しかし、非同期の支払い確認フローにおけるレースコンディション(競合状態)を考慮していませんでした。私が明示的に伝えていなかったため、AIはそのエッジケースを知る由もありませんでした。また、一部AIが生成したテストスイートも、それをカバーしていませんでした。
繰り返し発生した7つの失敗パターン
Claude Codeで構築を始めて1ヶ月後、私はリストを作り始めました。バグそのものではなく、パターンのリストです。同じような失敗が繰り返し起こっており、それらはClaudeのせいというよりは(少なくとも完全には)、AIが「明日動くコード」ではなく「今動くコード」を優先して最適化した結果、予測できたことでした。
1. 一貫性の問題
Claudeは、作業中のファイルや直近で参照した例、あるいは単なるランダムな変動によって、同じロジックを異なる方法で実装しました。あるAPIエンドポイントは { data: users } を返し、別のエンドポイントは { users } を返しました。どちらも動作はしますが、互いに一致していません。デバッグはもはや考古学のようでした。
2. コピペの問題
コードを複製する方が速く、既存の機能を壊すリスクもないのに、なぜAIが共有ユーティリティを作成するでしょうか?既存の機能に似た新機能を依頼するたびに、リファクタリングされた共有ソリューションではなく、新しい実装が提供されました。3週間後、コードベースのあちこちに5つの異なる「通貨フォーマット」関数が散在していました。
3. 型の乖離(Type Drift)の問題
新しいステータス値が1つのファイルに追加されても、enum定義には追加されない。APIレスポンスではフィールドがオプションなのに、フロントエンドの型では必須になっている。TypeScriptはこれらの一部をキャッチしましたが、意味的な不一致(型は技術的に正しいが、論理的に矛盾しているケース)は防げませんでした。
4. 設定の分散問題
データベースのURL、APIキー、機能フラグ、レート制限。Claudeは現在のタスクに都合の良い場所にそれらを配置しました。環境変数にあることもあれば、設定ファイルにあることも、ハードコードされていることもありました。値が定義されているすべての場所を探し出すのは、宝探しのようになりました。
5. テストカバレッジの幻想
AIが生成したテストは、正常系(ハッピーパス)を徹底的にテストする一方で、エッジケースを完全に見逃す傾向があります。課金バグは完璧な例です。テストスイートは通常の支払いフローを見事にカバーしていましたが、2つの支払い確認が同じミリ秒以内に到着した場合に何が起こるかは一度もテストされませんでした。
6. サイレントエラーの問題
Claudeは例外を飲み込む catch (error) { console.log(error) } ブロックを追加しがちでした。開発中、エラーはコンソールに表示されるため問題ないように見えました。しかし本番環境では、重大な障害が静かにログに記録され、忘れ去られていきました。
7. ドキュメントの欠如
Claudeは優れたコードコメントを書きます。しかし、アーキテクチャのドキュメントは苦手です。関数が何をするかは説明できても、なぜシステムがそのような構造になっているのか、あるいは特定の設計上の決定に至った制約は何だったのかを説明することはできません。
解決策としてのCLAUDE.md
転機は3週目に訪れました。プロジェクトのルートに CLAUDE.md を作成したのです。これは、Claudeが知っておくべきすべての規約、制約、アーキテクチャ上の決定事項を記述したファイルです。
人間用のドキュメントではなく、AI用のドキュメントです。
## API Response Format
Always use: { success: true, data: T } or { success: false, error: string }
Never return raw data without the wrapper.
## Currency
Internal storage: USD. Display: formatCurrency(amount, currency, rate).
Never hardcode exchange rates. Never store CNY directly.
## Error Handling
Never use catch(e) { console.log(e) }.
Always use the logger: logger.error('context', { error }).
効果は即座に現れました。Claudeは一貫して規約に従うようになりました。ルールに違反するコードを生成したときも、CLAUDE.md の特定の行を指摘すれば、自ら修正するようになりました。
しかし、CLAUDE.md だけでは不十分でした。自動化された強制力が必要でした。
セーフティネットの構築:AI生成コードのためのCIゲート
私たちは、従来のコードベースでは過剰に思えるほどのゲートを備えたCIパイプラインを構築しました。これらは、AIが生成したバグがユーザーに届く前にキャッチするために存在します。
- モノレポ全体での型チェック(型の乖離をキャッチ)
- 重複した実装がないかを確認するSSOT(信頼できる唯一の情報源)監査
- データベースのenumとTypeScriptのenumが一致しているかを確認するEnum同期チェック
- APIレスポンス形式のバリデーション(一貫性の問題をキャッチ)
- 課金、権限、認証コードのためのセキュリティゲート
重要な洞察:Claudeは増幅器であり、代替品ではありません。生産性を増幅させますが、間違いも増幅させます。強力な規約がなければ、Claudeは独自の規約を作り出し、それらは一貫性のないものになります。自動チェックがなければ、Claudeのバグは人間が作るバグよりも早く本番環境に到達してしまいます。
あの課金バグはもう起こり得ません。それはClaudeが賢くなったからではなく、パイプラインが非同期のレースコンディションの明示的な処理を要求し、支払いフローにおける適切なロックをチェックするゲートによって検証されるようになったからです。
「AIネイティブ開発」の本当の意味
LemonDataが「AIネイティブ・インフラストラクチャ」であると言うとき、既存の製品にAI機能を追加したという意味ではありません。開発プロセス全体が、AIコーディングパートナーと協力するという現実に合わせて形作られたという意味です。
私たちのドキュメントは、通常よりも詳細です。人間のチームメイトなら推測できるような明示的なコンテキストをClaudeが必要とするからです。私たちの型システムは必要以上に厳格です。Claudeは曖昧さがあればそこを突いてくるからです。私たちのCIパイプラインには、従来のコードベースでは過剰に見えるゲートがあります。AIが生成したバグをユーザーに届く前にキャッチするためです。
その結果、これまで携わってきたどのコードベースよりもメンテナンスしやすいものが出来上がりました。AIが人間より優れたコードを書くからではなく、AI支援開発のために構築したことで、通常はシニア開発者の頭の中にしかないすべての規約やチェックを明文化せざるを得なかったからです。
AIネイティブの哲学についての詳細は、What Is AI Native? をご覧ください。
AIコーディングアシスタントで構築する開発者への教訓
Claude Code、Cursor、またはその他のAIコーディングアシスタントを使ってプロジェクトを始めるなら:
- 初日にCLAUDE.mdを作成する — 私のように3週目まで待たないこと
- 規約の適用を自動化する — AIがルールを覚えていることに頼らない
- AIのコードをジュニア開発者が書いたものとしてレビューする — 高速で有能ですが、コンテキストが欠けています
- エッジケースを手動でテストする — AI生成のテストは正常系をカバーしますが、レースコンディションはカバーしません
- 最初から設定を集中管理する — 分散問題は急速に悪化します
- 厳格なTypeScriptを使用する — 型の乖離に対する最善の防御策です
- 早い段階でCIゲートを構築する — 最初の1週間で元が取れます
もう一度やるか?
もちろんです。ただし、3週目ではなく初日から CLAUDE.md を使い始めます。そして、10倍の生産性向上には、間違いがもたらす影響も10倍になるということを忘れないようにします。
私たちが構築したプラットフォーム(300以上のAIモデル、統合API、多通貨請求、13言語の国際化)は、従来のチームなら数ヶ月かかったでしょう。私たちはそれを30日で出荷しました。バグは現実でしたが、スピードもまた本物でした。
AI支援開発は魔法ではありません。それは新しい種類のエンジニアリング規律です。そして、すべての規律と同様に、その制約を尊重する者に報いてくれます。
FAQ
一人の開発者が本当にClaude Codeで本番用プラットフォームを構築できますか?
はい、ただし注意点があります。AIはコード生成やリファクタリングを驚異的なスピードでこなしますが、依然として強力なアーキテクチャ上の判断、自動化された品質ゲート、そしてすべてを注意深くレビューする規律が必要です。10倍のスピードは、注意を怠れば10倍速いバグも生み出します。
CLAUDE.mdとは何ですか?
CLAUDE.mdは、AIコーディングアシスタントがコンテキストとして読み取るプロジェクトレベルの指示ファイルです。コーディング規約、アーキテクチャ上の決定、AIが従うべき制約などが含まれます。AIのチームメイトのためのオンボーディングドキュメントのようなものだと考えてください。
AIが生成したバグが本番環境に出るのをどう防ぎますか?
自動化されたCIゲートが不可欠です。型チェック、SSOT監査、enum同期の検証、ドメイン固有のセキュリティゲートなどです。重要なのは、AIは生産性と間違いの両方を増幅させるということであり、増幅された間違いをキャッチするための自動チェックが必要だということです。
AI支援開発は課金や支払いシステムに適していますか?
はい、ただし細心の注意が必要です。支払いコードには、明示的なレースコンディションの処理、適切なロック、徹底的なエッジケースのテストが必要です。AIが生成したテストは正常系をカバーする傾向があるため、失敗シナリオや同時実行操作は手動でテストする必要があります。
LemonDataは、単一のAPIを通じて 300以上のAIモデル へのアクセスを提供します。私たちはAIのために、AIを使って構築しました。 無料で始める — 新規ユーザーには1ドル分のクレジットをプレゼントします。