1. บทนำ
ภาพรวม
ใน Codelab นี้ คุณจะได้ดูวิธีสร้างแชทบ็อตพื้นฐานที่เขียนด้วย Node โดยใช้ Vertex AI Gemini API และไลบรารีของไคลเอ็นต์ Vertex AI แอปนี้ใช้ที่เก็บเซสชันด่วนที่ได้รับการสนับสนุนโดย Google Cloud Firestore
สิ่งที่คุณจะได้เรียนรู้
- วิธีใช้ htmx, tailwindcss และ express.js เพื่อสร้างบริการ Cloud Run
- วิธีใช้ไลบรารีของไคลเอ็นต์ Vertex AI เพื่อตรวจสอบสิทธิ์กับ Google API
- วิธีสร้างแชทบ็อตเพื่อโต้ตอบกับโมเดล Gemini
- วิธีทำให้บริการ Cloud Run ใช้งานได้โดยไม่ต้องใช้ Dockerfile
- วิธีใช้ที่เก็บเซสชันด่วนที่ขับเคลื่อนโดย Google Cloud Firestore
2. การตั้งค่าและข้อกำหนด
ข้อกำหนดเบื้องต้น
- คุณเข้าสู่ระบบ Cloud Console แล้ว
- คุณเคยทำให้บริการ Cloud Run ใช้งานได้แล้ว เช่น คุณสามารถทำตามคู่มือเริ่มใช้งานฉบับย่อการทำให้ใช้งานได้บริการเว็บจากซอร์สโค้ดเพื่อเริ่มต้นใช้งาน
เปิดใช้งาน Cloud Shell
- จาก Cloud Console ให้คลิกเปิดใช้งาน Cloud Shell


หากคุณเริ่มใช้ Cloud Shell เป็นครั้งแรก คุณจะเห็นหน้าจอระดับกลางที่อธิบายว่า 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
ตั้งค่าตัวแปรสภาพแวดล้อม
คุณตั้งค่าตัวแปรสภาพแวดล้อมที่จะใช้ตลอดทั้งโค้ดแล็บนี้ได้
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
- เมื่อสร้างโปรเจ็กต์แล้ว ให้คลิกต่อไป
- จากเมนูสร้าง คลิกฐานข้อมูล 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 สำหรับโค้ดแล็บ
cd .. && pwd
จากนั้นติดตั้งการอ้างอิงโดยเรียกใช้คำสั่งต่อไปนี้
npm install
การใช้ ADC เมื่อเรียกใช้ในเครื่อง
หากคุณใช้งานใน Cloud Shell แสดงว่าคุณกำลังใช้งานเครื่องเสมือนของ Google Compute Engine อยู่แล้ว ข้อมูลรับรองที่เชื่อมโยงกับเครื่องเสมือนนี้ (ตามที่แสดงโดยการเรียกใช้ gcloud auth list) จะถูกใช้โดยข้อมูลรับรองเริ่มต้นของแอปพลิเคชันโดยอัตโนมัติ จึงไม่จำเป็นต้องใช้คำสั่ง gcloud auth application-default login คุณข้ามไปยังส่วนสร้างลับเซสชันในเครื่องได้
อย่างไรก็ตาม หากคุณเรียกใช้ในเทอร์มินัลในเครื่อง (เช่น ไม่ได้อยู่ใน Cloud Shell) คุณจะต้องใช้ข้อมูลรับรองเริ่มต้นของแอปพลิเคชันเพื่อตรวจสอบสิทธิ์ใน Google APIs คุณสามารถ 1) เข้าสู่ระบบโดยใช้ข้อมูลเข้าสู่ระบบ (หากมีทั้งบทบาทผู้ใช้ Vertex AI และผู้ใช้ Datastore) หรือ 2) เข้าสู่ระบบโดยการแอบอ้างเป็นบัญชีบริการที่ใช้ในโค้ดแล็บนี้
ตัวเลือกที่ 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
เรียกใช้แอปในเครื่อง
สุดท้าย คุณสามารถเริ่มแอปได้โดยเรียกใช้สคริปต์ต่อไปนี้ นอกจากนี้ สคริปต์นี้จะสร้างไฟล์ output.css จาก tailwindCSS ด้วย
npm run dev
คุณสามารถดูตัวอย่างเว็บไซต์ได้โดยเปิดปุ่มแสดงตัวอย่างเว็บแล้วเลือกพอร์ตแสดงตัวอย่าง 8080

8. ติดตั้งใช้งานบริการ
ก่อนอื่น ให้เรียกใช้คำสั่งนี้เพื่อเริ่มการติดตั้งใช้งานและระบุบัญชีบริการที่จะใช้ หากไม่ได้ระบุบัญชีบริการ ระบบจะใช้บัญชีบริการ Compute เริ่มต้น
gcloud run deploy $SERVICE \ --service-account $SERVICE_ACCOUNT_ADDRESS \ --source . \ --region $REGION \ --allow-unauthenticated \ --set-secrets="SESSION_SECRET=$(echo $SECRET_ID):1"
หากระบบแจ้งว่า "การติดตั้งใช้งานจากแหล่งที่มาต้องใช้ที่เก็บ Docker ของ Artifact Registry เพื่อจัดเก็บคอนเทนเนอร์ที่สร้างขึ้น ระบบจะสร้างที่เก็บชื่อ [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 ใช้งานได้โดยไม่ต้องใช้ Dockerfile
- วิธีใช้ที่เก็บเซสชันด่วนที่ขับเคลื่อนโดย 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