使用 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 專案已啟用計費功能。瞭解如何檢查專案是否已啟用計費功能
  1. 您將使用 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 控制台中,將「Vertex AI 使用者」角色授予 AlloyDB 服務帳戶 (看起來像這樣:service-<<PROJECT_NUMBER>>@gcp-sa-alloydb.iam.gserviceaccount.com)。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檔案,一律將 .env 新增至 .gitignore

「連線逾時」失效

您在 .env 檔案中使用了私有 IP 位址,但嘗試從虛擬私有雲外部 (例如本機) 連線。私人 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 值區讀取資料的權限。

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 的最佳化向量處理功能相輔相成,為社群主導的平台開創全新局面。