使用 Gemini 3 Flash 和 AlloyDB 建構即時剩餘引擎

1. 總覽

在本程式碼研究室中,您將建構 Neighbor Loop,這是一個分享剩餘物資響應永續生活的應用程式,並將智慧功能視為資料層的一等公民。

整合 Gemini 3.0 Flash 和 AlloyDB AI 後,您將超越基本儲存功能,進入資料庫內建智慧的領域。您將瞭解如何直接在 SQL 中執行多模態項目分析和語意探索,消除延遲和架構膨脹的「AI 稅」。

1da27e0c4d9a33e0.jpeg

建構項目

高效能的「向左滑動配對」網頁應用程式,可供社群分享剩餘物資。

課程內容

  • 一鍵佈建:瞭解如何設定專為 AI 工作負載設計的 AlloyDB 叢集和執行個體。
  • 資料庫內嵌:直接在 INSERT 陳述式中生成 text-embedding-005 向量。
  • 多模態推論:使用 Gemini 3.0 Flash「查看」項目,並自動生成幽默的約會風格簡介。
  • 語意探索:在 SQL 查詢中使用 ai.if() 函式執行邏輯式「氛圍檢查」,根據情境 (而不只是數學) 篩選結果。

架構

Neighbor Loop 可避開傳統應用程式層的瓶頸。我們不會提取資料來處理,而是使用:

  1. AlloyDB AI:即時生成及儲存向量。
  2. Google Cloud Storage:儲存圖片
  3. Gemini 3.0 Flash:直接透過 SQL 對圖片和文字資料執行次秒級的推論作業。
  4. Cloud Run:託管輕量型單一檔案 Flask 後端。

需求條件

  • 瀏覽器,例如 ChromeFirefox
  • 已啟用計費功能的 Google Cloud 專案。
  • 對 SQL 和 Python 有基本瞭解。

2. 事前準備

建立專案

  1. Google Cloud 控制台的專案選取器頁面中,選取或建立 Google Cloud 專案
  2. 確認 Cloud 專案已啟用計費功能。瞭解如何檢查專案是否已啟用計費功能
  3. 您將使用 Cloud Shell,這是 Google Cloud 中執行的指令列環境。按一下 Google Cloud 控制台頂端的「啟用 Cloud Shell」。

「啟用 Cloud Shell」按鈕圖片

  1. 連至 Cloud Shell 後,請使用下列指令確認驗證已完成,專案也已設為獲派的專案 ID:
gcloud auth list
  1. 在 Cloud Shell 中執行下列指令,確認 gcloud 指令已瞭解您的專案。
gcloud config list project
  1. 如果未設定專案,請使用下列指令設定:
gcloud config set project <YOUR_PROJECT_ID>
  1. 啟用必要的 API:按照連結啟用 API。

或者,您也可以使用 gcloud 指令。如要瞭解 gcloud 指令和用法,請參閱說明文件

常見問題與疑難排解

「幽靈專案」 症候群

您執行了 gcloud config set project,但實際上在控制台 UI 中查看的是其他專案。檢查左上方的下拉式選單中的專案 ID!

帳單 路障

您已啟用專案,但忘記帳單帳戶。AlloyDB 是高效能引擎,如果「油箱」(帳單) 空了,就無法啟動。

API 傳播 延遲

您點選了「啟用 API」,但指令列仍顯示 Service Not Enabled。等待 60 秒。雲端需要一點時間喚醒神經元。

配額 Quags

如果您使用的是全新試用帳戶,可能會達到 AlloyDB 執行個體的區域配額。如果 us-central1 失敗,請嘗試 us-east1

「隱藏」服務專員

有時系統不會自動將 aiplatform.user 角色授予 AlloyDB 服務代理。如果 SQL 查詢之後無法與 Gemini 對話,通常就是這個原因。

3. 資料庫設定

在本實驗室中,我們將使用 AlloyDB 做為測試資料的資料庫。並使用「叢集」保存所有資源,例如資料庫和記錄檔。每個叢集都有「主要執行個體」,可做為資料的存取點。資料表會保存實際資料。

我們來建立 AlloyDB 叢集、執行個體和資料表,以便載入測試資料集。

  1. 按一下按鈕,或將下方連結複製到已登入 Google Cloud 控制台使用者的瀏覽器。

  1. 完成這個步驟後,存放區會複製到本機 Cloud Shell 編輯器,您就能從專案資料夾執行下列指令 (請務必確認您位於專案目錄中):
