使用事件非同步叫用代理式 AI 應用程式

1. 簡介

總覽

本實驗室會示範如何使用 Eventarc 和 Pub/Sub 服務,安全地實作事件導向的 ADK 代理程式叫用作業,並將代理程式部署在 Cloud Run 上。代理程式通常是由使用者或另一個代理程式直接呼叫。不過,如果代理程式要整合到現有的事件型工作流程,直接呼叫就需要變更現有軟體。根據事件觸發代理程式呼叫,即可將代理程式併入現有工作流程,而不必變更工作流程。

學習內容

在本實驗室中,您將建立 ZooKeeper 代理程式應用程式,其中包含 AI 代理程式,並使用幾項工具提供虛構動物園的動物資訊。

動物園管理員插圖

您會將 ZooKeeper 應用程式部署為 Cloud Run 服務。Cloud Run 是全代管的無伺服器運算平台,可在 Google 基礎架構上執行無狀態容器。接著,您將設定 Eventarc 觸發條件,叫用服務端點,以非同步方式處理發布至 Pub/Sub 主題的訊息。您將確保部署作業遵循最佳做法,包括使用指定的 IAM 服務帳戶、授予最低權限存取權,以及只向 Eventarc 公開 ZooKeeper 應用程式的端點,盡量減少潛在的攻擊面。您將在 Cloud Shell 和 Cloud 控制台的協助下完成這項作業。您將使用 ADK 和 Python 適用的 Cloud SDK 程式庫。如要檢查行為,請使用 gcloud CLI。

課程內容

  • 將 ADK 代理程式部署至 Google Cloud Run。
  • 將 Eventarc 觸發條件與在 Google Cloud Run 上執行的 ADK 代理程式整合。
  • 使用 Google Cloud IAM 遵循最低權限存取原則,確保部署及整合 Eventarc 時的安全。
  • 將訊息發布至 Pub/Sub,以及從 Pub/Sub 提取訊息。
  • 盡量減少部署至 Google Cloud Run 的應用程式公開曝光。

軟硬體需求

  • Chrome 網路瀏覽器 †
  • 個人 Google 帳戶 ‡
  • 連結至有效帳單帳戶的 Google Cloud 專案

請注意,您的帳戶必須具備專案的 IAM 存取權,才能佈建資源及設定這些資源的 IAM 存取權。

使用其他瀏覽器時,使用者體驗可能與實驗室所述不同。

使用公司或學校帳戶時,可能無法執行實驗室中描述的部分操作。

2. 設定環境

為確保實驗室的開發環境能正常運作,您將使用Google Cloud Shell,其中已預先安裝所有必要工具。按照操作說明設定環境。

如果你沒有 Google 帳戶,請按這裡建立帳戶。

設定操作說明

  1. 使用 Google 帳戶登入 Google Cloud 控制台
  2. 👉 開啟頂端導覽列中的專案挑選器 (可能顯示「選取專案」或現有專案名稱),或按一下 Ctrl+O 鍵盤快速鍵,然後選擇現有專案或建立新專案。建立新專案需要幾秒鐘的時間。等待專案準備就緒,然後使用專案挑選器選取專案。
  1. 👉 點選 Google Cloud 控制台頂端的「Cloud Shell」圖示。(以紅色矩形標示):Cloud Shell 按鈕
    如果系統要求授權,請在彈出式對話方塊中按一下「授權」,允許 Cloud Shell 使用您帳戶的憑證。
    授權對話方塊
  2. 👉💻 確認 gcloud CLI 已設定為使用您選取 (或建立) 的專案。執行下列指令,檢查已設定的專案 ID:
    gcloud config get-value project
    
    您應該會看到類似以下的輸出內容:
    Your active configuration is: [cloudshell-19597]
    [PROJECT_ID]
    
    ,其中 [PROJECT_ID] 是您選取或建立的專案 ID。👉💻 如果看到其他值,請執行下列指令,將專案 ID 設定為 gcloud CLI 指令的預設專案 ID:
    gcloud config set project [YOUR_PROJECT_ID]
    
    舉例來說,如果專案 ID 是 lab-project-id-example-123,則指令應為:
    gcloud config set project lab-project-id-example-123
    
    🤔💻 如果您忘記專案 ID,請使用下列指令列出您有權存取的所有專案 ID,並從最近的專案開始:
    gcloud projects list \
        --format='value(projectId)' \
        --sort-by='~createTime'
    
  1. 👉💻 在環境變數中設定資源佈建位置,以及專案的 ID 和編號:
    export LOCATION="us-central1"
    export PROJECT_ID=$(gcloud config get-value project)
    export PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format="value(projectNumber)")
    
  2. 👉💻 啟用本實驗室所需的 Google API。
    gcloud services enable \
        aiplatform.googleapis.com \
        eventarc.googleapis.com \
        run.googleapis.com \
        artifactregistry.googleapis.com \
        cloudbuild.googleapis.com \
        pubsub.googleapis.com
    
    請耐心等候,這個指令可能需要幾分鐘才能完成。成功執行指令後,您應該會看到類似以下的訊息:
    Operation "operations/ab12345c-6e7f-8ghi-jkl9-m0e1d23456f7" finished successfully.
    

