1. ภาพรวม
ยินดีต้อนรับสู่ "วันที่ 2" แม้ว่าการสร้างแอปและกด "เผยแพร่" จะเป็นเรื่องง่าย แต่การเข้าชมในโลกแห่งความเป็นจริงก็อาจทำให้เกิดข้อผิดพลาดในโลกแห่งความเป็นจริงได้ คุณสามารถสร้างฝูงเอเจนต์เฉพาะทางเพื่อจัดการการเชื่อมต่อการดำเนินงานให้คุณได้ แทนที่จะต้องเสียเวลาทั้งวันไปกับการจัดการ YAML หรือการค้นหาในบันทึก Codelab นี้แสดงให้เห็นว่าสแต็กแบบรวมของ Google Cloud (Eventarc, Cloud Run, Firestore, Cloud Build, BigQuery) ช่วยให้เอเจนต์ดึงข้อมูลลับ สตรีมบันทึก และแก้ไขปัญหาได้อย่างปลอดภัยได้ง่ายๆ โดยไม่ต้องดำเนินการใดๆ เพิ่มเติม

ใน Codelab นี้ คุณจะได้สร้าง DinoQuest ซึ่งเป็นเกมผจญภัยไดโนเสาร์ที่ขับเคลื่อนโดย Gemini ตั้งแต่ต้นจนจบ และเชื่อมต่อกับไปป์ไลน์ CI/CD ที่เป็น Agent อย่างเต็มรูปแบบ เมื่อจบหลักสูตร คุณจะได้รับสิ่งต่อไปนี้
- เว็บแอป DinoQuest ที่ใช้งานได้ซึ่งทำงานบน Cloud Run (ชื่อบริการ:
dinoquest) - ไปป์ไลน์การวิเคราะห์บันทึกที่สตรีมบันทึกของ Cloud Run ไปยัง BigQuery และสร้างแดชบอร์ดข้อมูลเชิงลึกเกี่ยวกับเกมแบบอินเทอร์แอกทีฟ
- Remediation Agent (
remediation-agent) - ADK Remediation Agent ที่ตรวจสอบข้อผิดพลาดของ Cloud Run และแก้ไขโดยอัตโนมัติ ซึ่งติดตั้งใช้งานเป็นบริการ Cloud Run ของตัวเองที่ทริกเกอร์โดย Eventarc - เอเจนต์ CI (
ci-agent) ที่อ่าน Diff ของ PR, กำหนดขอบเขตการทดสอบอย่างชาญฉลาด, สร้างอิมเมจ Docker ผ่าน Cloud Build และโพสต์สถานะคอมมิตกลับไปยัง GitHub - เอเจนต์ CD ที่ให้คะแนนความเสี่ยงในการติดตั้งใช้งาน แยกการเข้าชม ตรวจสอบเมตริก และโปรโมตหรือย้อนกลับโดยอัตโนมัติ
สิ่งที่คุณจะได้เรียนรู้
- วิธีทำให้แอป Vite + FastAPI แบบฟูลสแต็กใช้งานได้ใน Cloud Run เป็นคอนเทนเนอร์เดียว
- วิธีกำหนดค่า Firebase Auth และ Firestore สำหรับแอป React
- วิธีสร้างและทำให้ใช้งานได้ Agent ประเภท ADK ที่ตอบสนองต่อเหตุการณ์ Pub/Sub ผ่าน Eventarc
- วิธีกำหนดเส้นทางบันทึกของ Cloud Run ไปยัง BigQuery และค้นหาข้อมูลวิเคราะห์เกม
- วิธีเขียนทักษะที่เป็น Agent สำหรับ CI และการทำให้ Canary ใช้งานได้
สิ่งที่คุณต้องมี
- โปรเจ็กต์ Google Cloud ที่เปิดใช้การเรียกเก็บเงิน
- โปรเจ็กต์ Firebase (อาจเป็นโปรเจ็กต์ GCP เดียวกัน)
- บัญชี GitHub และ Fork ของที่เก็บ DinoQuest
- สิทธิ์เข้าถึง Antigravity ด้วย Gemini (ตัวเรียกใช้เอเจนต์ของ Google)
gcloudติดตั้งและตรวจสอบสิทธิ์ CLI แล้ว - ดูวิธีการติดตั้งด้านล่างnode≥ 18 และnpmpython3≥ 3.11gitและgh(GitHub CLI)
ติดตั้ง gcloud CLI
macOS
brew install --cask google-cloud-sdk
หรือดาวน์โหลดโปรแกรมติดตั้งจาก cloud.google.com/sdk/docs/install
Windows
winget install Google.CloudSDK
หรือดาวน์โหลดโปรแกรมติดตั้ง Windows (.exe) จาก cloud.google.com/sdk/docs/install แล้วดำเนินการ
หลังจากติดตั้งแล้ว ให้เริ่มต้นและตรวจสอบสิทธิ์โดยทำดังนี้
gcloud init
gcloud auth login
gcloud auth application-default login
2. ตั้งค่า Firebase
ตัวแทนทุกรายต้องมีข้อมูลเพื่อใช้ในการให้เหตุผล DinoQuest ใช้ Firestore และ Firebase Auth เพื่อจัดเตรียมเลเยอร์ข้อมูลที่พร้อมใช้งานจริง ซึ่งเอเจนต์ของเราจะค้นพบ สำรวจ และอัปเดตในภายหลังโดยใช้ภาษาที่เป็นธรรมชาติ
เนื่องจากแอปนี้สร้างขึ้นผ่าน AI Studio จึงผสานรวมกับ Firebase อย่างมาก การใช้ Firebase มีข้อดีหลายประการ โดยข้อดีที่สำคัญที่สุดคือสถาปัตยกรรมที่ได้รับการรักษาความปลอดภัยล่วงหน้าและการเข้าถึงข้อมูลที่มีการจัดการแบบพร้อมใช้งาน ซึ่งช่วยให้มั่นใจได้ว่าสถานะของเกมจะได้รับการปกป้องตั้งแต่วันแรก
ก. สร้างโปรเจ็กต์ Firebase
- ไปที่ console.firebase.google.com
- คลิกเพิ่มโปรเจ็กต์ (ซ่อนอยู่ในตัวเลือกสร้างโปรเจ็กต์ใหม่) → เลือกโปรเจ็กต์ GCP ที่มีอยู่ (หรือสร้างโปรเจ็กต์ใหม่)
- ปิดใช้ Google Analytics หากได้รับแจ้ง → สร้างโปรเจ็กต์ (หรือจะใช้การตั้งค่าเริ่มต้นก็ได้)
ข. เปิดใช้การตรวจสอบสิทธิ์ด้วย Google
- ในคอนโซล Firebase ให้ไปที่ความปลอดภัย → การตรวจสอบสิทธิ์ (เริ่มต้นใช้งาน) → วิธีลงชื่อเข้าใช้
- คลิก Google → เปิดเปิดใช้ → บันทึกอีเมลสนับสนุน → บันทึก
ค. เพิ่ม localhost เป็นโดเมนที่ได้รับอนุญาต
- ในส่วนการตรวจสอบสิทธิ์ ให้คลิกแท็บการตั้งค่า
- ในส่วนโดเมนที่ได้รับอนุญาต ให้ตรวจสอบว่ามี
localhostอยู่ในรายการ (ควรจะมีโดยค่าเริ่มต้น)
ง. สร้างฐานข้อมูล Firestore
- ไปที่ฐานข้อมูลและพื้นที่เก็บข้อมูล → ฐานข้อมูล Firestore → สร้างฐานข้อมูล
- เลือก Standard Edition → ถัดไป
- เลือกภูมิภาค
us-central1(หรือเลือกภูมิภาค Cloud Run ที่ตรงกัน) - เลือกเริ่มในโหมดที่ใช้งานจริง → สร้าง
เมื่อสร้างแล้ว ให้จดรหัสฐานข้อมูล ซึ่งจะมีลักษณะเป็น (default) เว้นแต่คุณจะตั้งชื่อไว้
จ. ตั้งค่ากฎการรักษาความปลอดภัยของ Firebase
ใน Firestore Database → Rules ให้แทนที่กฎเริ่มต้นด้วยกฎต่อไปนี้
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
// ===============================================================
// Helper Functions
// ===============================================================
function isAuthenticated() {
return request.auth != null;
}
function isOwner(userId) {
return isAuthenticated() && request.auth.uid == userId;
}
function isValidUser(data) {
return data.keys().hasAll(['uid', 'email']) &&
data.uid is string && data.uid.size() > 0 &&
(data.email == null || (data.email is string && data.email.matches("^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$")));
}
function isValidDinosaur(data) {
return data.keys().hasAll(['userId', 'name', 'type']) &&
data.userId == request.auth.uid &&
data.name is string && data.name.size() > 0 && data.name.size() < 50 &&
data.type in ['Speedy', 'Tank', 'Balanced', 'Agile'];
}
function isValidGame(data) {
return data.keys().hasAll(['userId', 'score']) &&
data.userId == request.auth.uid &&
data.score is number && data.score >= 0;
}
match /users/{userId} {
allow read: if isOwner(userId);
allow create: if isOwner(userId) && isValidUser(request.resource.data);
allow update: if isOwner(userId) && isValidUser(request.resource.data);
match /dinosaurs/{dinoId} {
allow read: if isOwner(userId);
allow create: if isOwner(userId) && isValidDinosaur(request.resource.data);
allow update: if isOwner(userId) && isValidDinosaur(request.resource.data);
}
match /games/{gameId} {
allow read: if isOwner(userId);
allow create: if isOwner(userId) && isValidGame(request.resource.data);
}
match /seenAnnouncements/{announcementId} {
allow read, create: if isOwner(userId);
}
}
match /announcements/{announcementId} {
allow read: if isAuthenticated();
}
// Default deny
match /{document=**} {
allow read, write: if false;
}
match /scores/{scoreId} {
allow read: if true;
allow create: if isAuthenticated();
allow update: if false;
}
}
}
คลิกเผยแพร่
ฉ. เพิ่มเว็บแอปและรับการกำหนดค่า
- ไปที่การตั้งค่าโปรเจ็กต์ (ไอคอนรูปเฟือง) → แท็บทั่วไป
- เลื่อนไปที่แอปของคุณ → คลิกเพิ่มแอป → เลือกไอคอนเว็บ (
) - ตั้งชื่อว่า
dinoquest→ Register app - คัดลอก
firebaseConfigออบเจ็กต์ที่แสดง คุณจะต้องใช้ในอีกสักครู่
3. การเรียกใช้เกม
บทบาทของเอเจนต์: สภาพแวดล้อม ก่อนที่จะให้เอเจนต์ทำงานได้ เราต้องมีโลกให้เอเจนต์จัดการ ในขั้นตอนนี้ เราจะติดตั้งใช้งาน DinoQuest เวอร์ชัน "Day One" ซึ่งจะสร้างบริการสด บันทึก และสถานะที่ฝูงของเราจะค้นพบและจัดการในภายหลัง

