一百萬個向量,零迴圈:使用 AlloyDB 大規模產生嵌入

1. 總覽

在本程式碼實驗室中,您將建構可擴充的知識庫搜尋應用程式。您不必使用 Python 指令碼和迴圈管理複雜的 ETL 管道來生成向量嵌入,而是使用 AlloyDB AI,在資料庫中以單一 SQL 指令生成嵌入。

d4324260c68d4a70.png

建構項目

高效能的「可搜尋」知識庫資料庫應用程式。

課程內容

您將學習下列內容:

  • 佈建 AlloyDB 叢集並啟用 AI 擴充功能。
  • 使用 SQL 生成合成資料 (超過 50,000 列)。
  • 使用批次處理功能,為整個資料集補充向量嵌入。
  • 設定即時增量觸發條件,自動嵌入新資料。
  • 對「Flexing Context」執行混合型搜尋 (向量 + SQL 篩選器)。

需求條件

  • Chrome 或 Firefox 瀏覽器。
  • 已啟用計費功能的 Google Cloud 專案。
  • 對 SQL 有基本瞭解。

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 services enable \
  alloydb.googleapis.com \
  compute.googleapis.com \
  cloudresourcemanager.googleapis.com \
  servicenetworking.googleapis.com \
  aiplatform.googleapis.com

常見錯誤與疑難排解

「幽靈專案」症候群

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

帳單障礙

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

API 傳播延遲

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

Quota Quags

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

「隱藏」服務代理

有時 AlloyDB 服務代理不會自動獲得 aiplatform.user 角色。如果 SQL 查詢之後無法與 Gemini 通訊,通常是這個原因。

3. 資料庫設定

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

接著建立 AlloyDB 叢集、執行個體和資料表,用於載入測試資料集。

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

  1. 完成這個步驟後,存放區就會複製到本機 Cloud Shell 編輯器,您就能在專案資料夾中執行下列指令 (請務必確認您位於專案目錄中):
sh run.sh
  1. 現在請使用 UI (點選終端機中的連結,或點選終端機中的「在網頁上預覽」連結)。
  2. 輸入專案 ID、叢集和執行個體名稱等詳細資料,即可開始使用。
  3. 在記錄捲動時,您可以喝杯咖啡,並在這裡閱讀幕後運作方式。這項作業大約需要 10 到 15 分鐘。

常見錯誤與疑難排解

「耐心」問題

資料庫叢集是龐大的基礎架構。如果因為頁面「似乎卡住」而重新整理頁面或終止 Cloud Shell 工作階段,可能會產生「幽靈」執行個體,這類執行個體只會部分佈建,且無法在不手動介入的情況下刪除。

區域不符

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

殭屍叢集

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

Cloud Shell 逾時

如果您的 Coffee Break 休息 30 分鐘,Cloud Shell 可能會進入休眠狀態,並中斷 sh run.sh 程序。請保持分頁開啟!

4. 結構定義佈建

在這個步驟中,我們將說明下列事項:

879263c907f3cac6.png

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

1e3ac974b18a8113.png

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

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

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

28cb9a8b6aa0789f.png

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

啟用擴充功能

建構這個應用程式時,我們會使用 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;

建立資料表

我們需要一個資料集來展示規模。我們不會匯入 CSV,而是使用 SQL 立即生成 50,000 列合成「說明文章」。

您可以在 AlloyDB Studio 中使用下列 DDL 陳述式建立資料表:

-- 1. Create the table
CREATE TABLE help_articles (
    id SERIAL PRIMARY KEY,
    title TEXT,
    category TEXT,
    product_version TEXT,
    content_body TEXT,
    embedding vector(768) -- Dimension for text-embedding-005
);

-- 2. Generate 50,000 rows of synthetic data
INSERT INTO help_articles (title, category, product_version, content_body)
SELECT
    'Help Article ' || i,
    CASE 
        WHEN i % 3 = 0 THEN 'Billing' 
        WHEN i % 3 = 1 THEN 'Technical' 
        ELSE 'General' 
    END,
    CASE 
        WHEN i % 2 = 0 THEN '2.0' 
        ELSE '1.0' 
    END,
    'This article covers common issues regarding ' || 
    CASE 
        WHEN i % 3 = 0 THEN 'payment failures, invoice disputes, and credit card updates.'
        WHEN i % 3 = 1 THEN 'connection timeouts, latency issues, and API errors.'
        ELSE 'account profile settings, password resets, and user roles.' 
    END
FROM generate_series(1, 50000) AS i;

item_vector 資料欄可用來儲存文字的向量值。

驗證資料:

SELECT count(*) FROM help_articles;
-- Output: 50000

啟用資料庫旗標