3. 部署 ZooKeeper 示範應用程式

下列步驟會佈建及設定資源,包括部署代理程式 AI 應用程式。

設定 Pub/Sub 資源

您將建立兩個 Pub/Sub 主題。其中一個會由第三方服務使用,將事件傳送至代理 AI 應用程式。另一個則用於發布事件處理結果。

  1. 👉💻 建立用於觸發代理程式 AI 應用程式的 Pub/Sub 主題:
    gcloud pubsub topics create invoke_agent
    export INVOKE_TOPIC_ID=$(gcloud pubsub topics describe invoke_agent --format="value(name)")
    
  2. 👉💻 建立 Pub/Sub 主題,供應用程式發布回覆:
    gcloud pubsub topics create agent_responses
    export RESPONSE_TOPIC_ID=$(gcloud pubsub topics describe agent_responses --format="value(name)")
    gcloud pubsub subscriptions create agent_responses \
        --topic=agent_responses
    
    這些指令也會為建立的 Pub/Sub 主題建立訂閱項目。執行試用版時,系統會使用訂閱方案來顯示結果。

設定服務帳戶和專案層級的身分與存取權管理政策

您將建立兩個服務帳戶,並遵循最低權限存取原則,將 Cloud Run 服務和 Eventarc 觸發程序的存取範圍限制在最低限度。Cloud Run 服務需要寫入記錄和追蹤記錄、在 Google Vertex AI 上呼叫 Gemini LLM,以及將結果發布至 Pub/Sub 主題的權限。Eventarc 觸發條件的最低存取權限,是呼叫 Cloud Run ZooKeeper 服務和存取 Pub/Sub 以讀取發布事件的權限。這些操作說明會引導您授予觸發程序的服務帳戶權限,以便模擬 Pub/Sub 系統服務。建立 Eventarc 觸發程序資源後,請執行指令授予 roles/run.invoker 角色,讓觸發程序的服務帳戶可以呼叫 Cloud Run 服務。

  1. 👉💻 為 Cloud Run 服務建立服務帳戶:
    gcloud iam service-accounts create zookeeper-cloudrun-sa
    export ZOOKEEPER_SA="zookeeper-cloudrun-sa@${PROJECT_ID}.iam.gserviceaccount.com"
    
  2. 👉💻 授予服務帳戶權限,以便在 Vertex AI 上寫入記錄和追蹤記錄,並使用 Gemini 模型:
    gcloud projects add-iam-policy-binding "${PROJECT_ID}" \
         --member="serviceAccount:${ZOOKEEPER_SA}" \
         --role="roles/logging.logWriter" \
         --condition=None
    gcloud projects add-iam-policy-binding "${PROJECT_ID}" \
        --member="serviceAccount:${ZOOKEEPER_SA}" \
        --role="roles/cloudtrace.agent" \
        --condition=None
    gcloud projects add-iam-policy-binding "${PROJECT_ID}" \
        --member="serviceAccount:${ZOOKEEPER_SA}" \
        --role="roles/aiplatform.user" \
        --condition=None
    
  3. 👉💻 授予服務帳戶將訊息發布至「agent_responses」主題的權限:
    gcloud pubsub topics add-iam-policy-binding agent_responses \
        --member="serviceAccount:${ZOOKEEPER_SA}" \
        --role="roles/pubsub.publisher"
    
  4. 👉💻 為 Eventarc 觸發條件建立服務帳戶:
    gcloud iam service-accounts create zookeeper-trigger-sa
    export TRIGGER_SA="zookeeper-trigger-sa@${PROJECT_ID}.iam.gserviceaccount.com"
    
  5. 👉💻 授予 Pub/Sub 系統服務帳戶權限,以發出經過驗證的推送要求:
    gcloud iam service-accounts add-iam-policy-binding "${TRIGGER_SA}" \
           --member="serviceAccount:service-${PROJECT_NUMBER}@gcp-sa-pubsub.iam.gserviceaccount.com" \
        --role="roles/iam.serviceAccountTokenCreator"
    
    如果專案是在 2021 年 4 月 8 日之後建立,則這個指令為選用

將 ZooKeeper 應用程式部署至 Cloud Run