sh run.sh
  1. 現在請使用 UI (按一下終端機中的連結,或按一下終端機中的「preview on web」連結)。
  2. 輸入專案 ID、叢集和執行個體名稱等詳細資料,即可開始使用。
  3. 在記錄檔捲動時,您可以去喝杯咖啡,並在這裡瞭解系統在幕後執行的作業。

常見問題與疑難排解

「耐心」問題

資料庫叢集是繁重的基礎架構,如果因為「看起來卡住」而重新整理頁面或終止 Cloud Shell 工作階段,可能會導致「虛擬」執行個體部分佈建完成,且必須手動介入才能刪除。

區域不符

如果您在 us-central1 中啟用 API,但嘗試在 asia-south1 中佈建叢集,可能會遇到配額問題或服務帳戶權限延遲。整個實驗室都使用同一個區域!

殭屍叢集

如果您先前使用過相同名稱的叢集,但未刪除,指令碼可能會顯示叢集名稱已存在。叢集名稱在專案內不得重複。

Cloud Shell 逾時

如果咖啡休息時間為 30 分鐘,Cloud Shell 可能會進入休眠狀態,並中斷 sh run.sh 程序。請保持分頁啟用狀態!

4. 結構定義佈建

AlloyDB 叢集和執行個體啟動後,請前往 AlloyDB Studio SQL 編輯器啟用 AI 擴充功能,並佈建結構定義。

1e3ac974b18a8113.png

您可能需要等待執行個體建立完成。完成後,請使用建立叢集時建立的憑證登入 AlloyDB。使用下列資料向 PostgreSQL 進行驗證:

  • 使用者名稱:「postgres
  • 資料庫:「postgres
  • 密碼:「alloydb」(或您在建立時設定的密碼)

成功驗證 AlloyDB Studio 後,即可在編輯器中輸入 SQL 指令。如要新增多個編輯器視窗,請按一下最後一個視窗右側的加號。

28cb9a8b6aa0789f.png

您會在編輯器視窗中輸入 AlloyDB 指令,並視需要使用「執行」、「格式化」和「清除」選項。

啟用擴充功能

我們會使用 pgvectorgoogle_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;

建立資料表

您可以在 AlloyDB 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;

為 AlloyDB 服務帳戶授予 Vertex AI 使用者角色

Google Cloud IAM 控制台,授予 AlloyDB 服務帳戶 (格式如下:service-<<PROJECT_NUMBER>>@gcp-sa-alloydb.iam.gserviceaccount.com)「Vertex AI 使用者」角色存取權。PROJECT_NUMBER 會顯示您的專案編號。

或者,您也可以從 Cloud Shell 終端機執行下列指令:

PROJECT_ID=$(gcloud config get-value project)


gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member="serviceAccount:service-$(gcloud projects describe $PROJECT_ID --format="value(projectNumber)")@gcp-sa-alloydb.iam.gserviceaccount.com" \
--role="roles/aiplatform.user"

在 AlloyDB 註冊 Gemini 3 Flash 模型

從 AlloyDB 查詢編輯器執行下列 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 => 'llm',
   model_auth_type => 'alloydb_service_agent_iam'
);
--replace <<YOUR_PROJECT_ID>> with your project id.

常見問題與疑難排解

「密碼失憶」迴圈

如果您使用「一鍵」設定,但忘記密碼,請前往控制台的「執行個體基本資訊」頁面,然後按一下「編輯」重設 postgres 密碼。

「找不到擴充功能」錯誤

如果 CREATE EXTENSION 失敗,通常是因為例項仍處於初始佈建的「維護」或「更新」狀態。檢查執行個體建立步驟是否完成,並視需要等待幾秒鐘。

IAM 傳播落差

您已執行 gcloud IAM 指令,但 SQL CALL 仍因權限錯誤而失敗。IAM 變更可能需要一段時間才會透過 Google 骨幹網路傳播。深呼吸。

向量維度不符

items 資料表設為 VECTOR(768)。如果之後嘗試使用其他模型 (例如 1536 維度模型),插入的內容就會爆炸。請使用 text-embedding-005

專案 ID 拼字錯誤

create_model 呼叫中,如果保留方括號 « » 或專案 ID 輸入錯誤,模型註冊看起來會成功,但第一次實際查詢時會失敗。請仔細檢查字串!

5. 圖片儲存空間 (Google Cloud Storage)

我們使用 GCS bucket 儲存多餘物品的相片。為了這個試用版應用程式,我們希望圖片可公開存取,以便在滑動資訊卡中立即顯示。

  1. 建立值區:在 GCP 專案中建立新值區 (例如 neighborloop-images),最好與資料庫和應用程式位於相同區域。
  2. 設定公開存取權: * 前往 bucket 的「Permissions」分頁。
  3. 新增「allUsers」allUsers主體。
  4. 指派「Storage 物件檢視者」角色 (讓所有人都能查看相片),以及「Storage 物件建立者」角色 (用於上傳示範)。

