自動將生成式 AI Go 網頁應用程式從版本控制部署至 Cloud Run

1. 總覽

首次部署網頁應用程式時可能會感到困難重重,即使完成首次部署,如果這個程序太過繁瑣,您可能會避免部署新版應用程式。透過持續部署,您可以輕鬆自動部署應用程式的變更。

在本實驗室中,您將編寫網路應用程式,並設定 Cloud Run,在應用程式的原始碼變更時自動部署應用程式。然後修改應用程式,並再次部署。

學習目標

  • 使用 Cloud Shell 編輯器編寫網頁應用程式
  • 在 GitHub 中儲存應用程式程式碼
  • 自動將應用程式部署至 Cloud Run
  • 使用 Vertex AI 在應用程式中加入生成式 AI

2. 必要條件

  1. 如果沒有 Google 帳戶,請先建立帳戶
    • 請改用個人帳戶,而非公司或學校帳戶。公司和學校帳戶可能設有限制,導致您無法啟用本實驗室所需的 API。
  2. 如果您還沒有 GitHub 帳戶,必須先建立帳戶
    • 如果有 GitHub 帳戶,可以直接使用。GitHub 比較可能將新帳戶視為垃圾內容帳戶並封鎖。
    • 設定雙重驗證的 GitHub 帳戶,較不容易被當成垃圾內容帳戶。

3. 專案設定

  1. 登入 Google Cloud 控制台
  2. 在 Cloud 控制台中啟用帳單
    • 完成本實驗室的 Cloud 資源費用應不到 $1 美元。
    • 您可以按照本實驗室結尾的步驟刪除資源,避免產生額外費用。
    • 新使用者可享有價值 $300 美元的免費試用期
    • 參加「Gen AI for Devs」活動?你可能可以獲得 $1 美元抵免額
  3. 建立新專案,或選擇重複使用現有專案。
  4. 確認 Cloud Billing 的「我的專案」
    • 如果新專案在「Billing account」欄中顯示 Billing is disabled,請按照下列步驟操作:
      1. 按一下「Actions」欄中的三點圖示
      2. 按一下「變更帳單」
      3. 選取要使用的帳單帳戶
    • 如果您參加的是「開發人員專用生成式 AI」活動,帳戶名稱可能為「Google Cloud Platform 試用帳單帳戶」

4. 開啟 Cloud Shell 編輯器

  1. 前往 Cloud Shell 編輯器
  2. 如果畫面底部未顯示終端機,請開啟終端機:
    • 按一下漢堡選單 漢堡選單圖示
    • 按一下「終端機」
    • 按一下「New Terminal」(新增終端機)在 Cloud Shell 編輯器中開啟新終端機
  3. 在終端機中,使用下列指令設定專案:
    • 格式:
      gcloud config set project [PROJECT_ID]
      
    • 範例:
      gcloud config set project lab-project-id-example
      
    • 如果忘記專案 ID,請按照下列步驟操作:
      • 您可以使用下列指令列出所有專案 ID:
        gcloud projects list | awk '/PROJECT_ID/{print $2}'
        
      在 Cloud Shell 編輯器終端機中設定專案 ID
  4. 如果系統提示您授權,請點選「授權」繼續操作。按一下即可授權 Cloud Shell
  5. 您應該會看到下列訊息:
    Updated property [core/project].
    
    如果看到 WARNING 並收到 Do you want to continue (Y/N)? 提示,表示您可能輸入了錯誤的專案 ID。按下 NEnter,然後再次嘗試執行 gcloud config set project 指令。

5. 啟用 API

在終端機中啟用 API:

gcloud services enable \
  run.googleapis.com \
  cloudbuild.googleapis.com \
  aiplatform.googleapis.com

這個指令可能需要幾分鐘才能完成,但最終應該會產生類似以下的成功訊息:

Operation "operations/acf.p2-73d90d00-47ee-447a-b600" finished successfully.

