広告からエンジニアリングへ:DIALOGUEを構築して学んだ技術的教訓
AWSからGCPに移行し、92%のコスト削減と10倍のパフォーマンス向上を達成しました。「ベストプラクティス」を捨てて実際に機能するプラグマティックなアーキテクチャを選んだ教訓をお伝えします。
*これはDIALOGUEの紹介の技術的深掘りのコンパニオン記事です。DIALOGUEとは何か、なぜ構築したかをまだ読んでいない方は、まずそちらからどうぞ!*
旅:広告プロフェッショナルからフルスタックエンジニアへ
さて、部屋の中の象に触れましょう — はい、私は広告の出身です。データ構造やアルゴリズムではなく、メディアプランとクリエイティブブリーフの世界。でも面白いことに、システムの仕組みを理解するということは、マーケティングファネルでも分散アーキテクチャでも、同じ分析的思考が必要です。違いは?エンジニアリングでは、失敗したらコンピュータがすぐに教えてくれます。キャンペーン結果を待つ必要はありません haha。
DIALOGUEの構築は...凄まじかったです。単にコードを書くだけではありません(もちろんたくさん書きましたが)。複数のAIサービスをオーケストレーションし、非同期ワークフローを処理し、ユーザーが予想外のことをしてもバラバラにならない複雑なシステムを設計することです。この旅が実際に教えてくれたこと — 良い点、イライラする点、「なぜ誰も教えてくれなかったの?」という瞬間を共有します。
アーキテクチャの決定:なぜ複雑さは敵なのか
始めたばかりの人には誰も教えてくれないことがあります:複雑さはあなたの味方ではありません。これを痛い思いをして学びました。本当に痛い思いをして。CloudWatchログに溺れながら、美しく設計したシステムが...うまくいかない理由を解明しようとしている自分を想像してください。 T.T
初期アーキテクチャ(過度に複雑)
最初はオーケストレーションにLangGraphを使い始めました。なぜか?グラフベースのアプローチがとてもエレガントに見えたからです!柔軟性が得られるはず!美しくスケールするはず!
現実確認:痛いほど遅かったです。ローカルで実行しても。クラウドデプロイメントでも。美しい抽象化はすべて...オーバーヘッドでした。大量のオーバーヘッド。
最終アーキテクチャ(プラグマティックにシンプル)
多くの自問自答(とデバッグ)の末、実際に機能するものはこちらです:
```
Frontend (Next.js) → API Gateway → Cloud Run Services → Cloud Workflows → Cloud Storage
↓
Supabase (Auth + Real-time + PostgreSQL + Edge Functions)
```
注意:2025年7月にAWS Lambda/Step FunctionsからGCP Cloud Run/Workflowsに移行し、92%のコスト削減と10倍のパフォーマンス向上を達成しました。
大きな発見: すべてをAPIでラップする代わりに直接Supabaseクエリに切り替えたところ、10倍のパフォーマンス改善が得られました(450ms → 45ms)。あの「適切な」APIレイヤリング?すべてを遅くしていただけでした。このデータベースファーストアーキテクチャがGCP移行の基盤になりました。
AIモデルの選択:ハイプの先にあるもの
モデル環境の現実
さて、AIモデルについて話しましょう。すべて試しました。本当にすべて — 午後にちょっと遊んだだけではありません。何ヶ月ものテスト(そして認めたくないほどのAPIクレジット消費)の後、実際に何かを構築するときに機能するものはこちらです:
現在の主力スタック:
- Claude(Claude code経由)& Gemini 2.5 Pro(Gemini CLI経由): コア開発の二頭体制。これら2つのモデルは非常に高性能になり、ワークフローの他のすべてを事実上置き換えました。
- Claude Sonnet 4 API: JSON信頼性のためtemperature 0でDIALOGUEのスクリプト生成に使用
以前のスタックに含まれていたもの:
DeepSeek: 以前はトリッキーなバグのデバッグ、特に深夜のトラブルシューティングセッションに頼っていました。しかしClaude 4とGemini 2.5 Proが登場してから?これらのモデルがエッジケースを同等以上に処理します。モデル能力の進化により、ワークフローにおいて専用のデバッグモデルは不要になりました。
実際に機能するもの:
ここが面白いところです:各モデルはそれ自体で非常にパワフルです。Claudeはアーキテクチャ思考と複雑な推論で優れています。Gemini 2.5 Pro?実装と大規模コードベース全体のコンテキスト維持で驚異的です。Gemini 2.0から2.5へのジャンプはすごかった — 文字通り違いを_感じ_ました。より速いレスポンス、1Mトークンのコンテキストウィンドウ(本当です)、そして私が構築しようとしていることを実際に理解してくれます。
しかし、本当のマジックは:お互いの仕事を批評させることです。Claudeにアプローチを設計させ、Geminiにレビューと改善提案を依頼します。またはGeminiがソリューションを生成し、Claudeにエッジケースやアーキテクチャ上の懸念を分析させます。このやり取り、この協調的な批評プロセス — ここにこそ、どちらか単独では到達できなかったブレークスルーの解決策があります。
機能しなかったもの(ハイプにもかかわらず):
- OpenAI o1/o3: みんなが話題にしていますが、実際の開発では?遅すぎ、高すぎ、そして正直なところ私のユースケースではそれほど良くない
- GitHub Copilot Workspace: 素晴らしいアイデアですが、トークン制限が...実質的なことをしようとするたびに上限に達していました
本当の洞察: 誰も教えてくれないことを知っていますか?異なるモデルは異なる失敗の仕方をします。初期のGeminiは特定のエラーで奇妙なループに陥り、問題が見えませんでした。Claudeならすぐに発見します。しかしClaudeはGeminiなら数秒でこなすシンプルな実装を考えすぎることがあります。トリックは「最高の」モデルを見つけることではなく、いつ切り替えるかを知ることです。
フルスタック開発:複数の帽子を被る
ターミナル戦略
実際に正気を保ってくれた実用的なことがあります:異なるコンテキスト用に別々のターミナルウィンドウ。シンプルに聞こえますか?ゲームチェンジャーです。
```bash
# Terminal 1: Frontend Developer Me
cd podcast_generator_frontend_v2
npm run dev
# This is where I think about React components and user experience
# Terminal 2: Backend Developer Me
cd gcp_services
./deploy/deploy-service.sh [service-name]
# This is where Cloud Run services live (much happier than Lambda!)
# Terminal 3: Database Me
supabase start --workdir supabase
# Local Supabase for testing, production for real work
```
ばかげて聞こえるかもしれませんが、物理的にターミナル間を切り替えることで脳のコンテキストが切り替わるのを助けます。フロントエンドの私とバックエンドの私は別人であり、それぞれのスペースが必要なのです。
クロススタックコミュニケーション
ソロでフルスタック作業するのは奇妙です。基本的に自分自身と会話しています。そこでメモを残し始めました:
```
// Note from Frontend Me to Backend Me
/**
* BACKEND TODO:
* - Need endpoint GET /api/podcasts/:id/segments
* - Should return: { segments: Array<{id, title, status, content}> }
* - Must handle: 404 (not found), 403 (unauthorized)
* - Real-time updates via Supabase subscription would be ideal
* - Future me will thank you for error handling!
*/
```
```
## Backend Developer Summary for Frontend Integration
Current State:
- Endpoints implemented: POST /podcasts, GET /podcasts/:id
- Authentication: Bearer token via Supabase JWT
- Real-time: Supabase channel "podcast-updates"
Next Frontend Tasks:
1. Implement podcast creation form
2. Subscribe to real-time updates
3. Handle error states (401, 403, 404, 500)
```
このちょっとしたメモ?1週間後にコードに戻って、過去の自分が何を考えていたか全く思い出せないときの命綱です。
主要な技術的要点
1. システム思考はドメインを超越する
広告のバックグラウンドはシステム思考を教えてくれました — ユーザージャーニー、コンバージョンファネル、アトリビューションモデル。これらのメンタルモデルは以下に直接変換されます:
- 分散システム設計
- ユーザーエクスペリエンスフロー
- パフォーマンス最適化
- エラーハンドリング戦略
2. プロダクションファースト思考
# 優先すべきと学んだこと
if works_in_production and meets_user_needs:
ship_it()
else:
fix_only_blockers()
# 完璧は善の敵
3. フルスタック能力は本物
DIALOGUEの構築に必要だったもの:
- フロントエンド: React 19、Next.js 15、TypeScript、リアルタイムサブスクリプション、WebSocket管理(メモリリークを修正!)
- バックエンド: Python 3.12、Cloud Run(14マイクロサービス)、Cloud Workflows、PostgreSQL(Supabase経由)
- インフラ: GCP(AWSから移行)、API Gateway、Cloud Storage、フロントエンド用Vercel
- AI/ML: Claude 4.0、Perplexity API、OpenAI TTS、temperature最適化(JSONには0)
- DevOps: Dockerコンテナ、Cloud Build、モニタリング、JWTセキュリティ(P-256移行)
- データベース: RLS付きPostgreSQL、Edge Functions、競合状態防止のためのアトミック操作
4. クラシカルなトレーニングの重要性
正式なソフトウェアエンジニアリングのトレーニング(システム設計、データ構造、アルゴリズム)は非常に貴重でした。AIにコードを書かせるだけではなく、何を依頼し、どう設計するかを知ることが重要です。
最後に
これが私のたどり着いた結論です:DIALOGUEの構築は、職業人としての自己認識を完全に変えました。以前は技術チームをマネジメントする人間でした。今は?実際に一緒に構築できます。正直に言って、かなりすごい気分です。 :D この進化は、Swiftを知らずにネイティブiOSアプリを構築し始めたときにも続きました — 広告のスキル(テイスト、クリエイティブディレクション、「良い」がどういう感覚かを知ること)がコーディングスキルよりも重要だとわかりました。
広告からエンジニアリングへの旅は、単に構文やフレームワークを学ぶことではありません。脳をシステムで考えるように、方法論的にデバッグするように、そして時にはセミコロンの欠落に3時間費やすことを受け入れるように再配線することです(TypeScriptはそれをキャッチしますが、言いたいことはわかりますよね)。
面白いのは?広告での分析的思考 — ユーザージャーニーの理解、コンバージョンファネルの最適化 — これらすべてがエンジニアリングに直接変換されます。違いは、コードでは何かが機能しないとき、コンピュータがすぐに教えてくれることです。キャンペーンレポートを待つ必要はありません。即座の、容赦ないフィードバックです。
「製品」はpodcast.chandlernguyen.comで公開中です。動作します。完璧ではありませんが、自分のものです。そしてバグ修正、機能追加、「なるほど!」の瞬間 — すべてがこの進行中の旅の一部です。
広告から全く違うものへのキャリアの大転換をしたことはありますか?トランジションで最も驚いたことを聞きたいです。教えてください!
よろしくお願いします、Chandler
P.S: 痛い思いをして学んだと言えば — たった1つのAIパラメータ変更が月$54のコストになったことを知りたいですか?1つのAIパラメータ変更で月$54のコストをチェックしてください。本番環境の制約を明示せずにAIアシスタントに本番コードを任せたときに何が起こるかの教訓です。ネタバレ:「動かして」と「本番対応にして」はまったく異なるリクエストです。
P.P.S: まだこのエンジニアリングの世界を、一つずつバグを潰しながら探っています。現在AIを活用したアプリケーションを構築中で、本番環境を壊さないよう努力しています。また後でこのブログに戻ってきてください。