替代做法 (服務帳戶):如果您不想使用公開存取權,請確保應用程式的服務帳戶已獲得 AlloyDB 的完整存取權,以及管理物件所需的 Storage 角色。

常見問題與疑難排解

區域拖曳

如果資料庫位於 us-central1,而 bucket 位於 europe-west1,AI 運作速度就會變慢。「氛圍檢查」會快速完成,但擷取圖片以顯示在 UI 中時,速度會感覺很慢。請務必將兩者放在相同區域!

值區名稱的專屬性

值區名稱屬於全域命名空間,如果您嘗試將 bucket 命名為 neighborloop-images,很可能已經有人使用這個名稱。如果建立失敗,請新增隨機後置字元

「建立者」與「檢視者」混淆

「建立者」與「檢視者」混淆:如果您只新增「檢視者」,使用者嘗試列出新項目時,應用程式會當機,因為應用程式沒有寫入檔案的權限。您需要這兩項設定才能進行這項特定示範設定。

6. 建立應用程式

將這個存放區複製到專案中,然後逐步瞭解。

  1. 如要複製這個專案,請在 Cloud Shell 終端機 (位於根目錄或要建立這個專案的位置) 執行下列指令:
git clone https://github.com/AbiramiSukumaran/neighbor-loop

這應該會建立專案,您可以在 Cloud Shell 編輯器中驗證。

53a398aff6ba7d5b.png

  1. 如何取得 Gemini API 金鑰
  2. 前往 Google AI Studio:前往 aistudio.google.com
  3. 登入:使用與 Google Cloud 專案相同的 Google 帳戶。
  4. 建立 API 金鑰:
  5. 在左側邊欄中,按一下「取得 API 金鑰」。
  6. 按一下「在新的專案中建立 API 金鑰」按鈕。
  7. 複製金鑰:金鑰產生後,按一下複製圖示。
  8. 現在請在 .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 - 每分鐘要求數)。如果在鄰居迴圈中「滑動」太快,可能會收到 429 Too Many Requests 錯誤。放慢速度!

公開金鑰安全性

如果您不小心git commit了含有金鑰的 .env 檔案,請務必在 .gitignore 中加入 .env

「連線逾時」無效

您在 .env 檔案中使用了私有 IP 位址,但嘗試從 VPC 外部 (例如本機) 連線。私人 IP 只能從同一個 Google Cloud 網路存取。切換至公開 IP!

通訊埠 5432 假設

雖然 5432 是標準的 PostgreSQL 連接埠,但如果您使用 Auth Proxy,AlloyDB 有時會需要特定的連接埠設定。在本實驗室中,請務必在主機字串結尾使用 :5432。

「授權網路」Gatekeeper

即使您有公開 IP,除非將執行程式碼的機器的 IP 位址加入允許清單,否則 AlloyDB 會「拒絕連線」。修正方式:在 AlloyDB 執行個體設定中,將 0.0.0.0/0 (僅適用於暫時測試!) 或特定 IP 新增至「已授權網路」。

SSL/TLS 握手失敗

AlloyDB 偏好使用安全連線。如果 DATABASE_URL 未正確指定驅動程式 (例如使用 pg8000),交握可能會無聲無息地失敗,導致您收到一般「資料庫無法連線」錯誤。

「主要與讀取集區」交換

如果誤複製了讀取集區的 IP 位址,而非主要執行個體,應用程式雖然可以搜尋項目,但嘗試列出新項目時會當機,並顯示「唯讀」錯誤。寫入時一律使用主要執行個體 IP。

7. 讓我們檢查程式碼

你的物品「約會資料」

c2c543562cc9b353.png

使用者上傳商品相片後,不必撰寫詳細說明,我使用 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")
)

21f871a1b549efcf.png

即時資料庫內嵌

aa783a459f1b02da.png

AlloyDB 最酷的功能之一,就是不必離開 SQL 環境即可產生嵌入項目。我沒有在 Python 中呼叫嵌入模型,然後將向量傳回資料庫,而是使用 embedding() 函式,在一個 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 進行進階向量搜尋和智慧篩選

標準關鍵字搜尋功能有限。如果搜尋「something to fix my chair」,傳統資料庫可能會傳回任何結果,因為「chair」一字不在標題中。Neighbor Loop 運用 AlloyDB AI 的進階向量搜尋功能解決了這個問題。