6. 設定 Git

  1. 設定全域 git 使用者電子郵件:
    git config --global user.email "you@example.com"
    
  2. 設定全域 git 使用者名稱:
    git config --global user.name "Your Name"
    
  3. 將全域 git 預設分支版本設為 main
    git config --global init.defaultBranch main
    

7. 編寫程式碼

如要以 Go 語言編寫應用程式,請按照下列步驟操作:

  1. 前往主目錄:
    cd ~
    
  2. 建立 codelab-genai 目錄:
    mkdir codelab-genai
    
  3. 請前往 codelab-genai 目錄:
    cd codelab-genai
    
  4. 初始化 go.mod 檔案,宣告模組:
    go mod init codelab-genai
    
  5. 建立 main.go 檔案:
    touch main.go
    
  6. 在 Cloud Shell 編輯器中開啟 main.go 檔案:
    cloudshell edit main.go
    
    畫面頂端現在應該會顯示空白檔案。您可以在這裡編輯這個 main.go 檔案。顯示代碼會出現在畫面頂端
  7. 編輯 main.go,然後將下列程式碼貼入其中:
    package main
    
    import (
        "fmt"
        "log"
        "net/http"
        "os"
    )
    
    func main() {
        http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
            fmt.Fprintln(w, "Hello, world!")
        })
    
        port := os.Getenv("PORT")
    
        if port == "" {
            port = "8080"
        }
        if err := http.ListenAndServe(":"+port, nil); err != nil {
            log.Fatal(err)
        }
    }
    
    幾秒後,Cloud Shell 編輯器就會自動儲存程式碼。這段程式碼會以「Hello world!」問候語回應 HTTP 要求。

應用程式的初始程式碼已完成,可以儲存在版本控制系統中。

8. 建立存放區

  1. 返回畫面底部的 Cloud Shell 終端機。
  2. 確認您仍位於正確的目錄:
    cd ~/codelab-genai
    
  3. 初始化 Git 存放區
    git init -b main
    
  4. 登入 GitHub CLI
    gh auth login
    
    按下 Enter 鍵接受預設選項,然後按照 GitHub CLI 工具中的指示操作,包括:
    1. 你想登入哪個帳戶? GitHub.com
    2. 您偏好使用哪種通訊協定,在這個主機上執行 Git 作業? HTTPS
    3. 是否要使用 GitHub 憑證驗證 Git?Y (如果沒有顯示這個選項,請略過。)
    4. 您要如何驗證 GitHub CLI? Login with a web browser
    5. 複製一次性驗證碼
    6. 開啟 https://github.com/login/device
    7. 貼上一次性代碼
    8. 按一下「Authorize github」(授權 GitHub)
    9. 完成登入
  5. 執行下列指令,確認您已登入:
    gh api user -q ".login"
    
    如已成功登入,輸出內容應為您的 GitHub 使用者名稱。
  6. 建立 GITHUB_USERNAME 變數
    GITHUB_USERNAME=$(gh api user -q ".login")
    
  7. 執行下列指令,確認已建立環境變數:
    echo ${GITHUB_USERNAME}
    
    如已成功建立變數,輸出內容應為您的 GitHub 使用者名稱。
  8. 建立空的 GitHub 存放區,並命名為 codelab-genai
    gh repo create codelab-genai --private
    
    如果收到這則錯誤訊息:
    GraphQL: Name already exists on this account (createRepository)
    
    這樣您就已經有名為「codelab-genai」的存放區。如要繼續本教學課程,有兩種方式:
  9. codelab-genai 存放區新增為遠端 origin
    git remote add origin https://github.com/${GITHUB_USERNAME}/codelab-genai
    

9. 分享代碼

  1. 確認您位於正確的目錄:
    cd ~/codelab-genai
    
  2. 將目前目錄中的所有檔案新增至這個提交:
    git add .
    
  3. 建立第一個修訂版本:
    git commit -m "add http server"
    
  4. 將提交內容推送至 origin 存放區的 main 分支版本:
    git push -u origin main
    

