🗼

GCP開発 Excuse AIで学ぶ生成AIアプリ構築(前編)

に公開

はじめに

GCPの習得にあたり、そろそろ実際のアプリ開発をするとよさそうなタイミングだと思いました。不真面目なテーマでやってみると逆にいろいろ見えるものがあるかもしれないと思い、着想にいたります。

今回の「Excuse AI(言い訳AI)」は、軽いテーマを題材にしつつ GCPの主要サービス(Cloud Run / Pub/Sub / GCS / Vertex AI)を使ってスケーラブルな生成AIアプリ基盤を実装した記録です。実装では今回はClaudeをフル活用しました。


🎯この記事のゴール

この記事を読むと、以下のことが理解できます。

✅ GCS→Pub/Sub→Cloud Run のイベント駆動アーキテクチャ
✅ Gemini APIを呼び出す最小構成のサーバレス実装
✅ 個人でも月数百円で運用できる低コスト構成の考え方


Phase 1:アーキテクチャを描く

前編では、ファイルをトリガーにAIを呼び出す仕組みを構築します。まだフロントも作りません。

GCS(JSONの入力ファイル)
    ↓
Pub/Sub(イベント通知)
    ↓
Cloud Run(Gemini API呼び出し)
    ↓
GCS(JSONの出力ファイル)

非同期・疎結合・スケーラブル。
GCPらしいマネージド構成で、リトライや再処理も容易です。

インプットはこのようなファイルです。システム障害とその詳細です。

{
  "incident_id": "TEST-001",
  "system_name": "テスト決済システム",
  "failure_type": "API応答遅延",
  "occurred_at": "2025-09-23T02:00:00+09:00",
  "detected_at": "2025-09-23T10:30:00+09:00",
  "impact": "中",
  "day_of_week": "火曜",
  "business_hours": true
}

Phase 2:GCSトリガーとPub/Sub

1️⃣ GCSバケット作成

gsutil mb -p <PROJECT_ID> -l asia-northeast1 gs://excuse-ai-input/
gsutil mb -p <PROJECT_ID> -l asia-northeast1 gs://excuse-ai-output/

2️⃣ Pub/Subトピック作成
3️⃣ 通知設定 ※この操作はコンソールではできませんでした。

gsutil notification create -t excuse-ai-topic -f json gs://excuse-ai-input/

GCSにファイルがアップロードされるたびに、Pub/Subが動きます。

Phase 3:Cloud RunでVertex APIを呼ぶ

Cloud Run側ではPython(Flask)を使用。
トピックから受信したメッセージをJSONで受け取り、Gemini APIを呼び出します。Vertex AIを使っている部分の抜粋です。

    try:
        # Vertex AI Generative AI Studio経由でGemini呼び出し
        print("Attempting to call Gemini...")
        from vertexai.preview.generative_models import GenerativeModel
        model = GenerativeModel("gemini-2.0-flash-lite-001")
        print("Model created successfully")
        
        response = model.generate_content(prompt)
        print(f"Gemini response received")
        llm_output = response.text
        
        print(f"Gemini raw response: {llm_output[:500]}...")  # デバッグ用
        
        # JSON抽出(```jsonブロックがある場合に対応)
        if "```json" in llm_output:
            llm_output = llm_output.split("```json")[1].split("```")[0].strip()
        elif "```" in llm_output:
            llm_output = llm_output.split("```")[1].split("```")[0].strip()
        
        excuses = json.loads(llm_output)

✅ ポイント

  • Cloud Runはサーバレスで常時起動不要
  • Pub/SubがHTTP PushでCloud Runを叩く
  • 処理完了後にGCSへ結果出力

Phase 4:デプロイ

requirements.txtに個別のバージョンを指定するとCloud Runの場合うまくいかなかったため、バージョンは削除しました。

〇最終型(後編含む)のrequirements.txt
Flask
google-cloud-storage
google-cloud-firestore
google-cloud-aiplatform
gunicorn

※ちょっと後編の先出しですが、Firestore側の出力イメージ 4種類の障害言い訳をレベル別に出力してくれます。

デプロイ後は、Cloud RunをエンドポイントにしてPub/Subのサブスクリプションをセットして仕上げです。

Phase 5:トラブルと突破口

💥 Gemini 1.5 Flash 廃止(2025/9/24)
開発中の二日間の間にAPIモデルが利用停止。
→ gemini-2.0-flash-lite-001 に即切り替え。
→ AIもクラウドも常に変わることを再認識。
💥 Vertex AIが大阪リージョンで使えない
筆者の地元に近い大阪を最初リージョン指定進めていたところ、東京リージョンのみVertex AIが使えるという衝撃の事実がエラー対処で判明。

<衝撃のコメント> えっ…大阪ダメなの!?

https://cloud.google.com/vertex-ai/generative-ai/docs/learn/locations?hl=ja#asia-pacific

Phase 6:実行結果とコスト感

  • 処理時間:約3〜5秒/件
  • 月100リクエスト時の費用:数十円程度
    Cloud Run, Pub/Sub, GCS維持費 →開発時に数十件登録しましたが、課金は10円未満でした。

クラウドのスケーラビリティと「使わなければ課金されない」従量制は、
個人開発との相性が抜群です。

🧭 まとめ(前編)

  • Pub/Subで疎結合化し、失敗時のリトライを自動化
  • Cloud RunでAI呼び出しをサーバレス化
  • GCSを起点としたイベント駆動設計を体験

これで「入力 → AI生成 → 出力」の一連の流れが完成しました。

🔮 次回予告(後編)

後編ではこの仕組みを フロントを作り、さらにFirestore・BigQuery・Looker Studio に接続し、
データ分析と可視化、CI/CDによる自動デプロイまで発展させます。

「遊び心から始まったアイデアが、学びの教材に果たして至るのか」
― そんな実例を、次回もう少し深掘りしてみます。

Accenture Japan (有志)

Discussion