使用 pgvector 擴充功能和 AlloyDB 的最佳化儲存空間,我們就能執行極快的相似度搜尋。不過,結合向量鄰近性和 LLM 邏輯時,才是真正「神奇」的時刻。

AlloyDB AI 可讓我們直接在 SQL 查詢中呼叫 Gemini 等模型。也就是說,我們可以執行語意探索,包括使用 ai.if() 函式進行邏輯式「健全性檢查」:

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
 AND ai.if(
       prompt => 'Does this text: "' || bio ||'" match the user request: "' ||  :query || '", at least 60%? "',
       model_id => 'gemini-3-flash-preview'
     ) 
ORDER BY score DESC
LIMIT 5

這項查詢代表架構的重大轉變:我們將邏輯移至資料。Gemini 3 Flash 會在資料庫引擎中執行「氛圍檢查」,而不是將數千筆結果拉進應用程式程式碼中進行篩選。這項功能可縮短延遲時間、降低輸出成本,並確保結果不僅在數學上相似,在脈絡上也有關聯。

語意搜尋功能螢幕截圖

「滑動配對」迴圈

使用者介面是經典的卡牌。

向左滑動:捨棄。

向右滑動:配對成功!

「滑動配對」功能螢幕截圖

向右滑動時,後端會在滑動表格中記錄互動,並將項目標示為相符。前端會立即觸發顯示供應商聯絡資訊的模式,方便你安排取貨。

8. 將其部署至 Cloud Run

  1. 在 Cloud Shell 終端機中執行下列指令,將專案複製到 Cloud Run 並部署。請務必位於專案的根資料夾中

在 Cloud Shell 終端機中執行下列指令:

gcloud beta run deploy neighbor-loop \
   --source . \
   --region=us-central1 \
   --network=<<YOUR_NETWORK_NAME>> \
   --subnet=<<YOUR_SUBNET_NAME>> \
   --allow-unauthenticated \
   --vpc-egress=all-traffic \
   --set-env-vars GEMINI_API_KEY=<<YOUR_GEMINI_API_KEY>>,DATABASE_URL=postgresql+pg8000://postgres:<<YOUR_PASSWORD>>@<<PRIVATE_IP_HOST>>:<<PORT>>/postgres,GCS_BUCKET_NAME=<<YOUR_GCS_BUCKET>>

將預留位置 <<YOUR_GEMINI_API_KEY>>, <<YOUR_PASSWORD>, <<PRIVATE_IP_HOST>>, <<PORT>> and <<YOUR_GCS_BUCKET>> 的值替換為

指令完成後,會輸出服務網址。複製。

  1. 將「AlloyDB Client」(AlloyDB 用戶端) 角色授予 Cloud Run 服務帳戶。這樣一來,無伺服器應用程式就能安全地連線至資料庫。

在 Cloud Shell 終端機中執行下列指令:

# 1. Get your Project ID and Project Number
PROJECT_ID=$(gcloud config get-value project)
PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format="value(projectNumber)")

# 2. Grant the AlloyDB Client role
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:$PROJECT_NUMBER-compute@developer.gserviceaccount.com" \
--role="roles/alloydb.client"

現在請使用服務網址 (您先前複製的 Cloud Run 端點) 測試應用程式。上傳舊電動工具的照片,其餘工作就交給 Gemini 處理!

常見問題與疑難排解

「修訂版本失敗」迴圈

如果部署完成,但網址顯示 500 Internal Server Error,請檢查記錄!這通常是因為缺少環境變數 (例如 DATABASE_URL 中有錯字),或是 Cloud Run 服務帳戶缺少從 GCS bucket 讀取資料的權限。

IAM「影子」角色

即使有權部署,Cloud Run 服務帳戶 (通常為 [project-number]-compute@developer.gserviceaccount.com) 也需要 AlloyDB Client 角色,才能實際建立與資料庫的連線。

9. 高階疑難排解

b6cdd3785d5461a9.jpeg

10. 試用版

您應該可以將端點用於測試。

但為了方便示範,您可以在幾天內使用以下內容:

11. 清理

完成本實驗室後,請務必刪除 AlloyDB 叢集和執行個體。

這項作業應會清理叢集及其執行個體。

12. 恭喜

您已成功使用 Google Cloud 建構 Neighbor Loop 應用程式,為永續發展社群盡一份心力。將嵌入和 Gemini 3 Flash AI 邏輯移至 AlloyDB 後,應用程式速度會大幅提升 (視部署設定而定),程式碼也會變得非常簡潔。我們儲存的不只是資料,更是意圖

Gemini 3 Flash 的速度和 AlloyDB 的最佳化向量處理功能相輔相成,為社群主導的平台開創全新局面。