เลือกตัวเลือกใดตัวเลือกหนึ่งจาก 2 ตัวเลือกด้านล่าง หรือสร้าง GEMINI_API_KEY ที่คุณใช้เหมือนกันในทุกขั้นตอนต่อๆ ไป โดยไม่ต้องทำการเปลี่ยนแปลงอื่นๆ
ก. ตั้งค่าคีย์ Gemini API
ตัวเลือก ก. - คีย์ Vertex AI Gemini API (แนะนำหากคุณมีโปรเจ็กต์ GCP)
Vertex AI ช่วยให้คุณสร้างคีย์ Gemini API ที่เชื่อมโยงกับโปรเจ็กต์ GCP โดยตรงและเรียกเก็บเงินจากโปรเจ็กต์นั้นได้โดยใช้บัญชีบริการเริ่มต้นของโปรเจ็กต์ โดยไม่ต้องมีบัญชี AI Studio แยกต่างหาก
- ส่งออกรหัสโปรเจ็กต์ GCP
export PROJECT_ID=<YOUR_PROJECT_ID> - เปิดใช้ API ที่จำเป็นและให้สิทธิ์ที่จำเป็นแก่บัญชีบริการเริ่มต้นของ Compute Engine โดยทำดังนี้
gcloud auth application-default set-quota-project $PROJECT_ID gcloud config set project $PROJECT_ID # Enable Vertex AI, Compute Engine, and Generative Language APIs gcloud services enable aiplatform.googleapis.com \ compute.googleapis.com \ generativelanguage.googleapis.com # Grant Vertex AI User role to the default compute service account PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format="value(projectNumber)") gcloud projects add-iam-policy-binding $PROJECT_ID \ --member="serviceAccount:${PROJECT_NUMBER}-compute@developer.gserviceaccount.com" \ --role="roles/aiplatform.user" \ --condition=None - เปิดหน้าคีย์ Vertex AI API ใน Cloud Console
- คลิกสร้างข้อมูลเข้าสู่ระบบ → เลือกคีย์ API
- ในกล่องโต้ตอบการสร้าง ให้ทำดังนี้
- ตั้งชื่อคีย์เป็น
Dino_Key - เลือกช่องตรวจสอบสิทธิ์การเรียก API ผ่านบัญชีบริการ
- ในส่วนบัญชีบริการ ให้เลือกบัญชีบริการ Compute เริ่มต้น (
PROJECT_NUMBER-compute@developer.gserviceaccount.com) - กลับไปที่เลือกการจำกัด API แล้วเลือก GEMINI API
- คลิกสร้าง
- ตั้งชื่อคีย์เป็น
- คัดลอกคีย์ที่สร้างขึ้น
ตัวเลือก ข - AI Studio (เร็วที่สุดสำหรับการพัฒนาในเครื่อง)
- เปิด aistudio.google.com
- คลิกรับคีย์ API ในแถบด้านข้างทางซ้าย
- คลิกสร้างคีย์ API → เลือกโปรเจ็กต์ GCP → คัดลอกคีย์
คุณตั้งค่าคีย์ใดก็ได้เป็น GEMINI_API_KEY ในขั้นตอนถัดไป โดยแบ็กเอนด์จะถือว่าคีย์ทั้ง 2 เหมือนกัน
โคลนที่เก็บ
ที่เก็บหลักสูตรจะอยู่ใน https://github.com/gca-americas/dinoquest โปรดฟอร์กไปยังบัญชี GitHub ของคุณก่อน เราจะให้ตัวแทนดำเนินการกับที่เก็บของคุณแทน
หลังจาก Fork แล้ว ให้โคลนmain Branch ของที่เก็บ DinoQuest ที่ Fork ไว้ แล้วเข้าสู่ไดเรกทอรีโปรเจ็กต์
git clone https://github.com/YOUR_GITHUB_USERNAME/dinoquest.git
cd dinoquest
ข. ตั้งค่าตัวแปรสภาพแวดล้อม
ในทุกเทอร์มินัล Bash ใหม่ที่คุณเปิดระหว่าง Codelab นี้ โปรดตรวจสอบว่าได้ตั้งค่าตัวแปรสภาพแวดล้อมที่จำเป็นเหล่านี้แล้ว แทนที่ค่าตัวยึดตำแหน่งด้วยรายละเอียดโปรเจ็กต์จริง
ก่อนอื่น ให้ส่งออก URL ของที่เก็บ GitHub โดยทำดังนี้
export GITHUB_REPO_URL=https://github.com/YOUR_GITHUB_USERNAME/dinoquest
จากนั้นส่งออกตัวแปรสภาพแวดล้อมที่เหลือ
export PROJECT_ID=your-project-id
export GOOGLE_CLOUD_PROJECT=$PROJECT_ID
export CLOUD_RUN_REGION=us-central1
export GOOGLE_GENAI_USE_VERTEXAI=True
export HARNESS_EVENTS_TOPIC=projects/$PROJECT_ID/topics/harness-events
export CLOUD_BUILD_REPO=<YOUR_GITHUB_USERNAME>-dinoquest
ตรวจสอบว่าโครงสร้างถูกต้อง
dinoquest/
├── backend/ # FastAPI backend (serves frontend + Gemini API calls)
├── frontend/ # React/Vite frontend
├── skills/ # Agentic CI/CD skill files
├── Dockerfile # Multi-stage build (React → Python)
├── start.sh # Local dev launcher
└── README.md
ข. สร้างไฟล์สภาพแวดล้อมแบ็กเอนด์
ก่อนอื่น ให้ส่งออกคีย์ Gemini API โดยทำดังนี้
export GEMINI_API_KEY=YOUR_GEMINI_API_KEY_FROM_STEP_2
จากนั้นสร้างไฟล์ .env โดยทำดังนี้
cat > backend/.env <<EOF
GEMINI_API_KEY=$GEMINI_API_KEY
GOOGLE_GENAI_USE_VERTEXAI=False
GOOGLE_CLOUD_PROJECT=$PROJECT_ID
EOF
ค. เปิดใช้ Firebase App Check / บัญชีบริการ (สำหรับ Cloud Run)
เมื่อทำงานใน Cloud Run ส่วนแบ็กเอนด์จะใช้ข้อมูลรับรองเริ่มต้นของแอปพลิเคชันเพื่อสื่อสารกับ Firebase โดยไม่ต้องใช้ไฟล์คีย์บัญชีบริการ firebase_admin.initialize_app() ใน backend/main.py จะรับสายนี้โดยอัตโนมัติ
สำหรับการพัฒนาในเครื่อง ให้ตรวจสอบสิทธิ์เพียงครั้งเดียวโดยทำดังนี้
gcloud auth application-default login
ง. สร้างไฟล์การกำหนดค่าแอป Firebase
ในไดเรกทอรี frontend/ ให้สร้าง firebase-applet-config.json ด้วยการกำหนดค่าจากขั้นตอนก่อนหน้า
{
"apiKey": "YOUR_API_KEY",
"authDomain": "YOUR_PROJECT_ID.firebaseapp.com",
"projectId": "YOUR_PROJECT_ID",
"storageBucket": "YOUR_PROJECT_ID.appspot.com",
"messagingSenderId": "YOUR_SENDER_ID",
"appId": "YOUR_APP_ID",
"firestoreDatabaseId": "(default)"
}
หมายเหตุ: firestoreDatabaseId ควรตรงกับรหัสฐานข้อมูลที่คุณสร้างไว้ในขั้นตอนก่อนหน้า หากคุณใช้ค่าเริ่มต้น ให้ปล่อยไว้เป็น "(default)"
คอมมิตการเปลี่ยนแปลงกลับไปยังที่เก็บ
git add frontend/firebase-applet-config.json
git commit -m "chore: add firebase config"
git push origin main
ค. เรียกใช้ DinoQuest ในเครื่อง
1. เปิดใช้ API ที่จำเป็น
gcloud services enable \
run.googleapis.com \
cloudbuild.googleapis.com \
artifactregistry.googleapis.com \
secretmanager.googleapis.com \
firestore.googleapis.com \
logging.googleapis.com \
pubsub.googleapis.com \
eventarc.googleapis.com \
aiplatform.googleapis.com \
bigquery.googleapis.com \
aiplatform.googleapis.com
2. เริ่ม DinoQuest
สคริปต์ start.sh สร้างฟรอนท์เอนด์ React และส่งเทอร์มินัลไปยังแบ็กเอนด์ FastAPI ซึ่งแสดงไฟล์แบบคงที่ที่คอมไพล์แล้ว
cd backend
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt -q
cd ..
# Force-remove the Vertex AI flag from the current terminal session to avoid conflicts
unset GOOGLE_GENAI_USE_VERTEXAI
./start.sh
เปิด http://localhost:8000 ในเบราว์เซอร์ คุณควรเห็นหน้าจอชื่อ DinoQuest ลงชื่อเข้าใช้ด้วย Google สร้างไดโนเสาร์ตัวแรก และยืนยันว่าระบบบันทึกไดโนเสาร์ลงใน Firestore
การแก้ปัญหา: หากเห็นหน้าว่างหรือข้อผิดพลาดในการตรวจสอบสิทธิ์ Firebase ให้ตรวจสอบอีกครั้งว่า frontend/firebase-applet-config.json มีค่าที่ถูกต้องและ localhost อยู่ในรายการโดเมนที่ได้รับอนุญาต
จ. ทำให้ DinoQuest ใช้งานได้ใน Cloud Run
1. ตั้งค่าโปรเจ็กต์
export PROJECT_ID=$(gcloud config get-value project)
3. สร้างที่เก็บ Artifact Registry
gcloud artifacts repositories create dinoquest \
--repository-format=docker \
--location=$CLOUD_RUN_REGION \
--description="DinoQuest container images"
4. จัดเก็บคีย์ Gemini API ใน Secret Manager
echo -n $GEMINI_API_KEY | \
gcloud secrets create gemini-api-key --data-file=-
# Grant the default compute service account access to the secret
PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format="value(projectNumber)")
gcloud secrets add-iam-policy-binding gemini-api-key \
--member="serviceAccount:${PROJECT_NUMBER}-compute@developer.gserviceaccount.com" \
--role="roles/secretmanager.secretAccessor"
5. สร้างอิมเมจคอนเทนเนอร์ด้วย Cloud Build
gcloud builds submit \
--tag $CLOUD_RUN_REGION-docker.pkg.dev/$PROJECT_ID/dinoquest/app:latest .
ซึ่งจะเรียกใช้ Dockerfile แบบหลายขั้นตอน โดยจะสร้างแอป React ก่อน แล้วจึงแพ็กเอาต์พุตลงในอิมเมจ FastAPI ใช้เวลาประมาณ 3–5 นาที
6. ทำให้ใช้งานได้กับ Cloud Run
ก่อนอื่น ให้ส่งออกอีเมลของผู้ดูแลระบบโดยทำดังนี้
export ADMIN_EMAIL=<YOUR_TEST_ACCOUNT_EMAIL>
จากนั้นให้ติดตั้งใช้งานบริการโดยใช้คำสั่งต่อไปนี้
gcloud run deploy dinoquest \
--image=$CLOUD_RUN_REGION-docker.pkg.dev/$PROJECT_ID/dinoquest/app:latest \
--region=$CLOUD_RUN_REGION \
--platform=managed \
--allow-unauthenticated \
--memory=128Mi \
--set-secrets="GEMINI_API_KEY=gemini-api-key:latest" \
--set-env-vars="ADMIN_EMAILS=$ADMIN_EMAIL" \
--set-env-vars="GOOGLE_GENAI_USE_VERTEXAI=False" \
--set-env-vars="GOOGLE_CLOUD_PROJECT=$PROJECT_ID"
เมื่อคำสั่งเสร็จสมบูรณ์แล้ว Cloud Run จะพิมพ์URL ของบริการ คัดลอก URL นี้ คุณจะต้องใช้ URL นี้เพื่อให้สิทธิ์โดเมนใน Firebase
7. ให้สิทธิ์โดเมน Cloud Run ใน Firebase
หากต้องการอนุญาตให้ผู้ใช้ลงชื่อเข้าใช้จากแอปที่ติดตั้งใช้งาน คุณต้องเพิ่ม URL ของ Cloud Run ลงในโดเมนที่ได้รับอนุญาตของ Firebase โดยทำดังนี้
- กลับไปที่คอนโซล Firebase → การตรวจสอบสิทธิ์ → การตั้งค่า → โดเมนที่ได้รับอนุญาต
- คลิกเพิ่มโดเมน
- วาง URL ของบริการ Cloud Run (เช่น
dinoquest-xxxxx.us-central1.run.app) — นำคำนำหน้าhttps://ออก - คลิกบันทึก
8. เริ่มต้นใช้งานข้อมูลลีดเดอร์บอร์ด
หากต้องการให้เกมมี "ชีวิต" ในช่วงแรกและตรวจสอบว่าเอเจนต์มีข้อมูล คุณสามารถเริ่มต้นลีดเดอร์บอร์ดด้วยคะแนนเริ่มต้นได้
- ตรวจสอบว่าคุณอยู่ใน
dinoquestไดเรกทอรีรากcd ~/dinoquest - สร้างและเปิดใช้งานสภาพแวดล้อมเสมือนโดยใช้คำสั่งต่อไปนี้
python3 -m venv venv source venv/bin/activate - ติดตั้งทรัพยากร Dependency ของ Firestore ที่จำเป็น
pip install google-cloud-firestore - เรียกใช้สคริปต์การเริ่มต้น
python3 prep/seed_scores.py - ปิดใช้งานสภาพแวดล้อมเสมือน
deactivate
ตอนนี้คุณสามารถเปิด URL ของบริการในเบราว์เซอร์ได้แล้ว DinoQuest พร้อมให้บริการอย่างเต็มรูปแบบแล้ว
4. ตั้งค่า Dino Theater
บทบาทของตัวแทน: Visualizer คุณจะตรวจสอบทีมเอเจนต์อัตโนมัติได้อย่างไร Dino Theater จะแสดงข้อมูลแบบเรียลไทม์เกี่ยวกับความคิดของฝูงเอเจนต์ คุณสามารถดูเอเจนต์ให้เหตุผล เรียกใช้กัน และดำเนินการต่างๆ ในระบบคลาวด์ได้ในแดชบอร์ดแบบเรียลไทม์ที่มองเห็นได้ แทนที่จะต้องจ้องมองบันทึกของเทอร์มินัล

