1. บทนำ
ภาพรวม
ใน Codelab นี้ คุณจะได้ดูวิธีสร้างแชทบ็อตพื้นฐานที่เขียนในโหนดโดยใช้ Vertex AI Gemini API และไลบรารีไคลเอ็นต์ Vertex AI แอปนี้ใช้ร้านค้าเซสชันด่วนที่ได้รับการสนับสนุนโดย Google Cloud Firestore
สิ่งที่คุณจะได้เรียนรู้
- วิธีใช้ htmx, tailwindcss และ express.js เพื่อสร้างบริการ Cloud Run
- วิธีใช้ไลบรารีของไคลเอ็นต์ Vertex AI เพื่อตรวจสอบสิทธิ์กับ Google API
- วิธีสร้างแชทบ็อตเพื่อโต้ตอบกับโมเดล Gemini
- วิธีทำให้บริการ Cloud Run ใช้งานได้โดยไม่ต้องใช้ไฟล์ Docker
- วิธีใช้ที่เก็บเซสชันด่วนที่ได้รับการสนับสนุนจาก Google Cloud Firestore
2. การตั้งค่าและข้อกำหนด
ข้อกำหนดเบื้องต้น
- คุณเข้าสู่ระบบ Cloud Console แล้ว
- คุณได้ทำให้บริการ Cloud Run ใช้งานได้ก่อนหน้านี้ ตัวอย่างเช่น คุณทำตามวิธีทำให้บริการเว็บใช้งานได้จากการเริ่มต้นอย่างรวดเร็วสำหรับซอร์สโค้ดเพื่อเริ่มต้นใช้งาน
เปิดใช้งาน Cloud Shell
- คลิกเปิดใช้งาน Cloud Shell จาก Cloud Console
หากเริ่มต้นใช้งาน Cloud Shell เป็นครั้งแรก คุณจะเห็นหน้าจอตรงกลางที่อธิบายว่านี่คืออะไร หากระบบแสดงหน้าจอตรงกลาง ให้คลิกต่อไป
การจัดสรรและเชื่อมต่อกับ Cloud Shell ใช้เวลาเพียงไม่กี่นาที
เครื่องเสมือนนี้โหลดด้วยเครื่องมือการพัฒนาทั้งหมดที่จำเป็น โดยมีไดเรกทอรีหลักขนาด 5 GB ถาวรและทำงานใน Google Cloud ซึ่งช่วยเพิ่มประสิทธิภาพของเครือข่ายและการตรวจสอบสิทธิ์ได้อย่างมาก งานส่วนใหญ่ใน Codelab นี้สามารถทำได้โดยใช้เบราว์เซอร์
เมื่อเชื่อมต่อกับ Cloud Shell แล้ว คุณควรเห็นข้อความตรวจสอบสิทธิ์และโปรเจ็กต์ได้รับการตั้งค่าเป็นรหัสโปรเจ็กต์แล้ว
- เรียกใช้คำสั่งต่อไปนี้ใน Cloud Shell เพื่อยืนยันว่าคุณได้รับการตรวจสอบสิทธิ์แล้ว
gcloud auth list
เอาต์พุตจากคำสั่ง
Credentialed Accounts ACTIVE ACCOUNT * <my_account>@<my_domain.com> To set the active account, run: $ gcloud config set account `ACCOUNT`
- เรียกใช้คำสั่งต่อไปนี้ใน Cloud Shell เพื่อยืนยันว่าคำสั่ง gcloud รู้เกี่ยวกับโปรเจ็กต์ของคุณ
gcloud config list project
เอาต์พุตจากคำสั่ง
[core] project = <PROJECT_ID>
หากไม่ใช่ ให้ตั้งคำสั่งด้วยคำสั่งนี้
gcloud config set project <PROJECT_ID>
เอาต์พุตจากคำสั่ง
Updated property [core/project].
3. เปิดใช้ API และตั้งค่าตัวแปรสภาพแวดล้อม
เปิดใช้ API
ก่อนที่คุณจะเริ่มใช้ Codelab นี้ได้ คุณจะต้องเปิดใช้ API หลายรายการ Codelab นี้ต้องใช้ API ต่อไปนี้ คุณเปิดใช้ API เหล่านั้นได้โดยเรียกใช้คำสั่งต่อไปนี้
gcloud services enable run.googleapis.com \ cloudbuild.googleapis.com \ aiplatform.googleapis.com \ secretmanager.googleapis.com
ตั้งค่าตัวแปรสภาพแวดล้อม
คุณกำหนดตัวแปรสภาพแวดล้อมที่จะใช้ตลอดทั้ง Codelab ได้
PROJECT_ID=<YOUR_PROJECT_ID> REGION=<YOUR_REGION, e.g. us-central1> SERVICE=chat-with-gemini SERVICE_ACCOUNT="vertex-ai-caller" SERVICE_ACCOUNT_ADDRESS=$SERVICE_ACCOUNT@$PROJECT_ID.iam.gserviceaccount.com SECRET_ID="SESSION_SECRET"
4. สร้างและกำหนดค่าโปรเจ็กต์ Firebase
- ในคอนโซล Firebase ให้คลิกเพิ่มโปรเจ็กต์
- ป้อน <YOUR_PROJECT_ID> เพื่อเพิ่ม Firebase ไปยังหนึ่งในโปรเจ็กต์ Google Cloud ที่คุณมีอยู่
- หากได้รับข้อความแจ้ง ให้ตรวจสอบและยอมรับข้อกำหนดของ Firebase
- คลิกต่อไป
- คลิกยืนยันแผนเพื่อยืนยันแผนการเรียกเก็บเงินของ Firebase
- คุณเลือกที่จะเปิดใช้ Google Analytics สำหรับ Codelab หรือไม่ก็ได้
- คลิกเพิ่ม Firebase
- เมื่อสร้างโปรเจ็กต์แล้ว ให้คลิกต่อไป
- จากเมนู Build ให้คลิกฐานข้อมูล Firestore
- คลิกสร้างฐานข้อมูล
- เลือกภูมิภาคจากเมนูแบบเลื่อนลงสถานที่ แล้วคลิกถัดไป
- ใช้ค่าเริ่มต้นเริ่มต้นในโหมดใช้งานจริง จากนั้นคลิกสร้าง
5. สร้างบัญชีบริการ
Cloud Run จะใช้บัญชีบริการนี้เพื่อเรียกใช้ Vertex AI Gemini API บัญชีบริการนี้จะมีสิทธิ์ในการอ่านและเขียนใน Firestore รวมถึงอ่านข้อมูลลับจาก Secret Manager ด้วย
ก่อนอื่น ให้สร้างบัญชีบริการโดยเรียกใช้คำสั่งนี้
gcloud iam service-accounts create $SERVICE_ACCOUNT \ --display-name="Cloud Run to access Vertex AI APIs"
ประการที่ 2 ให้บทบาทผู้ใช้ Vertex AI แก่บัญชีบริการ
gcloud projects add-iam-policy-binding $PROJECT_ID \ --member serviceAccount:$SERVICE_ACCOUNT_ADDRESS \ --role=roles/aiplatform.user
ตอนนี้ ให้สร้างข้อมูลลับใน Secret Manager บริการ Cloud Run จะเข้าถึงข้อมูลลับนี้เป็นตัวแปรสภาพแวดล้อม ซึ่งจะได้รับการแก้ไขเมื่อเริ่มต้นอินสแตนซ์ ดูข้อมูลเพิ่มเติมเกี่ยวกับข้อมูลลับและ Cloud Run
gcloud secrets create $SECRET_ID --replication-policy="automatic" printf "keyboard-cat" | gcloud secrets versions add $SECRET_ID --data-file=-
และให้สิทธิ์เข้าถึงข้อมูลลับของเซสชันด่วนใน Secret Manager แก่บัญชีบริการ
gcloud secrets add-iam-policy-binding $SECRET_ID \ --member serviceAccount:$SERVICE_ACCOUNT_ADDRESS \ --role='roles/secretmanager.secretAccessor'
สุดท้าย ให้สิทธิ์การอ่านและเขียน Firestore แก่บัญชีบริการ
gcloud projects add-iam-policy-binding $PROJECT_ID \ --member serviceAccount:$SERVICE_ACCOUNT_ADDRESS \ --role=roles/datastore.user
6. สร้างบริการ Cloud Run
ขั้นแรก ให้สร้างไดเรกทอรีสำหรับซอร์สโค้ดและ cd ลงในไดเรกทอรีนั้น
mkdir chat-with-gemini && cd chat-with-gemini
จากนั้นสร้างไฟล์ package.json
ที่มีเนื้อหาต่อไปนี้
{ "name": "chat-with-gemini", "version": "1.0.0", "description": "", "main": "app.js", "scripts": { "start": "node app.js", "nodemon": "nodemon app.js", "cssdev": "npx tailwindcss -i ./input.css -o ./public/output.css --watch", "tailwind": "npx tailwindcss -i ./input.css -o ./public/output.css", "dev": "npm run tailwind && npm run nodemon" }, "keywords": [], "author": "", "license": "ISC", "dependencies": { "@google-cloud/connect-firestore": "^3.0.0", "@google-cloud/firestore": "^7.5.0", "@google-cloud/vertexai": "^0.4.0", "axios": "^1.6.8", "express": "^4.18.2", "express-session": "^1.18.0", "express-ws": "^5.0.2", "htmx.org": "^1.9.10" }, "devDependencies": { "nodemon": "^3.1.0", "tailwindcss": "^3.4.1" } }
จากนั้นสร้างไฟล์ต้นฉบับ app.js
ที่มีเนื้อหาด้านล่าง ไฟล์นี้ประกอบด้วยจุดแรกเข้าสำหรับบริการและประกอบด้วยตรรกะหลักสำหรับแอป
const express = require("express"); const app = express(); app.use(express.urlencoded({ extended: true })); app.use(express.json()); const path = require("path"); const fs = require("fs"); const util = require("util"); const { spinnerSvg } = require("./spinnerSvg.js"); // cloud run retrieves secret at instance startup time const secret = process.env.SESSION_SECRET; const { Firestore } = require("@google-cloud/firestore"); const { FirestoreStore } = require("@google-cloud/connect-firestore"); var session = require("express-session"); app.set("trust proxy", 1); // trust first proxy app.use( session({ store: new FirestoreStore({ dataset: new Firestore(), kind: "express-sessions" }), secret: secret, /* set secure to false for local dev session history testing */ /* see more at https://expressjs.com/en/resources/middleware/session.html */ cookie: { secure: true }, resave: false, saveUninitialized: true }) ); const expressWs = require("express-ws")(app); app.use(express.static("public")); // Vertex AI Section const { VertexAI } = require("@google-cloud/vertexai"); // instance of Vertex model let generativeModel; // on startup const port = parseInt(process.env.PORT) || 8080; app.listen(port, async () => { console.log(`demo1: listening on port ${port}`); // get project and location from metadata service const metadataService = require("./metadataService.js"); const project = await metadataService.getProjectId(); const location = await metadataService.getRegion(); // Vertex client library instance const vertex_ai = new VertexAI({ project: project, location: location }); // Instantiate models generativeModel = vertex_ai.getGenerativeModel({ model: "gemini-1.0-pro-001" }); }); app.ws("/sendMessage", async function (ws, req) { if (!req.session.chathistory || req.session.chathistory.length == 0) { req.session.chathistory = []; } let chatWithModel = generativeModel.startChat({ history: req.session.chathistory }); ws.on("message", async function (message) { console.log("req.sessionID: ", req.sessionID); // get session id let questionToAsk = JSON.parse(message).message; console.log("WebSocket message: " + questionToAsk); ws.send(`<div hx-swap-oob="beforeend:#toupdate"><div id="questionToAsk" class="text-black m-2 text-right border p-2 rounded-lg ml-24"> ${questionToAsk} </div></div>`); // to simulate a natural pause in conversation await sleep(500); // get timestamp for div to replace const now = "fromGemini" + Date.now(); ws.send(`<div hx-swap-oob="beforeend:#toupdate"><div id=${now} class=" text-blue-400 m-2 text-left border p-2 rounded-lg mr-24"> ${spinnerSvg} </div></div>`); const results = await chatWithModel.sendMessage(questionToAsk); const answer = results.response.candidates[0].content.parts[0].text; ws.send(`<div id=${now} hx-swap-oob="true" hx-swap="outerHTML" class="text-blue-400 m-2 text-left border p-2 rounded-lg mr-24"> ${answer} </div>`); // save to current chat history let userHistory = { role: "user", parts: [{ text: questionToAsk }] }; let modelHistory = { role: "model", parts: [{ text: answer }] }; req.session.chathistory.push(userHistory); req.session.chathistory.push(modelHistory); // console.log( // "newly saved chat history: ", // util.inspect(req.session.chathistory, { // showHidden: false, // depth: null, // colors: true // }) // ); req.session.save(); }); ws.on("close", () => { console.log("WebSocket was closed"); }); }); function sleep(ms) { return new Promise((resolve) => { setTimeout(resolve, ms); }); } // gracefully close the web sockets process.on("SIGTERM", () => { server.close(); });
สร้างไฟล์ tailwind.config.js
สำหรับ tailwindCSS
/** @type {import('tailwindcss').Config} */ module.exports = { content: ["./**/*.{html,js}"], theme: { extend: {} }, plugins: [] };
สร้างไฟล์ metadataService.js
เพื่อรับรหัสโปรเจ็กต์และภูมิภาคสำหรับบริการ Cloud Run ที่ทำให้ใช้งานได้แล้ว ระบบจะใช้ค่าเหล่านี้เพื่อสร้างอินสแตนซ์ของไลบรารีไคลเอ็นต์ Vertex AI
const your_project_id = "YOUR_PROJECT_ID"; const your_region = "YOUR_REGION"; const axios = require("axios"); module.exports = { getProjectId: async () => { let project = ""; try { // Fetch the token to make a GCF to GCF call const response = await axios.get( "http://metadata.google.internal/computeMetadata/v1/project/project-id", { headers: { "Metadata-Flavor": "Google" } } ); if (response.data == "") { // running locally on Cloud Shell project = your_project_id; } else { // running on Clodu Run. Use project id from metadata service project = response.data; } } catch (ex) { // running locally on local terminal project = your_project_id; } return project; }, getRegion: async () => { let region = ""; try { // Fetch the token to make a GCF to GCF call const response = await axios.get( "http://metadata.google.internal/computeMetadata/v1/instance/region", { headers: { "Metadata-Flavor": "Google" } } ); if (response.data == "") { // running locally on Cloud Shell region = your_region; } else { // running on Clodu Run. Use region from metadata service let regionFull = response.data; const index = regionFull.lastIndexOf("/"); region = regionFull.substring(index + 1); } } catch (ex) { // running locally on local terminal region = your_region; } return region; } };
สร้างไฟล์ชื่อ spinnerSvg.js
module.exports.spinnerSvg = `<svg class="animate-spin -ml-1 mr-3 h-5 w-5 text-blue-500" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" > <circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4" ></circle> <path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z" ></path></svg>`;
สุดท้าย ให้สร้างไฟล์ input.css
สำหรับ tailwindCSS
@tailwind base; @tailwind components; @tailwind utilities;
จากนั้นสร้างไดเรกทอรี public
ใหม่
mkdir public cd public
และภายในไดเรกทอรีสาธารณะนั้น ให้สร้างไฟล์ index.html
สำหรับส่วนหน้า ซึ่งจะใช้ htmx
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <script src="https://unpkg.com/htmx.org@1.9.10" integrity="sha384-D1Kt99CQMDuVetoL1lrYwg5t+9QdHe7NLX/SoJYkXDFfX37iInKRy5xLSi8nO7UC" crossorigin="anonymous" ></script> <link href="./output.css" rel="stylesheet" /> <script src="https://unpkg.com/htmx.org/dist/ext/ws.js"></script> <title>Demo 1</title> </head> <body> <div id="herewego" text-center> <!-- <div id="replaceme2" hx-swap-oob="true">Hello world</div> --> <div class="container mx-auto mt-8 text-center max-w-screen-lg" > <div class="overflow-y-scroll bg-white p-2 border h-[500px] space-y-4 rounded-lg m-auto" > <div id="toupdate"></div> </div> <form hx-trigger="submit, keyup[keyCode==13] from:body" hx-ext="ws" ws-connect="/sendMessage" ws-send="" hx-on="htmx:wsAfterSend: document.getElementById('message').value = ''" > <div class="mb-6 mt-6 flex gap-4"> <textarea rows="2" type="text" id="message" name="message" class="block grow rounded-lg border p-6 resize-none" required > Is C# a programming language or a musical note?</textarea > <button type="submit" class="bg-blue-500 text-white px-4 py-2 rounded-lg text-center text-sm font-medium" > Send </button> </div> </form> </div> </div> </body> </html>
7. เรียกใช้บริการในเครื่อง
ก่อนอื่น ให้ตรวจสอบว่าคุณอยู่ในไดเรกทอรีราก chat-with-gemini
ของ Codelab
cd .. && pwd
ถัดไป ให้ติดตั้งการอ้างอิงโดยเรียกใช้คำสั่งต่อไปนี้
npm install
การใช้ ADC เมื่อทำงานในเครื่อง
หากคุณเรียกใช้ใน Cloud Shell ก็หมายความว่าคุณกำลังทำงานบนเครื่องเสมือนของ Google Compute Engine อยู่แล้ว ข้อมูลเข้าสู่ระบบเริ่มต้นของแอปพลิเคชันจะใช้ข้อมูลเข้าสู่ระบบของคุณที่เชื่อมโยงกับเครื่องเสมือนนี้ (ตามที่แสดงโดยการเรียกใช้ gcloud auth list
) โดยอัตโนมัติ ดังนั้นจึงไม่จำเป็นต้องใช้คำสั่ง gcloud auth application-default login
คุณสามารถข้ามไปยังส่วน Create a local session Secret
แต่หากคุณกำลังทำงานบนเทอร์มินัลในเครื่อง (ไม่ใช่ใน Cloud Shell) คุณจะต้องใช้ข้อมูลเข้าสู่ระบบเริ่มต้นของแอปพลิเคชันเพื่อตรวจสอบสิทธิ์ Google APIs 1) เข้าสู่ระบบโดยใช้ข้อมูลเข้าสู่ระบบ (ในกรณีที่คุณมีทั้งบทบาทผู้ใช้ Vertex AI และพื้นที่เก็บข้อมูล) หรือ 2) คุณเข้าสู่ระบบได้โดยแอบอ้างบัญชีบริการที่ใช้ใน Codelab นี้
ตัวเลือกที่ 1) การใช้ข้อมูลเข้าสู่ระบบสำหรับ ADC
หากต้องการใช้ข้อมูลเข้าสู่ระบบ ให้เรียกใช้ gcloud auth list
เพื่อยืนยันวิธีตรวจสอบสิทธิ์ใน gcloud ก่อน ถัดไป คุณอาจต้องมอบบทบาทผู้ใช้ Vertex AI ให้กับข้อมูลระบุตัวตนของคุณ หากข้อมูลประจำตัวของคุณมีบทบาทเจ้าของ แสดงว่าคุณมีบทบาทของผู้ใช้ Vertex AI นี้อยู่แล้ว หากไม่มี ให้เรียกใช้คำสั่งนี้เพื่อมอบบทบาทของผู้ใช้ Vertex AI และบทบาทผู้ใช้ Datastore
USER=<YOUR_PRINCIPAL_EMAIL> gcloud projects add-iam-policy-binding $PROJECT_ID \ --member user:$USER \ --role=roles/aiplatform.user gcloud projects add-iam-policy-binding $PROJECT_ID \ --member user:$USER \ --role=roles/datastore.user
จากนั้นเรียกใช้คำสั่งต่อไปนี้
gcloud auth application-default login
ตัวเลือกที่ 2) การแอบอ้างเป็นบัญชีบริการสำหรับ ADC
หากต้องการใช้บัญชีบริการที่สร้างใน Codelab นี้ บัญชีผู้ใช้ของคุณจะต้องมีบทบาทผู้สร้างโทเค็นบัญชีบริการ คุณสามารถรับบทบาทนี้ได้โดยการเรียกใช้คำสั่งต่อไปนี้:
gcloud projects add-iam-policy-binding $PROJECT_ID \ --member user:$USER \ --role=roles/iam.serviceAccountTokenCreator
ถัดไป คุณจะต้องเรียกใช้คำสั่งต่อไปนี้เพื่อใช้ ADC กับบัญชีบริการ
gcloud auth application-default login --impersonate-service-account=$SERVICE_ACCOUNT_ADDRESS
สร้างรหัสลับเซสชันในเครื่อง
สร้างข้อมูลลับของเซสชันในเครื่องสำหรับการพัฒนาในเครื่องได้เลย
export SESSION_SECRET=local-secret
เรียกใช้แอปในเครื่อง
สุดท้าย คุณสามารถเริ่มแอปได้โดยเรียกใช้สคริปต์ต่อไปนี้ สคริปต์นี้จะสร้างไฟล์ Export.css จาก tailwindCSS ด้วย
npm run dev
คุณดูตัวอย่างเว็บไซต์ได้โดยเปิดปุ่ม "แสดงตัวอย่างเว็บ" แล้วเลือก "แสดงตัวอย่างพอร์ต 8080"
8. ทำให้บริการใช้งานได้
ก่อนอื่นให้เรียกใช้คำสั่งนี้เพื่อเริ่มการทำให้ใช้งานได้และระบุบัญชีบริการที่จะใช้ หากไม่ได้ระบุบัญชีบริการ ระบบจะใช้บัญชีบริการประมวลผลเริ่มต้น
gcloud run deploy $SERVICE \ --service-account $SERVICE_ACCOUNT_ADDRESS \ --source . \ --region $REGION \ --allow-unauthenticated \ --set-secrets="SESSION_SECRET=$(echo $SECRET_ID):1"
หากระบบแจ้งว่า "การทำให้ใช้งานได้จากต้นทางต้องใช้ที่เก็บ Artifact Registry Docker เพื่อจัดเก็บคอนเทนเนอร์ที่สร้างขึ้น ระบบจะสร้างที่เก็บชื่อ [cloud-run-source-deploy] ในภูมิภาค [us-central1]" ให้กด "y" เพื่อยอมรับและดำเนินการต่อ
9. ทดสอบบริการ
เมื่อติดตั้งใช้งานแล้ว ให้เปิด URL ของบริการในเว็บเบราว์เซอร์ จากนั้นถามคำถาม Gemini เช่น "ฉันฝึกเล่นกีตาร์ แต่ก็เป็นวิศวกรซอฟต์แวร์ด้วย เมื่อเห็น "C#" ให้นึกว่าเป็นภาษาโปรแกรมหรือโน้ตดนตรี ฉันควรเลือกอันไหน"
10. ยินดีด้วย
ขอแสดงความยินดีที่เรียน Codelab จนจบ
เราขอแนะนำให้ดูเอกสารประกอบ Cloud Run และ Vertex AI Gemini API
หัวข้อที่ครอบคลุม
- วิธีใช้ htmx, tailwindcss และ express.js เพื่อสร้างบริการ Cloud Run
- วิธีใช้ไลบรารีของไคลเอ็นต์ Vertex AI เพื่อตรวจสอบสิทธิ์กับ Google API
- วิธีสร้างแชทบ็อตเพื่อโต้ตอบกับโมเดล Gemini
- วิธีทำให้บริการ Cloud Run ใช้งานได้โดยไม่ต้องใช้ไฟล์ Docker
- วิธีใช้ที่เก็บเซสชันด่วนที่ได้รับการสนับสนุนจาก Google Cloud Firestore
11. ล้างข้อมูล
เพื่อหลีกเลี่ยงการเรียกเก็บเงินที่ไม่ตั้งใจ (เช่น หากมีการเรียกใช้บริการ Cloud Run โดยไม่ได้ตั้งใจมากกว่าการจัดสรรการเรียกใช้ Cloud Run รายเดือนในรุ่นฟรี) คุณจะลบ Cloud Run หรือลบโปรเจ็กต์ที่สร้างไว้ในขั้นตอนที่ 2 ก็ได้
หากต้องการลบบริการ Cloud Run ให้ไปที่ Cloud Console ของ Cloud Run ที่ https://console.cloud.google.com/run แล้วลบบริการ chat-with-gemini
นอกจากนี้ คุณอาจต้องลบบัญชีบริการ vertex-ai-caller
หรือเพิกถอนบทบาทผู้ใช้ Vertex AI เพื่อหลีกเลี่ยงการเรียกใช้ Gemini โดยไม่ตั้งใจ
หากเลือกลบทั้งโปรเจ็กต์ ให้ไปที่ https://console.cloud.google.com/cloud-resource-manager เลือกโปรเจ็กต์ที่คุณสร้างในขั้นตอนที่ 2 แล้วเลือกลบ หากลบโปรเจ็กต์ คุณจะต้องเปลี่ยนโปรเจ็กต์ใน Cloud SDK คุณสามารถดูรายการโปรเจ็กต์ที่ใช้ได้ทั้งหมดโดยเรียกใช้ gcloud projects list