1. 概要
この Codelab では、インテリジェンスをデータレイヤのファーストクラス市民として扱う、持続可能な余剰共有アプリ Neighbor Loop を構築します。
Gemini 3.0 Flash と Cloud SQL の ML インテグレーションを統合することで、基本的なストレージからデータベース内インテリジェンスの領域に移行します。SQL 内でマルチモーダル アイテム分析とセマンティック検索を直接実行する方法について説明します。

作成するアプリの概要
コミュニティの余剰共有のための高性能な「スワイプしてマッチ」ウェブ アプリケーション。
学習内容
- ワンクリック プロビジョニング: AI ワークロード向けに設計された Cloud SQL と インスタンスを設定する方法。
- データベース内エンベディング: INSERT ステートメント内で text-embedding-005 ベクトルを直接生成する。
- マルチモーダル推論: Gemini 3.0 Flash を使用してアイテムを「認識」し、デートスタイルのウィットに富んだプロフィールを自動的に生成する。
- セマンティック ディスカバリ: ai.if() 関数を使用して SQL クエリ内でロジックベースの「バイブチェック」を実行し、数学だけでなくコンテキストに基づいて結果をフィルタする。
アーキテクチャ
Neighbor Loop は、従来型のアプリケーション レイヤのボトルネックを回避します。データを抽出して処理する代わりに、次のものを使用します。
- Cloud SQL + ML インテグレーション: ベクトルをリアルタイムで生成して保存します。
- Google Cloud Storage: 画像を保存します。
- Gemini 3.0 Flash: SQL を介して画像データとテキストデータに対して 1 秒未満の推論を実行します。
- Cloud Run: 軽量な単一ファイルの Flask バックエンドをホストします。
要件
2. 始める前に
プロジェクトを作成する
- Google Cloud コンソールのプロジェクト選択ページで、Google Cloud プロジェクトを選択または作成します。
- Cloud プロジェクトに対して課金が有効になっていることを確認します。プロジェクトで課金が有効になっているかどうかを確認する方法については、こちらをご覧ください。
- Google Cloud 上で動作するコマンドライン環境の Cloud Shell を使用します。Google Cloud コンソールの上部にある「Cloud Shell をアクティブにする」アイコン をクリックします。
![[Cloud Shell をアクティブにする] ボタンの画像](https://codelabs.developers.google.com/static/gemini-3-on-cloudsql-sustainability-app/img/91567e2f55467574.png?hl=ja)
- Cloud Shell に接続したら、次のコマンドを使用して、すでに認証済みであることと、プロジェクトがプロジェクト ID に設定されていることを確認します。
gcloud auth list
- Cloud Shell で次のコマンドを実行して、gcloud コマンドがプロジェクトを認識していることを確認します。
gcloud config list project
- プロジェクトが設定されていない場合は、次のコマンドを使用して設定します。
gcloud config set project <YOUR_PROJECT_ID>
- 必要な API を有効にします。リンクに沿って API を有効にします。
または、gcloud コマンドを使用することもできます。gcloud コマンドとその使用方法については、ドキュメントをご覧ください。
注意点とトラブルシューティング
「ゴースト プロジェクト」 シンドローム |
|
課金 の障壁 | プロジェクトを有効にしましたが、請求先アカウントを忘れていました。課金が空の場合、Cloud SQL は起動しません。 |
API の伝播 の遅延 | [API を有効にする] をクリックしましたが、コマンドラインに |
3. データベースの設定
このラボでは、テストデータのデータベースとして Cloud SQL for PostgreSQL を使用します。
テストデータセットが読み込まれる Cloud SQL インスタンスを作成しましょう。
- ボタンをクリックするか、以下のリンクを Google Cloud コンソール ユーザーがログインしているブラウザにコピーします。
- この手順が完了すると、リポジトリがローカルの Cloud Shell エディタにクローンされ、プロジェクト フォルダから次のコマンドを実行できるようになります(プロジェクト ディレクトリにいることを確認することが重要です)。
sh run.sh
- UI を使用します(ターミナル内のリンクをクリックするか、ターミナル内の [ウェブでプレビュー] リンクをクリックします)。
- プロジェクト ID とインスタンス名の詳細を入力して開始します。
- ログがスクロールしている間にコーヒーを飲んでください。この処理の舞台裏については、こちらをご覧ください。
注意点とトラブルシューティング
リージョンが一致しない |
|
Cloud Shell のタイムアウト | コーヒー ブレイクに 30 分かかると、Cloud Shell がスリープ状態になり、 |
4. スキーマのプロビジョニング
Cloud SQL インスタンスが実行されたら、Cloud SQL Studio SQL エディタに移動して AI 拡張機能を有効にし、スキーマをプロビジョニングします。

インスタンスの作成が完了するまで待つ必要がある場合があります。 完了したら、作成時に作成した認証情報を使用して Cloud SQL インスタンスにログインします。PostgreSQL の認証には次のデータを使用します。
- ユーザー名: "
postgres" - データベース: "
postgres" - パスワード: "
cloudsql"(作成時に設定した値)
Cloud SQL Studio で認証が成功したら、エディタに SQL コマンドを入力します。最後のウィンドウの右側にあるプラス記号を使用して、複数のエディタ ウィンドウを追加できます。

必要に応じて [実行]、[フォーマット]、[クリア] オプションを使用して、エディタ ウィンドウに Cloud SQL のコマンドを入力します。
拡張機能を有効にする
このアプリの構築には、pgvector 拡張機能と google_ml_integration 拡張機能を使用します。pgvector 拡張機能を使用すると、ベクトル エンベディングを保存して検索できます。 google_ml_integration 拡張機能は、Vertex AI 予測エンドポイントにアクセスして SQL で予測を取得するために使用する関数を提供します。次の DDL を実行して、これらの拡張機能を有効にします。
CREATE EXTENSION IF NOT EXISTS google_ml_integration CASCADE;
CREATE EXTENSION IF NOT EXISTS vector;
テーブルを作成する
Cloud SQL Studio で次の DDL ステートメントを使用してテーブルを作成できます。
-- Items Table (The "Profile" you swipe on)
CREATE TABLE items (
item_id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
owner_id UUID,
provider_name TEXT,
provider_phone TEXT,
title TEXT,
bio TEXT,
category TEXT,
image_url TEXT,
item_vector VECTOR(768),
status TEXT DEFAULT 'available',
created_at TIMESTAMP DEFAULT NOW()
);
-- Swipes Table (The Interaction)
CREATE TABLE swipes (
swipe_id SERIAL PRIMARY KEY,
swiper_id UUID,
item_id UUID REFERENCES items(item_id),
direction TEXT CHECK (direction IN ('left', 'right')),
is_match BOOLEAN DEFAULT FALSE,
created_at TIMESTAMP DEFAULT NOW()
);
item_vector 列には、テキストのベクトル値を格納できます。
権限を付与
次のステートメントを実行して、「embedding」関数に対する実行権限を付与します。
GRANT EXECUTE ON FUNCTION embedding TO postgres;
ML の統合を有効にする
データベース内で機械学習機能を直接利用するには、ML インテグレーション フラグを有効にする必要があります。
Cloud Shell ターミナルから次のコマンドを実行できます。
INSTANCE_NAME="<<The name of your Cloud SQL Instance>>"
gcloud sql instances patch $INSTANCE_NAME --tier=db-custom-1-3840
gcloud sql instances patch $INSTANCE_NAME \
--database-flags=cloudsql.enable_google_ml_integration=on
gcloud sql instances patch $INSTANCE_NAME --enable-google-ml-integration
Cloud SQL サービス アカウントに Vertex AI ユーザーロールを付与する
Google Cloud IAM コンソールから、Cloud SQL サービス アカウント(service-<<PROJECT_NUMBER>>@cp-sa-cloud-sql.iam.gserviceaccount.com)に「Vertex AI ユーザー」ロールへのアクセス権を付与します。PROJECT_NUMBER にはプロジェクト番号が設定されます。
または、Cloud Shell ターミナルから次のコマンドを実行することもできます。
INSTANCE_NAME="<<The name of your Cloud SQL Instance>>"
PROJECT_ID=$(gcloud config get-value project)
SA_EMAIL=$(gcloud sql instances describe $INSTANCE_NAME --format='value(serviceAccountEmailAddress)')
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:$SA_EMAIL" \
--role="roles/aiplatform.user"
Cloud SQL に Gemini 3 Flash モデルを登録する
Cloud SQL クエリ エディタから次の SQL ステートメントを実行します。
CALL google_ml.create_model(
model_id => 'gemini-3-flash-preview',
model_request_url => 'https://aiplatform.googleapis.com/v1/projects/<<YOUR_PROJECT_ID>>/locations/global/publishers/google/models/gemini-3-flash-preview:generateContent',
model_qualified_name => 'gemini-3-flash-preview',
model_provider => 'google',
model_type => 'generic',
model_auth_type => 'cloudsql_service_agent_iam'
);
--replace <<YOUR_PROJECT_ID>> with your project id.
注意点とトラブルシューティング
「パスワードを忘れた」ループ | [ワンクリック] 設定を使用し、パスワードを忘れた場合は、コンソールのインスタンスの基本情報ページに移動して [編集] をクリックし、 |
「拡張機能が見つかりません」エラー |
|
IAM の伝播のギャップ |
|
ベクトルの次元が一致しない |
|
プロジェクト ID の入力ミス |
|
Vertex AI のインテグレーションは無効です |
|
5. 画像ストレージ(Google Cloud Storage)
余剰アイテムの写真を保存するには、GCS バケットを使用します。このデモアプリでは、スワイプカードにすぐにレンダリングされるように、画像に一般公開アクセス権を付与します。
- バケットを作成する: 作成 GCP プロジェクトに新しいバケットを作成します(例: neighborloop-images)。データベースとアプリケーションと同じリージョンに作成することをおすすめします。
- 一般公開アクセス権を構成する: バケットの [権限] タブに移動します。
- allUsers プリンシパルを追加します。
- Storage オブジェクト閲覧者 ロール(誰でも写真を見ることができるように)と Storage オブジェクト作成者 ロール(デモのアップロード用)を割り当てます。
代替 (サービス アカウント): 一般公開アクセス権を使用しない場合は、アプリケーションのサービス アカウントに Cloud SQL へのフルアクセス権と、オブジェクトを安全に管理するために必要な Storage ロールが付与されていることを確認してください。
コマンドを実行して一般公開アクセス権を付与する場合は、Cloud Shell ターミナルで次のコマンドを実行します。
BUCKET_NAME="<<your-bucket-name>>"
gcloud storage buckets add-iam-policy-binding gs://$BUCKET_NAME \
--member="allUsers" \
--role="roles/storage.objectViewer"
注意点とトラブルシューティング
リージョンのドラッグ | データベースが |
バケット名の一意性 | バケット名はグローバルな名前空間です。バケットに |
「作成者」と「閲覧者」の混同 | 「作成者」と「閲覧者」の混同: 「閲覧者」のみを追加すると、ユーザーが新しいアイテムを一覧表示しようとしたときに、ファイルに書き込む権限がないため、アプリがクラッシュします。 この特定のデモ設定では両方が必要です。 |
6. アプリケーションを作成しましょう
このリポジトリをプロジェクトにクローンして、手順を確認しましょう。
- これをクローンするには、Cloud Shell ターミナルから(ルート ディレクトリまたはこのプロジェクトを作成する場所から)、次のコマンドを 1 つずつ実行します。
git clone https://github.com/flazer99/neighbor-loop-cloud-sql
cd neighbor-loop-cloud-sql/
これでプロジェクトが作成されます。Cloud Shell エディタで確認できます。

- Gemini API キーを取得する方法
- Google AI Studio にアクセスする: aistudio.google.com に移動します。
- ログイン: Google Cloud プロジェクトで使用している同じ Google アカウントを使用します。
- API キーを作成する:
- 左側のサイドバーで [API キーを取得] をクリックします。
- [新しいプロジェクトで API キーを作成] ボタンをクリックします。
- キーをコピーする: キーが生成されたら、コピー アイコンをクリックします。
- .env ファイルで環境変数を設定します。
GEMINI_API_KEY=<<YOUR_GEMINI_API_KEY>>
DATABASE_URL=postgresql+pg8000://postgres:<<YOUR_PASSWORD>>@<<HOST_IP>>:<<PORT>>/postgres
GCS_BUCKET_NAME=<<YOUR_GCS_BUCKET>>
プレースホルダ <<YOUR_GEMINI_API_KEY>>, <<YOUR_PASSWORD>, <<HOST_IP>>, <<PORT>> and <<YOUR_GCS_BUCKET>>. の値を置き換えます。
注意点とトラブルシューティング
複数のアカウントの混乱 | 複数の Google アカウント(個人用と仕事用)にログインしている場合、AI Studio が誤ったアカウントにデフォルト設定されることがあります。右上のアバターを確認 して、GCP プロジェクト アカウントと一致していることを確認してください。 |
「無料枠」の割り当てに達した | 無料枠を使用している場合は、レート制限(RPM - 1 分あたりのリクエスト数)があります。Neighbor Loop で「スワイプ」が速すぎると、 |
公開鍵のセキュリティ | キーを含む |
7. コードを確認しましょう
アイテムの「デート プロフィール」

ユーザーがアイテムの写真をアップロードするときに、長い説明を入力する必要はありません。Gemini 3 Flash を使用してアイテムを「認識」し、リスティングを作成します。
バックエンドでは、ユーザーはタイトルと写真のみを提供します。残りの処理は Gemini が行います。
prompt = """
You are a witty community manager for NeighborLoop.
Analyze this surplus item and return JSON:
{
"bio": "First-person witty dating-style profile bio for the product, not longer than 2 lines",
"category": "One-word category",
"tags": ["tag1", "tag2"]
}
"""
response = genai_client.models.generate_content(
model="gemini-3-flash-preview",
contents=[types.Part.from_bytes(data=image_bytes, mime_type="image/jpeg"), prompt],
config=types.GenerateContentConfig(response_mime_type="application/json")
)

リアルタイムのデータベース内エンベディング

Cloud SQL の最も優れた機能の 1 つは、SQL コンテキストを離れることなくエンベディングを生成できることです。Python でエンベディング モデルを呼び出してベクトルを DB に送信する代わりに、embedding() 関数を使用して 1 つの INSERT ステートメントで実行します。
INSERT INTO items (owner_id, provider_name, provider_phone, title, bio, category, image_url, status, item_vector)
VALUES (
:owner, :name, :phone, :title, :bio, :cat, :url, 'available',
embedding('text-embedding-005', :title || ' ' || :bio)::vector
)
これにより、投稿されたアイテムはすぐに意味で「検索可能」になります。これは、Neighbor Loop アプリの「商品を掲載する」機能をカバーする部分です。

Gemini 3.0 による高度なベクトル検索とスマート フィルタリング
標準のキーワード検索には制限があります。「椅子の修理」を検索しても、タイトルに「椅子」という単語が含まれていない場合、従来のデータベースでは何も返されないことがあります。Neighbor Loop は、Cloud SQL AI の高度なベクトル検索でこの問題を解決します。
pgvector 拡張機能と Cloud SQL の最適化されたストレージを使用することで、非常に高速な類似性検索を実行できます。しかし、真価が発揮されるのは、ベクトル近接性と LLM ベースのロジックを組み合わせたときです。
SELECT item_id, title, bio, category, image_url,
1 - (item_vector <=> embedding('text-embedding-005', :query)::vector) as score
FROM items
WHERE status = 'available'
AND item_vector IS NOT NULL
ORDER BY score DESC
LIMIT 5
このクエリは、ロジックをデータに移行するという大きなアーキテクチャの変更を表しています。数千件の結果をアプリケーション コードにプルしてフィルタする代わりに、Gemini 3 Flash はデータベース エンジン内で「バイブチェック」を実行します。これにより、レイテンシが短縮され、下り(外向き)の費用が削減され、結果が数学的に類似しているだけでなく、コンテキストに関連していることが保証されます。

「スワイプしてマッチ」ループ
UI は定番のカードのデッキです。
左にスワイプ: 破棄。
右にスワイプ: マッチしました。

右にスワイプすると、バックエンドはスワイプ テーブルにインタラクションを記録し、アイテムをマッチ済みとしてマークします。フロントエンドは、プロバイダの連絡先情報を表示するモーダルをすぐにトリガーし、受け取りの手配ができるようにします。
8. Cloud Run にデプロイしましょう
- プロジェクトがクローンされた Cloud Shell ターミナルから次のコマンドを実行して Cloud Run にデプロイします。プロジェクトのルートフォルダにいることを確認してください。
Cloud Shell ターミナルで次のコマンドを実行します。
gcloud run deploy neighbor-loop-cloud-sql \
--source . \
--region=us-central1 \
--allow-unauthenticated \
--network=easy-cloudsql-vpc \
--subnet=easy-cloudsql-subnet \
--vpc-egress=private-ranges-only \
--set-env-vars GEMINI_API_KEY=<<YOUR_GEMINI_API_KEY>>,DATABASE_URL=postgresql+pg8000://postgres:<<YOUR_PASSWORD>>@<<PRIVATE_IP_HOST>>:5432/postgres,GCS_BUCKET_NAME=<<YOUR_GCS_BUCKET>>
プレースホルダ <<YOUR_GEMINI_API_KEY>>, <<YOUR_PASSWORD>, <<PRIVATE_IP_HOST>>, <<PORT>> and <<YOUR_GCS_BUCKET>> の値を置き換えます。
コマンドが完了すると、サービス URL が出力されます。コピーします。
サービス URL(先ほどコピーした Cloud Run エンドポイント)を使用して、アプリをテストします。古い電動工具の写真をアップロードして、残りの処理は Gemini に任せましょう。
注意点とトラブルシューティング
「リビジョンに失敗しました」ループ | デプロイが完了しても URL に |
9. 高度なトラブルシューティング

10. デモ
目的地をテストに使用できます。
ただし、数日間デモを行う場合は、次のものを使用できます。
11. クリーンアップ
このラボが完了したら、Cloud SQL インスタンスを削除することを忘れないでください。
12. 完了
Google Cloud を使用して、持続可能なコミュニティ向けの Neighbor Loop アプリを正常に構築できました。エンベディングと Gemini 3 Flash AI ロジックを Cloud SQL に移行することで、アプリは非常に高速になり(デプロイ設定によって異なります)、コードは非常にクリーンになります。データを保存するだけでなく、インテント を保存します。
Gemini 3 Flash の速度と Cloud SQL の最適化されたベクトル処理の組み合わせは、コミュニティ主導型プラットフォームの真のフロンティアです。