ก. ติดตั้งใช้งาน Dino Theater ใน Cloud Run
ก่อนอื่น ให้กลับไปที่ไดเรกทอรีหน้าแรกแล้วโคลนโค้ด Dino Theater
cd ~
git clone https://github.com/gca-americas/dinoquest-theater.git
cd dinoquest-theater
- สร้างและพุชคอนเทนเนอร์:
gcloud builds submit --tag $CLOUD_RUN_REGION-docker.pkg.dev/$PROJECT_ID/dinoquest/dino-theater:latest . - ตั้งค่าบัญชีบริการและสิทธิ์:
# Create the service account gcloud iam service-accounts create dino-theater # Create the Pub/Sub topic (if you haven't yet) gcloud pubsub topics create harness-events # Create the subscription gcloud pubsub subscriptions create harness-events-theater \ --topic=harness-events # Grant subscriber role gcloud pubsub subscriptions add-iam-policy-binding harness-events-theater \ --member="serviceAccount:dino-theater@${PROJECT_ID}.iam.gserviceaccount.com" \ --role="roles/pubsub.subscriber" - ทำให้แอปพลิเคชันใช้งานได้
หมายเหตุ:gcloud run deploy dino-theater \ --image $CLOUD_RUN_REGION-docker.pkg.dev/$PROJECT_ID/dinoquest/dino-theater:latest \ --region=$CLOUD_RUN_REGION \ --service-account=dino-theater@${PROJECT_ID}.iam.gserviceaccount.com \ --set-env-vars="GOOGLE_CLOUD_PROJECT=$PROJECT_ID" \ --allow-unauthenticated \ --min-instances=1--min-instances=1ขอแนะนำให้ใช้เพื่อรักษาการเชื่อมต่อ SSE ให้ใช้งานได้ระหว่างเหตุการณ์ - ตรวจสอบว่าใช้งานได้: เปิด URL ของบริการที่ติดตั้งใช้งานในเบราว์เซอร์ (เช่น
https://dino-theater-xxx-uc.a.run.app/demo)
5. DevOps ที่ใช้ Agent ใน IDE
บทบาทของเอเจนต์: Native Antigravity เราเชื่อมต่อ Antigravity กับเซิร์ฟเวอร์ MCP ที่มีการจัดการของ Google Cloud เพื่อลดช่องว่างระหว่าง IDE กับระบบคลาวด์ ซึ่งจะช่วยให้เอเจนต์เนทีฟมี "ดวงตา" ในโปรเจ็กต์ของคุณ ทำให้สามารถแยกวิเคราะห์บันทึก ตรวจสอบเมตริก และให้เหตุผลเกี่ยวกับโครงสร้างพื้นฐานได้โดยไม่ต้องสลับคีย์ API หรือสลับบริบทไปยังคอนโซล
ก่อนที่จะเรียกใช้ทักษะใดๆ คุณต้องกำหนดค่าการเข้าถึง Google Cloud ของ Antigravity และโหลด Playbook ของทักษะ DinoQuest
ก. ติดตั้งบริการ MCP ที่มีการจัดการของ Google
บริการ MCP ที่มีการจัดการของ Google ให้สิทธิ์เข้าถึง Google Cloud API ทั้งหมดผ่านปลายทางเดียวที่โฮสต์
ตรวจสอบสิทธิ์โดยใช้ข้อมูลรับรองเริ่มต้นของแอปพลิเคชัน:
gcloud auth application-default login
ข. กำหนดค่า mcp_config.json
สร้างหรืออัปเดต mcp_config.json ในไดเรกทอรีการกำหนดค่า Antigravity (โดยปกติคือ ~/.gemini/antigravity/mcp_config.json) หรือจากคอนโซล ซึ่งจะช่วยให้ Antigravity เข้าถึงเครื่องมือของ Google Cloud และ GitHub ที่จำเป็นต่อทักษะได้ ดังนี้
{
"mcpServers": {
"google-developer-knowledge": {
"serverUrl": "https://developerknowledge.googleapis.com/mcp",
"authProviderType": "google_credentials"
},
"google-bigquery": {
"serverUrl": "https://bigquery.googleapis.com/mcp",
"authProviderType": "google_credentials"
},
"google-cloud-logging": {
"serverUrl": "https://logging.googleapis.com/mcp",
"authProviderType": "google_credentials"
},
"google-cloud-monitoring": {
"serverUrl": "https://monitoring.googleapis.com/mcp",
"authProviderType": "google_credentials",
"disabledTools": [
"get_dashboard",
"list_dashboards"
]
},
"google-cloud-run": {
"serverUrl": "https://run.googleapis.com/mcp",
"authProviderType": "google_credentials",
"disabledTools": [
"deploy_service_from_image",
"deploy_service_from_archive",
"deploy_service_from_file_contents"
]
},
"google-cloud-sql": {
"serverUrl": "https://sqladmin.googleapis.com/mcp",
"authProviderType": "google_credentials",
"disabled": true
},
"google-cloud-trace": {
"serverUrl": "https://cloudtrace.googleapis.com/mcp",
"authProviderType": "google_credentials"
},
"google-error-reporting": {
"serverUrl": "https://clouderrorreporting.googleapis.com/mcp",
"authProviderType": "google_credentials"
},
"google-firestore": {
"serverUrl": "https://firestore.googleapis.com/mcp",
"authProviderType": "google_credentials"
},
"google-resource-manager": {
"serverUrl": "https://cloudresourcemanager.googleapis.com/mcp",
"authProviderType": "google_credentials"
},
"gemini-cloud-assist": {
"serverUrl": "https://geminicloudassist.googleapis.com/mcp",
"authProviderType": "google_credentials"
}
}
}
ค. โหลดทักษะลงใน Antigravity (ไม่บังคับ)
Antigravity จะค้นพบทักษะในไดเรกทอรีมาตรฐานที่เฉพาะเจาะจง คัดลอกทักษะ DinoQuest จากที่เก็บที่โคลนไปยังโฟลเดอร์ทักษะ Antigravity ทั่วโลก โดยทำดังนี้
# Create the standard skills directory if it doesn't exist
mkdir -p ~/.gemini/antigravity/skills
# Copy all DinoQuest skills into the global skills folder
cp -r skills/* ~/.gemini/antigravity/skills/
ง. รีสตาร์ท Antigravity(ไม่บังคับ)
หากต้องการใช้mcp_config.jsonการเปลี่ยนแปลงและโหลดทักษะที่คัดลอกใหม่ ให้รีสตาร์ทแอปพลิเคชัน Antigravity
เมื่อรีสตาร์ทแล้ว ให้ทำดังนี้
- ตรวจสอบว่าเซิร์ฟเวอร์ MCP ของ google และ github แสดงสถานะ "เชื่อมต่อแล้ว" เป็นสีเขียวในการตั้งค่า
- ตรวจสอบว่าทักษะ DinoQuest ปรากฏในรายการทักษะ
หมายเหตุ: ทักษะแต่ละอย่างจะมีตาราง ## Configuration ที่ด้านบนของ SKILL.md หลังจากคัดลอกแล้ว คุณควรอัปเดตค่าใน ~/.gemini/antigravity/skills/ ให้ตรงกับโปรเจ็กต์
จ. แก้ไขบริการระบบคลาวด์ใน IDE ภายใน
- ทริกเกอร์ข้อผิดพลาด: เปิด URL ของ DinoQuest ที่คุณติดตั้งใช้งาน (จากขั้นตอนสุดท้าย) ในเบราว์เซอร์
- ไปที่ลีดเดอร์บอร์ด: คลิกปุ่มลีดเดอร์บอร์ด การติดตั้งใช้งานลีดเดอร์บอร์ดในปัจจุบันตั้งใจให้ไม่มีประสิทธิภาพ ซึ่งจะพยายามโหลดข้อมูลจำนวนมากไปยังหน่วยความจำ ซึ่งจะทําให้เกิดข้อผิดพลาดหน่วยความจำไม่พอ (OOM)
- ใน Antigravity Agent Manager (Agent HUB) ให้ขอความช่วยเหลือในการกู้คืนข้อผิดพลาดและอาจแก้ไขสาเหตุที่มาของปัญหา
- พรอมต์ 1: ค้นหาว่า dinoquest มีปัญหาอะไร
- พรอมต์ 2: คุณดูโค้ดของเกม Dinoquest และแก้ไขสิ่งที่ทำให้เกิดข้อผิดพลาดหน่วยความจำไม่เพียงพอได้ไหม
6. สตรีมบันทึกไปยัง BigQuery และสร้างข้อมูลวิเคราะห์
บทบาทของตัวแทน: ตัวแทนข้อมูล การเปลี่ยนบันทึกดิบให้เป็นกลยุทธ์ผลิตภัณฑ์ที่นำไปใช้ได้จริงไม่ควรใช้เวลาหลายชั่วโมงในการรวบรวมข้อมูลด้วยตนเอง การใช้ Data Agent Kit และ BigQuery MCP ทำให้เราสร้างไปป์ไลน์ "Zero ETL" ที่สตรีมบันทึกโดยตรงไปยัง BigQuery ซึ่งช่วยให้ Agent สร้างแดชบอร์ดข้อมูลวิเคราะห์ระดับพรีเมียมได้ภายในเวลาไม่ถึง 2 นาที
log-router-bq-reportทักษะจะตั้งค่าซิงก์ Cloud Logging ที่สตรีมบันทึก Cloud Run ของ DinoQuest ไปยัง BigQuery อย่างต่อเนื่อง จากนั้นจะค้นหาข้อมูลเพื่อสร้างรายงานการรับส่งข้อมูลและข้อมูลเชิงลึกด้านการวิเคราะห์เกม

ก. กำหนดค่าตัวแปรของทักษะ
เปิด skills/log-router-bq-report/SKILL.md ในที่เก็บ DinoQuest และอัปเดตส่วนการกำหนดค่าที่ด้านบน
| Variable | Your Value |
|---------------|--------------------|
| SERVICE_NAME | dinoquest |
| BQ_DATASET | dinoquest_logs |
| LOG_SINK_NAME | dinoquest-bq-sink |
ข. เรียกใช้ทักษะใน Antigravity
เปิด Antigravity โดยใช้ที่เก็บ DinoQuest เป็นบริบท แล้วบอก Gemini ว่า
Run the log-router-bq-report skill
ทักษะจะทำสิ่งต่อไปนี้
- แก้ไขโปรเจ็กต์ GCP โดยอัตโนมัติ
- ตรวจสอบว่ามี Sink ของ BigQuery อยู่แล้วหรือไม่ หากไม่มี ระบบจะสร้างชุดข้อมูลและ Sink
- ให้สิทธิ์ IAM: การดำเนินการนี้จะให้บทบาทผู้แก้ไขข้อมูล BigQuery แก่
writerIdentityของ Sink ในชุดข้อมูล
หมายเหตุ: เช่นเดียวกับ Sink ของ Eventarc คุณอาจเห็นคำเตือนจาก gcloud ในระหว่างกระบวนการนี้ว่า "โปรดอย่าลืมให้บทบาทผู้แก้ไขข้อมูล BigQuery แก่ serviceAccount:service-... ในชุดข้อมูล" ทักษะจะจัดการเรื่องนี้โดยอัตโนมัติ
ค. การใช้ Antigravity เพื่อสร้างรายงาน
เพียงขอให้ Antigravity "ตั้งค่าซิงก์บันทึกของ BigQuery และสร้างรายงานข้อมูลวิเคราะห์" ตัวแทนจะทำสิ่งต่อไปนี้
- กำหนดค่าโครงสร้างพื้นฐาน: สร้างชุดข้อมูล BigQuery และซิงก์ Cloud Logging
- จัดการสิทธิ์: มอบบทบาท IAM ที่จำเป็นให้กับข้อมูลประจำตัวของผู้เขียนของ Sink โดยอัตโนมัติ
- สร้างข้อมูลเชิงลึก: วิเคราะห์บันทึกและสร้างแดชบอร์ด HTML แบบอินเทอร์แอกทีฟระดับพรีเมียมพร้อมการวัดและวิเคราะห์อัตราการชนะของเกม
7. Self-Healing Remediation Agent
บทบาทของตัวแทน: ตัวแทน SRE เมื่อบริการที่ใช้งานจริงล้มเหลวตอน 02:00 น. คุณไม่ควรต้องตื่นขึ้นมา เอเจนต์นี้จะทำหน้าที่เป็นผู้ตอบคำถามแรก ระบบจะเรียกใช้โดยบันทึกข้อผิดพลาดของ Cloud Run ผ่าน Eventarc ซึ่งจะวิเคราะห์ข้อขัดข้อง เสนอการแก้ไข และเริ่มไปป์ไลน์การแก้ไขโดยอัตโนมัติ ทั้งหมดนี้เกิดขึ้นก่อนที่คุณจะเข้าสู่ระบบคอนโซลด้วยซ้ำ
DinoAgent เป็นตัวแทน ADK ที่รอรับฟังบันทึกข้อผิดพลาดของ Cloud Run ผ่าน Eventarc วินิจฉัยสาเหตุหลัก และแก้ไขโดยอัตโนมัติ ไม่ว่าจะด้วยการเพิ่มหน่วยความจำ การย้อนกลับการรับส่งข้อมูล หรือการยื่นคำขอ PR เพื่อแก้ไขโค้ดใน GitHub

ก. โคลนที่เก็บของ Remediation Agent
cd ~
git clone https://github.com/gca-americas/dinoquest-reme-agent.git
cd dinoquest-reme-agent
โครงสร้างโปรเจ็กต์
dinoquest-reme-agent/
├── main.py # Service entrypoint — receives Eventarc HTTP POST, runs agent
├── runner.py # ADK Runner + session service
├── agent.py # LlmAgent definition, loads skill from file
├── tools.py # Cloud Run v2 API tools (list/get/rollback/update)
├── skills/
│ └── remediation/
│ ├── SKILL.md # Agent playbook — edit this to change behavior
│ └── scripts/ # Shell scripts for the code-fix track
│ ├── clone_repo.sh
│ ├── read_file.sh
│ ├── apply_fix.sh
│ ├── commit_branch.sh
│ ├── open_pr.sh
│ └── rollback_fix.sh
├── requirements.txt
└── Dockerfile
ข. ตั้งค่าการเข้าถึง GitHub (แทร็กการแก้ไขโค้ด)
แทร็กการแก้ไขโค้ดจะโคลนที่เก็บ DinoQuest อ่านไฟล์ต้นฉบับ ใช้แพตช์ และเปิด PR โดยต้องใช้โทเค็นเพื่อการเข้าถึงส่วนบุคคลของ GitHub ที่มีขอบเขต repo
- ไปที่ github.com/settings/tokens → สร้างโทเค็นใหม่ (คลาสสิก)
- ตั้งชื่อ เลือก
repoขอบเขต → สร้างโทเค็น → คัดลอก
จัดเก็บไว้ใน Secret Manager โดยทำดังนี้
ก่อนอื่น ให้ส่งออกโทเค็น GitHub โดยทำดังนี้
export GH_TOKEN=ghp_YOUR_TOKEN_HERE
จากนั้นสร้างข้อมูลลับโดยทำดังนี้
echo -n $GH_TOKEN | \
gcloud secrets create github-token --data-file=-
ค. ตั้งค่าการแจ้งเตือนของ Slack (ไม่บังคับ)
เมื่อการแก้ไขเสร็จสมบูรณ์ DinoAgent จะโพสต์สรุปไปยังช่องทาง Slack
- ไปที่ api.slack.com/apps → สร้างแอปใหม่ → ตั้งแต่ต้น
- ตั้งชื่อว่า
DinoAgentเลือกพื้นที่ทำงาน → สร้างแอป - ในส่วนฟีเจอร์ → เว็บฮุคขาเข้า → เปิด/ปิด
- คลิกเพิ่มเว็บบุ๊กใหม่ไปยังพื้นที่ทำงาน → เลือกช่อง → อนุญาต
- คัดลอก URL ของเว็บฮุก (
https://hooks.slack.com/services/...)
จัดเก็บไว้ใน Secret Manager โดยทำดังนี้
export SLACK_TOKEN=YOUR_SLACK_WEBHOOK
echo -n "https://hooks.slack.com/services/$SLACK_TOKEN" | \
gcloud secrets create slack-webhook --data-file=-
ง. สร้างบัญชีบริการ DinoAgent
gcloud iam service-accounts create remediation-agent \
--display-name="Cloud Run Remediation Agent"
export SA="remediation-agent@${PROJECT_ID}.iam.gserviceaccount.com"
for ROLE in \
roles/run.admin \
roles/iam.serviceAccountUser \
roles/eventarc.eventReceiver \
roles/aiplatform.user \
roles/artifactregistry.reader \
roles/secretmanager.secretAccessor \
roles/pubsub.publisher \
roles/logging.viewer; do
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:${SA}" --role="$ROLE" \
--condition=None
done
ให้สิทธิ์เข้าถึงข้อมูลลับ
for SECRET in github-token slack-webhook; do
gcloud secrets add-iam-policy-binding $SECRET \
--member="serviceAccount:${SA}" \
--role="roles/secretmanager.secretAccessor"
done
จ. สร้างและติดตั้งใช้งาน DinoAgent ใน Cloud Run
# Get Project Number for the CIAgent URL
PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format="value(projectNumber)")
export CIAGENT_URL=https://ci-agent-${PROJECT_NUMBER}.${CLOUD_RUN_REGION}.run.app
export SA="remediation-agent@${PROJECT_ID}.iam.gserviceaccount.com"
export GITHUB_REPO_URL=https://github.com/YOUR_REPO
HARNESS_EVENTS_TOPIC=projects/$PROJECT_ID/topics/harness-events
AGENT_IMAGE="$CLOUD_RUN_REGION-docker.pkg.dev/${PROJECT_ID}/dinoquest/remediation-agent:latest"
gcloud builds submit --tag $AGENT_IMAGE .
gcloud run deploy remediation-agent \
--image=$AGENT_IMAGE \
--region=$CLOUD_RUN_REGION \
--service-account=$SA \
--memory=2Gi \
--set-env-vars="GOOGLE_CLOUD_PROJECT=${PROJECT_ID},GOOGLE_GENAI_USE_VERTEXAI=True" \
--set-env-vars="GITHUB_REPO_URL=${GITHUB_REPO_URL}" \
--set-secrets="SLACK_WEBHOOK_URL=slack-webhook:latest" \
--set-env-vars="HARNESS_EVENTS_TOPIC=${HARNESS_EVENTS_TOPIC}" \
--set-env-vars="CIAGENT_URL=${CIAGENT_URL}" \
--set-secrets="GITHUB_TOKEN=github-token:latest" \
--no-allow-unauthenticated \
--min-instances=1 \
--no-cpu-throttling \
--timeout=300
ฉ. เชื่อมต่อทริกเกอร์ Eventarc
สร้างหัวข้อ Pub/Sub เพื่อรับบันทึกข้อผิดพลาดของ Cloud Run โดยทำดังนี้
gcloud pubsub topics create cloud-run-errors
สร้างซิงก์ Cloud Logging ที่กรองบันทึกข้อผิดพลาดจากdinoquestบริการและกำหนดเส้นทางไปยังหัวข้อ
export SERVICE_NAME=dinoquest
FILTER="resource.type=\"cloud_run_revision\" resource.labels.service_name=\"$SERVICE_NAME\" severity=ERROR NOT logName=~\"cloudaudit\" NOT httpRequest.requestUrl=~\"/_ah/health\""
gcloud logging sinks create cloud-run-errors-sink \
pubsub.googleapis.com/projects/${PROJECT_ID}/topics/cloud-run-errors \
--log-filter="$FILTER"
หมายเหตุ: เมื่อเรียกใช้คำสั่งข้างต้น gcloud จะพิมพ์ข้อความข้อมูลที่ระบุว่า "โปรดอย่าลืมให้บทบาทผู้เผยแพร่ Pub/Sub แก่ serviceAccount:service-... ในหัวข้อ" ขั้นตอนถัดไปจะจัดการเรื่องนี้โดยเฉพาะ
ให้สิทธิ์การเผยแพร่แก่ข้อมูลประจำตัวของผู้เขียนของซิงก์ (บัญชีบริการที่กล่าวถึงในคำเตือน) ดังนี้
SINK_SA=$(gcloud logging sinks describe cloud-run-errors-sink \
--format='value(writerIdentity)')
gcloud pubsub topics add-iam-policy-binding cloud-run-errors \
--member="${SINK_SA}" --role="roles/pubsub.publisher"
ตรวจสอบว่าเปิดใช้อยู่
gcloud eventarc triggers describe remediation-trigger --location=$CLOUD_RUN_REGION
ให้สิทธิ์ Eventarc ในการเรียกใช้ตัวแทนการแก้ไข
gcloud run services add-iam-policy-binding remediation-agent \
--region=$CLOUD_RUN_REGION \
--member="serviceAccount:${SA}" \
--role="roles/run.invoker"
สร้างทริกเกอร์ Eventarc โดยทำดังนี้
gcloud eventarc triggers create remediation-trigger \
--location=$CLOUD_RUN_REGION \
--destination-run-service=remediation-agent \
--destination-run-region=$CLOUD_RUN_REGION \
--event-filters="type=google.cloud.pubsub.topic.v1.messagePublished" \
--transport-topic=projects/${PROJECT_ID}/topics/cloud-run-errors \
--service-account=${SA}
ตอนนี้การแก้ไขเป็นแบบอัตโนมัติทั้งหมดแล้ว นอกเหนือจากการปรับขนาดโครงสร้างพื้นฐานแล้ว DinoAgent ยังทำการวิเคราะห์สาเหตุหลักอย่างละเอียดในโค้ดของแอปพลิเคชัน ใช้แพตช์เชิงความหมาย และใช้การสื่อสารAgent-to-Agent (A2A) เพื่อส่งต่อการแก้ไขไปยัง CI Agent เพื่อการยืนยันและการติดตั้งใช้งาน คุณสามารถดูรายละเอียดการใช้งานได้ในฐานโค้ดของ reme-agent
8. ตั้งค่า Agent CI
บทบาทของเอเจนต์: ไปป์ไลน์ CI ไม่ต้องกังวลกับไฟล์ YAML ที่ซับซ้อนและสคริปต์บิลด์ที่ต้องทำเองอีกต่อไป เอเจนต์นี้จัดการการทำงานภายในของคำขอให้รวมโค้ด โดยจะอ่านการเปลี่ยนแปลงโค้ด ทำความเข้าใจบริบท กำหนดขอบเขตการทดสอบที่จำเป็น และสร้างอิมเมจ Docker ผ่าน Cloud Build เพื่อให้มั่นใจว่าทุกการคอมมิตจะ "ได้รับการอนุมัติจากเอเจนต์" ก่อนที่จะไปถึง Branch หลัก
ci-agent คือ Agent ไปป์ไลน์ CI แบบอัตโนมัติที่ติดตั้งใช้งานเป็นบริการ Cloud Run โดยจะส่งบิลด์ Docker ไปยัง Cloud Build, ทำการสำรวจเพื่อดูว่าบิลด์เสร็จสมบูรณ์แล้วหรือไม่, ยืนยันอิมเมจใน Artifact Registry และรายงานไปยัง GitHub

เหตุใดจึงควรใช้เอเจนต์สำหรับไปป์ไลน์ CI ไปป์ไลน์ CI ที่เป็น Agent มีข้อดีดังนี้ ซึ่งต่างจากสคริปต์แบบคงที่แบบเดิม
- การจัดประเภทขอบเขตการรับรู้: ระบบจะกำหนดความลึกของการทดสอบที่จำเป็นอย่างชาญฉลาด โดยสลับระหว่างการตรวจสอบประเภท การทดสอบหน่วย หรือชุดการทดสอบการผสานรวมแบบเต็มตามผลกระทบเชิงความหมายของการเปลี่ยนแปลงโค้ด
- การจัดการ PR แบบอัตโนมัติ: Agent สามารถสร้าง PR โดยอัตโนมัติ โพสต์สรุปการเปลี่ยนแปลงแบบละเอียด และแม้แต่จัดการการสแกนหาข้อมูลลับและการตรวจสอบความปลอดภัยโดยไม่ต้องมีคนเข้ามาเกี่ยวข้อง
- การวินิจฉัยความล้มเหลวแบบเรียลไทม์: เมื่อบิลด์ล้มเหลว เอเจนต์ไม่ได้แสดงเพียงแค่บันทึก แต่จะวิเคราะห์สแต็กเทรซ ระบุสาเหตุที่เป็นไปได้ และโพสต์การวินิจฉัยที่มนุษย์อ่านได้ไปยัง PR โดยตรง
ก. โคลนที่เก็บ CIAgent
cd ~
git clone https://github.com/gca-americas/dinoquest-ci-agent.git
cd dinoquest-ci-agent
ข. สร้างบัญชีบริการ CIAgent
gcloud iam service-accounts create ci-agent \
--display-name="CIAgent CI Pipeline"
export SA="ci-agent@${PROJECT_ID}.iam.gserviceaccount.com"
# Grant necessary roles to the service account
for ROLE in \
roles/cloudbuild.builds.editor \
roles/cloudbuild.builds.builder \
roles/artifactregistry.reader \
roles/artifactregistry.writer \
roles/aiplatform.user \
roles/secretmanager.secretAccessor \
roles/pubsub.publisher \
roles/developerconnect.admin; do
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:${SA}" --role="$ROLE" \
--condition=None
done
# ci-agent needs to act as itself when running build steps
gcloud iam service-accounts add-iam-policy-binding $SA \
--member="serviceAccount:${SA}" \
--role="roles/iam.serviceAccountUser"
ค. เชื่อมต่อที่เก็บ GitHub กับ Cloud Build
CIAgent ส่งบิลด์ผ่าน repoSource ซึ่งต้องเชื่อมต่อที่เก็บ GitHub กับ Cloud Build Developer Connect
- ไปที่ GCP Console → Cloud Build → ที่เก็บ
- คลิกเชื่อมต่อที่เก็บ
- เลือก GitHub (แอป Cloud Build GitHub)
- ให้สิทธิ์และเลือกที่เก็บ
YOUR_GITHUB_USERNAME/dinoquest - คลิกเชื่อมต่อและข้ามเมื่อระบบแจ้งให้สร้างทริกเกอร์
- จดชื่อการเชื่อมต่อ (โดยค่าเริ่มต้นมักจะเป็นชื่อผู้ใช้ GitHub หรือชื่อที่คล้ายกัน)
ง. ให้สิทธิ์เข้าถึงข้อมูลลับแก่ CIAgent
เราจะใช้ข้อมูลลับที่สร้างไว้ก่อนหน้านี้สำหรับ DinoAgent อีกครั้ง
gcloud secrets add-iam-policy-binding github-token \
--member="serviceAccount:${SA}" \
--role="roles/secretmanager.secretAccessor"
gcloud secrets add-iam-policy-binding slack-webhook-ci \
--member="serviceAccount:${SA}" \
--role="roles/secretmanager.secretAccessor"
จ. สร้างและติดตั้งใช้งาน CIAgent ใน Cloud Run
# Set up required variables for orchestration
PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format="value(projectNumber)")
export CDAGENT_URL=https://cd-agent-${PROJECT_NUMBER}.${CLOUD_RUN_REGION}.run.app
export CI_AGENT_URL=ci-agent-${PROJECT_NUMBER}.${CLOUD_RUN_REGION}.run.app
export GITHUB_OWNER="YOUR_GITHUB_USERNAME"
export CLOUD_BUILD_CONNECTION="YOUR_CONNECTION_NAME" # Update this if your connection name is different
export CLOUD_BUILD_REPO="YOUR_GITHUB_USERNAME-dinoquest" # Update this if your connection name is different
export SLACK_TOKEN=YOUR_SLACK_WEBHOOK
echo -n "https://hooks.slack.com/services/$SLACK_TOKEN" | \
gcloud secrets create slack-webhook-ci --data-file=-
export SA="ci-agent@${PROJECT_ID}.iam.gserviceaccount.com"
AGENT_IMAGE="$CLOUD_RUN_REGION-docker.pkg.dev/${PROJECT_ID}/dinoquest/ci-agent:latest"
gcloud builds submit --tag $AGENT_IMAGE .
gcloud run deploy ci-agent \
--image=$AGENT_IMAGE \
--region=$CLOUD_RUN_REGION \
--service-account=$SA \
--memory=1Gi \
--timeout=600 \
--allow-unauthenticated \
--min-instances=1 \
--set-env-vars="GOOGLE_CLOUD_PROJECT=${PROJECT_ID},GOOGLE_GENAI_USE_VERTEXAI=True" \
--set-env-vars="HARNESS_EVENTS_TOPIC=${HARNESS_EVENTS_TOPIC}" \
--set-env-vars="HOST=${CI_AGENT_URL},PROTOCOL=https" \
--set-secrets="SLACK_WEBHOOK_URL=slack-webhook-ci:latest" \
--set-env-vars="GITHUB_OWNER=${GITHUB_OWNER},GITHUB_REPO=dinoquest" \
--set-env-vars="CLOUD_BUILD_CONNECTION=${CLOUD_BUILD_CONNECTION},CLOUD_BUILD_REPO=${CLOUD_BUILD_REPO},CLOUD_BUILD_REGION=${CLOUD_RUN_REGION}" \
--set-env-vars="CDAGENT_URL=${CDAGENT_URL}" \
--set-secrets="GITHUB_TOKEN=github-token:latest" \
--min-instances=1
ฉ. การตั้งค่าคำสั่งเครื่องหมายทับของ Slack
- ไปที่ api.slack.com/apps → สร้างแอปใหม่ → ตั้งแต่ต้น
- ตั้งชื่อ
CIAgentเลือกพื้นที่ทำงาน → สร้างแอป - ในส่วนฟีเจอร์ → คำสั่งเครื่องหมายทับ → สร้างคำสั่งใหม่
- คำสั่ง:
/runci - URL ของคำขอ: URL ของ CIAgent Cloud Run จากด้านบนโดยมี
/slackต่อท้าย (เช่นhttps://ci-agent-xxx-.us-central1.run.app/slack) - คำอธิบายอย่างย่อ:
Trigger CI - บันทึก
- ในส่วนการตั้งค่า → ติดตั้งแอป ให้คลิกติดตั้งใน Workspace แล้วคลิกอนุญาต
Agent CI ทำหน้าที่เป็น "สมอง" ที่อยู่เหนือบริการ Google Cloud ที่มีประสิทธิภาพ เช่น Cloud Build และ Artifact Registry เมื่อยืนยันบิลด์แล้ว ระบบจะทริกเกอร์ระยะการติดตั้งใช้งานสุดท้ายโดยเรียกใช้เอเจนต์ CD ผ่าน A2A เพื่อให้มั่นใจว่าการส่งต่อระหว่างวงจรบิลด์และวงจรการเผยแพร่จะเป็นไปอย่างราบรื่น
9. ตั้งค่าการทำให้ใช้งานได้
บทบาทของตัวแทน: ตัวแทน CD การติดตั้งใช้งานไม่ควรเป็นการเสี่ยง เอเจนต์นี้จะจัดการความเสี่ยงให้คุณ โดยจะให้คะแนนความปลอดภัยในการติดตั้งใช้งาน จัดการการแยกการรับส่งข้อมูลของ Canary และตรวจสอบเมตริกแบบเรียลไทม์เพื่อตัดสินใจว่าจะโปรโมตการเผยแพร่หรือย้อนกลับ ซึ่งเป็นผู้ดูแลขั้นสุดท้ายในฝูงเอเจนต์อิสระ
cd-agent คือเอเจนต์การทำให้ Canary ใช้งานได้แบบอัตโนมัติที่ทำให้ใช้งานได้เป็นบริการ Cloud Run โดยจะรับคำขอการติดตั้งใช้งาน A2A จาก ci-agent คำนวณคะแนนความเสี่ยง กำหนดเปอร์เซ็นต์ Canary ที่ปรับตามความเสี่ยง ตรวจสอบเมตริก และเลื่อนระดับหรือย้อนกลับโดยอัตโนมัติ นอกจากนี้ยังเรียนรู้จากการติดตั้งใช้งานที่ผ่านมาโดยใช้ Firestore ด้วย

การเชื่อมต่อเอเจนต์โดยตรงจะสร้าง "ไปป์ไลน์การรับรู้" ซึ่งการส่งต่อแต่ละครั้งเป็นการโอนความตั้งใจและบริบทที่สมบูรณ์ การสื่อสารแบบ A2A ต่างจากเว็บฮุคแบบดั้งเดิมตรงที่ช่วยให้ทำสิ่งต่อไปนี้ได้
- การแชร์บริบทอัจฉริยะ: เจ้าหน้าที่ส่งหน่วยความจำของเซสชันทั้งหมด, ความแตกต่างของคำขอแก้ไข และคะแนนความเสี่ยง เพื่อให้เจ้าหน้าที่คนถัดไปทราบ "เหตุผล" ทั้งหมดก่อนเริ่มงาน
- การสื่อสารเพื่อทำความเข้าใจ: ตัวแทนสามารถเจรจาต่อรองเกตได้ ตัวอย่างเช่น CD Agent สามารถขอการทดสอบ Smoke Test ที่เฉพาะเจาะจงจาก CI Agent ในระหว่างการเปิดตัว Canary เพื่อยืนยันการแก้ไขแบบเรียลไทม์
- การแก้ไขร่วมกัน: หากการติดตั้งใช้งานล้มเหลว CD Agent จะแจ้งเตือน Remediation Agent อย่างรวดเร็วด้วยเมตริกที่ล้มเหลว ซึ่งจะเริ่มการวิเคราะห์หาสาเหตุหลักโดยอัตโนมัติก่อนที่ระบบจะแจ้งเตือนเจ้าหน้าที่
- การเจรจาต่อรองทรัพยากร: ตัวแทนสามารถเจรจาต่อรองความต้องการด้านโครงสร้างพื้นฐานได้ เช่น CI Agent สามารถขอให้ Remediation Agent จัดสรรความสามารถในการสร้างเพิ่มเติมได้หากตรวจพบการรีแฟกเตอร์ขนาดใหญ่ หรือ CD Agent สามารถแนะนำให้ปรับขนาดคลัสเตอร์ Production ก่อนการเปิดตัวครั้งใหญ่ได้
- ฉันทามติแบบหลายเอเจนต์: สำหรับการเปลี่ยนแปลงที่มีความเสี่ยงสูง เอเจนต์หลายราย (เช่น เอเจนต์ด้านความปลอดภัยและเอเจนต์ CD) สามารถดำเนินการ "ลงนามร่วมกัน" ผ่าน A2A เพื่อให้มั่นใจว่าโค้ดไม่เพียงแต่สร้างและติดตั้งใช้งานเท่านั้น แต่ยังเป็นไปตามนโยบายด้านความปลอดภัยก่อนที่จะเข้าสู่การผลิตด้วย
ก. โคลนที่เก็บ CDAgent
cd ~
git clone https://github.com/gca-americas/dinoquest-cd-agent.git
cd dinoquest-cd-agent
ข. สร้างฐานข้อมูล Firestore
CDAgent จะจัดเก็บรูปแบบหน่วยความจำในการติดตั้งใช้งานไว้ใน Firestore
gcloud firestore databases create \
--region=$CLOUD_RUN_REGION \
--project=$PROJECT_ID
(หากสร้างฐานข้อมูลในโปรเจ็กต์นี้แล้ว คุณสามารถข้ามขั้นตอนนี้ได้)
ค. สร้างบัญชีบริการ CDAgent
gcloud iam service-accounts create cd-agent \
--display-name="CDAgent Canary Deployer"
export SA="cd-agent@${PROJECT_ID}.iam.gserviceaccount.com"
# Grant necessary roles
for ROLE in \
roles/run.developer \
roles/iam.serviceAccountUser \
roles/artifactregistry.reader \
roles/artifactregistry.writer \
roles/monitoring.viewer \
roles/datastore.user \
roles/aiplatform.user \
roles/run.admin \
roles/pubsub.publisher; do
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:${SA}" --role="$ROLE" \
--condition=None
done
ง. ให้สิทธิ์เข้าถึงข้อมูลลับแก่ CDAgent
เราจะนำโทเค็น GitHub และเว็บฮุก Slack จากก่อนหน้านี้มาใช้ซ้ำ และให้สิทธิ์เข้าถึงบัญชีบริการของบริการประมวลผล Cloud Run สำหรับคีย์ Gemini API เพื่อให้แอปที่ติดตั้งใช้งานใช้คีย์ดังกล่าวได้
gcloud secrets add-iam-policy-binding github-token \
--member="serviceAccount:${SA}" \
--role="roles/secretmanager.secretAccessor"
gcloud secrets add-iam-policy-binding slack-webhook-cd \
--member="serviceAccount:${SA}" \
--role="roles/secretmanager.secretAccessor"
# Grant the compute service account access to Gemini API key
PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format="value(projectNumber)")
gcloud secrets add-iam-policy-binding gemini-api-key \
--project=$PROJECT_ID \
--member="serviceAccount:${PROJECT_NUMBER}-compute@developer.gserviceaccount.com" \
--role="roles/secretmanager.secretAccessor"
จ. สร้างและติดตั้งใช้งาน CDAgent ใน Cloud Run
export GITHUB_OWNER="YOUR_GITHUB_USERNAME"
export CD_AGENT_URL=cd-agent-${PROJECT_NUMBER}.${CLOUD_RUN_REGION}.run.app
export SLACK_TOKEN=YOUR_SLACK_WEBHOOK
echo -n "https://hooks.slack.com/services/$SLACK_TOKEN" | \
gcloud secrets create slack-webhook-cd --data-file=-
AGENT_IMAGE="$CLOUD_RUN_REGION-docker.pkg.dev/${PROJECT_ID}/dinoquest/cd-agent:latest"
gcloud builds submit --tag $AGENT_IMAGE .
export SA="cd-agent@${PROJECT_ID}.iam.gserviceaccount.com"
gcloud run deploy cd-agent \
--image=$AGENT_IMAGE \
--region=$CLOUD_RUN_REGION \
--service-account=$SA \
--memory=1Gi \
--set-env-vars="GOOGLE_CLOUD_PROJECT=${PROJECT_ID}" \
--set-env-vars="GOOGLE_GENAI_USE_VERTEXAI=True" \
--set-env-vars="HOST=${CD_AGENT_URL},PROTOCOL=https" \
--set-env-vars="CD_TARGET_SERVICE=dinoquest" \
--set-env-vars="HARNESS_EVENTS_TOPIC=${HARNESS_EVENTS_TOPIC}" \
--set-env-vars="GITHUB_OWNER=${GITHUB_OWNER}" \
--set-env-vars="GITHUB_REPO=dinoquest" \
--set-env-vars="DEMO_MODE=true" \
--set-env-vars="LEADERBOARD_ENABLED=true" \
--set-secrets="SLACK_WEBHOOK_URL=slack-webhook-cd:latest" \
--set-secrets="GITHUB_TOKEN=github-token:latest" \
--allow-unauthenticated \
--min-instances=1 \
--no-cpu-throttling \
--timeout=300
หมายเหตุ: --min-instances=1 --no-cpu-throttling จะทำให้อินสแตนซ์พร้อมใช้งานอยู่เสมอเพื่อให้ตอบสนองต่อคำสั่งใน Slack และ A2A ได้อย่างรวดเร็ว
เอเจนต์ CD เป็นผู้ดูแลขั้นสุดท้ายของสภาพแวดล้อมฮาร์ดแวร์และซอฟต์แวร์ โดยจะประเมินความเสี่ยงของการติดตั้งใช้งานแต่ละครั้ง เรียกใช้การทดสอบเวอร์ชันใหม่ และตรวจสอบเมตริกแบบเรียลไทม์ หากตรวจพบความผิดปกติ ระบบจะเริ่มการย้อนกลับโดยอัตโนมัติ
10. การขยายขนาด: ปลดล็อกระดับ 2 ด้วย Agent Swarm
ก. ทดสอบ Full Swarm
- ทริกเกอร์ข้อผิดพลาด: เปิด URL ของ DinoQuest ที่คุณติดตั้งใช้งาน (จากขั้นตอนสุดท้าย) ในเบราว์เซอร์
- ไปที่ลีดเดอร์บอร์ด: คลิกปุ่มลีดเดอร์บอร์ด การติดตั้งใช้งานลีดเดอร์บอร์ดในปัจจุบันตั้งใจให้ไม่มีประสิทธิภาพ ซึ่งจะพยายามโหลดข้อมูลจำนวนมากไปยังหน่วยความจำ ซึ่งจะทําให้เกิดข้อผิดพลาดหน่วยความจำไม่พอ (OOM)
- รอ Agent: ภายในประมาณ 60 วินาที
remediation-agentจะได้รับเหตุการณ์ข้อผิดพลาดผ่าน Eventarc และเริ่มการวินิจฉัย - ตรวจสอบ Slack: คุณควรเห็นการแจ้งเตือนในช่อง Slack ที่มีลักษณะดังนี้สรุปการแก้ไขของ DinoAgent
- บริการ: dinoquest
- การแก้ไขที่ไม่สำเร็จ: dinoquest-xxxx-xxxx
- หลักฐาน: "ใช้หน่วยความจำเกินขีดจำกัด 128 MiB โดยใช้ไป 13x MiB"
- เหตุใดการแก้ไขนี้จึงไม่ดี: ปลายทาง
/api/leaderboardxxxxx อย่างไม่มีประสิทธิภาพ ทำให้เกิดข้อผิดพลาด OOM - การดำเนินการที่ทำ: เพิ่มหน่วยความจำจาก xMi เป็น yGi สำหรับบริการ
dinoquestสร้างการแก้ไขใหม่แล้ว - PR สาเหตุของปัญหา: https://github.com/YOUR_USERNAME/DinoQuest/pull/x
- ยืนยันการแก้ไข
- GitHub: ตรวจสอบที่เก็บเพื่อหา Branch ใหม่และคำขอ Pull เอเจนต์ได้แก้ไขโค้ดของแอปพลิเคชันเพื่อแก้ไขหน่วยความจำรั่วไหลพื้นฐาน
- Cloud Run: ในคอนโซล GCP คุณจะเห็นรีวิชันใหม่ของบริการ
dinoquestที่มีการจัดสรรหน่วยความจำที่อัปเดตแล้ว - ลีดเดอร์บอร์ด: ลองใช้ลีดเดอร์บอร์ดอีกครั้ง ตอนนี้ควรโหลดได้สำเร็จแล้วเนื่องจากมีการเพิ่มหน่วยความจำและแก้ไขโค้ดในที่สุด
ข. Evolution: Implementing Level 2 Game Logic
คุณจะเพิ่มฟีเจอร์ใหม่ที่สำคัญ นั่นคือเลเวล 2 (ทำลายดาวเคราะห์น้อย) ซึ่งจะช่วยให้ไดโนเสาร์ที่มีคะแนนสูงได้เลื่อนไปสู่โหมดเกมใหม่
- กลับไปที่ที่เก็บ dinoquest
cd ~/dinoquest - สร้างและเปลี่ยนไปใช้ Branch ใหม่
git checkout -b level_2 - ใช้แพตช์ระดับ 2: เรียกใช้สคริปต์ที่ให้ไว้เพื่อแก้ไขฐานของโค้ดในเครื่องด้วยชิ้นงาน คอมโพเนนต์ และตรรกะของเกมระดับ 2
bash level_2_backup/levelup.sh - คอมมิตและพุชการเปลี่ยนแปลง
git add . git commit -m "feat: add Level 2" git push origin level_2
แทนที่จะใช้ curl เพื่อทริกเกอร์เอเจนต์ด้วยตนเอง เราจะใช้คำสั่ง Slack Slash ที่คุณกำหนดค่าไว้ก่อนหน้านี้ นี่คือวิธีที่คุณโต้ตอบกับไปป์ไลน์ CI แบบอัตโนมัติในสถานการณ์จริง
- เปิด Slack แล้วไปที่ช่องที่ติดตั้งแอป
CIAgent - ทริกเกอร์บิลด์ CI โดยพิมพ์คำสั่งต่อไปนี้
/runci run ci on branch level_2 - ตรวจสอบความคืบหน้า
- Slack: เอเจนต์จะรับทราบคำสั่งของคุณและโพสต์ข้อมูลอัปเดตเมื่อบิลด์คืบหน้า
- Dino Theater: ดู "ฟองความคิด" ขณะที่เอเจนต์จัดประเภทการเปลี่ยนแปลง ส่งงาน Cloud Build และสื่อสารกับเอเจนต์ CD
- GitHub: ตรวจสอบ
level_2PR คุณจะเห็นเอเจนต์โพสต์สถานะการคอมมิตและความคิดเห็นรายงาน CI แบบเต็ม
- ดูขั้นตอน
- ดูว่า CI Agent คิดอย่างไร จัดประเภทการเปลี่ยนแปลง และเรียกใช้ไปป์ไลน์ได้ที่Dino Theater
- ตรวจสอบ PR ของ GitHub เพื่อดูว่า CI Agent โพสต์สถานะการคอมมิตและรายงานสุดท้ายหรือไม่
11. บทสรุป
คุณได้สร้างสแต็ก DevOps ที่สมบูรณ์แบบบน Google Cloud แล้ว
ส่วนประกอบ | การทำงาน |
DinoQuest (Cloud Run | เกมที่ทำงานด้วย Gemini - ส่วนหน้า React + ส่วนหลัง FastAPI |
Firebase Auth + Firestore | การตรวจสอบสิทธิ์ผู้ใช้และการจัดเก็บโปรไฟล์ไดโนเสาร์ |
Agent การแก้ไข (Cloud Run + Eventarc) | ตัวแทน SRE ที่แก้ไขข้อผิดพลาด OOM และข้อบกพร่องของโค้ดโดยอัตโนมัติ |
log-router-bq-report | ตัวแทนข้อมูลที่สตรีมบันทึกไปยัง BigQuery และสร้างข้อมูลเชิงลึก |
CIAgent (Cloud Run) | CI Agent ที่กำหนดขอบเขตการทดสอบ สร้างอิมเมจ และเรียกใช้ CD ผ่าน A2A |
CDAgent (Cloud Run) | เอเจนต์ CD ที่เรียกใช้การติดตั้งใช้งาน Canary ที่ให้คะแนนความเสี่ยงพร้อมการเปลี่ยนกลับอัตโนมัติ |
ลักษณะการทำงานของ Agent ทั้งหมดจะอยู่ในไดเรกทอรี skills/ เป็นเพลย์บุ๊ก Markdown โดยเปลี่ยนลักษณะการทำงานด้วยการแก้ไขทักษะ ไม่ใช่โค้ด ทักษะจะทำงานบน Antigravity ด้วย Gemini และจะเรียกใช้ได้โดยการบอก Agent ว่าจะเรียกใช้ทักษะใด