您可以執行這項指令,並前往產生的網址,在 GitHub 上查看應用程式程式碼:

echo -e "\n\nTo see your code, visit this URL:\n \
    https://github.com/${GITHUB_USERNAME}/codelab-genai/blob/main/main.go \n\n"

10. 設定自動部署

  1. 請讓 Cloud Shell 編輯器分頁保持開啟。稍後會再返回這個分頁。
  2. 在新分頁中前往 Cloud Run 頁面
  3. 在控制台中選取正確的 Google Cloud 專案 Google Cloud 控制台專案下拉式選單
  4. 按一下「CONNECT REPO」(連結存放區)
  5. 按一下「SET UP WITH CLOUD BUILD」(設定 Cloud Build)
    1. 選取「GitHub」做為「存放區供應商」
      • 如果尚未在瀏覽器中登入 GitHub 帳戶,請使用憑證登入。
    2. 依序點選「驗證」和「繼續」
    3. 登入後,Cloud Run 頁面會顯示「您的所有存放區均未安裝 GitHub 應用程式」訊息。
    4. 按一下「INSTALL GOOGLE CLOUD BUILD」按鈕。
      • 在「安裝設定」頁面中,選取「Only select repositories」,然後選擇透過 CLI 建立的「codelab-genai」存放區。
      • 按一下「安裝」
      • 注意:如果 GitHub 存放區數量眾多,載入作業可能需要幾分鐘的時間。
    5. 選取 your-user-name/codelab-genai 做為存放區
      • 如果沒有看到存放區,請按一下「管理已連結的存放區」連結。
    6. 將「Branch」(分支版本) 保留為 ^main$
    7. 按一下「Go、Node.js、Python、Java、.NET Core、Ruby 或 PHP (透過 Google Cloud 的 Buildpacks 使用)」
      • 其他欄位 (Build context directoryEntrypointFunction target) 則維持原狀。
    8. 按一下「儲存」
  6. 向下捲動至「驗證」
  7. 按一下「允許未經驗證的叫用」
  8. 按一下 [Create]

建構完成後 (需要幾分鐘),請執行這項指令並前往產生的網址,查看正在執行的應用程式:

echo -e "\n\nOnce the build finishes, visit your live application:\n \
    "$( \
        gcloud run services list | \
        grep codelab-genai | \
        awk '/URL/{print $2}' | \
        head -1 \
    )" \n\n"

11. 變更驗證碼

  1. 返回畫面底部的 Cloud Shell 終端機。
  2. 確認您仍位於正確的目錄:
    cd ~/codelab-genai
    
  3. 在 Cloud Shell 編輯器中重新開啟 main.go
    cloudshell edit main.go
    
  4. 安裝 Go 適用的 Vertex AI SDK:
    go get cloud.google.com/go/vertexai/genai
    
  5. 安裝 Go 的中繼資料程式庫,取得目前的專案 ID:
    go get cloud.google.com/go/compute/metadata
    
  6. main.go 檔案中的程式碼替換為:
    package main
    
    import (
        "context"
        "fmt"
        "log"
        "net/http"
        "os"
    
        "cloud.google.com/go/compute/metadata"
        "cloud.google.com/go/vertexai/genai"
    )
    
    func main() {
        ctx := context.Background()
        var projectId string
        var err error
        projectId = os.Getenv("GOOGLE_CLOUD_PROJECT")
        if projectId == "" {
            projectId, err = metadata.ProjectIDWithContext(ctx)
            if err != nil {
                return
            }
        }
        var client *genai.Client
        client, err = genai.NewClient(ctx, projectId, "us-central1")
        if err != nil {
            return
        }
        defer client.Close()
    
        model := client.GenerativeModel("gemini-1.5-flash-001")
    
        http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
            animal := r.URL.Query().Get("animal")
            if animal == "" {
                animal = "dog"
            }
    
            resp, err := model.GenerateContent(
                ctx,
                genai.Text(
                    fmt.Sprintf("Give me 10 fun facts about %s. Return the results as HTML without markdown backticks.", animal)),
            )
    
            if err != nil {
                w.WriteHeader(http.StatusServiceUnavailable)
                return
            }
    
            if len(resp.Candidates) > 0 && len(resp.Candidates[0].Content.Parts) > 0 {
                htmlContent := resp.Candidates[0].Content.Parts[0]
                w.Header().Set("Content-Type", "text/html; charset=utf-8")
                fmt.Fprint(w, htmlContent)
            }
        })
    
        port := os.Getenv("PORT")
    
        if port == "" {
            port = "8080"
        }
        if err := http.ListenAndServe(":"+port, nil); err != nil {
            log.Fatal(err)
        }
    }
    