前往執行個體設定控制台,點選「編輯主要執行個體」,然後前往「進階設定」並點選「新增資料庫旗標」。

  1. 確認 google_ml_integration.enable_model_support 旗標已設為啟用:

如果沒有,請在旗標下拉式選單中輸入,並設為「ON」,然後更新執行個體。

  1. 確認 google_ml_integration.enable_faster_embedding_generation 旗標已設為啟用:

如果沒有,請在旗標下拉式選單中輸入,並設為「ON」,然後更新執行個體。

設定資料庫旗標的步驟:

  1. 前往 Google Cloud 控制台的「Clusters」(叢集) 頁面。

前往「Clusters」(叢集) 頁面

  1. 在「Resource Name」(資源名稱) 欄中,按一下叢集。
  2. 在「總覽」頁面,前往叢集中的「執行個體」,選取執行個體,然後點選「編輯」。
  3. 新增、修改或刪除執行個體的資料庫旗標:

新增標記

  1. 如要為執行個體新增資料庫旗標,請按一下「新增旗標」。
  2. 從「New database flag」(新增資料庫旗標) 清單中選取旗標。
  3. 提供旗標值。
  4. 按一下 [完成]。
  5. 按一下「更新執行個體」。
  6. 確認 google_ml_integration 擴充功能為 1.5.2 以上版本:

如要使用下列指令檢查擴充功能版本:

SELECT extversion FROM pg_extension WHERE extname = 'google_ml_integration';

如需將擴充功能更新至更高版本,請使用下列指令:

ALTER EXTENSION google_ml_integration UPDATE;

授予權限

  1. 如要允許使用者管理自動嵌入生成作業,請授予 google_ml.embed_gen_progress 和 google_ml.embed_gen_settings 資料表的 INSERT、UPDATE 和 DELETE 權限:
GRANT INSERT, UPDATE, DELETE ON google_ml.embed_gen_progress TO postgres;

「postgres」是獲得權限的 USER_NAME。

  1. 執行下列陳述式,授予「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"

常見錯誤與疑難排解

「忘記密碼」循環

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

「找不到擴充功能」錯誤

如果 CREATE EXTENSION 失敗,通常是因為執行個體仍處於初始佈建的「維護中」或「更新中」狀態。請確認執行個體建立步驟是否已完成,並視需要稍候幾秒。

5. 「一次性」向量生成

這是本實驗室的核心。我們不會編寫 Python 迴圈來處理這 50,000 列,而是使用 ai.initialize_embeddings 函式。

這個指令會執行兩項操作:

  1. 補充所有現有資料列。
  2. 建立觸發條件,自動嵌入未來新增的資料列。

在 AlloyDB 查詢編輯器執行下列 SQL 陳述式

CALL ai.initialize_embeddings(
  model_id => 'text-embedding-005',
  table_name => 'help_articles',
  content_column => 'content_body',
  embedding_column => 'embedding',
  incremental_refresh_mode => 'transactional'
);

驗證嵌入

檢查 embedding 欄是否已填入資料:

SELECT id, left(content_body, 30), substring(embedding::text, 1, 30) as vector_partial 
FROM help_articles;

您應該會看到類似下方的結果:

a872b8926a164275.png

發生什麼事了?

  1. 大規模回填:自動掃描現有的 50,000 列資料,並透過 Vertex AI 生成嵌入。
  2. 自動化:設定 incremental_refresh_mode => 'transactional' 後,AlloyDB 會自動設定內部觸發條件。插入 help_articles 的任何新資料列都會立即生成嵌入。
  3. 您可以視需要設定 incremental_refresh_mode => ‘None',這樣就只能取得陳述式來執行大量更新,並手動呼叫 ai.refresh_embeddings() 來更新所有資料列嵌入。

您剛才用 6 行 SQL 取代了 Kafka 佇列、Python worker 和遷移指令碼。如需所有屬性的詳細官方說明文件,請參閱這裡。

即時觸發條件測試

接著,請確認「Zero Loop」自動化動作可處理新資料。

  1. 插入新資料列:
INSERT INTO help_articles (title, category, product_version, content_body)
VALUES ('New Scaling Guide', 'Technical', '2.0', 'How to scale AlloyDB to millions of transactions.');
  1. 立即檢查:
SELECT embedding FROM help_articles WHERE title = 'New Scaling Guide';

結果:

您應該會看到向量立即生成,不必執行任何外部指令碼。

調整批量

AlloyDB 目前預設的批次大小為 50。雖然預設值開箱即用,但 AlloyDB 仍可讓使用者控管,針對獨特的模型和資料集調整完美設定。

CALL ai.initialize_embeddings(
  model_id => 'text-embedding-005',
  table_name => 'help_articles',
  content_column => 'content_body',
  embedding_column => 'embedding',
  incremental_refresh_mode => 'transactional',
  batch_size => 20
);

