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

1. 總覽

首次部署網頁應用程式可能會讓您感到困惑,即使在首次部署後,如果程序的工作量太大,您可能會避免部署應用程式的新版本。透過持續部署功能,您可以輕鬆自動部署應用程式變更。

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

學習目標

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

2. 先決條件

  1. 如果您還沒有 Google 帳戶,請務必建立 Google 帳戶
    • 請改用個人帳戶,不要使用公司或學校帳戶。工作和學校帳戶可能有限制,導致您無法啟用本實驗室所需的 API。
  2. 如果您還沒有 GitHub 帳戶,請務必建立 GitHub 帳戶
    • 如果您已有 GitHub 帳戶,請使用該帳戶。GitHub 更有可能將新帳戶視為垃圾內容而封鎖。
    • 為 GitHub 帳戶設定雙重驗證,降低帳戶被標示為垃圾內容的機率。

3. 專案設定

  1. 登入 Google Cloud 控制台
  2. 在 Cloud 控制台中啟用帳單
    • 完成本研究室所需的 Cloud 資源費用應低於 $1 美元。
    • 您可以按照本實驗室課程結尾的步驟刪除資源,避免產生其他費用。
    • 新使用者可享有價值 $300 美元的免費試用期
    • 您是否參加「Gen AI for Devs」活動?你可能會獲得 $1 美元的抵免額
  3. 建立新專案或選擇重複使用現有專案。

4. 開啟 Cloud Shell 編輯器

  1. 前往 Cloud Shell 編輯器
  2. 如果終端機未顯示在畫面底部,請開啟:
    • 按一下漢堡選單 漢堡選單圖示
    • 按一下「Terminal」
    • 按一下「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. 按一下「授權 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. 建立名為 codelab-genai 的空白 GitHub 存放區:
    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. 按一下「連結存放區」
  5. 按一下「Set up with 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 做為「存放區」
        • 如果沒有存放區,請按一下「管理已連結的存放區」連結。
      • 將「Branch」保留為 ^main$
      • 按一下「透過 Google Cloud 的 Buildpacks 使用」Go、Node.js、Python、Java、.NET Core、Ruby 或 PHP
        • 其他欄位 (Build context directoryEntrypointFunction target) 則保留預設值。
      • 點選「儲存」
  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 用量

您可以稽核 Vertex AI 作業,這與其他 Google Cloud 服務相同。稽核記錄可協助您回答「從事活動的人員、內容、地點及時間為何?」Vertex AI 的管理稽核記錄預設為啟用。如要稽核產生內容的要求,請啟用資料存取稽核記錄

  1. 在 Google Cloud 控制台中,前往「Audit Logs」頁面:

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

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

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

  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 中的記錄代理程式會擷取輸出內容,並將此格式寫入 Cloud Logging。stdout
  5. 重新開啟 Cloud Shell,然後輸入下列指令,確認您位於正確的目錄:
    cd ~/codelab-genai
    
  6. 提交變更:
    git commit -am "Observe generated content"
    
  7. 將變更推送至 GitHub,觸發修改版本的重新部署作業:
    git push
    

新版本部署完成後,您可以查看 Vertex AI 呼叫的偵錯資訊。

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

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

  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

您也可以從雲端磁碟中刪除不必要的資源。您可以:

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

16. 恭喜

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

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

如有意參與使用者體驗 (UX) 研究,協助改善您目前使用的產品,請按這裡註冊。

以下提供一些繼續學習的選項: