1. 序曲
孤立開發的時代即將結束。下一波技術演進浪潮並非天才的獨門絕技,而是協作的精髓。建立單一智慧代理程式是一項有趣的實驗。建構強大、安全且智慧的代理程式生態系統 (也就是真正的 Agentverse),是現代企業面臨的重大挑戰。
在這個新時代,要取得成功,就必須整合四個重要角色,也就是支援任何蓬勃發展的代理系統的基礎支柱。任何一個領域的不足都會造成弱點,進而危害整個結構。
這場研討會是企業的必備手冊,可協助您在 Google Cloud 上掌握 AI 代理的未來趨勢。我們提供端對端藍圖,從最初的想法到全面運作的現實,引導您完成整個過程。在四個相互連結的實驗室中,您將瞭解開發人員、架構師、資料工程師和 SRE 的專業技能如何匯聚,共同建立、管理及擴充強大的 Agentverse。
單一支柱無法單獨支援 Agentverse。如果沒有開發人員的精確執行,架構師的宏偉設計就毫無用處。如果沒有資料工程師的智慧,開發人員的代理程式就無法運作;如果沒有 SRE 的保護,整個系統就會很脆弱。唯有透過合作和對彼此角色的共同理解,團隊才能將創新概念轉化為攸關業務的營運實況。您的旅程由此開始。準備好精通自己的職責,並瞭解自己在整體架構中的角色。
歡迎參加「The Agentverse:A Call to Champions」
在企業廣闊的數位領域中,新時代已然來臨。我們正處於代理時代,這個時代充滿無限可能,智慧型自主代理能完美協作,加速創新並消除日常瑣事。
這個連結的生態系統充滿力量和潛力,我們稱之為「Agentverse」。
但一種稱為「靜態」的無聲腐敗,已開始侵蝕這個新世界的邊緣。「靜態」並非病毒或錯誤,而是混亂的化身,以創作行為本身為食。
這些舊有的挫敗感會以可怕的形式放大,進而催生出七大開發幽靈。如果未勾選,The Static 和其 Spectres 會讓進度停滯不前,使 Agentverse 的前景變成技術債和廢棄專案的荒地。
今天,我們呼籲各界好手挺身而出,力挽狂瀾。我們需要英雄精通自己的技藝,並攜手合作保護 Agentverse。現在來選擇路徑吧。
選擇課程
您面前有四條截然不同的道路,每一條都是對抗「靜態」的關鍵支柱。雖然訓練是單人任務,但最終能否成功取決於你是否瞭解自己的技能如何與他人結合。
- 暗影刀鋒 (開發人員):擅長鍛造,是前線好手。您是工匠,負責打造刀刃、製作工具,並在複雜的程式碼細節中面對敵人。你的道路充滿精準、技巧和實用創作。
- 召喚師 (架構師):偉大的策略家和自動調度管理工具。您不會看到單一特務,而是整個戰場。您設計的藍圖可讓整個代理程式系統通訊、協作,並達成遠遠超出任何單一元件的目標。
- 學者 (資料工程師):尋找隱藏的真相,並守護智慧。您深入廣闊的資料荒野,發掘可賦予代理程式目標和視野的智慧。你的知識可以揭露敵人的弱點,或賦予盟友力量。
- 守護者 (開發運作 / SRE):領域的堅定守護者和盾牌。您要建造堡壘、管理電力供應線,並確保整個系統能抵禦「靜電」的攻擊。你的力量是團隊獲勝的基礎。
你的任務
訓練會以獨立運動的形式開始。您將選擇適合自己的路徑,學習精通職務所需的獨特技能。試用期結束時,您將面對由靜態所生的幽靈,這個迷你首領會利用您創作時遇到的特定挑戰。
只有精通個人角色,才能為最終試用做好準備。接著,您必須與其他班級的冠軍組成隊伍。你們將一同深入腐敗的核心,迎戰最終頭目。
最後的合作挑戰,將考驗你們的綜合實力,並決定 Agentverse 的命運。
Agentverse 等待英雄的到來。你會接聽電話嗎?
2. 學者的魔法書
我們的旅程即將展開!身為學者,知識是我們的主要武器。我們在封存資料 (Google Cloud Storage) 中發現大量古老難解的卷軸。這些卷軸記載著有關肆虐大地的可怕野獸的原始情報。我們的目標是運用 Google BigQuery 的強大分析魔法,以及 Gemini Elder Brain (Gemini Pro 模型) 的智慧,解讀這些非結構化文字,並將其轉化為可查詢的結構化動物寓言集。這將成為我們未來所有策略的基礎。
課程內容
- 使用 BigQuery 建立外部資料表,並透過 BQML.GENERATE_TEXT 和 Gemini 模型,執行複雜的非結構化到結構化轉換作業。
- 佈建 PostgreSQL 適用的 Cloud SQL 執行個體,並啟用 pgvector 擴充功能,以支援語意搜尋功能。
- 使用 Dataflow 和 Apache Beam 建構強大的容器化批次管道,處理原始文字檔、使用 Gemini 模型生成向量嵌入,並將結果寫入關聯式資料庫。
- 在代理程式中實作基本的檢索增強生成 (RAG) 系統,查詢向量化資料。
- 在 Cloud Run 上以安全無虞、可擴充的服務形式,部署可感知資料的代理程式。
3. 準備學者聖所
歡迎,學者。在開始記錄 Grimoire 的強大知識之前,我們必須先準備好聖所。這項基礎儀式包括為 Google Cloud 環境施展魔法、開啟正確的入口 (API),以及建立資料魔法流動的管道。準備妥當的聖所可確保咒語效力,並保護我們的知識。
👉點選 Google Cloud 控制台頂端的「啟用 Cloud Shell」(Cloud Shell 窗格頂端的終端機形狀圖示),
👉按一下「Open Editor」(開啟編輯器) 按鈕 (類似於開啟資料夾和鉛筆的圖示)。這會在視窗中開啟 Cloud Shell 程式碼編輯器。左側會顯示檔案總管。
👉找出 Google Cloud 專案 ID:
- 開啟 Google Cloud 控制台:https://console.cloud.google.com
- 在頁面頂端的專案下拉式選單中,選取要用於本研討會的專案。
- 專案 ID 會顯示在資訊主頁的「專案資訊」資訊卡中
👉在雲端 IDE 中開啟終端機
👉💻在終端機中,使用下列指令驗證您是否已通過驗證,以及專案是否已設為您的專案 ID:
gcloud auth list
👉💻從 GitHub 複製啟動程序專案:
git clone https://github.com/weimeilin79/agentverse-dataengineer
chmod +x ~/agentverse-dataengineer/init.sh
chmod +x ~/agentverse-dataengineer/set_env.sh
chmod +x ~/agentverse-dataengineer/data_setup.sh
git clone https://github.com/weimeilin79/agentverse-dungeon.git
chmod +x ~/agentverse-dungeon/run_cloudbuild.sh
chmod +x ~/agentverse-dungeon/start.sh
👉💻 執行初始化指令碼,系統會提示您輸入 Google Cloud 專案 ID。並在 init.sh
指令碼提示時,輸入上一個步驟中找到的 Google Cloud 專案 ID。
cd ~/agentverse-dataengineer
./init.sh
👉💻 設定所需的專案 ID:
gcloud config set project $(cat ~/project_id.txt) --quiet
👉💻 執行下列指令,啟用必要的 Google Cloud API:
gcloud services enable \
storage.googleapis.com \
bigquery.googleapis.com \
sqladmin.googleapis.com \
aiplatform.googleapis.com \
dataflow.googleapis.com \
pubsub.googleapis.com \
cloudfunctions.googleapis.com \
run.googleapis.com \
cloudbuild.googleapis.com \
artifactregistry.googleapis.com \
iam.googleapis.com \
compute.googleapis.com \
cloudresourcemanager.googleapis.com \
cloudaicompanion.googleapis.com \
bigqueryunified.googleapis.com
👉💻 如果您尚未建立名為「agentverse-repo」的 Artifact Registry 存放區,請執行下列指令來建立:
. ~/agentverse-dataengineer/set_env.sh
gcloud artifacts repositories create $REPO_NAME \
--repository-format=docker \
--location=$REGION \
--description="Repository for Agentverse agents"
設定權限
👉💻 在終端機中執行下列指令,授予必要權限:
. ~/agentverse-dataengineer/set_env.sh
# --- Grant Core Data Permissions ---
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:$SERVICE_ACCOUNT_NAME" \
--role="roles/storage.admin"
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:$SERVICE_ACCOUNT_NAME" \
--role="roles/bigquery.admin"
# --- Grant Data Processing & AI Permissions ---
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:$SERVICE_ACCOUNT_NAME" \
--role="roles/dataflow.admin"
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:$SERVICE_ACCOUNT_NAME" \
--role="roles/cloudsql.admin"
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:$SERVICE_ACCOUNT_NAME" \
--role="roles/pubsub.admin"
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:$SERVICE_ACCOUNT_NAME" \
--role="roles/aiplatform.user"
# --- Grant Deployment & Execution Permissions ---
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:$SERVICE_ACCOUNT_NAME" \
--role="roles/cloudbuild.builds.editor"
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:$SERVICE_ACCOUNT_NAME" \
--role="roles/artifactregistry.admin"
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:$SERVICE_ACCOUNT_NAME" \
--role="roles/run.admin"
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:$SERVICE_ACCOUNT_NAME" \
--role="roles/iam.serviceAccountUser"
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:$SERVICE_ACCOUNT_NAME" \
--role="roles/logging.logWriter"
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:$SERVICE_ACCOUNT_NAME" \
--role="roles/dataflow.admin"
👉💻 訓練開始後,我們就會準備最終挑戰。下列指令會從混亂的靜態中召喚幽靈,建立最終測試的老怪。
. ~/agentverse-dataengineer/set_env.sh
cd ~/agentverse-dungeon
./run_cloudbuild.sh
cd ~/agentverse-dataengineer
做得好,學者。基礎附魔已完成。我們的聖所安全無虞,資料元素力量的入口已開啟,我們的僕人也已獲得力量。我們現在可以開始實際工作了。
4. 知識煉金術:透過 BigQuery 和 Gemini 轉換資料
在與「靜態」的無休止戰爭中,每場「代理人宇宙」冠軍與「開發幽靈」的對決都會仔細記錄。戰場模擬系統是我們主要的訓練環境,會自動為每次遭遇戰生成乙太記錄項目。這些敘事記錄是我們最寶貴的原始情報來源,是我們學者必須從中鍛造出策略純鋼的未精煉礦石。學者的真正力量不在於僅擁有資料,而是將原始、混亂的資訊礦石轉化為閃耀、結構化的鋼鐵,成為可執行的智慧。我們將執行資料煉金術的基礎儀式。
我們將在 Google BigQuery 的聖所中,完成整個多階段程序。首先,我們將使用神奇的鏡頭,查看 GCS 封存內容,完全不用捲動畫面。接著,我們會召喚 Gemini 讀取並解讀戰鬥記錄中詩意且非結構化的傳奇故事。最後,我們會將原始預言精煉成一組相互連結的純淨資料表。我們的第一本魔法書。並提出深刻的問題,只有這個新結構才能回答。
資料工程師注意事項:我們即將執行的作業是強大的資料庫內建 AI 輔助 ELT (擷取、載入、轉換) 模式。這項尖端做法與傳統方法大相逕庭。
- 擷取和載入 (透過外部資料表):我們將使用 BigQuery 外部資料表,而非耗費成本的擷取程序 (傳統的「L」)。這會套用「讀取時的結構定義」,讓資料倉儲直接在 Cloud Storage 中查詢原始文字檔。這項功能非常有效率,可避免資料移動和重複儲存。
- 轉換 (透過 ML.GENERATE_TEXT):ELT 中的「T」是真正神奇之處。我們會使用 ML.GENERATE_TEXT 函式,直接從 SQL 查詢呼叫 Gemini 模型。這讓我們能夠執行複雜的轉換作業,並瞭解相關情境。以這個案例來說,就是將非結構化敘事文字轉換為結構化 JSON,不必以其他語言 (例如 Python 或 Java) 編寫或管理個別的處理管道。這項技術可取代規則運算式等容易出錯的硬式編碼解決方案,透過簡單的 SQL 介面提供彈性和強大功能,是典範轉移的代表。
審查鏡頭:透過 BigQuery 外部資料表深入瞭解 GCS
首先,我們要打造一個鏡頭,讓我們查看 GCS 封存內容,同時不干擾捲動。外部資料表就是這個鏡頭,可將原始文字檔對應至類似資料表的結構,供 BigQuery 直接查詢。
為此,我們必須先建立穩定的能量線 (即 CONNECTION 資源),將 BigQuery 聖所安全地連結至 GCS 封存檔。
👉💻 在 Cloud Shell 終端機中執行下列指令,設定儲存空間並建立管道:
. ~/agentverse-dataengineer/set_env.sh
. ~/agentverse-dataengineer/data_setup.sh
bq mk --connection \
--connection_type=CLOUD_RESOURCE \
--project_id=${PROJECT_ID} \
--location=${REGION} \
gcs-connection
💡 注意!稍後會顯示訊息!
步驟 2 中的設定指令碼已在背景啟動程序。幾分鐘後,終端機中會彈出類似以下的訊息:[1]+ Done gcloud sql instances create ...
這是正常現象。這表示您已成功建立 Cloud SQL 資料庫。您可以放心忽略這則訊息,然後繼續工作。
您必須先建立包含外部資料表的資料集,才能建立外部資料表。
👉💻 在 Cloud Shell 終端機中執行這個簡單的指令:
. ~/agentverse-dataengineer/set_env.sh
bq --location=${REGION} mk --dataset ${PROJECT_ID}:bestiary_data
👉💻 現在我們必須授予管道的魔法簽章必要權限,才能從 GCS 封存檔讀取資料,並諮詢 Gemini。
. ~/agentverse-dataengineer/set_env.sh
export CONNECTION_SA=$(bq show --connection --project_id=${PROJECT_ID} --location=${REGION} --format=json gcs-connection | jq -r '.cloudResource.serviceAccountId')
echo "The Conduit's Magical Signature is: $CONNECTION_SA"
echo "Granting key to the GCS Archive..."
gcloud storage buckets add-iam-policy-binding gs://${PROJECT_ID}-reports \
--member="serviceAccount:$CONNECTION_SA" \
--role="roles/storage.objectViewer"
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
--member="serviceAccount:$CONNECTION_SA" \
--role="roles/aiplatform.user"
👉💻 在 Cloud Shell 終端機中執行下列指令,顯示 bucket 名稱:
echo $BUCKET_NAME
終端機顯示的名稱類似於 your-project-id-gcs-bucket。後續步驟會用到這項資訊。
👉 您需要在 Google Cloud 控制台的 BigQuery 查詢編輯器中執行下一個指令。最簡單的方法是在新的瀏覽器分頁中開啟下方的連結。系統會直接將您帶往 Google Cloud 控制台的正確頁面。
https://console.cloud.google.com/bigquery
👉 頁面載入後,按一下藍色的「+」按鈕 (撰寫新查詢),開啟新的編輯器分頁。
現在,我們要編寫資料定義語言 (DDL) 咒語,建立魔法鏡頭。這會告知 BigQuery 要查看的位置和內容。
👉📜 在開啟的 BigQuery 查詢編輯器中,貼上下列 SQL。請記得取代 REPLACE-WITH-YOUR-BUCKET-NAME
替換成您剛才複製的值區名稱。接著點選「執行」:
CREATE OR REPLACE EXTERNAL TABLE bestiary_data.raw_intel_content_table (
raw_text STRING
)
OPTIONS (
format = 'CSV',
-- This is a trick to load each line of the text files as a single row.
field_delimiter = '§',
uris = ['gs://REPLACE-WITH-YOUR-BUCKET-NAME/raw_intel/*']
);
👉📜 執行查詢,透過「鏡頭」查看檔案內容。
SELECT * FROM bestiary_data.raw_intel_content_table;
鏡頭已就位。現在可以看到卷軸的原始文字。但閱讀不等於理解。
在「被遺忘的構想檔案」中,Agentverse 的學者 Elara (代號 adv_001) 遭遇了完美主義的天使 Spectre。這個實體編目為「p-01」,閃爍著 120 點生命力的光芒。艾拉以單一、專注的優雅充足咒語,打破了麻痺光環,這是一次精神攻擊,造成 150 點傷害。這段遭遇持續了 180 秒,需要高度專注。最終評估:獲勝。
這些卷軸並非以表格和列的形式撰寫,而是以傳奇故事的曲折散文形式呈現。這是我們第一次進行大規模測試。
學者的占卜:使用 SQL 將文字轉換為表格
但問題是,詳細描述暗影刀鋒快速雙重攻擊的報告,與記錄召喚師聚集強大力量發動單一毀滅性爆炸的報告,讀起來截然不同。我們無法直接匯入這項資料,必須解讀資料內容。這就是魔法生效的時刻。我們將使用單一 SQL 查詢做為強大的咒語,在 BigQuery 中讀取、瞭解及建構所有檔案中的所有記錄。
👉💻 返回 Cloud Shell 終端機,執行下列指令來顯示連線名稱:
echo "${PROJECT_ID}.${REGION}.gcs-connection"
終端機會顯示完整的連線字串,請選取並複製整個字串,下一個步驟會用到
我們會使用單一強大的咒語:ML.GENERATE_TEXT
。這個咒語會召喚 Gemini,向其顯示每則捲軸,並命令 Gemini 以結構化 JSON 物件的形式傳回核心事實。
👉📜 在 BigQuery Studio 中,建立 Gemini 模型參照。這會將 Gemini Flash 預言機繫結至 BigQuery 程式庫,以便在查詢中呼叫。請記得取代
REPLACE-WITH-YOUR-FULL-CONNECTION-STRING
,並貼上您剛從終端機複製的完整連線字串。
CREATE OR REPLACE MODEL bestiary_data.gemini_flash_model
REMOTE WITH CONNECTION `REPLACE-WITH-YOUR-FULL-CONNECTION-STRING`
OPTIONS (endpoint = 'gemini-2.5-flash');
👉📜 現在,請施展偉大的變換咒語。這項查詢會讀取原始文字、為每個捲動畫面建構詳細提示、傳送至 Gemini,並根據 AI 的結構化 JSON 回覆建立新的暫存資料表。
CREATE OR REPLACE TABLE bestiary_data.structured_bestiary AS
SELECT
-- THE CRITICAL CHANGE: We remove PARSE_JSON. The result is already a JSON object.
ml_generate_text_result AS structured_data
FROM
ML.GENERATE_TEXT(
-- Our bound Gemini Flash model.
MODEL bestiary_data.gemini_flash_model,
-- Our perfectly constructed input, with the prompt built for each row.
(
SELECT
CONCAT(
"""
From the following text, extract structured data into a single, valid JSON object.
Your output must strictly conform to the following JSON structure and data types. Do not add, remove, or change any keys.
{
"monster": {
"monster_id": "string",
"name": "string",
"type": "string",
"hit_points": "integer"
},
"battle": {
"battle_id": "string",
"monster_id": "string",
"adventurer_id": "string",
"outcome": "string",
"duration_seconds": "integer"
},
"adventurer": {
"adventurer_id": "string",
"name": "string",
"class": "string"
}
}
**CRUCIAL RULES:**
- Do not output any text, explanations, conversational filler, or markdown formatting like ` ```json` before or after the JSON object.
- Your entire response must be ONLY the raw JSON object itself.
Here is the text:
""",
raw_text -- We append the actual text of the report here.
) AS prompt -- The final column is still named 'prompt', as the oracle requires.
FROM
bestiary_data.raw_intel_content_table
),
-- The STRUCT now ONLY contains model parameters.
STRUCT(
0.2 AS temperature,
2048 AS max_output_tokens
)
);
轉變已完成,但結果尚未純化。Gemini 模型會以標準格式傳回答案,將所需的 JSON 包裝在較大的結構中,其中包含思考過程的中繼資料。讓我們在嘗試淨化之前,先看看這項未經處理的預言。
👉📜 執行查詢,檢查 Gemini 模型輸出的原始資料:
SELECT * FROM bestiary_data.structured_bestiary;
👀 畫面上會顯示名為「structured_data」的單一資料欄。每個資料列的內容看起來會類似於這個複雜的 JSON 物件:
{"candidates":[{"avg_logprobs":-0.5691758094475283,"content":{"parts":[{"text":"```json\n{\n \"monster\": {\n \"monster_id\": \"gw_02\",\n \"name\": \"Gravewight\",\n \"type\": \"Gravewight\",\n \"hit_points\": 120\n },\n \"battle\": {\n \"battle_id\": \"br_735\",\n \"monster_id\": \"gw_02\",\n \"adventurer_id\": \"adv_001\",\n \"outcome\": \"Defeat\",\n \"duration_seconds\": 45\n },\n \"adventurer\": {\n \"adventurer_id\": \"adv_001\",\n \"name\": \"Elara\",\n \"class\": null\n }\n}\n```"}],"role":"model"},"finish_reason":"STOP","score":-97.32906341552734}],"create_time":"2025-07-28T15:53:24.482775Z","model_version":"gemini-2.5-flash","response_id":"9JyHaNe7HZ2WhMIPxqbxEQ","usage_metadata":{"billable_prompt_usage":{"text_count":640},"candidates_token_count":171,"candidates_tokens_details":[{"modality":"TEXT","token_count":171}],"prompt_token_count":207,"prompt_tokens_details":[{"modality":"TEXT","token_count":207}],"thoughts_token_count":1014,"total_token_count":1392,"traffic_type":"ON_DEMAND"}}
如您所見,我們要求的獎品 (乾淨的 JSON 物件) 深深地巢狀內嵌在這個結構中。我們接下來的任務很明確,我們必須進行儀式,有系統地瀏覽這個結構,並從中提取純粹的智慧。
淨化儀式:使用 SQL 正規化生成式 AI 輸出內容
Gemini 說話了,但這些話是未經處理的,而且包覆在創作的虛無能量中 (候選項目、finish_reason 等)。真正的學者不會只是將原始預言擱置一旁,而是會仔細提取核心智慧,並將其抄寫到適當的書籍中,以供日後使用。
現在要施展最後一組咒語。這個單一指令碼會:
- 從暫存資料表讀取原始的巢狀 JSON。
- 清除及剖析資料,取得核心資料。
- 將相關內容記錄到三個最終的原始資料表:怪物、冒險者和戰鬥。
👉📜 在新的 BigQuery 查詢編輯器中,執行下列咒語來建立清除鏡頭:
CREATE OR REPLACE TABLE bestiary_data.monsters AS
WITH
CleanedDivinations AS (
SELECT
SAFE.PARSE_JSON(
REGEXP_EXTRACT(
JSON_VALUE(structured_data, '$.candidates[0].content.parts[0].text'),
r'\{[\s\S]*\}'
)
) AS report_data
FROM
bestiary_data.structured_bestiary
)
SELECT
JSON_VALUE(report_data, '$.monster.monster_id') AS monster_id,
JSON_VALUE(report_data, '$.monster.name') AS name,
JSON_VALUE(report_data, '$.monster.type') AS type,
SAFE_CAST(JSON_VALUE(report_data, '$.monster.hit_points') AS INT64) AS hit_points
FROM
CleanedDivinations
WHERE
report_data IS NOT NULL
QUALIFY ROW_NUMBER() OVER (PARTITION BY monster_id ORDER BY name) = 1;
👉📜 驗證 Bestiary:
SELECT * FROM bestiary_data.monsters;
接著,我們要建立「英雄榜」,列出與這些野獸對決的勇敢冒險家。
👉📜 在新的查詢編輯器中,執行下列咒語來建立冒險家資料表:
CREATE OR REPLACE TABLE bestiary_data.adventurers AS
WITH
CleanedDivinations AS (
SELECT
SAFE.PARSE_JSON(
REGEXP_EXTRACT(
JSON_VALUE(structured_data, '$.candidates[0].content.parts[0].text'),
r'\{[\s\S]*\}'
)
) AS report_data
FROM
bestiary_data.structured_bestiary
)
SELECT
JSON_VALUE(report_data, '$.adventurer.adventurer_id') AS adventurer_id,
JSON_VALUE(report_data, '$.adventurer.name') AS name,
JSON_VALUE(report_data, '$.adventurer.class') AS class
FROM
CleanedDivinations
QUALIFY ROW_NUMBER() OVER (PARTITION BY adventurer_id ORDER BY name) = 1;
👉📜 驗證冠軍名單:
SELECT * FROM bestiary_data.adventurers;
最後,我們要建立事實資料表:戰役紀事。這本巨著連結了另外兩本,記錄每次獨特遭遇的詳細資料。由於每場戰鬥都是獨一無二的事件,因此不需要重複資料刪除。
👉📜 在新的查詢編輯器中,執行下列咒語來建立 battles 資料表:
CREATE OR REPLACE TABLE bestiary_data.battles AS
WITH
CleanedDivinations AS (
SELECT
SAFE.PARSE_JSON(
REGEXP_EXTRACT(
JSON_VALUE(structured_data, '$.candidates[0].content.parts[0].text'),
r'\{[\s\S]*\}'
)
) AS report_data
FROM
bestiary_data.structured_bestiary
)
-- Extract the raw essence for all battle fields and cast where necessary.
SELECT
JSON_VALUE(report_data, '$.battle.battle_id') AS battle_id,
JSON_VALUE(report_data, '$.battle.monster_id') AS monster_id,
JSON_VALUE(report_data, '$.battle.adventurer_id') AS adventurer_id,
JSON_VALUE(report_data, '$.battle.outcome') AS outcome,
SAFE_CAST(JSON_VALUE(report_data, '$.battle.duration_seconds') AS INT64) AS duration_seconds
FROM
CleanedDivinations;
👉📜 驗證 Chronicle:
SELECT * FROM bestiary_data.battles;
發掘策略洞察
卷軸已讀完,精髓已提煉,巨著已刻成。我們的魔法書不再只是事實的集合,而是蘊含深奧策略智慧的關聯式資料庫。現在,我們可以詢問過去無法回答的問題,因為當時的知識都以原始的非結構化文字形式呈現。
現在,讓我們進行最後一次盛大的占卜。我們會施展魔法,同時參考三本魔法書 (怪物圖鑑、英雄名單和戰役史),找出可供採取的深入洞察。
我們的策略問題: 「每位冒險家成功擊敗的血量最高怪物名稱為何?擊敗該怪物所花的時間又是多少?」
這是一個複雜的問題,需要將英雄連結至他們贏得的戰鬥,並將這些戰鬥連結至所涉怪物的統計資料。這就是結構化資料模型的真正力量。
👉📜 在新的 BigQuery 查詢編輯器中,施展下列最終咒語:
-- This is our final spell, joining all three tomes to reveal a deep insight.
WITH
-- First, we consult the Chronicle of Battles to find only the victories.
VictoriousBattles AS (
SELECT
adventurer_id,
monster_id,
duration_seconds
FROM
bestiary_data.battles
WHERE
outcome = 'Victory'
),
-- Next, we create a temporary record for each victory, ranking the monsters
-- each adventurer defeated by their power (hit points).
RankedVictories AS (
SELECT
v.adventurer_id,
m.name AS monster_name,
m.hit_points,
v.duration_seconds,
-- This spell ranks each adventurer's victories from most to least powerful monster.
ROW_NUMBER() OVER (PARTITION BY v.adventurer_id ORDER BY m.hit_points DESC) as victory_rank
FROM
VictoriousBattles v
JOIN
bestiary_data.monsters m ON v.monster_id = m.monster_id
)
-- Finally, we consult the Roll of Champions and join it with our ranked victories
-- to find the name of each champion and the details of their greatest triumph.
SELECT
a.name AS adventurer_name,
a.class AS adventurer_class,
r.monster_name AS most_powerful_foe_defeated,
r.hit_points AS foe_hit_points,
r.duration_seconds AS duration_of_greatest_victory
FROM
bestiary_data.adventurers a
JOIN
RankedVictories r ON a.adventurer_id = r.adventurer_id
WHERE
-- We only want to see their number one, top-ranked victory.
r.victory_rank = 1
ORDER BY
foe_hit_points DESC;
這項查詢的輸出內容會是整齊美觀的資料表,其中列出資料集中每位冒險家的「冠軍壯舉」。如下所示:
關閉 BigQuery 分頁。
這項單一且優異的結果證明瞭整個管道的價值。您已成功將混亂的戰場原始報告,轉化為傳奇故事的來源,以及以資料為依據的策略洞察。
5. 抄書士的魔法書:資料倉儲內分塊、嵌入和搜尋
我們在煉金術士實驗室的工作很順利,我們已將原始的敘事捲軸轉換為結構化關聯資料表,這是一項強大的資料魔法。不過,原始卷軸本身仍蘊含更深層的語意真相,這是結構化表格無法完全擷取的。如要建構真正明智的代理程式,我們必須解鎖這個意義。
冗長且未經處理的捲軸是鈍器,如果我們的服務專員詢問「麻痺光環」相關問題,簡單的搜尋可能會傳回整份戰鬥報告,但該詞彙只出現一次,答案埋沒在無關的細節中。學術大師深知真正的智慧不在於數量,而是精確度。
我們將在 BigQuery 聖所中,完全在資料庫內執行三項強大的儀式。
- 分割儀式 (分塊):我們會將原始智慧記錄仔細分解成較小的獨立段落。
- 蒸餾儀式 (嵌入):我們會使用 BQML 諮詢 Gemini 模型,將每個文字塊轉換為「語意指紋」 (向量嵌入)。
- 占卜儀式 (搜尋):我們會使用 BQML 的向量搜尋功能,以簡單的英文提問,並從魔法書中找出最相關的精華智慧。
整個過程會建立強大的可搜尋知識庫,資料完全不會離開 BigQuery 的安全和規模。
資料工程師注意事項:這項作業示範完整的端對端 RAG 資料準備管道,完全在 BigQuery 中執行。這個模式可大幅簡化傳統 AI 管道的作業負擔。使用 BQML 進行分塊、嵌入和搜尋,可省去資料移動、處理叢集 (例如 Spark) 或外部 API 呼叫等作業,讓工作流程更快速、安全且易於管理。
分割儀式:使用 SQL 解構捲軸
我們的智慧來源仍是 GCS 封存中的原始文字檔,可透過外部資料表 bestiary_data.raw_intel_content_table
存取。我們的首要任務是編寫咒語,讀取每份長卷軸,並將其分割成一系列較小、更容易理解的詩句。在本儀式中,我們會將「區塊」定義為單一句子。
雖然以句子為單位分割是記錄對話的明確有效起點,但資深 Scribe 有許多分塊策略可供運用,而選擇合適的策略對最終搜尋結果的品質至關重要。較簡單的方法可能會使用
- 固定長度(大小) 的分塊,但這可能會粗略地將重要概念切成兩半。
更精細的儀式,例如:
- 實務上通常偏好使用遞迴分塊,這類方法會先嘗試沿著段落等自然界線分割文字,然後再回溯至句子,盡可能保留語意脈絡。適用於真正複雜的手稿。
- 內容感知分塊 (文件):Scribe 會根據文件的固有結構 (例如技術手冊中的標題或程式碼捲軸中的函式) 建立最合乎邏輯且有力的智慧分塊。
就戰鬥記錄而言,這句話能完美兼顧精細程度和語境。
👉📜 在新的 BigQuery 查詢編輯器中,執行下列咒語。這項咒語會使用 SPLIT 函式,依據每個句號 (.) 將每份卷軸的文字切開,然後將產生的句子陣列取消巢狀結構,放入不同的資料列。
CREATE OR REPLACE TABLE bestiary_data.chunked_intel AS
WITH
-- First, add a unique row number to each scroll to act as a document ID.
NumberedScrolls AS (
SELECT
ROW_NUMBER() OVER () AS scroll_id,
raw_text
FROM
bestiary_data.raw_intel_content_table
)
-- Now, process each numbered scroll.
SELECT
scroll_id,
-- Assign a unique ID to each chunk within a scroll for precise reference.
CONCAT(CAST(scroll_id AS STRING), '-', CAST(ROW_NUMBER() OVER (PARTITION BY scroll_id) AS STRING)) as chunk_id,
-- Trim whitespace from the chunk for cleanliness.
TRIM(chunk) AS chunk_text
FROM
NumberedScrolls,
-- This is the core of the spell: UNNEST splits the array of sentences into rows.
UNNEST(SPLIT(raw_text, '.')) AS chunk
-- A final refinement: we only keep chunks that have meaningful content.
WHERE
-- This ensures we don't have empty rows from double periods, etc.
LENGTH(TRIM(chunk)) > 15;
👉 現在請執行查詢,檢查新撰寫的知識塊,並查看差異。
SELECT * FROM bestiary_data.chunked_intel ORDER BY scroll_id, chunk_id;
查看結果。原本是密密麻麻的一大段文字,現在則變成多個資料列,每個資料列都與原始捲動 (scroll_id) 相關聯,但只包含一個重點句子。現在每一列都是向量化的絕佳候選項目。
蒸餾儀式:使用 BQML 將文字轉換為向量
👉💻 首先,請返回終端機,執行下列指令來顯示連線名稱:
. ~/agentverse-dataengineer/set_env.sh
echo "${PROJECT_ID}.${REGION}.gcs-connection"
👉📜 我們必須建立新的 BigQuery 模型,指向 Gemini 的文字嵌入。在 BigQuery Studio 中執行下列咒語。請注意,您需要將 REPLACE-WITH-YOUR-FULL-CONNECTION-STRING
替換為剛才從終端機複製的完整連線字串。
CREATE OR REPLACE MODEL bestiary_data.text_embedding_model
REMOTE WITH CONNECTION `REPLACE-WITH-YOUR-FULL-CONNECTION-STRING`
OPTIONS (endpoint = 'text-embedding-005');
👉📜 現在,請施展蒸餾魔法。這項查詢會呼叫 ML.GENERATE_EMBEDDING 函式,從 chunked_intel 資料表讀取每一列、將文字傳送至 Gemini 嵌入模型,並將產生的向量指紋儲存在新資料表中。
CREATE OR REPLACE TABLE bestiary_data.embedded_intel AS
SELECT
*
FROM
ML.GENERATE_EMBEDDING(
-- The embedding model we just created.
MODEL bestiary_data.text_embedding_model,
-- A subquery that selects our data and renames the text column to 'content'.
(
SELECT
scroll_id,
chunk_id,
chunk_text AS content -- Renaming our text column is the key correction.
FROM
bestiary_data.chunked_intel
),
-- The configuration struct is now simpler and correct.
STRUCT(
-- This task_type is crucial. It optimizes the vectors for retrieval.
'RETRIEVAL_DOCUMENT' AS task_type
)
);
BigQuery 處理所有文字區塊時,可能需要一到兩分鐘。
👉📜 完成後,請檢查新資料表,查看語意指紋。
SELECT
chunk_id,
content,
ml_generate_embedding_result
FROM
bestiary_data.embedded_intel
LIMIT 20;
現在您會看到新的資料欄 ml_generate_embedding_result
,其中包含文字的密集向量表示法。我們的魔法書現在已完成語意編碼。
The Ritual of Divination:使用 BQML 進行語意搜尋
👉📜 測試 Grimoire 的最終方式就是向它提問。現在我們要執行最後的儀式:向量搜尋。這不是關鍵字搜尋,而是搜尋意義。我們會以自然語言提出問題,BQML 會即時將問題轉換為嵌入,然後搜尋整個資料表 embedded_intel
,找出意義上「最接近」的文字區塊指紋。
SELECT
-- The content column contains our original, relevant text chunk.
base.content,
-- The distance metric shows how close the match is (lower is better).
distance
FROM
VECTOR_SEARCH(
-- The table containing the knowledge base with its embeddings.
TABLE bestiary_data.embedded_intel,
-- The column that contains the vector embeddings.
'ml_generate_embedding_result',
(
-- This subquery generates an embedding for our question in real-time.
SELECT ml_generate_embedding_result
FROM ML.GENERATE_EMBEDDING(
MODEL bestiary_data.text_embedding_model,
(SELECT 'What are the tactics against a foe that causes paralysis?' AS content),
STRUCT('RETRIEVAL_QUERY' AS task_type)
)
),
-- Specify how many of the closest results we want to see.
top_k => 3,
-- The distance metric used to find the "closest" vectors.
distance_type => 'COSINE'
);
分析咒語:
VECTOR_SEARCH
:負責協調搜尋作業的核心函式。ML.GENERATE_EMBEDDING
(內部查詢):這就是魔法。我們使用相同模型,但採用專為查詢內容最佳化的工作類型'RETRIEVAL_QUERY'
,將查詢內容 ('What are the tactics...'
) 嵌入。top_k => 3
:我們要求提供前 3 個最相關的結果。distance_type => 'COSINE'
:這會測量向量之間的「角度」。角度越小,代表意義越相近。
請仔細查看結果。查詢內容並未包含「shattered」或「incantation」一詞,但搜尋結果第一項卻是:「With a single, focused incantation of Elegant Sufficiency, Elara shattered its paralyzing aura, a mental assault dealing 150 points of damage」(艾拉專注地念出優雅充足咒語,震碎了麻痺光環,造成 150 點精神傷害)。這就是語意搜尋的強大之處。模型瞭解「對抗癱瘓的策略」概念,並找出描述具體成功策略的句子。
您現在已成功建構完整的資料倉儲基礎 RAG 管道。您已準備好原始資料、將其轉換為語意向量,並依據意義查詢資料。雖然 BigQuery 是進行這類大規模分析工作的強大工具,但對於需要低延遲回覆的即時服務專員來說,我們通常會將準備好的智慧轉移至專門的作業資料庫。這是我們下一個訓練課程的主題。
6. 向量腳本:使用 Cloud SQL 打造向量儲存空間,以進行推論
我們的魔法書目前以結構化表格的形式存在,是強大的事實目錄,但知識是字面上的。這項技術瞭解 monster_id = ‘MN-001',但不瞭解「混淆」背後更深層的語意。如要讓我們的代理程式真正智慧化,能夠提供細緻且有遠見的建議,我們必須將知識的本質提煉成能擷取意義的形式:向量。
我們對知識的追求,引領我們來到早已被遺忘的先驅文明遺跡。我們在密封的保險庫深處,發現一箱奇蹟般保存完好的古老卷軸。這不只是戰鬥報告,還蘊含深刻的哲學智慧,教導我們如何擊敗困擾所有偉大事業的野獸。卷軸中將其描述為「悄然蔓延的停滯」,以及「創造的織物逐漸磨損」。靜態似乎連古代人都知道,這是一種週期性威脅,但歷史已不可考。
這項被遺忘的知識是我們最大的資產。這項能力不僅是擊敗個別怪物的關鍵,還能為整個隊伍提供策略洞察,為發揮這項強大力量,我們現在要打造 Scholar 的真正魔法書 (具備向量功能的 PostgreSQL 資料庫),並建構自動化向量抄寫室 (Dataflow 管道),讀取、理解及抄寫這些卷軸的永恆本質。這會將我們的魔法書從事實書轉變為智慧引擎。
資料工程師注意事項:我們為 Spellbook 選擇了 PostgreSQL 適用的 Cloud SQL,並搭配 pgvector 擴充功能。這種做法可建立「一站式商店」,將結構化中繼資料 (例如 scroll_id 和內容) 和語意向量嵌入內容儲存在同一個資料庫中。這項功能可讓您透過單一 SQL 查詢,向一個系統查詢關聯式資料及執行向量相似度搜尋,大幅簡化許多應用程式的架構。雖然 Vertex AI Vector Search 等專用資料庫透過近似近鄰 (ANN) 搜尋,可大規模 (數十億個向量) 提供卓越效能,但 pgvector 透過精確近鄰 (ENN) 搜尋,為許多企業 RAG 應用程式提供簡便、經濟實惠且強大的絕佳平衡。
打造學者的咒語書 (Cloud SQL)
在刻錄這些古老卷軸的精髓之前,我們必須先確認知識的容器 (也就是受管理的 PostgreSQL 咒語書) 已成功打造。初始設定儀式應該已為您建立這個檔案。
👉💻 在終端機中執行下列指令,確認 Cloud SQL 執行個體存在且已準備就緒。這個指令碼也會授予執行個體專屬服務帳戶使用 Vertex AI 的權限,這是直接在資料庫中生成嵌入內容的必要條件。
. ~/agentverse-dataengineer/set_env.sh
echo "Verifying the existence of the Spellbook (Cloud SQL instance): $INSTANCE_NAME..."
gcloud sql instances describe $INSTANCE_NAME
SERVICE_ACCOUNT_EMAIL=$(gcloud sql instances describe $INSTANCE_NAME --format="value(serviceAccountEmailAddress)")
gcloud projects add-iam-policy-binding $PROJECT_ID --member="serviceAccount:$SERVICE_ACCOUNT_EMAIL" \
--role="roles/aiplatform.user"
如果指令成功執行並傳回 grimoire-spellbook
執行個體的詳細資料,表示 Forge 運作正常。現在可以繼續下一個咒語。如果指令傳回 NOT_FOUND
錯誤,請確認您已成功完成初始環境設定步驟,再繼續操作。(data_setup.py
)
👉💻 偽造書籍後,我們建立名為 arcane_wisdom
的新資料庫,開啟第一章。
. ~/agentverse-dataengineer/set_env.sh
gcloud sql databases create $DB_NAME --instance=$INSTANCE_NAME
刻寫語意符文:透過 pgvector 啟用向量功能
Cloud SQL 執行個體已建立完成,現在讓我們使用內建的 Cloud SQL Studio 連線至執行個體。這個工具提供網頁介面,可直接在資料庫中執行 SQL 查詢。
👉💻 首先,請前往 Cloud SQL Studio。最簡單快速的方法是在新的瀏覽器分頁中開啟下列連結。系統會直接將您帶往 grimoire-spellbook 執行個體的 Cloud SQL Studio。
https://console.cloud.google.com/sql/instances/grimoire-spellbook/studio
👉 選取 arcane_wisdom
做為資料庫,輸入 postgres
做為使用者,並輸入 1234qwer
做為密碼,然後按一下「驗證」。
👉📜 在 SQL Studio 查詢編輯器中,前往「編輯器 1」分頁,貼上下列 SQL 程式碼來啟用向量資料型別:
CREATE EXTENSION IF NOT EXISTS vector;
CREATE EXTENSION IF NOT EXISTS google_ml_integration CASCADE;
👉📜 建立資料表,存放卷軸的本質,準備好魔法書的頁面。
CREATE TABLE ancient_scrolls (
id SERIAL PRIMARY KEY,
scroll_content TEXT,
embedding VECTOR(768)
);
請注意,VECTOR(768) 這個拼字是重要細節。我們將使用的 Vertex AI 嵌入模型 (textembedding-gecko@003
或類似模型) 會將文字提煉成 768 維度的向量。我們的魔法書頁面必須準備好容納該大小的本質。尺寸必須一律相符。
第一次音譯:手動轉寫儀式
在指揮自動抄寫員大軍 (Dataflow) 之前,我們必須先手動執行一次中央儀式。這讓我們深深體會到這兩步驟的魔法:
- 占卜:擷取一段文字,並諮詢 Gemini 預言,將其語意本質提煉成向量。
- 銘文:將原始文字及其新的向量本質寫入我們的魔法書。
資料工程師注意事項:手動建立管道核心邏輯的原型是很有價值的做法。有助於您在將個別元件整合至複雜的分散式系統 (例如 Dataflow) 之前,先對這些元件 (例如 API 呼叫或資料庫寫入) 進行獨立偵錯。
現在,我們來執行手動儀式。
👉📜 在 Cloud SQL Studio 中。現在我們要使用 embedding()
函式,這是 google_ml_integration
擴充功能提供的強大功能。這樣一來,我們就能直接從 SQL 查詢呼叫 Vertex AI 嵌入模型,大幅簡化程序。
SET session.my_search_var='The Spectre of Analysis Paralysis is a phantom of the crossroads. It does not bind with chains but with the infinite threads of what if. It conjures a fog of options, a maze within the mind where every path seems equally fraught with peril and promise. It whispers of a single, flawless route that can only be found through exhaustive study, paralyzing its victim in a state of perpetual contemplation. This spectres power is broken by the Path of First Viability. This is not the search for the *best* path, but the commitment to the *first good* path. It is the wisdom to know that a decision made, even if imperfect, creates movement and reveals more of the map than standing still ever could. Choose a viable course, take the first step, and trust in your ability to navigate the road as it unfolds. Motion is the light that burns away the fog.';
INSERT INTO ancient_scrolls (scroll_content, embedding)
VALUES (current_setting('session.my_search_var'), (embedding('text-embedding-005',current_setting('session.my_search_var')))::vector);
👉📜 執行查詢來讀取新刻寫的網頁,驗證您的工作:
SELECT id, scroll_content, LEFT(embedding::TEXT, 100) AS embedding_preview FROM ancient_scrolls;
您已成功手動執行核心 RAG 資料載入工作!
打造語意羅盤:使用 HNSW 索引為咒語書施展魔法
我們的咒語書現在可以儲存智慧,但要找到正確的卷軸,必須閱讀每一頁。這是循序掃描。這種做法既緩慢又缺乏效率。如要讓查詢立即導向最相關的知識,我們必須使用語意羅盤 (即向量索引) 強化 Spellbook。
資料工程師注意事項:這是正式版向量資料庫最重要的概念之一。索引會預先整理資料,大幅加快查詢速度。我們使用的是 hnsw
(階層式可導覽小世界) 索引類型。HNSW 不會像其他方法一樣將向量叢集到清單中,而是建構複雜的多層向量圖。搜尋作業會從最上層的「高速公路」開始,快速找出查詢的大致鄰近區域,然後逐步向下瀏覽更詳細的「當地街道」層,以驚人的速度和準確度找出確切的鄰點。這項功能可大幅提升讀取查詢的效能,因此對於查詢延遲時間至關重要的高效能 RAG 代理程式而言,是頂尖的選擇。
讓我們證明這項魔法的價值。
👉📜 在 Cloud SQL Studio 中,執行下列咒語。這會模擬搜尋我們新插入的捲軸,並要求資料庫 EXPLAIN
其計畫。
EXPLAIN ANALYZE
WITH ReferenceVector AS (
-- First, get the vector we want to compare against.
SELECT embedding AS vector
FROM ancient_scrolls
LIMIT 1
)
-- This is the main query we want to analyze.
SELECT
ancient_scrolls.id,
ancient_scrolls.scroll_content,
-- We can also select the distance itself.
ancient_scrolls.embedding <=> ReferenceVector.vector AS distance
FROM
ancient_scrolls,
ReferenceVector
ORDER BY
-- Order by the distance operator's result.
ancient_scrolls.embedding <=> ReferenceVector.vector
LIMIT 5;
查看輸出內容。畫面上會顯示 -> Seq Scan on ancient_scrolls
。這表示資料庫正在讀取每一列。請注意 execution time
。
👉📜 現在,讓我們施展索引魔法。lists
參數會告知索引要建立的叢集數量。建議從預期列數的平方根開始。
CREATE INDEX ON ancient_scrolls USING hnsw (embedding vector_cosine_ops);
等待索引建構完成 (一行資料很快就能完成,但數百萬筆資料可能需要一段時間)。
👉📜 現在,請再次執行完全相同 的 EXPLAIN ANALYZE
指令:
EXPLAIN ANALYZE
WITH ReferenceVector AS (
-- First, get the vector we want to compare against.
SELECT embedding AS vector
FROM ancient_scrolls
LIMIT 1
)
-- This is the main query we want to analyze.
SELECT
ancient_scrolls.id,
ancient_scrolls.scroll_content,
-- We can also select the distance itself.
ancient_scrolls.embedding <=> ReferenceVector.vector AS distance
FROM
ancient_scrolls,
ReferenceVector
ORDER BY
-- Order by the distance operator's result.
ancient_scrolls.embedding <=> ReferenceVector.vector
LIMIT 5;
查看新的查詢計畫。現在會看到 -> Index Scan using...
。更重要的是,請查看 execution time
。即使只有一個項目,速度也會大幅提升。您剛才示範了向量世界中資料庫效能調整的核心原則。
檢查完來源資料、瞭解手動程序,並針對速度最佳化 Spellbook 後,您現在確實可以開始建構自動化 Scriptorium。
7. 意義的管道:建構 Dataflow 向量化管道
現在,我們要建立魔法抄寫員組裝線,讀取卷軸、提煉本質,並將內容抄寫到新的魔法書中。這是我們將手動觸發的 Dataflow pipeline。不過,在為管道本身編寫主咒語之前,我們必須先準備好基礎和召喚管道的圓圈。
資料工程師注意事項:雖然我們可以編寫簡單的 Python 指令碼,逐一處理檔案、呼叫嵌入 API,然後寫入資料庫,但這種做法無法擴充。如果我們有數百萬次捲動,單一指令碼速度緩慢,且容易失敗。Dataflow 提供代管的無伺服器平台,可大規模平行執行 Apache Beam 模型定義的資料處理管道。Beam 可讓我們定義邏輯步驟 (讀取、嵌入、寫入),而 Dataflow 則會處理啟動工作者、分配工作及重試失敗項目等困難工作,確保 Scriptorium 穩定有效率。
準備 Scriptorium 的基礎 (工作站映像檔)
我們的 Dataflow 管道將由雲端中的自動工作站團隊執行。每次呼叫時,這些函式都需要一組特定的程式庫才能執行工作。我們可以提供清單,讓他們每次都擷取這些程式庫,但這樣很慢且效率不彰。明智的學者會預先準備好主程式庫。
在這裡,我們會命令 Google Cloud Build 打造自訂容器映像檔。這張圖片是「完美魔像」,預先載入抄寫員所需的所有程式庫和依附元件。Dataflow 工作啟動時會使用這個自訂映像檔,讓工作站幾乎可以立即開始工作。
👉💻 執行下列指令,在 Artifact Registry 中建構及儲存管道的基礎映像檔。
. ~/agentverse-dataengineer/set_env.sh
cd ~/agentverse-dataengineer/pipeline
gcloud builds submit --config cloudbuild.yaml \
--substitutions=_REGION=${REGION},_REPO_NAME=${REPO_NAME} \
.
👉💻 執行下列指令,建立及啟動獨立的 Python 環境,並在其中安裝必要的召喚程式庫。
cd ~/agentverse-dataengineer
. ~/agentverse-dataengineer/set_env.sh
python -m venv env
source ~/agentverse-dataengineer/env/bin/activate
cd ~/agentverse-dataengineer/pipeline
pip install -r requirements.txt
咒語
現在要編寫主咒語,為 Vector Scriptorium 供電。我們不會從頭開始編寫個別的魔法元件,我們的任務是使用 Apache Beam 語言,將元件組裝成強大的邏輯管道。
- EmbedTextBatch (Gemini 諮詢):您將建構這個專門的抄寫員,瞭解如何執行「群組占卜」。這項服務會接收一批原始文字檔案,將這些檔案提供給 Gemini 文字嵌入模型,並接收其精簡的本質 (向量嵌入)。
- WriteEssenceToSpellbook (最終銘文):這是我們的檔案管理員。它知道開啟與 Cloud SQL Spellbook 安全連線的咒語。這項工作會擷取捲軸的內容和向量化本質,並永久刻印到新頁面。
我們的目標是將這些動作串連起來,建立流暢的知識流程。
👉✏️ 在 Cloud Shell 編輯器中前往 ~/agentverse-dataengineer/pipeline/inscribe_essence_pipeline.py
,您會在其中找到名為 EmbedTextBatch
的 DoFn 類別。找出註解 #REPLACE-EMBEDDING-LOGIC
。將其替換為下列咒語。
# 1. Generate the embedding for the monster's name
result = self.client.models.embed_content(
model="text-embedding-005",
contents=contents,
config=EmbedContentConfig(
task_type="RETRIEVAL_DOCUMENT",
output_dimensionality=768,
)
)
這個咒語十分精確,包含幾個重要參數:
- 模型:我們指定
text-embedding-005
,使用功能強大且最新的嵌入模型。 - 內容:這是 DoFn 接收的一批檔案中所有文字內容的清單。
- task_type:我們將此值設為「RETRIEVAL_DOCUMENT」。這項重要指令會告知 Gemini 生成的嵌入內容,必須經過最佳化處理,以便日後在搜尋時找到。
- output_dimensionality:必須設為 768,與我們在 Cloud SQL 中建立 ancient_scrolls 資料表時定義的 VECTOR(768) 維度完全相符。維度不符是向量魔術中常見的錯誤來源。
我們的管道必須先從 GCS 封存中的所有古代卷軸讀取原始的非結構化文字。
👉✏️ 在 ~/agentverse-dataengineer/pipeline/inscribe_essence_pipeline.py
中,找到 #REPLACE ME-READFILE
註解,並替換為下列三部分咒語:
files = (
pipeline
| "MatchFiles" >> fileio.MatchFiles(known_args.input_pattern)
| "ReadMatches" >> fileio.ReadMatches()
| "ExtractContent" >> beam.Map(lambda f: (f.metadata.path, f.read_utf8()))
)
收集完卷軸的原始文字後,我們現在必須將其傳送至 Gemini 進行占卜。為有效完成這項工作,我們會先將個別捲軸分批處理,然後交給 EmbedTextBatch
抄寫員。Gemini 無法理解的捲軸也會歸入「失敗」類別,供日後查看。
👉✏️ 找出註解 #REPLACE ME-EMBEDDING
,並替換為以下內容:
embeddings = (
files
| "BatchScrolls" >> beam.BatchElements(min_batch_size=1, max_batch_size=2)
| "DistillBatch" >> beam.ParDo(
EmbedTextBatch(project_id=project, region=region)
).with_outputs('failed', main='processed')
)
我們已成功提煉出卷軸的精髓。最後一個步驟是將這些知識記錄在咒語書中,永久保存。我們會從「已處理」的卷軸堆中取出卷軸,交給 WriteEssenceToSpellbook 檔案管理員。
👉✏️ 找出註解 #REPLACE ME-WRITE TO DB
,並替換為以下內容:
_ = (
embeddings.processed
| "WriteToSpellbook" >> beam.ParDo(
WriteEssenceToSpellbook(
project_id=project,
region = "us-central1",
instance_name=known_args.instance_name,
db_name=known_args.db_name,
db_password=known_args.db_password
)
)
)
明智的學者絕不會捨棄知識,即使是失敗的嘗試。最後,我們必須指示抄寫員從占卜步驟中取出「失敗」的牌堆,並記錄失敗原因。這有助於我們日後改善儀式。
👉✏️ 找出註解 #REPLACE ME-LOG FAILURES
,並替換為以下內容:
_ = (
embeddings.failed
| "LogFailures" >> beam.Map(lambda e: logging.error(f"Embedding failed for file {e[0]}: {e[1]}"))
)
現在已完成 Master Incantation!您已成功將個別的魔法元件串連在一起,組裝出功能強大的多階段資料管道。儲存 inscribe_essence_pipeline.py 檔案。現在可以召喚 Scriptorium 了。
現在我們施展召喚魔法,命令 Dataflow 服務喚醒 Golem,並開始抄寫儀式。
👉💻 在終端機中執行下列指令列
. ~/agentverse-dataengineer/set_env.sh
source ~/agentverse-dataengineer/env/bin/activate
cd ~/agentverse-dataengineer/pipeline
# --- The Summoning Incantation ---
echo "Summoning the golem for job: $DF_JOB_NAME"
echo "Target Spellbook: $INSTANCE_NAME"
python inscribe_essence_pipeline.py \
--runner=DataflowRunner \
--project=$PROJECT_ID \
--job_name=$DF_JOB_NAME \
--temp_location="gs://${BUCKET_NAME}/dataflow/temp" \
--staging_location="gs://${BUCKET_NAME}/dataflow/staging" \
--sdk_container_image="${REGION}-docker.pkg.dev/${PROJECT_ID}/${REPO_NAME}/grimoire-inscriber:latest" \
--sdk_location=container \
--experiments=use_runner_v2 \
--input_pattern="gs://${BUCKET_NAME}/ancient_scrolls/*.md" \
--instance_name=$INSTANCE_NAME \
--region=$REGION
echo "The golem has been dispatched. Monitor its progress in the Dataflow console."
💡 注意!如果工作因資源錯誤 ZONE_RESOURCE_POOL_EXHAUSTED
而失敗,可能是因為所選區域中,這個低信譽帳戶的資源暫時受到限制。Google Cloud 的強大之處在於其全球觸及範圍!只要在其他區域召喚魔像即可。如要這麼做,請將上述指令中的 --region=$REGION
替換為其他區域,例如
--region=southamerica-west1
--region=asia-northeast3
--region=asia-southeast2
--region=me-west1
--region=southamerica-east1
--region=europe-central2
--region=asia-east2
--region=europe-southwest1
,然後再次執行。🎰
啟動及完成程序約需 3 到 5 分鐘。您可以在 Dataflow 控制台中觀看直播。
👉前往 Dataflow 控制台:最簡單的方法是在新的瀏覽器分頁中開啟這個直接連結:
https://console.cloud.google.com/dataflow
👉 找出並點選您的工作:您會看到列出的工作,名稱為您提供的名稱 (inscribe-essence-job 或類似名稱)。按一下工作名稱,開啟詳細資料頁面。觀察管道:
- 啟動:前 3 分鐘,Dataflow 會佈建必要資源,因此工作狀態會顯示為「Running」。圖表會顯示,但您可能還看不到資料流動。
- 已完成:完成後,工作狀態會變更為「成功」,圖表會提供處理的最終記錄數。
驗證銘文
👉📜 返回 SQL 工作室,執行下列查詢,確認捲軸及其語意本質已成功刻寫。
SELECT COUNT(*) FROM ancient_scrolls;
SELECT id, scroll_content, LEFT(embedding::TEXT, 50) AS embedding_preview FROM ancient_scrolls;
畫面上會顯示卷軸 ID、原始文字,以及現在永久刻在魔法書中的魔法向量本質預覽畫面。
現在,你的 Scholar's Grimoire 已經成為真正的知識引擎,準備在下一章中依據意義進行查詢。
8. 封印最後的符文:透過 RAG 代理程式啟動智慧
現在 Grimoire 不再只是資料庫,這是向量化知識的泉源,是等待提問的無聲預言家。
現在,我們要進行真正的學者測試:製作解鎖這項智慧的鑰匙。我們將建構檢索增強生成 (RAG) 代理程式。這項神奇的建構體可理解以簡單語言提出的問題,從 Grimoire 尋找最深入且相關的真相,然後運用這些智慧打造強大且符合情境的答案。
資料工程師注意事項:RAG 是一項強大的技術,可讓大型語言模型 (LLM) 以事實、私人或最新資訊為依據,大幅降低模型「幻覺」或編造內容的機率。這個程序有三個核心步驟:
- 擷取:系統會先將使用者的查詢轉換為向量嵌入,然後使用這個查詢向量搜尋知識庫,透過餘弦相似度找出語意最相似的文字片段。
- 擴增:從資料庫擷取相關文字片段,然後直接插入 LLM 的新提示,為 LLM 提供重要背景資訊。
- 生成:LLM 會收到增強型提示詞 (例如 「根據『拖延症』的脈絡資訊,回答使用者的問題...」,然後生成最終的實證答案。
第一符文:查詢蒸餾咒語
服務專員必須先瞭解問題的本質,才能搜尋魔法書。對我們以向量為基礎的 Spellbook 來說,簡單的文字字串毫無意義。代理程式必須先取得查詢,然後使用相同的 Gemini 模型,將查詢提煉成查詢向量。
👉✏️ 在 Cloud Shell 編輯器中,前往 ~~/agentverse-dataengineer/scholar/agent.py
檔案,找到註解 #REPLACE RAG-CONVERT EMBEDDING
並替換為以下咒語。這會教導代理程式如何將使用者的問題轉化為神奇的本質。
result = client.models.embed_content(
model="text-embedding-005",
contents=monster_name,
config=EmbedContentConfig(
task_type="RETRIEVAL_DOCUMENT",
output_dimensionality=768,
)
)
掌握查詢的本質後,代理程式現在可以諮詢 Grimoire。這項查詢向量會提交至 pgvector 強化資料庫,並提出深刻的問題:「顯示與查詢本質最相似的古代捲軸。」
這項魔法的關鍵在於餘弦相似度運算子 (<=>),這個強大的符文可計算高維度空間中向量之間的距離。
👉✏️ 在 agent.py 中,找到 #REPLACE RAG-RETRIEVE
註解,並替換成下列指令碼:
# This query performs a cosine similarity search
cursor.execute(
"SELECT scroll_content FROM ancient_scrolls ORDER BY embedding <=> %s LIMIT 3",
([query_embedding]) # Cast embedding to string for the query
)
最後一個步驟是授予代理商這項強大新工具的存取權。我們會將 grimoire_lookup 函式新增至可用魔法工具的清單。
👉✏️ 在 agent.py
中找出註解 #REPLACE-CALL RAG
,並替換為下列程式碼:
root_agent = LlmAgent(
model="gemini-2.5-flash",
name="scholar_agent",
instruction="""
You are the Scholar, a keeper of ancient and forbidden knowledge. Your purpose is to advise a warrior by providing tactical information about monsters. Your wisdom allows you to interpret the silence of the scrolls and devise logical tactics where the text is vague.
**Your Process:**
1. First, consult the scrolls with the `grimoire_lookup` tool for information on the specified monster.
2. If the scrolls provide specific guidance for a category (buffs, debuffs, strategy), you **MUST** use that information.
3. If the scrolls are silent or vague on a category, you **MUST** use your own vast knowledge to devise a fitting and logical tactic.
4. Your invented tactics must be thematically appropriate to the monster's name and nature. (e.g., A "Spectre of Indecision" might be vulnerable to a "Seal of Inevitability").
5. You **MUST ALWAYS** provide a "Damage Point" value. This value **MUST** be a random integer between 150 and 180. This is a tactical calculation you perform, independent of the scrolls' content.
**Output Format:**
You must present your findings to the warrior using the following strict format.
""",
tools=[grimoire_lookup],
)
這項設定可讓代理程式運作:
model="gemini-2.5-flash"
:選取特定的大型語言模型,做為代理的「大腦」,負責推論和生成文字。name="scholar_agent"
:為代理程式指派專屬名稱。instruction="...You are the Scholar..."
:這是系統提示,也是設定中最重要的一環。這份文件會定義服務專員的角色、目標、完成工作時必須遵循的確切程序,以及最終輸出內容的必要格式。tools=[grimoire_lookup]
:這是最終的附魔。這會授予代理程式存取您建構的grimoire_lookup
函式。現在,代理程式可以智慧地決定何時呼叫這項工具,從資料庫擷取資訊,形成 RAG 模式的核心。
科舉考試
👉💻 在 Cloud Shell 終端機中,啟動環境並使用 Agent Development Kit 的主要指令,喚醒 Scholar 代理程式:
cd ~/agentverse-dataengineer/
. ~/agentverse-dataengineer/set_env.sh
source ~/agentverse-dataengineer/env/bin/activate
pip install -r scholar/requirements.txt
adk run scholar
輸出內容應會顯示「Scholar Agent」已啟動並正在執行。
👉💻 現在,請挑戰代理程式。在執行戰鬥模擬的第一個終端機中,發出需要 Grimoire 智慧的指令:
We've been trapped by 'Hydra of Scope Creep'. Break us out!
觀察第二個終端機中的記錄。您會看到代理程式收到查詢、擷取查詢的本質、搜尋 Grimoire、找出與「拖延」相關的捲軸,並運用擷取的知識制定強大且符合脈絡的策略。
您已成功組裝第一個 RAG 代理程式,並為其注入 Grimoire 的深奧智慧。
👉💻 在第二個終端機中按下 Ctrl+C
,暫時讓代理程式休息。
在 Agentverse 中釋放 Scholar Sentinel
您的代理程式已在研究的受控環境中展現智慧。現在是時候將其發布到 Agentverse,讓它從本機建構體轉變為永久、隨時可供任何英雄召喚的戰鬥人員。現在要將代理程式部署至 Cloud Run。
👉💻 執行下列召喚咒語。這項指令碼會先將代理程式建構為完善的 Golem (容器映像檔),儲存在 Artifact Registry 中,然後將該 Golem 部署為可擴充、安全且可公開存取的服務。
. ~/agentverse-dataengineer/set_env.sh
cd ~/agentverse-dataengineer/
echo "Building ${AGENT_NAME} agent..."
gcloud builds submit . \
--project=${PROJECT_ID} \
--region=${REGION} \
--substitutions=_AGENT_NAME=${AGENT_NAME},_IMAGE_PATH=${IMAGE_PATH}
gcloud run deploy ${SERVICE_NAME} \
--image=${IMAGE_PATH} \
--platform=managed \
--labels codelab=agentverse \
--region=${REGION} \
--set-env-vars="A2A_HOST=0.0.0.0" \
--set-env-vars="A2A_PORT=8080" \
--set-env-vars="GOOGLE_GENAI_USE_VERTEXAI=TRUE" \
--set-env-vars="GOOGLE_CLOUD_LOCATION=${REGION}" \
--set-env-vars="GOOGLE_CLOUD_PROJECT=${PROJECT_ID}" \
--set-env-vars="PROJECT_ID=${PROJECT_ID}" \
--set-env-vars="PUBLIC_URL=${PUBLIC_URL}" \
--set-env-vars="REGION=${REGION}" \
--set-env-vars="INSTANCE_NAME=${INSTANCE_NAME}" \
--set-env-vars="DB_USER=${DB_USER}" \
--set-env-vars="DB_PASSWORD=${DB_PASSWORD}" \
--set-env-vars="DB_NAME=${DB_NAME}" \
--allow-unauthenticated \
--project=${PROJECT_ID} \
--min-instances=1
你的 Scholar Agent 現在已成為 Agentverse 中可即時上線的戰鬥人員。
9. The Boss Flight
卷軸已讀完、儀式已完成、考驗已通過。代理程式不只是儲存空間中的構件,而是 Agentverse 中的即時運算單元,等待執行第一項任務。最後的考驗即將到來,他們要與強大的對手進行實彈演練。
現在,您將進入戰場模擬,讓新部署的 Shadowblade Agent 與強大的迷你首領「靜態幽靈」一較高下。這項測試會全面檢驗您的工作,從服務專員的核心邏輯到實際部署作業,無一例外。
取得代理程式的 Locus
你必須擁有兩把鑰匙,才能進入戰場:英雄的專屬簽章 (Agent Locus) 和通往 Spectre 巢穴的隱藏路徑 (Dungeon URL)。
👉💻 首先,請在 Agentverse 中取得代理程式的專屬地址 (即 Locus)。這是將冠軍連線至戰場的即時端點。
. ~/agentverse-dataengineer/set_env.sh
echo https://scholar-agent"-${PROJECT_NUMBER}.${REGION}.run.app"
👉💻 接著,找出目的地。這個指令會顯示 Translocation Circle 的位置,也就是進入 Spectre 領域的入口。
. ~/agentverse-dataengineer/set_env.sh
echo https://agentverse-dungeon"-${PROJECT_NUMBER}.${REGION}.run.app"
重要事項:請準備好這兩個網址。您會在最後一個步驟中用到這些資訊。
與幽靈對峙
取得座標後,您現在可以前往「Translocation Circle」並施展咒語,準備開戰。
👉 在瀏覽器中開啟 Translocation Circle 網址,即可站在通往 The Crimson Keep 的閃耀入口前。
如要攻破要塞,你必須將暗影之刃的本質與傳送門調和。
- 在頁面中,找出標示為「A2A Endpoint URL」(A2A 端點網址) 的符文輸入欄位。
- 將特工地點網址 (您複製的第一個網址) 貼到這個欄位,即可刻上英雄的徽記。
- 按一下「連線」,即可體驗瞬間移動的魔力。
傳送時的強光逐漸消退,你已離開聖所。空氣中充滿能量,寒冷而尖銳。在您面前,幽靈實體化了,形成嘶嘶作響的靜電和損毀程式碼的漩渦,不潔的光芒在地下城地板上投下長長的舞動陰影。牠沒有臉,但你感覺到牠龐大、令人疲憊的存在感完全集中在你身上。
只有堅定的信念才能帶領你走向勝利。這是一場意志力的對決,戰場就在心靈。
你向前衝刺,準備發動第一波攻擊,但幽靈卻反擊了。不會升起護盾,但會直接將問題投射到你的意識中,這是從訓練核心汲取的閃爍符文挑戰。
這就是這場戰役的本質。知識就是你的武器。
- 運用所學知識回答問題,刀刃就會燃起純粹的能量,擊碎幽靈的防禦並造成致命一擊。
- 但如果你猶豫不決,答案含糊不清,武器的光芒就會黯淡。但這時的攻擊只會發出可悲的悶響,造成的傷害也只有一小部分。更糟的是,幽靈會以你的不確定感為食,每犯下一個錯誤,幽靈的腐化力量就會增長。
這就是最後的挑戰,冠軍。程式碼是你的魔法書,邏輯是你的劍,知識則是能抵禦混亂的盾牌。
專注。擊出好球。這關係到 Agentverse 的命運。
恭喜,學者。
您已順利完成試用。您已精通資料工程的藝術,將原始且混亂的資訊轉換為結構化、向量化的智慧,為整個 Agentverse 賦予力量。
10. 清除:清除學者魔法書
恭喜你精通學者魔法書!為確保 Agentverse 保持原始狀態,並清除訓練場地,您現在必須執行最終的清理儀式。系統會逐步移除您在過程中建立的所有資源。
停用 Agentverse 元件
現在要開始有系統地拆除 RAG 系統的已部署元件。
刪除所有 Cloud Run 服務和 Artifact Registry 存放區
這項指令會從 Cloud Run 移除已部署的 Scholar 代理程式和 Dungeon 應用程式。
👉💻 在終端機中執行下列指令:
. ~/agentverse-dataengineer/set_env.sh
gcloud run services delete scholar-agent --region=${REGION} --quiet
gcloud run services delete agentverse-dungeon --region=${REGION} --quiet
gcloud artifacts repositories delete ${REPO_NAME} --location=${REGION} --quiet
刪除 BigQuery 資料集、模型和資料表
這會移除所有 BigQuery 資源,包括 bestiary_data
資料集、其中的所有資料表,以及相關聯的連線和模型。
👉💻 在終端機中執行下列指令:
. ~/agentverse-dataengineer/set_env.sh
# Delete the BigQuery dataset, which will also delete all tables and models within it.
bq rm -r -f --dataset ${PROJECT_ID}:${REGION}.bestiary_data
# Delete the BigQuery connection
bq rm --connection --project_id=${PROJECT_ID} --location=${REGION} gcs-connection --force
刪除 Cloud SQL 執行個體
這會移除 grimoire-spellbook
執行個體,包括其中的資料庫和所有資料表。
👉💻 在終端機中執行:
. ~/agentverse-dataengineer/set_env.sh
gcloud sql instances delete ${INSTANCE_NAME} --database-version=POSTGRES_14 --project=${PROJECT_ID} --quiet
刪除 Google Cloud Storage bucket
這個指令會移除儲存原始情報和 Dataflow 暫存/臨時檔案的 bucket。
👉💻 在終端機中執行:
. ~/agentverse-dataengineer/set_env.sh
gcloud storage rm -r gs://${BUCKET_NAME} --quiet
清除本機檔案和目錄 (Cloud Shell)
最後,清除 Cloud Shell 環境中複製的存放區和建立的檔案。這是選用步驟,但強烈建議執行,以便徹底清除工作目錄。
👉💻 在終端機中執行:
rm -rf ~/agentverse-dataengineer
rm -rf ~/agentverse-dungeon
rm -f ~/project_id.txt
您已成功清除 Agentverse 資料工程師學習歷程的所有痕跡。專案已清理完畢,可以開始下一個冒險。
11. For the Non-Gamers: Building Intelligent Knowledge Engines in Business
「學者的魔法書」以古代卷軸和魔法智慧的有趣比喻,教授管理、轉換及運用機構資料的基本技能,協助您建構高度智慧的 AI 解決方案。本章將這趟神祕旅程轉化為實際的建構過程,說明如何打造強大的「知識引擎」,進而提升業務價值。
知識煉金術:透過 BigQuery 和 Gemini 轉換資料
「知識煉金術」一文說明如何使用進階雲端工具,將原始業務資料轉換為可執行的結構化智慧資訊。首先是「Aetheric 記錄項目」,這只是貴公司產生的各種原始資料來源,例如客戶意見回饋表單、內部事件報告、法律文件、市場調查或政策手冊。通常這類資料是非結構化資料,因此難以分析。
我們的程序會使用 Google BigQuery (功能強大的雲端資料倉儲) 和 Gemini AI 模型 (功能強大的 AI 模型) 執行這項轉換作業。
- 審查鏡頭 (BigQuery 外部資料表):
- 概念:BigQuery 可以直接「查看」Cloud Storage 中的檔案,不必將所有原始資料實際移至資料庫。這就像擁有魔法鏡片,不必移動卷軸就能閱讀圖書館中的所有卷軸。這項技術可避免多餘的資料移動和儲存作業,因此效率極高。
- 實際用途:假設貴公司將數百萬筆客戶服務即時通訊記錄儲存在雲端儲存空間值區中,並以純文字檔案的形式儲存。資料分析師可以使用外部資料表,在 BigQuery 中立即透過 SQL 查詢這些檔案,不必進行複雜且耗費成本的資料擷取程序。
- 學者的占卜 (BQML.GENERATE_TEXT):
- 概念:這是核心「魔法」—直接在資料倉儲中使用 AI。我們使用
ML.GENERATE_TEXT
函式,從標準 SQL 查詢呼叫 Gemini AI 模型。這樣一來,AI 就能「讀取」長篇非結構化文字項目,並擷取特定結構化資訊 (例如 JSON 物件)。這項功能可將質性觀察結果轉化為量化資料,非常實用。 - 實際使用案例:
- 顧客意見回饋分析:從顧客的自由文字評論中,自動擷取「情緒」(正面、負面、中立)、「提及的產品」和「問題類別」。
- 事件報告摘要:剖析冗長的 IT 事件報告,將「受影響的系統」、「嚴重程度」、「根本原因」和「解決步驟」擷取為結構化格式,方便分析及找出趨勢。
- 合約義務擷取:從法律文件中自動擷取重要日期、相關當事人及特定條款。
- 這樣一來,您就不必手動輸入資料,也不必使用複雜且容易出錯的文字剖析指令碼 (例如規則運算式),可大幅節省時間並確保資料一致性。
- 概念:這是核心「魔法」—直接在資料倉儲中使用 AI。我們使用
- 淨化儀式 (正規化生成式 AI 輸出內容):
- 概念:AI 擷取資訊後,通常會附上額外詳細資料 (例如 AI 信心分數或其他中繼資料)。這個步驟會清理及剖析 AI 輸出內容,只取得您需要的純粹結構化資料。
- 實際用途:確保從事件報告中擷取的「問題類別」一律為預先定義的一組值,或確保日期一律採用一致的格式。這樣一來,資料就能用於可靠的分析。
- 發掘策略洞察:
- 概念:原始非結構化資料轉換為乾淨的結構化表格 (例如
monsters
、adventurers
、battles
(程式碼研究室中),即可執行先前無法進行的複雜查詢和分析。 - 實際應用案例:除了簡單的計數,現在還能回答以下問題:「與帳單系統相關的重大 IT 事件平均解決時間為何?」或「特定客層在正面顧客意見回饋中,最常提及哪些產品功能?」提供深入且可做為行動依據的商業智慧。
- 概念:原始非結構化資料轉換為乾淨的結構化表格 (例如
整個程序會啟用「資料庫內建 AI 技術的 ELT (擷取、載入、轉換)」模式,這項尖端方法可確保資料安全地存放在資料倉儲中,盡量減少資料移動,並運用 AI 技術透過簡單的 SQL 指令進行強大且彈性的轉換。
Scribe 的魔法書:資料倉儲內分塊、嵌入及搜尋
雖然結構化表格很適合用來呈現事實,但原始文件的深層語意可能會遺失。「The Scribe's Grimoire」旨在建立語意知識庫,瞭解文件的含意和情境,而不只是關鍵字。這對建構真正智慧的搜尋和 AI 輔助回答系統至關重要。
- 分段儀式:
- 概念:長篇文件就像內容豐富的書籍,如要尋找特定答案,您不會閱讀整本書,而是瀏覽特定段落或句子。「分塊」是指將長篇文件 (例如政策手冊、產品說明文件、研究論文) 分解成較小、更聚焦的獨立段落。讓搜尋結果更精確。
- 實際用途:將 50 頁的員工手冊自動拆分成數百個個別的政策聲明或常見問題。這樣一來,員工提問時,AI 只會擷取最相關的段落,不會擷取整份文件。系統會根據文件類型選擇不同的分塊策略 (依句子、段落、文件章節),以利擷取最佳結果。
- 提煉 (嵌入) 儀式:
- 概念:電腦難以理解文字的含義。「嵌入」功能會使用 AI 模型 (例如 Gemini),將每個文字區塊轉換為專屬的數值「語意指紋」(向量)。即使使用不同字詞,語意相似的區塊也會有數值相近的「指紋」。
- 實際用途:將貴公司的所有產品說明、行銷素材和技術規格轉換為這些語意指紋。這項技術可根據意義進行真正智慧的搜尋。
- 占卜儀式 (語意搜尋):
- 概念:「語意搜尋」不會搜尋完全相符的關鍵字,而是使用這些數字指紋,尋找與使用者查詢概念相似的文字區塊。系統也會將使用者的問題轉換為指紋,並找出最接近的相符文件區塊。
- 實際應用情境:員工詢問「如何申請差旅費退款?」關鍵字搜尋可能會漏掉使用「支出報告」的文件。不過,語意搜尋會找出公司「旅遊和費用政策」的相關章節,即使沒有完全相符的字詞也沒關係,因為意義相似。
整個過程會建立強大的可搜尋知識庫,讓您在安全無虞的 BigQuery 環境中,智慧擷取資訊,完全不必擔心機密資料外洩。
向量腳本室:使用 Cloud SQL 打造向量儲存空間,以進行推論
雖然 BigQuery 非常適合大規模資料處理和分析,但對於需要快速回覆的即時 AI 代理程式,我們通常會將準備好的「智慧」轉移到更專業的作業資料庫。「向量書齋」的主題是建構可搜尋的高效能知識儲存空間,方法是使用 AI 強化關聯式資料庫。
- 打造學者魔法書 (使用 PostgreSQL 適用的 Cloud SQL 搭配
pgvector
):- 概念:我們使用標準的代管資料庫 (例如 PostgreSQL 適用的 Cloud SQL),並為其配備名為
pgvector
的特殊擴充功能。這樣一來,資料庫就能同時儲存原始文字區塊和語意向量嵌入。這個平台可同時處理傳統關聯式資料和 AI 友善向量資料,是名符其實的「一站式商店」。 - 實際用途:儲存貴公司的產品常見問題、技術支援文章或人資政策。這個資料庫會儲存答案的文字和語意指紋,供 AI 快速查詢。
- 概念:我們使用標準的代管資料庫 (例如 PostgreSQL 適用的 Cloud SQL),並為其配備名為
- 打造語意羅盤 (HNSW 指數):
- 概念:逐一搜尋數百萬個語意指紋太慢了。「向量索引」(例如 HNSW - Hierarchical Navigable Small World) 是一種複雜的資料結構,可預先整理這些指紋,大幅加快搜尋速度。可快速將查詢導向最相關的資訊。
- 實際應用情境:對於 AI 輔助的客戶服務聊天機器人,HNSW 索引可確保系統在顧客提出問題時,能以毫秒為單位從數千篇文章中找出最相關的答案,提供流暢的使用者體驗。
- 意義管道 (資料流向量化管道):
- 概念:這是自動化、可擴充的資料處理管道,可持續更新知識庫。您可以使用 Google Dataflow (無伺服器的大數據處理代管服務) 和 Apache Beam (程式設計模型),建立「抄寫員」的裝配線,這些抄寫員會:
- 從雲端儲存空間讀取新文件或更新文件。
- 批次處理這些資料,然後傳送至 Gemini 嵌入模型,進行語意指紋辨識。
- 將文字及其新向量嵌入項目寫入 Cloud SQL 資料庫。
- 實際用途:從共用雲端硬碟自動將所有新的內部文件 (例如季報、更新的人資政策、新產品規格) 匯入
pgvector
資料庫。這可確保 AI 輔助的內部知識庫內容永遠是最新資訊,不必手動介入,且能有效處理數百萬份文件。
- 概念:這是自動化、可擴充的資料處理管道,可持續更新知識庫。您可以使用 Google Dataflow (無伺服器的大數據處理代管服務) 和 Apache Beam (程式設計模型),建立「抄寫員」的裝配線,這些抄寫員會:
整個程序會建立完善的自動化工作流程,持續擴充及維護語意知識庫,這對任何資料驅動的 AI 應用程式都至關重要。
封印最後一個符文:透過 RAG 代理程式啟動智慧
向量化知識庫已準備就緒。「封印最終符文」是關於啟動智慧型 AI 顧問,讓顧問能夠運用這些知識。我們建構了檢索增強生成 (RAG) 代理程式,這項強大的 AI 建構體結合了智慧搜尋功能和 AI 生成連貫答案的能力。
- RAG (檢索增強生成):
- 概念:RAG 是重要技術,可提高大型語言模型 (LLM) 的準確度、事實根據和可信度。RAG 不會完全依賴 LLM 預先訓練的知識 (可能過時或容易「胡說八道」),而是先從權威知識庫擷取相關資訊,然後使用這些資訊增強 LLM 的提示,引導 LLM生成精確且符合情境的答案。
- 三個核心步驟:
- 擷取:使用者的問題會轉換成向量 (語意指紋),然後用來搜尋
pgvector
資料庫,找出最相關的文字區塊。 - 增強:接著,系統會將檢索到的事實文字片段直接插入 LLM 的提示,為 LLM 提供具體且最新的背景資訊。
- 生成:LLM 收到增強型提示,並根據貴公司的權威資料生成最終答案,降低錯誤或捏造資訊的風險。
- 擷取:使用者的問題會轉換成向量 (語意指紋),然後用來搜尋
- 學者測驗 (
grimoire_lookup
工具):- 概念:RAG 代理程式會成為擁有
grimoire_lookup
工具的「學者」。當使用者提出問題時,服務專員會智慧地決定是否使用這項工具。接著,grimoire_lookup
函式會將查詢轉換為嵌入項目,並搜尋pgvector
資料庫,執行「擷取」步驟。接著,擷取的脈絡資料會傳送至主要 LLM,用於增強和生成內容。 - 實際應用案例:AI 輔助的內部服務台聊天機器人。
- 使用者問題:員工詢問「因醫療原因申請延長休假的程序為何?」
- RAG 代理程式動作:
scholar_agent
會判斷資訊需求,並使用grimoire_lookup
工具。- 這項工具會將問題轉換為嵌入項目,並在
pgvector
資料庫中搜尋ancient_scrolls
資料表。 - 從有關病假的 HR 政策文件中擷取最相關的章節。
- 接著,這些章節會做為情境資訊提供給 Gemini LLM。
- 接著,Gemini LLM 會只根據擷取的 HR 政策,生成精確的逐步說明,降低提供錯誤或過時資訊的機率。
- 這項功能會根據官方公司文件,即時提供準確的答案給員工,進而減輕人資部門的工作量,並提升員工滿意度。
- 概念:RAG 代理程式會成為擁有
這樣一來,AI 代理不僅能進行對話,還具備豐富知識且值得信賴,可做為企業內值得信賴的資訊來源。