本教學課程說明如何將以檢索增強生成 (RAG) 為基礎的大型語言模型 (LLM) 應用程式,與您上傳至 Cloud Storage bucket 的 PDF 檔案整合。
本指南會使用資料庫做為儲存空間和語意搜尋引擎,儲存上傳文件的表示形式 (嵌入)。您可以使用 Langchain 架構與嵌入內容互動,並使用透過 Vertex AI 提供的 Gemini 模型。
Langchain 是熱門的開放原始碼 Python 架構,可簡化許多機器學習工作,並提供介面,方便整合不同的向量資料庫和 AI 服務。
本教學課程的適用對象為雲端平台管理員和架構師、機器學習工程師,以及有興趣將 RAG LLM 應用程式部署至 GKE 和 Cloud Storage 的 MLOps (DevOps) 專業人員。
目標
在本教學課程中,您將瞭解以下內容:
- 建構及部署應用程式,在向量資料庫中建立及儲存文件嵌入。
- 自動觸發應用程式,將新文件上傳至 Cloud Storage bucket。
- 部署聊天機器人應用程式,根據文件內容使用語意搜尋回答問題。
部署架構
在本教學課程中,您將建立 Cloud Storage bucket、Eventarc 觸發程序,以及下列服務:
embed-docs:每當使用者將新文件上傳至 Cloud Storage 值區時,Eventarc 就會觸發這項服務。這項服務會啟動 Kubernetes 工作,為上傳的文件建立嵌入項目,並將嵌入項目插入向量資料庫。chatbot:這項服務會使用語意搜尋和 Gemini API,回答有關上傳文件的自然語言問題。
下圖顯示上傳及向量化文件的程序:
在圖表中,使用者將檔案上傳至 Cloud Storage bucket。Eventarc 會訂閱 bucket 的物件 metadataUpdated 事件,並使用 Eventarc 的事件轉送器 (Kubernetes 工作負載),在您上傳新文件時呼叫 embed-docs 服務。接著,服務會為上傳的文件建立嵌入項目。embed-docs
服務會使用 Vertex AI 嵌入模型,將嵌入儲存在向量資料庫中。
下圖說明如何使用 chatbot 服務,詢問上傳文件內容相關問題:
使用者可以自然語言提問,聊天機器人會根據上傳檔案的內容生成答案。聊天機器人會使用語意搜尋從向量資料庫擷取情境,然後將問題和情境傳送給 Gemini。
費用
在本文件中,您會使用下列 Google Cloud的計費元件:
如要根據預測用量估算費用,請使用 Pricing Calculator。
完成本文所述工作後,您可以刪除建立的資源,避免繼續計費,詳情請參閱「清除所用資源」。
事前準備
在本教學課程中,您將使用 Cloud Shell 執行指令。Cloud Shell 是殼層環境,用於管理託管在 Google Cloud的資源。Cloud Shell 已預先安裝 Google Cloud CLI、kubectl 和 Terraform 指令列工具。如果您未使用 Cloud Shell,請安裝 Google Cloud CLI。
- 登入 Google Cloud 帳戶。如果您是 Google Cloud新手,歡迎 建立帳戶,親自評估產品在實際工作環境中的成效。新客戶還能獲得價值 $300 美元的免費抵免額,可用於執行、測試及部署工作負載。
-
安裝 Google Cloud CLI。
-
若您採用的是外部識別資訊提供者 (IdP),請先使用聯合身分登入 gcloud CLI。
-
執行下列指令,初始化 gcloud CLI:
gcloud init -
選取或建立專案所需的角色
- 選取專案:選取專案時,不需要具備特定 IAM 角色,只要您已獲授角色,即可選取任何專案。
-
建立專案:如要建立專案,您需要具備專案建立者角色 (
roles/resourcemanager.projectCreator),其中包含resourcemanager.projects.create權限。瞭解如何授予角色。
-
建立 Google Cloud 專案:
gcloud projects create PROJECT_ID
將
PROJECT_ID替換為您要建立的 Google Cloud 專案名稱。 -
選取您建立的 Google Cloud 專案:
gcloud config set project PROJECT_ID
將
PROJECT_ID替換為 Google Cloud 專案名稱。
啟用 Vertex AI、Cloud Build、Eventarc、Artifact Registry API:
啟用 API 時所需的角色
如要啟用 API,您需要具備服務使用情形管理員 IAM 角色 (
roles/serviceusage.serviceUsageAdmin),其中包含serviceusage.services.enable權限。瞭解如何授予角色。gcloud services enable aiplatform.googleapis.com
cloudbuild.googleapis.com eventarc.googleapis.com artifactregistry.googleapis.com -
安裝 Google Cloud CLI。
-
若您採用的是外部識別資訊提供者 (IdP),請先使用聯合身分登入 gcloud CLI。
-
執行下列指令,初始化 gcloud CLI:
gcloud init -
選取或建立專案所需的角色
- 選取專案:選取專案時,不需要具備特定 IAM 角色,只要您已獲授角色,即可選取任何專案。
-
建立專案:如要建立專案,您需要具備專案建立者角色 (
roles/resourcemanager.projectCreator),其中包含resourcemanager.projects.create權限。瞭解如何授予角色。
-
建立 Google Cloud 專案:
gcloud projects create PROJECT_ID
將
PROJECT_ID替換為您要建立的 Google Cloud 專案名稱。 -
選取您建立的 Google Cloud 專案:
gcloud config set project PROJECT_ID
將
PROJECT_ID替換為 Google Cloud 專案名稱。
啟用 Vertex AI、Cloud Build、Eventarc、Artifact Registry API:
啟用 API 時所需的角色
如要啟用 API,您需要具備服務使用情形管理員 IAM 角色 (
roles/serviceusage.serviceUsageAdmin),其中包含serviceusage.services.enable權限。瞭解如何授予角色。gcloud services enable aiplatform.googleapis.com
cloudbuild.googleapis.com eventarc.googleapis.com artifactregistry.googleapis.com -
將角色授予使用者帳戶。針對下列每個 IAM 角色,執行一次下列指令:
eventarc.admingcloud projects add-iam-policy-binding PROJECT_ID --member="user:USER_IDENTIFIER" --role=ROLE
更改下列內容:
PROJECT_ID:專案 ID。USER_IDENTIFIER:使用者帳戶的 ID。 例如:myemail@example.com。ROLE:授予使用者帳戶的 IAM 角色。
建立叢集
建立 Qdrant、Elasticsearch 或 Postgres 叢集:
Qdrant
按照「在 GKE 上部署 Qdrant 向量資料庫」一文中的操作說明,在 Autopilot 模式或標準模式的 GKE 叢集上建立 Qdrant 叢集。
Elasticsearch
按照「在 GKE 上部署 Elasticsearch 向量資料庫」一文中的操作說明,建立在 Autopilot 模式或 Standard 模式 GKE 叢集上執行的 Elasticsearch 叢集。
PGVector
按照「在 GKE 上部署 PostgreSQL 向量資料庫」一文中的操作說明,在 Autopilot 模式或標準模式 GKE 叢集上建立執行 PGVector 的 Postgres 叢集。
Weaviate
按照在 GKE 上部署 Weaviate 向量資料庫的說明,建立在 Autopilot 或標準模式 GKE 叢集上執行的 Weaviate 叢集。
設定環境
使用 Cloud Shell 設定環境:
為專案設定環境變數:
Qdrant
export PROJECT_ID=PROJECT_ID export KUBERNETES_CLUSTER_PREFIX=qdrant export CONTROL_PLANE_LOCATION=us-central1 export REGION=us-central1 export DB_NAMESPACE=qdrant將
PROJECT_ID替換為Google Cloud 專案 ID。Elasticsearch
export PROJECT_ID=PROJECT_ID export KUBERNETES_CLUSTER_PREFIX=elasticsearch export CONTROL_PLANE_LOCATION=us-central1 export REGION=us-central1 export DB_NAMESPACE=elastic將
PROJECT_ID替換為Google Cloud 專案 ID。PGVector
export PROJECT_ID=PROJECT_ID export KUBERNETES_CLUSTER_PREFIX=postgres export CONTROL_PLANE_LOCATION=us-central1 export REGION=us-central1 export DB_NAMESPACE=pg-ns將
PROJECT_ID替換為Google Cloud 專案 ID。Weaviate
export PROJECT_ID=PROJECT_ID export KUBERNETES_CLUSTER_PREFIX=weaviate export CONTROL_PLANE_LOCATION=us-central1 export REGION=us-central1 export DB_NAMESPACE=weaviate將
PROJECT_ID替換為Google Cloud 專案 ID。確認 GKE 叢集正在執行:
gcloud container clusters list --project=${PROJECT_ID} --location=${CONTROL_PLANE_LOCATION}輸出結果會與下列內容相似:
NAME LOCATION MASTER_VERSION MASTER_IP MACHINE_TYPE NODE_VERSION NUM_NODES STATUS [KUBERNETES_CLUSTER_PREFIX]-cluster us-central1 1.30.1-gke.1329003 <EXTERNAL IP> e2-standard-2 1.30.1-gke.1329003 6 RUNNING從 GitHub 複製程式碼範例存放區:
git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples請前往
databases目錄:cd kubernetes-engine-samples/databases
準備基礎架構
建立 Artifact Registry 存放區、建構 Docker 映像檔,並將 Docker 映像檔推送至 Artifact Registry:
建立 Artifact Registry 存放區:
gcloud artifacts repositories create ${KUBERNETES_CLUSTER_PREFIX}-images \ --repository-format=docker \ --location=${REGION} \ --description="Vector database images repository" \ --async在 Compute Engine 服務帳戶中設定
storage.objectAdmin和artifactregistry.admin權限,以便使用 Cloud Build 建構embed-docs和chatbot服務的 Docker 映像檔,並推送至 Container Registry。export PROJECT_NUMBER=PROJECT_NUMBER gcloud projects add-iam-policy-binding ${PROJECT_ID} \ --member="serviceAccount:${PROJECT_NUMBER}-compute@developer.gserviceaccount.com" \ --role="roles/storage.objectAdmin" gcloud projects add-iam-policy-binding ${PROJECT_ID} \ --member="serviceAccount:${PROJECT_NUMBER}-compute@developer.gserviceaccount.com" \ --role="roles/artifactregistry.admin"將
PROJECT_NUMBER替換為Google Cloud 專案編號。為
embed-docs和chatbot服務建構 Docker 映像檔。embed-docs映像檔包含 Python 程式碼,適用於接收 Eventarc 轉送器要求的應用程式和嵌入工作。Qdrant
export DOCKER_REPO="${REGION}-docker.pkg.dev/${PROJECT_ID}/${KUBERNETES_CLUSTER_PREFIX}-images" gcloud builds submit qdrant/docker/chatbot --region=${REGION} \ --tag ${DOCKER_REPO}/chatbot:1.0 --async gcloud builds submit qdrant/docker/embed-docs --region=${REGION} \ --tag ${DOCKER_REPO}/embed-docs:1.0 --asyncElasticsearch
export DOCKER_REPO="${REGION}-docker.pkg.dev/${PROJECT_ID}/${KUBERNETES_CLUSTER_PREFIX}-images" gcloud builds submit elasticsearch/docker/chatbot --region=${REGION} \ --tag ${DOCKER_REPO}/chatbot:1.0 --async gcloud builds submit elasticsearch/docker/embed-docs --region=${REGION} \ --tag ${DOCKER_REPO}/embed-docs:1.0 --asyncPGVector
export DOCKER_REPO="${REGION}-docker.pkg.dev/${PROJECT_ID}/${KUBERNETES_CLUSTER_PREFIX}-images" gcloud builds submit postgres-pgvector/docker/chatbot --region=${REGION} \ --tag ${DOCKER_REPO}/chatbot:1.0 --async gcloud builds submit postgres-pgvector/docker/embed-docs --region=${REGION} \ --tag ${DOCKER_REPO}/embed-docs:1.0 --asyncWeaviate
export DOCKER_REPO="${REGION}-docker.pkg.dev/${PROJECT_ID}/${KUBERNETES_CLUSTER_PREFIX}-images" gcloud builds submit weaviate/docker/chatbot --region=${REGION} \ --tag ${DOCKER_REPO}/chatbot:1.0 --async gcloud builds submit weaviate/docker/embed-docs --region=${REGION} \ --tag ${DOCKER_REPO}/embed-docs:1.0 --async驗證圖片:
gcloud artifacts docker images list $DOCKER_REPO \ --project=$PROJECT_ID \ --format="value(IMAGE)"輸出結果會與下列內容相似:
$REGION-docker.pkg.dev/$PROJECT_ID/${KUBERNETES_CLUSTER_PREFIX}-images/chatbot $REGION-docker.pkg.dev/$PROJECT_ID/${KUBERNETES_CLUSTER_PREFIX}-images/embed-docs部署具有執行 Kubernetes 工作權限的 Kubernetes 服務帳戶:
Qdrant
sed "s/<PROJECT_ID>/$PROJECT_ID/;s/<CLUSTER_PREFIX>/$KUBERNETES_CLUSTER_PREFIX/" qdrant/manifests/05-rag/service-account.yaml | kubectl -n qdrant apply -f -Elasticsearch
sed "s/<PROJECT_ID>/$PROJECT_ID/;s/<CLUSTER_PREFIX>/$KUBERNETES_CLUSTER_PREFIX/" elasticsearch/manifests/05-rag/service-account.yaml | kubectl -n elastic apply -f -PGVector
sed "s/<PROJECT_ID>/$PROJECT_ID/;s/<CLUSTER_PREFIX>/$KUBERNETES_CLUSTER_PREFIX/" postgres-pgvector/manifests/03-rag/service-account.yaml | kubectl -n pg-ns apply -f -Weaviate
sed "s/<PROJECT_ID>/$PROJECT_ID/;s/<CLUSTER_PREFIX>/$KUBERNETES_CLUSTER_PREFIX/" weaviate/manifests/04-rag/service-account.yaml | kubectl -n weaviate apply -f -使用 Terraform 建立 GKE 叢集並將
create_service_account設為 true 時,系統會建立個別的服務帳戶,供叢集和節點使用。將artifactregistry.serviceAgent角色授予這個 Compute Engine 服務帳戶,節點就能從為embed-docs和chatbot建立的 Artifact Registry 提取映像檔。export CLUSTER_SERVICE_ACCOUNT=$(gcloud container clusters describe ${KUBERNETES_CLUSTER_PREFIX}-cluster \ --location=${CONTROL_PLANE_LOCATION} \ --format="value(nodeConfig.serviceAccount)") gcloud projects add-iam-policy-binding ${PROJECT_ID} \ --member="serviceAccount:${CLUSTER_SERVICE_ACCOUNT}" \ --role="roles/artifactregistry.serviceAgent"如果未授予服務帳戶存取權,節點在部署
embed-docs和chatbot服務時,嘗試從 Artifact Registry 提取映像檔時可能會發生權限問題。為
embed-docs和chatbot服務部署 Kubernetes Deployment。 Deployment 是 Kubernetes API 物件,可讓您執行多個 Pod 副本,並將這些副本分散到叢集中的節點:Qdrant
sed "s|<DOCKER_REPO>|$DOCKER_REPO|" qdrant/manifests/05-rag/chatbot.yaml | kubectl -n qdrant apply -f - sed "s|<DOCKER_REPO>|$DOCKER_REPO|" qdrant/manifests/05-rag/docs-embedder.yaml | kubectl -n qdrant apply -f -Elasticsearch
sed "s|<DOCKER_REPO>|$DOCKER_REPO|" elasticsearch/manifests/05-rag/chatbot.yaml | kubectl -n elastic apply -f - sed "s|<DOCKER_REPO>|$DOCKER_REPO|" elasticsearch/manifests/05-rag/docs-embedder.yaml | kubectl -n elastic apply -f -PGVector
sed "s|<DOCKER_REPO>|$DOCKER_REPO|" postgres-pgvector/manifests/03-rag/chatbot.yaml | kubectl -n pg-ns apply -f - sed "s|<DOCKER_REPO>|$DOCKER_REPO|" postgres-pgvector/manifests/03-rag/docs-embedder.yaml | kubectl -n pg-ns apply -f -Weaviate
sed "s|<DOCKER_REPO>|$DOCKER_REPO|" weaviate/manifests/04-rag/chatbot.yaml | kubectl -n weaviate apply -f - sed "s|<DOCKER_REPO>|$DOCKER_REPO|" weaviate/manifests/04-rag/docs-embedder.yaml | kubectl -n weaviate apply -f -為 GKE 啟用 Eventarc 觸發條件:
gcloud eventarc gke-destinations init系統顯示提示訊息時,請輸入
y。使用 Terraform 部署 Cloud Storage bucket,並建立 Eventarc 觸發條件:
export GOOGLE_OAUTH_ACCESS_TOKEN=$(gcloud auth print-access-token) terraform -chdir=vector-database/terraform/cloud-storage init terraform -chdir=vector-database/terraform/cloud-storage apply \ -var project_id=${PROJECT_ID} \ -var region=${REGION} \ -var cluster_prefix=${KUBERNETES_CLUSTER_PREFIX} \ -var db_namespace=${DB_NAMESPACE}系統顯示提示訊息時,請輸入
yes。指令執行後,可能需要幾分鐘的時間才能完成。Terraform 會建立下列資源:
- 用於上傳文件的 Cloud Storage bucket
- Eventarc 觸發條件
- 有權使用 Eventarc 的 Google Cloud 服務帳戶
service_account_eventarc_name。 - 具備讀取 bucket 權限和存取 Vertex AI 模型權限的服務帳戶。 Google Cloud
service_account_bucket_name
輸出結果會與下列內容相似:
... # Several lines of output omitted Apply complete! Resources: 15 added, 0 changed, 0 destroyed. ... # Several lines of output omitted
載入文件並執行 Chatbot 查詢
上傳示範文件並執行查詢,使用聊天機器人搜尋示範文件:
將範例
carbon-free-energy.pdf文件上傳至值區:gcloud storage cp vector-database/documents/carbon-free-energy.pdf gs://${PROJECT_ID}-${KUBERNETES_CLUSTER_PREFIX}-training-docs確認文件嵌入器工作已順利完成:
kubectl get job -n ${DB_NAMESPACE}輸出結果會與下列內容相似:
NAME COMPLETIONS DURATION AGE docs-embedder1716570453361446 1/1 32s 71s取得負載平衡器的外部 IP 位址:
export EXTERNAL_IP=$(kubectl -n ${DB_NAMESPACE} get svc chatbot --output jsonpath='{.status.loadBalancer.ingress[0].ip}') echo http://${EXTERNAL_IP}:80在網路瀏覽器中開啟外部 IP 位址:
http://EXTERNAL_IP聊天機器人會傳回類似下列內容的訊息:
How can I help you?詢問上傳文件內容相關問題。如果找不到任何內容,聊天機器人會回答
I don't know。舉例來說,你可以詢問下列問題:You: Hi, what are Google plans for the future?聊天機器人的輸出內容範例如下:
Bot: Google intends to run on carbon-free energy everywhere, at all times by 2030. To achieve this, it will rely on a combination of renewable energy sources, such as wind and solar, and carbon-free technologies, such as battery storage.向聊天機器人詢問與上傳文件內容無關的問題。 例如,你可以提出下列要求:
You: What are Google plans to colonize Mars?聊天機器人的輸出內容範例如下:
Bot: I don't know. The provided context does not mention anything about Google's plans to colonize Mars.
關於應用程式程式碼
本節將說明應用程式程式碼的運作方式。Docker 映像檔內有三個指令碼:
endpoint.py:接收每個文件上傳作業的 Eventarc 事件,並啟動 Kubernetes Jobs 來處理這些事件。embedding-job.py:從 bucket 下載文件、建立嵌入項目,並將嵌入項目插入向量資料庫。chat.py:對儲存的文件內容執行查詢。
下圖顯示使用文件資料生成答案的過程:
在圖表中,應用程式會載入 PDF 檔案、將檔案分割為分塊,然後轉換為向量,再將向量傳送至向量資料庫。稍後,使用者向聊天機器人提出問題。RAG 鏈結會使用語意搜尋功能搜尋向量資料庫,然後將情境連同問題一併傳回給 LLM。LLM 會回答問題,並將問題儲存到對話記錄中。
關於「endpoint.py」
這個檔案會處理來自 Eventarc 的訊息、建立 Kubernetes Job 來嵌入文件,並接受通訊埠 5001 上任何位置的要求
Qdrant
Elasticsearch
PGVector
Weaviate
關於「embedding-job.py」
這個檔案會處理文件,並將文件傳送至向量資料庫。
Qdrant
Elasticsearch
PGVector
Weaviate
關於「chat.py」
這個檔案會將模型設定為僅使用提供的脈絡和先前的答案回答問題。如果內容或對話記錄與任何資料都不相符,模型會傳回 I don't know。
Qdrant
Elasticsearch
PGVector
Weaviate
清除所用資源
為避免因為本教學課程所用資源,導致系統向 Google Cloud 收取費用,請刪除含有相關資源的專案,或者保留專案但刪除個別資源。
刪除專案
如要避免付費,最簡單的方法就是刪除您為本教學課程建立的專案。
刪除 Google Cloud 專案:
gcloud projects delete PROJECT_ID
如果您已刪除專案,則清理作業完成。如果沒有刪除專案,請繼續刪除個別資源。
刪除個別資源
刪除 Artifact Registry 存放區:
gcloud artifacts repositories delete ${KUBERNETES_CLUSTER_PREFIX}-images \ --location=${REGION} \ --async系統顯示提示訊息時,請輸入
y。刪除 Cloud Storage bucket 和 Eventarc 觸發程序:
export GOOGLE_OAUTH_ACCESS_TOKEN=$(gcloud auth print-access-token) terraform -chdir=vector-database/terraform/cloud-storage destroy \ -var project_id=${PROJECT_ID} \ -var region=${REGION} \ -var cluster_prefix=${KUBERNETES_CLUSTER_PREFIX} \ -var db_namespace=${DB_NAMESPACE}系統顯示提示訊息時,請輸入
yes。建立和刪除端點時,Eventarc 都需要有效的端點目標。
後續步驟
- 瞭解在 GKE 上部署資料庫的最佳做法。
- 瞭解如何使用 GKE 執行資料密集型工作負載。