您將從 GitHub 下載示範應用程式的程式碼。並將程式碼部署至 Cloud Run。

  1. 👉💻 下載代理式 AI 應用程式:
    mkdir zoo-keeper-lab && cd zoo-keeper-lab
    git init
    git remote add origin https://github.com/GoogleCloudPlatform/devrel-demos
    git config set core.sparseCheckout true
    echo "ai-ml/agent-labs/adk_invoke_with_pubsub/" >> .git/info/sparse-checkout
    git pull origin main --depth 1
    cd ai-ml/agent-labs/adk_invoke_with_pubsub/
    
    這些指令會使用含有示範應用程式的資料夾進行 Git 稀疏簽出,以縮短下載時間。
  2. 👉💻 將代理式 AI 應用程式部署至 Cloud Run:
    gcloud run deploy zookeeper-agent \
        --region="${LOCATION}" \
        --source="." \
        --no-allow-unauthenticated \
        --quiet \
        --service-account="${ZOOKEEPER_SA}" \
        --set-env-vars="REPLY_TOPIC_ID=${RESPONSE_TOPIC_ID}"
    

設定 Eventarc 觸發條件

準備好所有資源 (Pub/Sub 主題、IAM 服務帳戶和 Cloud Run 服務) 後,即可設定 Eventarc 觸發條件資源。您將建立 Eventarc 觸發程序資源,並將呼叫 Cloud Run 服務的權限授予觸發程序的服務帳戶。

  1. 👉💻 建立 Eventarc 觸發條件:
    gcloud eventarc triggers create invoke-agent \
        --location="${LOCATION}" \
        --destination-run-service="zookeeper-agent" \
        --destination-run-path="/zookeeper" \
        --destination-run-region="${LOCATION}" \
        --event-filters="type=google.cloud.pubsub.topic.v1.messagePublished" \
        --transport-topic="${INVOKE_TOPIC_ID}" \
        --service-account="${TRIGGER_SA}"
    
  2. 👉💻 將權限授予觸發程序的服務帳戶,以叫用 Cloud Run 服務:
    gcloud run services add-iam-policy-binding zookeeper-agent \
        --region="${LOCATION}" \
        --member="serviceAccount:${TRIGGER_SA}" \
        --role="roles/run.invoker"
    

4. 檢視解決方案的運作方式

現在請檢查您剛部署的內容。下圖顯示所有資源,以及這些資源之間的互動方式。您將使用 gcloud CLI 將訊息發布至「invoke_agent」主題。這會模擬第三方服務記錄到訊息服務的事件,以叫用代理程式 AI 應用程式。

解決方案圖表

部署作業會遵循最低權限原則,確保安全無虞。Cloud Run 服務會強制執行驗證 (請參閱上一節步驟 9 中的 --no-allow-unauthenticated 引數)。只有具備 roles/run.invoker 或類似權限的身分,才能呼叫服務。這個角色只會授予 Eventarc 觸發程序的服務帳戶。同樣地,我們也會盡量減少「invoke_agent」主題的存取權,禁止未經授權發布事件。您仍可直接呼叫 ZooKeeper 代理程式,略過發布至 Pub/Sub 主題的程序。請參閱第 6 節,瞭解如何隱藏應用程式端點,避免公開存取。

執行工作流程

您將在 ZooKeeper 中以自然語言發布問題,模擬外部事件。

👉💻 使用下列指令將訊息發布至 Pub/Sub 主題:

gcloud pubsub topics publish invoke_agent \
    --message='{"user_id": "important_app", "prompt": "How many animals are in the zoo?"}'

但實際上,事件資訊可能不會這麼容易閱讀。如要處理這類事件,代理程式 AI 應用程式必須具備詳細的指令,說明事件格式、資料,以及代理程式應如何處理事件資訊。

您可以確認代理程式是否收到事件、處理要求,並將回應發布至「agent_responses」主題。如要讀取回應,您將使用「agent_responses」訂閱項目 (本程式碼研究室的主題和回應訂閱項目使用相同的 ID)。

👉💻 使用下列指令,從 Pub/Sub 訂閱項目讀取代理程式的回覆:

gcloud pubsub subscriptions pull agent_responses --auto-ack

輸出內容會列印表格,其中包含訊息中繼資料和酬載,酬載則包含動物園有 33 種物種的答案。--auto-ack 旗標會在訊息擷取後自動確認訊息,因此不會再次傳送。

運作方式

開啟 Cloud Shell 編輯器,查看 ~/zoo-keeper-lab 資料夾下的檔案,即可查看代理程式 AI 應用程式的原始碼。您也可以在 GitHub 上查看原始碼。

  • main.py 會實作基本的 FastAPI 網頁應用程式,其中包含處理 Eventarc 事件的單一處理常式。
  • processor.py 會剖析事件的訊息,以擷取使用者 ID 和要求。接著,ADK 執行器會在 Zookeeper 代理程式中建立新工作階段,並呼叫該代理程式來處理要求。代理程式的回應會發布至「agent_responses」Pub/Sub 主題。
  • 子資料夾 zookeeper_agent 存放 ADK 代理的原始碼。您可以從應用程式的根資料夾執行 adk run zookeeper_agent 指令,使用 adk CLI 與代理程式互動。

如何排解問題

如果先前的任何指令失敗,請仔細閱讀錯誤訊息。如果部署至 Cloud Run 失敗,第一步是判斷程序失敗的階段。

  • 如果「gcloud run deploy...」指令的輸出內容指出建構作業失敗,請查看輸出內容中的建構記錄網址,並在另一個視窗中開啟該網址。
  • 如果輸出內容顯示「service failed to start」或類似訊息,表示服務已部署,但執行健康檢查時失敗。在本例中,請開啟記錄檔總管,或參閱下一個段落的 gcloud CLI 指令。請閱讀記錄檔,找出失敗的根本原因。

如果將訊息發布至 Pub/Sub 後,代理程式沒有回應或回應內容有異,該怎麼辦?

👉💻 使用下列指令讀取最近執行作業發布的應用程式記錄:

gcloud logging read \
    'resource.type = "cloud_run_revision" AND \
     resource.labels.service_name = "zookeeper-agent" AND \
     resource.labels.location = "us-central1"'

記錄檔會追蹤執行作業並回報錯誤,例如訊息酬載不正確或無法剖析、Gemini 模型的回應無效、環境設定無效,以及其他可能問題。

5. 強化部署作業安全性

您部署的 Cloud Run 服務會公開端點,網際網路上的任何人都能呼叫。雖然端點受到保護,可防止未經授權的叫用,並嚴格驗證要求結構,但仍會留下這個攻擊向量,導致阻斷服務和阻斷錢包攻擊。由於目前設計中,服務的唯一叫用路徑是透過 Eventarc 觸發條件,因此服務不需要將端點公開在網際網路上。

👉💻 限制服務的呼叫來源,只允許特定來源集合 (包括 Eventarc 觸發條件) 呼叫服務,即可封鎖這個攻擊媒介:

gcloud run services update zookeeper-agent --region=${LOCATION} --ingress=internal

現在,如果您嘗試從本機呼叫服務的網址,會收到「404 Page not found」錯誤。

👉💻 使用 curl 將要求傳送至服務端點:

URL=$(gcloud run services describe zookeeper-agent --region=${LOCATION} --format='value(status.url)')
curl -X POST -d '{}' "${URL}/zookeeper"

畫面會顯示類似以下的輸出:

<html><head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<title>404 Page not found</title>
</head>
<body text=#000000 bgcolor=#ffffff>
<h1>Error: Page not found</h1>
<h2>The requested URL was not found on this server.</h2>
<h2></h2>
</body></html>

完成這項變更後,除非從相同專案的虛擬私有雲、修訂版本設定要傳送流量的共用虛擬私有雲網路,或屬於 VPC Service Controls 範圍的主機發出呼叫,否則無法直接呼叫 Cloud Run 服務端點來叫用 ZooKeeper。

6. 摘要

恭喜!您已成功設定環境,可非同步叫用由傳入事件觸發的代理式 AI 應用程式。

清除所用資源

請注意,保留您佈建的資源可能會導致帳單帳戶產生費用。如果您不打算將這個環境用於更多實驗,建議您刪除在本程式碼研究室中建立的資源,以免產生後續費用。

方法有兩種:

方法 1:關閉專案

關閉 (刪除) 專案會釋出專案的所有資源和資料,並取消連結帳單帳戶。使用這個方法可避免系統針對本程式碼研究室所用的任何資源或資料,收取額外費用。使用下列指令關閉專案:

gcloud projects delete $(gcloud config get-value project) --quiet

方法 2:刪除專案中的資源

刪除 Cloud Run 服務可避免系統對無伺服器平台的使用情況收取後續費用。請注意,這個方法不會完全移除程式碼研究室期間產生的所有資料,例如 Cloud Build 和應用程式記錄、容器映像檔等。請執行下列指令來刪除服務:

gcloud run services delete zookeeper-agent --region=${LOCATION}

Eventarc 觸發條件定義和 Pub/Sub 主題不會產生管理費用 (詳情請參閱 Eventarc 定價Pub/Sub 定價)。

進一步瞭解如何關閉專案

後續步驟