不過,使用者必須留意配額限制,以免影響效能。如要查看建議的 AlloyDB 配額,請參閱說明文件中的「事前準備」一節。

常見錯誤與疑難排解

IAM 傳播落差

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

向量維度不符

help_articles 資料表在 content_body 欄設為 VECTOR(768)。如果之後嘗試使用其他模型 (例如 1536 維模型),插入作業就會失敗。請使用 text-embedding-005。

6. 彈性內容比對搜尋

現在,我們要執行混合型搜尋。我們結合語意理解 (向量) 和商業邏輯 (SQL 篩選器)。

執行下列查詢,找出產品 2.0 版的帳單問題:

SELECT
  title,
  left(content_body, 100) as content_snippet,
  1 - (embedding <=> embedding('text-embedding-005', 'Invoice did not go through')::vector) as relevance
FROM help_articles
WHERE category = 'Billing'  -- Hard SQL Filter
  AND product_version = '2.0' -- Hard SQL Filter
ORDER BY relevance DESC
LIMIT 5;

這是 Flexing Context。搜尋功能會「彈性」理解使用者意圖 (「帳單問題」),同時遵守嚴格的業務限制 (2.0 版)。

f0fdb50d6195c462.png

新創公司和遷移作業的優勢

  1. 零基礎架構債:您不必啟動獨立的向量資料庫 (Pinecone/Milvus),您並未編寫獨立的 ETL 工作,全都在 Postgres 中。
  2. 即時更新:使用「交易」模式,搜尋索引就不會過時。資料一經提交,即可用於向量。
  3. 擴充:AlloyDB 建構於 Google 基礎架構,這項工具能大量生成數百萬個向量,速度比 Python 指令碼更快。

常見錯誤與疑難排解

正式版效能錯誤

問題:50,000 列資料可快速處理,如果類別篩選器的選擇性不夠,100 萬列資料的處理速度會非常慢。解決方案:新增向量索引:如果是正式環境規模,您必須建立索引:CREATE INDEX ON help_articles USING hnsw (embedding vector_cosine_ops);確認索引使用情形:執行 EXPLAIN ANALYZE SELECT ...,確保資料庫使用索引,而非執行循序掃描。

「模型不符」災難

問題:您在 CALL 程序中使用 text-embedding-005 初始化資料欄,如果您在 SELECT 查詢函式 embedding('model-name', ...) 中不小心使用其他模型 (例如 text-embedding-004 或 OSS 模型),維度可能會相符 (768),但向量空間會完全不同。查詢會順利執行,但結果完全不相關 (關聯分數極低)。疑難排解:請確認 ai.initialize_embeddings 中的 model_id 與 SELECT 查詢中的 model_id 完全一致。

「無聲空白」結果 (過度篩選)

問題:混合型搜尋是「AND」運算。這項作業需要語意比對和 SQL 比對。如果使用者搜尋「帳單說明」,但 product_version 欄包含 ‘2.0.1' 而非 ‘2.0',即使向量比對率為 99%,結果仍會是零列。疑難排解:

  • 先執行不含向量排序的查詢,確認 SQL 篩選器 (WHERE category...) 是否確實傳回資料。
  • 檢查大小寫是否正確 (Billing 與 billing)。

4. 權限/配額錯誤 (500 錯誤)

問題:SELECT 子句中的 embedding() 函式會對 Vertex AI 進行即時網路呼叫。如果資料庫服務帳戶失去 Vertex AI 使用者角色,或達到 Vertex AI API 配額 (QPM),整個 SQL 查詢就會失敗。疑難排解:

  • 查看 AlloyDB 的 Cloud Logging。
  • 確認 IAM 角色仍有效。
  • 如果需要高彈性,請將函式包裝在預存程序的 TRY/CATCH 區塊中。

5. 空值嵌入

問題:如果在模型完全初始化「之前」插入資料,或背景 worker 失敗,部分資料列的 embedding 欄可能會顯示 NULL。NULL <=> Vector 會傳回 NULL。這些列會從排列順序中消失。疑難排解:

  • 執行 SELECT count(*) FROM help_articles WHERE embedding IS NULL;,確認涵蓋率達到 100%。

7. 清除

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

這項操作會清除叢集及其執行個體。

8. 恭喜

您已成功建構可擴充的知識庫搜尋應用程式。您不必使用 Python 指令碼和迴圈管理複雜的 ETL 管道來生成向量嵌入,而是使用 AlloyDB AI,透過單一 SQL 指令在資料庫中原生處理嵌入生成作業。

內容回顧

  • 我們終止了用於資料處理的「Python For-Loop」。
  • 我們使用一個 SQL 指令生成了 50,000 個向量。
  • 我們使用觸發條件,自動生成未來的向量。
  • 我們執行了混合型搜尋。

後續步驟