12. 重新部署

  1. 確認您仍在 Cloud Shell 的正確目錄中:
    cd ~/codelab-genai
    
  2. 執行下列指令,將新版應用程式提交至本機 Git 存放區:
    git add .
    git commit -m "add latest changes"
    
  3. 將變更推送到 GitHub:
    git push
    
  4. 建構完成後,請執行下列指令並前往已部署的應用程式:
    echo -e "\n\nOnce the build finishes, visit your live application:\n \
        "$( \
            gcloud run services list | \
            grep codelab-genai | \
            awk '/URL/{print $2}' | \
            head -1 \
        )" \n\n"
    

建構作業可能需要幾分鐘才會完成,完成後您就能看到變更。

如要查看所有修訂版本的記錄,請前往:https://console.cloud.google.com/run/detail/us-central1/codelab-genai/revisions

13. (選用) 稽核 Vertex AI 使用情形

與其他 Google Cloud 服務一樣,您可以稽核 Vertex AI 作業。稽核記錄可協助您回答有關人事時地物的問題。Vertex AI 的管理稽核記錄預設為啟用。如要稽核生成內容的要求,請啟用資料存取稽核記錄

  1. 前往 Google Cloud 控制台的「稽核記錄」頁面:

    如果您是使用搜尋列尋找這個頁面,請選取子標題為「IAM & Admin」(IAM 與管理) 的結果
  2. 確認現有的 Google Cloud 專案是您建立 Cloud Run 應用程式的專案。
  3. 在「資料存取稽核記錄設定」表格中,找出「服務」欄並選取 Vertex AI API
  4. 在「記錄類型」分頁中,選取「資料存取稽核記錄」類型 Admin readData read
  5. 按一下 [儲存]

啟用後,您就能查看應用程式每次調用的稽核記錄。如要查看含有叫用詳細資料的稽核記錄,請按照下列步驟操作:

  1. 返回已部署的應用程式,然後重新整理頁面以觸發記錄。
  2. 前往 Google Cloud 控制台的「記錄檔探索工具」頁面:

  3. 在查詢視窗中輸入:
    LOG_ID("cloudaudit.googleapis.com%2Fdata_access")
    protoPayload.serviceName="aiplatform.googleapis.com"
    
  4. 點選「執行查詢」

稽核記錄會擷取 Vertex AI API 的使用情形,但無法觀察工作負載相關資料,例如提示或回應詳細資料。

14. (選用) 提高 AI 工作負載的可觀測性

稽核記錄不會擷取工作負載相關資訊。如要提高工作負載的可觀測性,您必須明確記錄這項資訊。您可以使用慣用的記錄架構來執行這項操作。下列步驟示範如何使用 Go 的結構化記錄程式庫。

  1. 在 Cloud Shell 編輯器中重新開啟 main.go
    cloudshell edit ~/codelab-genai/main.go
    
  2. 變更匯入區塊,加入 Go 的結構化記錄和 JSON 程式庫:
    import (
        "context"
        "encoding/json"
        "fmt"
        "log"
        "log/slog"
        "net/http"
        "os"
    
        "cloud.google.com/go/compute/metadata"
        "cloud.google.com/go/vertexai/genai"
    )
    
  3. 初始化 Vertex 用戶端後 (第 33 行),請新增下列程式碼行,初始化使用 Google Cloud Logging 適當欄位的結構化記錄器:
    opts := &slog.HandlerOptions{
    	Level: slog.LevelDebug,
    	ReplaceAttr: func(group []string, a slog.Attr) slog.Attr {
            if a.Key == slog.LevelKey {
                return slog.Attr{Key: "severity", Value: a.Value}
            }
            if a.Key == slog.MessageKey {
                return slog.Attr{Key: "message", Value: a.Value}
            }
            return slog.Attr{Key: a.Key, Value: a.Value}
    	},
    }
    
    jsonHandler := slog.NewJSONHandler(os.Stdout, opts)
    slog.SetDefault(slog.New(jsonHandler))
    
  4. 檢查 GenerateContent 的回應 (第 69 行) 後,在 if 區塊內新增下列幾行:
    jsonBytes, err := json.Marshal(resp)
    if err != nil {
        slog.Error("Failed to marshal response to JSON", "error", err)
    } else {
        jsonString := string(jsonBytes)
        slog.Debug("Complete response content", "json_response", jsonString)
    }
    
    這段程式碼會使用結構化記錄格式,將生成的內容相關資訊寫入 stdout。Cloud Run 中的記錄代理程式會擷取列印至 stdout 的輸出內容,並以這種格式寫入 Cloud Logging。
  5. 重新開啟 Cloud Shell,然後輸入下列指令,確認您位於正確的目錄:
    cd ~/codelab-genai
    
  6. 修訂變更:
    git commit -am "Observe generated content"
    
  7. 將變更推送至 GitHub,觸發修改版本的重新部署作業:
    git push
    

部署新版本後,您就能觀察對 Vertex AI 的呼叫相關偵錯資訊。

如要查看應用程式記錄,請按照下列步驟操作:

  1. 前往 Google Cloud 控制台的「記錄檔探索工具」頁面:

  2. 在查詢視窗中輸入:
    LOG_ID("run.googleapis.com%2Fstdout")
    severity=DEBUG
    
  3. 點選「執行查詢」

查詢結果會顯示含有提示和 Vertex AI 回覆的記錄,包括可用於監控安全做法的「安全評分」

15. (選用) 清除

不使用服務時,Cloud Run 不會收費,但您可能仍須支付在 Artifact Registry 中儲存容器映像檔的費用。您可以刪除 Cloud 專案,以免產生費用。刪除 Cloud 專案後,系統就會停止對專案使用的所有資源收取費用。

如要刪除專案,請按照下列步驟操作:

gcloud projects delete $GOOGLE_CLOUD_PROJECT

您也可以從 Cloud Shell 磁碟刪除不必要的資源。您可以:

  1. 刪除 Codelab 專案目錄:
    rm -rf ~/codelab-genai
    
  2. 清除可能不再需要的 Go 語言套件:
    cd ~
    go clean -modcache
    
  3. 警告!這項操作無法復原!如要刪除 Cloud Shell 中的所有內容來釋出空間,可以刪除整個主目錄。請務必將要保留的內容另存他處。
    sudo rm -rf $HOME
    

16. 恭喜

在本實驗室中,您編寫了網頁應用程式,並設定 Cloud Run,在應用程式的原始碼變更時自動部署應用程式。然後修改應用程式並重新部署。

如果你喜歡這項實驗室,可以嘗試使用其他程式設計語言或架構:

如要參與使用者體驗研究,協助我們改善您今天使用的產品,請按這裡註冊

以下提供幾種繼續學習的方式: