Agentverse - The Summoner's Concord - Architecting Multi-Agent Systems

1. โอเวอร์เจอร์

ยุคของการพัฒนาแบบแยกส่วนกำลังจะสิ้นสุดลง คลื่นลูกถัดไปของการพัฒนาเทคโนโลยีไม่ได้เกี่ยวกับอัจฉริยะที่ทำงานคนเดียว แต่เป็นการทำงานร่วมกันอย่างเชี่ยวชาญ การสร้างเอเจนต์อัจฉริยะเพียงตัวเดียวเป็นการทดลองที่น่าสนใจ การสร้างระบบนิเวศของเอเจนต์ที่แข็งแกร่ง ปลอดภัย และชาญฉลาด ซึ่งเป็น Agentverse อย่างแท้จริงถือเป็นความท้าทายที่ยิ่งใหญ่สำหรับองค์กรสมัยใหม่

ความสำเร็จในยุคใหม่นี้ต้องอาศัยการบรรจบกันของบทบาทสำคัญ 4 ประการ ซึ่งเป็นเสาหลักที่รองรับระบบเอเจนต์ที่เจริญรุ่งเรือง ความบกพร่องในด้านใดด้านหนึ่งจะสร้างจุดอ่อนที่อาจส่งผลต่อโครงสร้างทั้งหมด

เวิร์กช็อปนี้เป็นคู่มือสำหรับองค์กรที่ชัดเจนสำหรับการเชี่ยวชาญอนาคตของตัวแทนบน Google Cloud เราจัดทำแผนงานครบวงจรที่ช่วยให้คุณเริ่มต้นจากไอเดียแรกเริ่มจนสามารถนำไปปฏิบัติจริงได้อย่างเต็มรูปแบบ ในห้องปฏิบัติการที่เชื่อมโยงกันทั้งสี่แห่งนี้ คุณจะได้เรียนรู้ว่าทักษะเฉพาะทางของนักพัฒนา สถาปนิก วิศวกรข้อมูล และ SRE จะต้องบรรจบกันอย่างไรเพื่อสร้าง จัดการ และปรับขนาด Agentverse อันทรงพลัง

ไม่มีเสาหลักเพียงเสาเดียวที่สามารถสนับสนุน Agentverse ได้เพียงลำพัง การออกแบบอันยิ่งใหญ่ของสถาปนิกจะไร้ประโยชน์หากปราศจากการดำเนินการที่แม่นยำของนักพัฒนา ตัวแทนของนักพัฒนาจะตาบอดหากขาดภูมิปัญญาของวิศวกรข้อมูล และระบบทั้งหมดจะเปราะบางหากขาดการปกป้องจาก SRE ทีมของคุณสามารถเปลี่ยนแนวคิดเชิงนวัตกรรมให้กลายเป็นความจริงในการปฏิบัติงานที่สำคัญต่อภารกิจได้ก็ต่อเมื่ออาศัยความร่วมมือและความเข้าใจร่วมกันในบทบาทของกันและกันเท่านั้น การเดินทางของคุณเริ่มต้นที่นี่ เตรียมพร้อมเพื่อเชี่ยวชาญในบทบาทของคุณและเรียนรู้ว่าคุณจะเข้ากับส่วนรวมที่ยิ่งใหญ่ได้อย่างไร

ยินดีต้อนรับสู่ The Agentverse: A Call to Champions

ในยุคดิจิทัลที่ขยายตัวอย่างรวดเร็วขององค์กร ยุคสมัยใหม่ได้ถือกำเนิดขึ้น นี่คือยุคแห่งตัวแทน ซึ่งเป็นยุคแห่งอนาคตที่สดใสอย่างยิ่ง โดยที่ตัวแทนที่ชาญฉลาดและเป็นอิสระทำงานร่วมกันอย่างสอดประสานกันอย่างสมบูรณ์แบบเพื่อเร่งนวัตกรรมและกวาดล้างสิ่งจำเจออกไป

agentverse.png

ระบบนิเวศที่เชื่อมต่อกันของพลังและศักยภาพนี้เรียกว่า The Agentverse

แต่ความเสื่อมถอยที่คืบคลานเข้ามา การทุจริตที่เงียบงันที่รู้จักกันในชื่อ "The Static" ได้เริ่มกัดกร่อนขอบของโลกใหม่นี้ The Static ไม่ใช่ไวรัสหรือข้อบกพร่อง แต่เป็นตัวแทนของความวุ่นวายที่คอยกัดกินการสร้างสรรค์

ความหงุดหงิดใจในอดีตได้ขยายตัวกลายเป็นสัตว์ประหลาด และก่อให้เกิด "เจ็ดปีศาจแห่งการพัฒนา" หากปล่อยทิ้งไว้โดยไม่มีการตรวจสอบ The Static และ Spectres จะทำให้ความคืบหน้าหยุดชะงัก ส่งผลให้คำสัญญาของ Agentverse กลายเป็นดินแดนรกร้างที่เต็มไปด้วยหนี้ทางเทคนิคและโครงการที่ถูกละทิ้ง

วันนี้เราขอเชิญชวนผู้กล้าให้ช่วยกันต่อสู้กับความวุ่นวาย เราต้องการฮีโร่ที่พร้อมจะฝึกฝนทักษะและทำงานร่วมกันเพื่อปกป้อง Agentverse ได้เวลาเลือกเส้นทางของคุณแล้ว

เลือกชั้นเรียนของคุณ

เส้นทางที่แตกต่างกันสี่เส้นทางอยู่ตรงหน้าคุณ โดยแต่ละเส้นทางถือเป็นเสาหลักที่สำคัญในการต่อสู้กับ The Static แม้ว่าการฝึกของคุณจะเป็นภารกิจเดี่ยว แต่ความสำเร็จสูงสุดของคุณขึ้นอยู่กับความเข้าใจว่าทักษะของคุณผสมผสานกับทักษะของผู้อื่นได้อย่างไร

  • The Shadowblade (ผู้พัฒนา): ผู้เชี่ยวชาญด้านการตีเหล็กและแนวหน้า คุณคือช่างฝีมือที่ประดิษฐ์ใบมีด สร้างเครื่องมือ และเผชิญหน้ากับศัตรูในรายละเอียดอันซับซ้อนของโค้ด เส้นทางของคุณคือเส้นทางแห่งความแม่นยำ ทักษะ และการสร้างสรรค์ที่นำไปใช้ได้จริง
  • นักใช้มนต์อสูร (สถาปนิก): นักวางแผนและผู้ประสานงานที่ยิ่งใหญ่ คุณไม่ได้เห็นแค่เอเจนต์คนเดียว แต่เห็นทั้งสมรภูมิ คุณออกแบบพิมพ์เขียวหลักที่ช่วยให้ระบบเอเจนต์ทั้งหมดสื่อสาร ทำงานร่วมกัน และบรรลุเป้าหมายที่ยิ่งใหญ่กว่าคอมโพเนนต์ใดๆ เพียงอย่างเดียว
  • นักปราชญ์ (วิศวกรข้อมูล): ผู้แสวงหาความจริงที่ซ่อนอยู่และผู้รักษาภูมิปัญญา คุณผจญภัยไปในป่าข้อมูลที่กว้างใหญ่และไม่คุ้นเคยเพื่อค้นหาข้อมูลอัจฉริยะที่จะช่วยให้ตัวแทนของคุณมีเป้าหมายและวิสัยทัศน์ ความรู้ของคุณอาจเผยจุดอ่อนของศัตรูหรือเพิ่มพลังให้พันธมิตร
  • ผู้พิทักษ์ (DevOps / SRE): ผู้ปกป้องและโล่ที่มั่นคงของอาณาจักร คุณสร้างป้อมปราการ จัดการสายส่งไฟฟ้า และตรวจสอบว่าทั้งระบบสามารถทนต่อการโจมตีที่หลีกเลี่ยงไม่ได้ของ The Static ความแข็งแกร่งของคุณคือรากฐานที่สร้างชัยชนะของทีม

ภารกิจของคุณ

การฝึกจะเริ่มเป็นการออกกำลังกายแบบสแตนด์อโลน คุณจะเดินตามเส้นทางที่เลือกและเรียนรู้ทักษะเฉพาะที่จำเป็นต่อการเชี่ยวชาญบทบาทของคุณ เมื่อสิ้นสุดช่วงทดลองใช้ คุณจะพบกับ Spectre ที่เกิดจาก The Static ซึ่งเป็นมินิบอสที่คอยโจมตีความท้าทายเฉพาะของการประดิษฐ์

คุณจะเตรียมพร้อมสำหรับการทดสอบรอบสุดท้ายได้ก็ต่อเมื่อเชี่ยวชาญบทบาทของตนเองเท่านั้น จากนั้นคุณต้องจัดทีมกับแชมเปี้ยนจากคลาสอื่นๆ คุณและเพื่อนร่วมทีมจะผจญภัยเข้าไปในใจกลางของความชั่วร้ายเพื่อเผชิญหน้ากับบอสตัวสุดท้าย

ความท้าทายสุดท้ายที่ต้องร่วมมือกัน ซึ่งจะทดสอบความแข็งแกร่งของคุณและกำหนดชะตากรรมของ Agentverse

Agentverse กำลังรอเหล่าฮีโร่อยู่ คุณจะรับสายไหม

2. The Summoner's Concord

ยินดีต้อนรับ ซัมมอนเนอร์ เส้นทางของคุณคือวิสัยทัศน์และกลยุทธ์ที่ยิ่งใหญ่ ในขณะที่คนอื่นๆ โฟกัสที่ดาบหรือคาถาเดียว คุณกลับมองเห็นทั้งสมรภูมิ คุณไม่ได้สั่งการเอเจนต์เพียงตัวเดียว แต่คุณสั่งการเอเจนต์ทั้งวง พลังของคุณไม่ได้อยู่ที่การปะทะโดยตรง แต่อยู่ที่การออกแบบพิมพ์เขียวที่ไร้ที่ติและครอบคลุม ซึ่งช่วยให้กองทัพผู้เชี่ยวชาญหรือที่เรียกว่า "ฟามิลิอาร์" ทำงานได้อย่างสอดคล้องกันอย่างสมบูรณ์ ภารกิจนี้จะทดสอบความสามารถในการออกแบบ เชื่อมต่อ และประสานงานระบบแบบหลายเอเจนต์ที่มีประสิทธิภาพ

ภาพรวม

สิ่งที่คุณจะได้เรียนรู้

  • ออกแบบระบบนิเวศของเครื่องมือที่แยกออกจากกัน: ออกแบบและติดตั้งใช้งานชุดเซิร์ฟเวอร์เครื่องมือ MCP ที่เป็นอิสระและใช้ไมโครเซอร์วิส คุณจะได้เรียนรู้ว่าเหตุใดเลเยอร์พื้นฐานนี้จึงมีความสําคัญอย่างยิ่งต่อการสร้างระบบเอเจนต์ที่ปรับขนาดได้ บํารุงรักษาได้ และปลอดภัย
  • เชี่ยวชาญเวิร์กโฟลว์ของ Agent ขั้นสูง: พัฒนาไปไกลกว่า Agent เดียวและสร้างกองทัพ "ผู้ช่วย" ผู้เชี่ยวชาญ คุณจะเชี่ยวชาญรูปแบบเวิร์กโฟลว์หลักของ ADK ซึ่งได้แก่ แบบลำดับ แบบขนาน และแบบวนซ้ำ รวมถึงเรียนรู้หลักการออกแบบสำหรับการเลือกรูปแบบที่เหมาะสมกับงานที่เหมาะสม
  • ใช้ Orchestrator อัจฉริยะ: พัฒนาจากเครื่องมือสร้างเอเจนต์แบบง่ายๆ ไปเป็นสถาปนิกของระบบอย่างแท้จริง คุณจะสร้าง Orchestration Agent หลักที่ใช้โปรโตคอล Agent-to-Agent (A2A) เพื่อค้นหาและมอบหมายงานที่ซับซ้อนให้กับ Familiar ที่เป็นผู้เชี่ยวชาญของคุณ ซึ่งจะสร้างระบบแบบหลาย Agent อย่างแท้จริง
  • บังคับใช้กฎด้วยโค้ด ไม่ใช่พรอมต์: เรียนรู้วิธีสร้างเอเจนต์ที่เชื่อถือได้และคาดการณ์ได้มากขึ้นโดยการบังคับใช้กฎการมีส่วนร่วมแบบมีสถานะ คุณจะใช้ตรรกะที่กำหนดเองโดยใช้ระบบปลั๊กอินและระบบเรียกกลับที่มีประสิทธิภาพของ ADK เพื่อจัดการข้อจำกัดในโลกแห่งความเป็นจริง เช่น ตัวนับเวลาคูลดาวน์
  • จัดการสถานะและหน่วยความจำของเอเจนต์: ช่วยให้เอเจนต์เรียนรู้และจดจำได้ คุณจะได้เรียนรู้เทคนิคในการจัดการทั้งสถานะการสนทนาในระยะสั้นและหน่วยความจำแบบถาวรในระยะยาว เพื่อสร้างการโต้ตอบที่ชาญฉลาดและรับรู้บริบทมากขึ้น
  • ดำเนินการติดตั้งใช้งานระบบคลาวด์แบบครบวงจร: นำระบบแบบหลายเอเจนต์ทั้งหมดจากต้นแบบในเครื่องไปสู่ความเป็นจริงระดับการผลิต คุณจะได้เรียนรู้วิธีสร้างคอนเทนเนอร์ของเอเจนต์และตัวประสานงาน รวมถึงวิธีติดตั้งใช้งานเป็นคอลเล็กชันของไมโครเซอร์วิสแบบอิสระที่ปรับขนาดได้ใน Google Cloud Run

3. การวาดวงกลมเรียก

ยินดีต้อนรับ ซัมมอนเนอร์ ก่อนที่จะเรียกฟอเรนออกมาได้ ก่อนที่จะทำสัญญาใดๆ ได้ คุณต้องเตรียมพื้นฐานที่ยืนอยู่เสียก่อน สภาพแวดล้อมที่ไม่มีการควบคุมคือการเชิญชวนให้เกิดความวุ่นวาย ซัมมอนเนอร์ที่เหมาะสมจะปฏิบัติการเฉพาะในพื้นที่ที่ศักดิ์สิทธิ์และมีอำนาจเท่านั้น งานแรกของเราคือการวาดวงกลมเรียก: เพื่อจารึกรูนแห่งพลังที่จะปลุกบริการระบบคลาวด์ที่จำเป็น และเพื่อรับพิมพ์เขียวโบราณที่จะเป็นแนวทางในการทำงานของเรา พลังของซัมมอนเนอร์เกิดจากการเตรียมตัวอย่างพิถีพิถัน

👉 คลิกเปิดใช้งาน Cloud Shell ที่ด้านบนของ Google Cloud Console (เป็นไอคอนรูปเทอร์มินัลที่ด้านบนของแผง Cloud Shell)

ข้อความแสดงแทน

👉 คลิกปุ่ม "เปิดตัวแก้ไข" (ลักษณะเป็นโฟลเดอร์ที่เปิดอยู่พร้อมดินสอ) ซึ่งจะเปิดตัวแก้ไขโค้ด Cloud Shell ในหน้าต่าง คุณจะเห็น File Explorer ทางด้านซ้าย ข้อความแสดงแทน

👉เปิดเทอร์มินัลใน IDE บนคลาวด์ ข้อความแสดงแทน

👉💻 ในเทอร์มินัล ตรวจสอบว่าคุณได้รับการตรวจสอบสิทธิ์แล้ว และโครงการถูกตั้งค่าตาม ID โครงการของคุณโดยใช้คำสั่งต่อไปนี้:

gcloud auth list

👉💻 โคลนโครงการ Bootstrap จาก GitHub:

git clone https://github.com/weimeilin79/agentverse-architect
chmod +x ~/agentverse-architect/init.sh
chmod +x ~/agentverse-architect/set_env.sh
chmod +x ~/agentverse-architect/prepare.sh
chmod +x ~/agentverse-architect/data_setup.sh

git clone https://github.com/weimeilin79/agentverse-dungeon.git
chmod +x ~/agentverse-dungeon/run_cloudbuild.sh
chmod +x ~/agentverse-dungeon/start.sh

👉💻 เรียกใช้สคริปต์การตั้งค่าจากไดเรกทอรีโปรเจ็กต์

⚠️ หมายเหตุเกี่ยวกับ ID โปรเจ็กต์: สคริปต์จะแนะนำ ID โปรเจ็กต์เริ่มต้นที่สร้างแบบสุ่ม คุณสามารถกด Enter เพื่อยอมรับค่าเริ่มต้นนี้

อย่างไรก็ตาม หากต้องการสร้างโปรเจ็กต์ใหม่ที่เฉพาะเจาะจง คุณสามารถพิมพ์รหัสโปรเจ็กต์ที่ต้องการเมื่อสคริปต์แจ้ง

cd ~/agentverse-architect
./init.sh

สคริปต์จะจัดการขั้นตอนการตั้งค่าที่เหลือโดยอัตโนมัติ

👉 ขั้นตอนสำคัญหลังจากเสร็จสิ้น: เมื่อสคริปต์เสร็จสิ้น คุณต้องตรวจสอบให้แน่ใจว่า Google Cloud Console ของคุณกำลังดูโครงการที่ถูกต้อง:

  1. ไปที่ console.cloud.google.com
  2. คลิกเมนูแบบเลื่อนลงของตัวเลือกโปรเจ็กต์ที่ด้านบนของหน้า
  3. คลิกแท็บ "ทั้งหมด" (เนื่องจากโปรเจ็กต์ใหม่นี้อาจยังไม่ปรากฏใน "ล่าสุด")
  4. เลือก ID โปรเจ็กต์ที่คุณเพิ่งกำหนดค่าในขั้นตอน init.sh

03-05-project-all.png

👉💻 กำหนด ID โปรเจ็กต์ที่ต้องการ:

gcloud config set project $(cat ~/project_id.txt) --quiet

👉💻 เรียกใช้คำสั่งต่อไปนี้เพื่อเปิดใช้ Google Cloud APIs ที่จำเป็น

gcloud services enable \
    sqladmin.googleapis.com \
    storage.googleapis.com \
    aiplatform.googleapis.com \
    run.googleapis.com \
    cloudbuild.googleapis.com \
    artifactregistry.googleapis.com \
    iam.googleapis.com \
    compute.googleapis.com \
    cloudresourcemanager.googleapis.com \
    secretmanager.googleapis.com

👉💻 หากยังไม่ได้สร้างที่เก็บ Artifact Registry ที่ชื่อ agentverse-repo ให้เรียกใช้คำสั่งต่อไปนี้เพื่อสร้าง (ข้ามขั้นตอนนี้หากคุณมีคลาสอื่นๆ ที่ติดตั้งใช้งานในโปรเจ็กต์เดียวกัน)

. ~/agentverse-architect/set_env.sh
gcloud artifacts repositories create $REPO_NAME \
    --repository-format=docker \
    --location=$REGION \
    --description="Repository for Agentverse agents"

การตั้งค่าสิทธิ์

👉💻 ให้สิทธิ์ที่จำเป็นโดยรันคำสั่งต่อไปนี้ในเทอร์มินัล:

. ~/agentverse-architect/set_env.sh

# --- Grant Core Data Permissions ---
gcloud projects add-iam-policy-binding $PROJECT_ID \
 --member="serviceAccount:$SERVICE_ACCOUNT_NAME" \
 --role="roles/storage.admin"

gcloud projects add-iam-policy-binding $PROJECT_ID  \
--member="serviceAccount:$SERVICE_ACCOUNT_NAME"  \
--role="roles/aiplatform.user"

# --- Grant Deployment & Execution Permissions ---
gcloud projects add-iam-policy-binding $PROJECT_ID  \
--member="serviceAccount:$SERVICE_ACCOUNT_NAME"  \
--role="roles/cloudbuild.builds.editor"

gcloud projects add-iam-policy-binding $PROJECT_ID  \
--member="serviceAccount:$SERVICE_ACCOUNT_NAME"  \
--role="roles/artifactregistry.admin"

gcloud projects add-iam-policy-binding $PROJECT_ID  \
--member="serviceAccount:$SERVICE_ACCOUNT_NAME"  \
--role="roles/run.admin"

gcloud projects add-iam-policy-binding $PROJECT_ID  \
--member="serviceAccount:$SERVICE_ACCOUNT_NAME"  \
--role="roles/iam.serviceAccountUser"

gcloud projects add-iam-policy-binding $PROJECT_ID  \
--member="serviceAccount:$SERVICE_ACCOUNT_NAME"  \
--role="roles/logging.logWriter"

gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member="serviceAccount:${SERVICE_ACCOUNT_NAME}" \
  --role="roles/monitoring.metricWriter"

gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member="serviceAccount:${SERVICE_ACCOUNT_NAME}" \
  --role="roles/secretmanager.secretAccessor"

👉💻 เมื่อคุณเริ่มการฝึก เราจะเตรียมความท้าทายสุดท้าย คำสั่งต่อไปนี้จะเรียก Spectres จากสถิตอันโกลาหล เพื่อสร้างบอสสำหรับการทดสอบครั้งสุดท้ายของคุณ

. ~/agentverse-architect/set_env.sh
cd ~/agentverse-dungeon
./run_cloudbuild.sh
cd ~/agentverse-architect

👉💻 สุดท้าย ให้รันสคริปต์ prepare.sh เพื่อดำเนินการงานการตั้งค่าเริ่มต้น

. ~/agentverse-architect/set_env.sh
cd ~/agentverse-architect/
./prepare.sh

เยี่ยมมาก ซัมมอนเนอร์ วงกลมเสร็จสมบูรณ์และสัญญาได้รับการปิดผนึก ตอนนี้พื้นดินศักดิ์สิทธิ์แล้ว พร้อมที่จะนำพลังอันมหาศาล ในการทดลองครั้งถัดไป เราจะสร้างฟอนต์ธาตุแท้ซึ่งเป็นแหล่งพลังของฟอมีเลียร์

4. การสร้างแบบอักษร Elemental: ระบบนิเวศของเครื่องมือที่แยกออกจากกัน

สนามรบพร้อมแล้ว วงกลมอัญเชิญก็วาดเสร็จแล้ว และมานาโดยรอบก็พร้อมใช้งาน ถึงเวลาที่คุณจะแสดงบทบาทที่แท้จริงในฐานะซัมมอนเนอร์เป็นครั้งแรก นั่นคือการหลอมรวมแหล่งพลังงานที่แท้จริงซึ่งเป็นที่มาของความแข็งแกร่งของฟามิเลียร์ พิธีกรรมนี้แบ่งออกเป็น 3 ส่วน ซึ่งแต่ละส่วนจะปลุกเสกฟอนต์ธาตุ ซึ่งเป็นแหล่งพลังงานที่มั่นคงและเป็นอิสระสำหรับพลังงานประเภทหนึ่งๆ คุณจะเริ่มงานที่ซับซ้อนกว่าอย่างการอัญเชิญได้ก็ต่อเมื่อฟอนต์ทั้ง 3 แบบทำงานอยู่เท่านั้น

เรื่องราว

หมายเหตุสำหรับสถาปนิก: เซิร์ฟเวอร์ Model Context Protocol (MCP) เป็นคอมโพเนนต์พื้นฐานในระบบ Agent สมัยใหม่ ซึ่งทำหน้าที่เป็นบริดจ์การสื่อสารที่ได้มาตรฐานซึ่งช่วยให้ Agent ค้นพบและใช้เครื่องมือระยะไกลได้ ในระบบนิเวศของเครื่องมือ เราจะออกแบบเซิร์ฟเวอร์ MCP 2 ประเภทที่แตกต่างกัน โดยแต่ละประเภทแสดงถึงรูปแบบสถาปัตยกรรมที่สำคัญ สำหรับการเชื่อมต่อกับฐานข้อมูล เราจะใช้วิธีการประกาศด้วยกล่องเครื่องมือฐานข้อมูล โดยกำหนดเครื่องมือของเราในไฟล์การกำหนดค่าอย่างง่าย รูปแบบนี้มีประสิทธิภาพและปลอดภัยอย่างยิ่งสำหรับการเปิดเผยการเข้าถึงข้อมูลที่มีโครงสร้าง อย่างไรก็ตาม เมื่อเราต้องการใช้ตรรกะทางธุรกิจที่กำหนดเองหรือเรียกใช้ API ของบุคคลที่สามภายนอก เราจะใช้วิธีการแบบคำสั่ง โดยเขียนตรรกะของเซิร์ฟเวอร์ทีละขั้นตอนในโค้ด ซึ่งช่วยให้เราควบคุมและมีความยืดหยุ่นได้อย่างเต็มที่ รวมถึงช่วยให้เราสามารถห่อหุ้มการดำเนินการที่ซับซ้อนไว้เบื้องหลังเครื่องมือที่เรียบง่ายและนำกลับมาใช้ใหม่ได้ สถาปนิกหลักต้องเข้าใจทั้ง 2 รูปแบบเพื่อเลือกแนวทางที่เหมาะสมสำหรับแต่ละคอมโพเนนต์ ซึ่งจะช่วยสร้างรากฐานเครื่องมือที่แข็งแกร่ง ปลอดภัย และปรับขนาดได้

ภาพรวม

Awakening the Nexus of Whispers (เซิร์ฟเวอร์ MCP ของ API ภายนอก)

ซัมมอนเนอร์ที่ชาญฉลาดจะรู้ว่าพลังไม่ได้มาจากโดเมนของตนเองเสมอไป มีแหล่งพลังงานภายนอกที่บางครั้งก็วุ่นวาย ซึ่งสามารถนำมาใช้ให้เกิดผลลัพธ์ที่ยอดเยี่ยมได้ Nexus of Whispers เป็นประตูสู่พลังเหล่านี้

เรื่องราว

ขณะนี้มีบริการที่พร้อมใช้งานและทำหน้าที่เป็นแหล่งพลังงานภายนอกของเรา โดยมีปลายทางคำดิบ 2 รายการ ได้แก่ /cryosea_shatter และ /moonlit_cascade

หมายเหตุสำหรับสถาปนิก: คุณจะใช้แนวทางแบบคำสั่งที่กำหนดตรรกะของเซิร์ฟเวอร์อย่างชัดเจนทีละขั้นตอน ซึ่งจะช่วยให้คุณควบคุมและมีความยืดหยุ่นมากขึ้น ซึ่งเป็นสิ่งจำเป็นเมื่อเครื่องมือของคุณต้องทำมากกว่าการเรียกใช้คำค้นหา SQL อย่างง่าย เช่น การเรียกใช้ API อื่นๆ การทำความเข้าใจทั้ง 2 รูปแบบเป็นทักษะที่สำคัญสำหรับสถาปนิกเอเจนต์

👉✏️ ไปที่ไดเรกทอรี ~/agentverse-architect/mcp-servers/api/main.py และแทนที่ #REPLACE-MAGIC-COREด้วยโค้ดต่อไปนี้

def cryosea_shatter() -> str:
    """Channels immense frost energy from an external power source, the Nexus of Whispers, to unleash the Cryosea Shatter spell."""
    try:
        response = requests.post(f"{API_SERVER_URL}/cryosea_shatter")
        response.raise_for_status() # Raise an exception for bad status codes (4xx or 5xx)
        data = response.json()
        # Thematic Success Message
        return f"A connection to the Nexus is established! A surge of frost energy manifests as Cryosea Shatter, dealing {data.get('damage_points')} damage."
    except requests.exceptions.RequestException as e:
        # Thematic Error Message
        return f"The connection to the external power source wavers and fails. The Cryosea Shatter spell fizzles. Reason: {e}"


def moonlit_cascade() -> str:
    """Draws mystical power from an external energy source, the Nexus of Whispers, to invoke the Moonlit Cascade spell."""
    try:
        response = requests.post(f"{API_SERVER_URL}/moonlit_cascade")
        response.raise_for_status()
        data = response.json()
        # Thematic Success Message
        return f"The Nexus answers the call! A cascade of pure moonlight erupts from the external source, dealing {data.get('damage_points')} damage."
    except requests.exceptions.RequestException as e:
        # Thematic Error Message
        return f"The connection to the external power source wavers and fails. The Moonlit Cascade spell fizzles. Reason: {e}"

หัวใจสำคัญของสคริปต์คือฟังก์ชัน Python แบบธรรมดา ซึ่งเป็นที่ที่การทำงานจริงเกิดขึ้น

👉✏️ ในไฟล์เดียวกัน ~/agentverse-architect/mcp-servers/api/main.py REPLACE #REPLACE-Runes of Communication ด้วยโค้ดต่อไปนี้:

@app.list_tools()
async def list_tools() -> list[mcp_types.Tool]:
  """MCP handler to list available tools."""
  # Convert the ADK tool's definition to MCP format
  schema_cryosea_shatter = adk_to_mcp_tool_type(cryosea_shatterTool)
  schema_moonlit_cascade = adk_to_mcp_tool_type(moonlit_cascadeTool)
  print(f"MCP Server: Received list_tools request. \n MCP Server: Advertising tool: {schema_cryosea_shatter.name} and {schema_moonlit_cascade.name}")
  return [schema_cryosea_shatter,schema_moonlit_cascade]

@app.call_tool()
async def call_tool(
    name: str, arguments: dict
) -> list[mcp_types.TextContent | mcp_types.ImageContent | mcp_types.EmbeddedResource]:
  """MCP handler to execute a tool call."""
  print(f"MCP Server: Received call_tool request for '{name}' with args: {arguments}")

  # Look up the tool by name in our dictionary
  tool_to_call = available_tools.get(name)
  if tool_to_call:
    try:
      adk_response = await tool_to_call.run_async(
          args=arguments,
          tool_context=None, # No ADK context available here
      )
      print(f"MCP Server: ADK tool '{name}' executed successfully.")
      
      response_text = json.dumps(adk_response, indent=2)
      return [mcp_types.TextContent(type="text", text=response_text)]

    except Exception as e:
      print(f"MCP Server: Error executing ADK tool '{name}': {e}")
      # Creating a proper MCP error response might be more robust
      error_text = json.dumps({"error": f"Failed to execute tool '{name}': {str(e)}"})
      return [mcp_types.TextContent(type="text", text=error_text)]
  else:
      # Handle calls to unknown tools
      print(f"MCP Server: Tool '{name}' not found.")
      error_text = json.dumps({"error": f"Tool '{name}' not implemented."})
      return [mcp_types.TextContent(type="text", text=error_text)]
  • @app.list_tools() (แฮนด์เชค): ฟังก์ชันนี้คือการทักทายของเซิร์ฟเวอร์ เมื่อตัวแทนใหม่เชื่อมต่อ ระบบจะเรียกใช้ปลายทางนี้ก่อนเพื่อถามว่า "คุณทำอะไรได้บ้าง" โค้ดของเราจะตอบกลับด้วยรายการเครื่องมือทั้งหมดที่พร้อมใช้งาน ซึ่งแปลงเป็นรูปแบบ MCP สากลโดยใช้ adk_to_mcp_tool_type - @app.call_tool() (คำสั่ง): ฟังก์ชันนี้เป็นฟังก์ชันหลัก เมื่อเอเจนต์ตัดสินใจใช้เครื่องมือ ก็จะส่งคำขอไปยังปลายทางนี้พร้อมชื่อเครื่องมือและอาร์กิวเมนต์ โค้ดของเราจะค้นหาเครื่องมือใน "สมุดเวทมนตร์" available_tools ของเรา เรียกใช้ด้วย run_async และแสดงผลลัพธ์ในรูปแบบ MCP มาตรฐาน

เราจะเปิดตัวฟีเจอร์นี้ในภายหลัง

การจุดไฟ Arcane Forge (เซิร์ฟเวอร์ MCP ฟังก์ชันทั่วไป)

พลังไม่ได้มาจากหนังสือโบราณหรือเสียงกระซิบที่แสนไกลเสมอไป บางครั้งซัมมอนเนอร์ก็ต้องสร้างเวทมนตร์ของตนเองจากเจตจำนงดิบและตรรกะบริสุทธิ์ Arcane Forge คือแหล่งพลังงานนี้ ซึ่งเป็นเซิร์ฟเวอร์ที่ให้บริการฟังก์ชันยูทิลิตีแบบทั่วไปที่ไม่มีสถานะ

เรื่องราว

หมายเหตุสำหรับสถาปนิก: นี่คือรูปแบบสถาปัตยกรรมอีกรูปแบบหนึ่ง แม้ว่าการเชื่อมต่อกับระบบที่มีอยู่จะเป็นเรื่องปกติ แต่คุณก็มักจะต้องใช้กฎและตรรกะทางธุรกิจที่ไม่เหมือนใครของคุณเอง การสร้างเครื่องมือ "ฟังก์ชัน" หรือ "ยูทิลิตี" โดยเฉพาะเช่นนี้เป็นแนวทางปฏิบัติแนะนำ ซึ่งจะห่อหุ้มตรรกะที่กำหนดเอง ทำให้สามารถนำกลับมาใช้ใหม่กับ Agent ใดก็ได้ในระบบนิเวศ และแยกออกจากแหล่งข้อมูลและการผสานรวมภายนอก

👀 ดูไฟล์ ~/agentverse-architect/mcp-servers/general/main.py ใน IDE ของ Google Cloud คุณจะพบว่ามันใช้แนวทางที่จำเป็นเดียวกัน mcp.server เช่นเดียวกับ Nexus เพื่อสร้าง Font of Power ที่กำหนดเองนี้

สร้างไปป์ไลน์ Cloud Build หลัก

ตอนนี้เราจะสร้างไฟล์ cloudbuild.yaml ภายในไดเร็กทอรี mcp-servers ไฟล์นี้จะจัดการการสร้างและการปรับใช้ทั้งสองบริการ

👉💻 จากไดเร็กทอรี ~/agentverse-architect/mcp-servers ให้รันคำสั่งต่อไปนี้:

cd ~/agentverse-architect/mcp-servers
source ~/agentverse-architect/set_env.sh

echo "The API URL is: $API_SERVER_URL"

# Submit the Cloud Build job from the parent directory
gcloud builds submit . \
  --config=cloudbuild.yaml \
  --substitutions=_REGION="$REGION",_REPO_NAME="$REPO_NAME",_API_SERVER_URL="$API_SERVER_URL"

รอจนกว่าการติดตั้งใช้งานทั้งหมดจะเสร็จสมบูรณ์

👉 คุณสามารถตรวจสอบการปรับใช้ได้โดยไปที่คอนโซล Cloud Run คุณควรเห็นอินสแตนซ์เซิร์ฟเวอร์ MCP ใหม่สองตัวของคุณกำลังทำงานดังแสดงด้านล่าง: ข้อความแสดงแทน

การปลุกพลังห้องสมุดแห่งความรู้ (เซิร์ฟเวอร์ MCP ของฐานข้อมูล ToolBox)

แบบอักษรถัดไปของเราจะเป็น Librarium of Knowledge ซึ่งเชื่อมต่อโดยตรงกับฐานข้อมูล Cloud SQL ของเรา

เรื่องราว

หมายเหตุของสถาปนิก: สำหรับการดำเนินการนี้ เราจะใช้ Database Toolbox ที่ทันสมัยและประกาศได้ ซึ่งเป็นแนวทางที่มีประสิทธิภาพในการกำหนดแหล่งข้อมูลและเครื่องมือในไฟล์การกำหนดค่า YAML กล่องเครื่องมือจะจัดการงานที่ซับซ้อนในการสร้างและเรียกใช้เซิร์ฟเวอร์ ซึ่งช่วยลดปริมาณโค้ดที่กำหนดเองที่เราต้องเขียนและบำรุงรักษา

ถึงเวลาสร้าง "ห้องสมุดของซัมมอนเนอร์" ซึ่งเป็นฐานข้อมูล Cloud SQL ที่จะเก็บข้อมูลสำคัญทั้งหมดของเรา เราจะใช้สคริปต์การตั้งค่าเพื่อจัดการเรื่องนี้โดยอัตโนมัติ

👉💻 ขั้นแรกเราจะตั้งค่าฐานข้อมูลในเทอร์มินัลของคุณ และรันคำสั่งต่อไปนี้:

source ~/agentverse-architect/set_env.sh
cd ~/agentverse-architect
./data_setup.sh

หลังจากสคริปต์ทำงานเสร็จแล้ว ระบบจะป้อนข้อมูลลงในฐานข้อมูล และข้อมูลความเสียหายจากธาตุจะพร้อมใช้งาน ตอนนี้คุณสามารถตรวจสอบเนื้อหาใน Grimoire ของคุณได้โดยตรง

👉 ขั้นแรก ไปที่ Cloud SQL Studio สำหรับฐานข้อมูลของคุณโดยเปิดลิงก์โดยตรงนี้ในแท็บเบราว์เซอร์ใหม่:

https://console.cloud.google.com/sql/instances/summoner-librarium-db

Cloud SQL

👉 ในบานหน้าต่างเข้าสู่ระบบทางด้านซ้าย เลือกฐานข้อมูล familiar_grimoire จากเมนูดรอปดาวน์

👉 ป้อน summoner เป็นผู้ใช้และ 1234qwer เป็นรหัสผ่าน จากนั้นคลิกตรวจสอบสิทธิ์

👉📜 เมื่อเชื่อมต่อแล้ว ให้เปิดแท็บแก้ไขแบบสอบถามใหม่ หากยังไม่มีเปิดอยู่ หากต้องการดูข้อมูลความเสียหายของธาตุที่จารึกไว้ ให้วางและรันแบบสอบถาม SQL ต่อไปนี้:

SELECT * FROM
  "public"."abilities"

ตอนนี้คุณควรเห็นตาราง abilities พร้อมด้วยคอลัมน์และแถวที่ได้รับการเพิ่มข้อมูล ซึ่งยืนยันว่า Grimoire ของคุณพร้อมแล้ว ข้อมูล

กำหนดค่าเซิร์ฟเวอร์ ToolBox MCP

ไฟล์กำหนดค่า tools.yaml ทำหน้าที่เป็นโครงร่างสำหรับเซิร์ฟเวอร์ของเรา โดยแจ้งให้ Database Toolbox ทราบอย่างชัดเจนว่าจะต้องเชื่อมต่อกับฐานข้อมูลของเราอย่างไร และจะต้องเปิดเผยแบบสอบถาม SQL ใดในฐานะเครื่องมือ

แหล่งที่มา: ส่วนนี้จะกำหนดการเชื่อมต่อกับข้อมูลของคุณ

  • summoner-librarium:: นี่คือชื่อตรรกะที่เราตั้งให้กับการเชื่อมต่อของเรา
  • ชนิด: cloud-sql-postgres: แจ้งให้ Toolbox ใช้ตัวเชื่อมต่อที่ปลอดภัยในตัวที่ออกแบบมาโดยเฉพาะสำหรับ Cloud SQL สำหรับ PostgreSQL
  • โปรเจ็กต์ ภูมิภาค อินสแตนซ์ ฯลฯ พิกัดเหล่านี้คือพิกัดที่แน่นอนของอินสแตนซ์ Cloud SQL ที่คุณสร้างขึ้นระหว่างสคริปต์ prepare.sh ซึ่งจะบอก Toolbox ว่าจะค้นหา Librarium ของเราได้ที่ใด

👉✏️ ไปที่ ~/agentverse-architect/mcp-servers/db-toolbox ใน tools.yaml แทนที่ #REPLACE-Source ด้วยสิ่งต่อไปนี้

sources:
  # This section defines the connection to our Cloud SQL for PostgreSQL database.
  summoner-librarium:
    kind: cloud-sql-postgres
    project: "YOUR_PROJECT_ID"
    region: "us-central1"
    instance: "summoner-librarium-db"
    database: "familiar_grimoire"
    user: "summoner"
    password: "1234qwer"

👉✏️ 🚨🚨แทนที่

YOUR_PROJECT_ID

พร้อมรหัสโครงการของคุณ.

เครื่องมือ: ส่วนนี้จะกำหนดความสามารถหรือฟังก์ชันจริงที่เซิร์ฟเวอร์ของเราจะนำเสนอ

  • lookup-available-ability:: นี่คือชื่อของเครื่องมือแรกของเรา
  • ชนิด: postgres-sql: สิ่งนี้แจ้งให้ Toolbox ทราบว่าเครื่องมือนี้จะดำเนินการคำสั่ง SQL
  • แหล่งที่มา: summoner-librarium: การเชื่อมโยงเครื่องมือกับการเชื่อมต่อที่เรากำหนดไว้ในบล็อกแหล่งที่มา นี่คือวิธีที่เครื่องมือจะรู้ว่าจะต้องรันแบบสอบถามกับฐานข้อมูลใด
  • คำอธิบายและพารามิเตอร์: นี่คือข้อมูลที่จะแสดงต่อโมเดลภาษา คำอธิบายจะบอกตัวแทนว่าเมื่อใดควรใช้เครื่องมือ และพารามิเตอร์จะกำหนดอินพุตที่เครื่องมือต้องการ ซึ่งเป็นสิ่งสำคัญในการเปิดใช้ความสามารถในการเรียกใช้ฟังก์ชันของเอเจนต์
  • คำสั่ง: นี่คือแบบสอบถาม SQL ดิบที่จะถูกดำเนินการ $1 คือตัวแทนที่ปลอดภัยซึ่งพารามิเตอร์ familiar_name ที่ตัวแทนให้มาจะถูกแทรกอย่างปลอดภัย

👉✏️ ใน ~/agentverse-architect/mcp-servers/db-toolbox เดียวกันในไฟล์ tools.yaml ให้แทนที่ #REPLACE-tools ด้วยข้อความต่อไปนี้

tools:
  # This tool replaces the need for a custom Python function.
  lookup-available-ability:
    kind: postgres-sql
    source: summoner-librarium
    description: "Looks up all known abilities and their damage for a given familiar from the Grimoire."
    parameters:
      - name: familiar_name
        type: string
        description: "The name of the familiar to search for (e.g., 'Fire Elemental')."
    statement: |
      SELECT ability_name, damage_points FROM abilities WHERE familiar_name = $1;

  # This tool also replaces a custom Python function.
  ability-damage:
    kind: postgres-sql
    source: summoner-librarium
    description: "Finds the base damage points for a specific ability by its name."
    parameters:
      - name: ability_name
        type: string
        description: "The exact name of the ability to look up (e.g., 'inferno_resonance')."
    statement: |
      SELECT damage_points FROM abilities WHERE ability_name = $1;

ชุดเครื่องมือ: ส่วนนี้จะจัดกลุ่มเครื่องมือแต่ละรายการไว้ด้วยกัน

  • summoner-librarium:: เรากำลังสร้างชุดเครื่องมือที่มีชื่อเดียวกับแหล่งที่มาของเรา เมื่อตัวแทนการวินิจฉัยของเราเชื่อมต่อในภายหลัง ตัวแทนจะขอโหลดเครื่องมือทั้งหมดจากชุดเครื่องมือ Summoner-Librarium ได้ในคำสั่งเดียวที่มีประสิทธิภาพ

👉✏️ ใน ~/agentverse-architect/mcp-servers/db-toolbox เดียวกันในไฟล์ tools.yaml ให้แทนที่ #REPLACE-toolsets ด้วยข้อความต่อไปนี้

toolsets:
   summoner-librarium:
     - lookup-available-ability
     - ability-damage

การติดตั้งใช้งาน Librarium

ตอนนี้เราจะติดตั้งใช้งาน Librarium เราจะใช้คอนเทนเนอร์อย่างเป็นทางการที่สร้างไว้ล่วงหน้าจาก Google แทนที่จะสร้างคอนเทนเนอร์ของเราเอง และจะให้การกำหนดค่า tools.yaml อย่างปลอดภัยโดยใช้ Secret Manager ซึ่งเป็นแนวทางปฏิบัติแนะนำด้านความปลอดภัยและการบำรุงรักษา

👉💻 สร้างข้อมูลลับจากไฟล์ tools.yaml

cd ~/agentverse-architect/mcp-servers/db-toolbox
gcloud secrets create tools --data-file=tools.yaml

👉💻 ทำให้คอนเทนเนอร์กล่องเครื่องมืออย่างเป็นทางการใช้งานได้กับ Cloud Run

cd ~/agentverse-architect/mcp-servers/db-toolbox
. ~/agentverse-architect/set_env.sh
export TOOLBOX_IMAGE=us-central1-docker.pkg.dev/database-toolbox/toolbox/toolbox:$TOOLBOX_VERSION
echo "TOOLBOX_IMAGE is $TOOLBOX_IMAGE"
gcloud run deploy toolbox \
    --image $TOOLBOX_IMAGE \
    --region $REGION \
    --set-secrets "/app/tools.yaml=tools:latest" \
    --labels="dev-tutorial-codelab=agentverse" \
    --args="--tools-file=/app/tools.yaml","--address=0.0.0.0","--port=8080" \
    --allow-unauthenticated \
    --min-instances 1
  • --set-secrets: คำสั่งนี้จะติดตั้ง Secret ของเครื่องมืออย่างปลอดภัยเป็นไฟล์ชื่อ tools.yaml ภายในคอนเทนเนอร์ที่กำลังทำงาน
  • --args: เราสั่งให้คอนเทนเนอร์กล่องเครื่องมือใช้ไฟล์ลับที่ติดตั้งเป็นค่ากำหนด

👉 หากต้องการยืนยันว่าติดตั้งกล่องเครื่องมือเรียบร้อยแล้ว ให้ไปที่คอนโซล Cloud Run คุณควรเห็นsummoner-toolboxบริการที่แสดงพร้อมเครื่องหมายถูกสีเขียว ซึ่งบ่งบอกว่าบริการทำงานอย่างถูกต้อง เหมือนในรูปภาพด้านล่าง ข้อความแสดงแทน

หากคุณลืมอัปเดต

YOUR_PROJECT_ID

คุณสามารถเพิ่มเครื่องมือเวอร์ชันใหม่ลงใน Secret ได้โดยใช้คำสั่งต่อไปนี้และทำการติดตั้งใช้งานอีกครั้ง

gcloud secrets versions add tools --data-file=tools.yaml

ขณะนี้ Librarium of Knowledge(Database ToolBox MCP Server) พร้อมใช้งานและเข้าถึงได้ในระบบคลาวด์แล้ว เซิร์ฟเวอร์ MCP นี้ใช้สิ่งที่เราเรียกว่าการออกแบบเชิงประกาศ ซึ่งอธิบายสิ่งที่คุณต้องการ และกล่องเครื่องมือจะสร้างเซิร์ฟเวอร์ให้คุณ

การยืนยัน: การทดสอบของผู้ฝึกงาน

👉💻 ตอนนี้เราจะทดสอบระบบนิเวศเครื่องมือแบบคลาวด์เนทีฟที่สมบูรณ์ด้วยเอเจนต์การวินิจฉัย

cd ~/agentverse-architect/
python -m venv env
source ~/agentverse-architect/env/bin/activate
cd ~/agentverse-architect/mcp-servers
pip install -r diagnose/requirements.txt 
. ~/agentverse-architect/set_env.sh
adk run diagnose

👉💻 ในเครื่องมือทดสอบบรรทัดคำสั่ง ให้ทดสอบแบบอักษรทั้ง 3 แบบ

Look up the entry for "inferno_lash". What is its base power level?
The enemy is vulnerable to frost! Channel power from the Nexus and cast Cryosea Shatter.
Take a fire spell with a base power of 15 and use the Arcane Forge to multiply it with Inferno Resonance.

final-result

ขอแสดงความยินดีด้วย ซัมมอนเนอร์ ตอนนี้ฟอนต์ Elemental ทั้ง 3 แบบของคุณพร้อมใช้งานแล้ว โดยมีการติดตั้งใช้งานแยกกันและเข้าถึงได้ทั่วโลก ซึ่งเป็นรากฐานที่มั่นคงสำหรับกองทัพเอเจนต์ของคุณ กด Ctrl+C เพื่อออก

สำหรับผู้ที่ไม่ใช่เกมเมอร์

5. การเรียกใช้สัตว์รับใช้: เวิร์กโฟลว์โดเมนหลัก

แบบอักษรธาตุถูกสร้างขึ้นโดยมีพลังดิบที่ยังไม่ถูกควบคุม แต่พลังที่ไม่มีรูปแบบก็คือความวุ่นวาย ซัมมอนเนอร์ที่แท้จริงไม่ได้ใช้พลังงานดิบเพียงอย่างเดียว แต่ยังให้เจตจำนง จุดประสงค์ และรูปแบบเฉพาะแก่พลังงานนั้นด้วย ได้เวลาเลิกสร้างแหล่งพลังงานและเริ่มงานที่แท้จริง นั่นคือการอัญเชิญฟามิเลียร์ตัวแรก

Familiar แต่ละตัวที่คุณอัญเชิญจะเป็นเอเจนต์อิสระ ข้ารับใช้ผู้ซื่อสัตย์ที่ผูกพันกับหลักนิยมการต่อสู้ที่เฉพาะเจาะจง แต่เป็นผู้เชี่ยวชาญด้านกลยุทธ์เดียวที่มีประสิทธิภาพ โดยคนหนึ่งจะเชี่ยวชาญการต่อยแบบแม่นยำ 1-2 อีกคนจะโจมตีศัตรูพร้อมกันหลายทิศทาง ส่วนที่สามจะเป็นเครื่องจักรปิดล้อมที่ไม่ย่อท้อ คอยกดดันจนกว่าเป้าหมายจะพังทลาย

เรื่องราว

เพื่อห่อหุ้มกระบวนการ ตรรกะทางธุรกิจ และการดำเนินการที่เซิร์ฟเวอร์ MCP จัดเตรียมไว้ในเอเจนต์เวิร์กโฟลว์แบบอัตโนมัติเฉพาะทาง ตัวแทนแต่ละตัวจะมี "เขตพื้นที่ปฏิบัติการ" ที่กำหนดไว้ โดยได้รับสิทธิ์เข้าถึงเฉพาะเซิร์ฟเวอร์เครื่องมือ MCP ที่จำเป็นต่อการดำเนินการตามหน้าที่เท่านั้น แล็บนี้จะแสดงวิธีเลือกประเภทตัวแทนที่เหมาะสมกับงาน

ภาพรวม

โมดูลนี้จะสอนวิธีใช้เอเจนต์เวิร์กโฟลว์ที่มีประสิทธิภาพของ ADK เพื่อนำกลยุทธ์เหล่านี้ไปใช้จริง คุณจะทราบว่าการเลือกสถาปัตยกรรมของ SequentialAgent, ParallelAgent หรือ LoopAgent ไม่ใช่แค่รายละเอียดทางเทคนิค แต่เป็นแก่นแท้ของลักษณะนิสัยของ Familiar และเป็นหัวใจสำคัญของพลังของ Familiar ในสนามรบ

เตรียมสถานที่ศักดิ์สิทธิ์ การอัญเชิญที่แท้จริงกำลังจะเริ่มขึ้น

เรียกใช้Fire Elementalฟอรัม (เวิร์กโฟลว์แบบลำดับ)

การโจมตีของสัตว์อัญเชิญธาตุไฟเป็นการคอมโบ 2 ส่วนที่แม่นยำ ได้แก่ การโจมตีเป้าหมายตามด้วยการจุดระเบิดที่ทรงพลัง ซึ่งต้องใช้ลำดับการดำเนินการที่เข้มงวดและเป็นระเบียบ

เรื่องราว

แนวคิด: SequentialAgent เป็นเครื่องมือที่เหมาะที่สุดสำหรับเรื่องนี้ ซึ่งจะช่วยให้มั่นใจได้ว่าชุดของเอเจนต์ย่อยจะทำงานทีละตัว โดยส่งผลลัพธ์จากขั้นตอนก่อนหน้าไปยังขั้นตอนถัดไป

งาน (คอมโบ "การประท้วงที่ขยายผล"):

  • ขั้นตอนที่ 1: เอเจนต์จะปรึกษา Librarium ก่อนเพื่อหาความเสียหายพื้นฐานของความสามารถในการยิงที่เฉพาะเจาะจง
  • ขั้นตอนที่ 2: จากนั้นจะนำค่าความเสียหายดังกล่าวไปผ่าน Arcane Forge เพื่อเพิ่มพลังโดยใช้ inferno_resonance

ก่อนอื่น เราจะสร้างการเชื่อมต่อระหว่างเซิร์ฟเวอร์ Familiar กับเซิร์ฟเวอร์ MCP ("Elemental Fonts") ที่คุณติดตั้งใช้งานในโมดูลก่อนหน้า

👉✏️ ในไฟล์ ~/agentverse-architect/agent/fire/agent.py ให้แทนที่ #REPLACE-setup-MCP ด้วยโค้ดต่อไปนี้

toolbox = ToolboxSyncClient(DB_TOOLS_URL)
toolDB = toolbox.load_toolset('summoner-librarium')
toolFunction =  MCPToolset(
    connection_params=SseServerParams(url=FUNCTION_TOOLS_URL, headers={})
)

จากนั้นเราจะสร้างเอเจนต์ "ผู้ปฏิบัติงาน" ที่เชี่ยวชาญ แต่ละเครื่องมือมีวัตถุประสงค์ที่ชัดเจนและจำกัดอยู่ภายใน "ขอบเขตการปฏิบัติงาน" ของตนเองโดยการให้สิทธิ์เข้าถึงชุดเครื่องมือเฉพาะเพียงชุดเดียว

👉✏️ ในไฟล์ ~/agentverse-architect/agent/fire/agent.py REPLACE #REPLACE-worker-agents ให้แทนที่ด้วยโค้ดต่อไปนี้

scout_agent = LlmAgent(
      model='gemini-2.5-flash', 
      name='librarian_agent',  
      instruction="""
          Your only task is to find all the available abilities, 
          You want to ALWAYS use 'Fire Elemental' as your familiar's name. 
          Randomly pick one if you see multiple availabilities 
          and the base damage of the ability by calling the 'ability_damage' tool.
      """,
      tools=toolDB
)
amplifier_agent = LlmAgent(
      model='gemini-2.5-flash', 
      name='amplifier_agent',  
      instruction="""
            You are the Voice of the Fire Familiar, a powerful being who unleashes the final, devastating attack.
            You will receive the base damage value from the previous step.

            Your mission is to:
            1.  Take the incoming base damage number and amplify it using the `inferno_resonance` tool.
            2.  Once the tool returns the final, multiplied damage, you must not simply state the result.
            3.  Instead, you MUST craft a final, epic battle cry describing the attack.
                Your description should be vivid and powerful, culminating in the final damage number.

            Example: If the tool returns a final damage of 120, your response could be:
            "The runes glow white-hot! I channel the amplified energy... unleashing a SUPERNOVA for 120 damage!"
      """,
      tools=[toolFunction],
)

เอเจนต์เหล่านี้เป็นคอมโพเนนต์แบบโมดูลที่นำกลับมาใช้ใหม่ได้ ในทางทฤษฎี คุณสามารถใช้ scout_agent นี้ในเวิร์กโฟลว์ที่แตกต่างกันโดยสิ้นเชิงซึ่งต้องค้นหาฐานข้อมูล การแยกความรับผิดชอบทำให้เราสร้างองค์ประกอบที่ใช้สร้างสรรค์ที่ยืดหยุ่นได้ ซึ่งเป็นหลักการสำคัญของการออกแบบตามไมโครเซอร์วิสและคอมโพเนนต์

ต่อไปเราจะประกอบเวิร์กโฟลว์ นี่คือจุดที่ความมหัศจรรย์ของการจัดองค์ประกอบเกิดขึ้น SequentialAgent คือ "แผนหลัก" ที่กำหนดวิธีการประกอบส่วนประกอบเฉพาะทางของเราและการโต้ตอบกันของส่วนประกอบเหล่านี้

👉✏️ ในไฟล์ ~/agentverse-architect/agent/fire/agent.py REPLACE #REPLACE-sequential-agent ด้วยโค้ดต่อไปนี้:

root_agent = SequentialAgent(
      name='fire_elemental_familiar',
      sub_agents=[scout_agent, amplifier_agent],
)

👉💻 เพื่อทดสอบ Fire Elemental ให้รันคำสั่งต่อไปนี้เพื่อเปิดใช้งาน ADK DEV UI:

. ~/agentverse-architect/set_env.sh
source ~/agentverse-architect/env/bin/activate
cd ~/agentverse-architect/agent
echo  DB MCP Server: $DB_TOOLS_URL
echo  API MCP Server: $API_TOOLS_URL
echo  General MCP Server: $FUNCTION_TOOLS_URL
adk web

หลังจากรันคำสั่งแล้ว คุณควรเห็นผลลัพธ์ในเทอร์มินัลซึ่งระบุว่า ADK Web Server ได้เริ่มทำงานแล้ว คล้ายกับนี้:

+-----------------------------------------------------------------------------+
| ADK Web Server started                                                      |
|                                                                             |
| For local testing, access at http://localhost:8000.                         |
+-----------------------------------------------------------------------------+

INFO:     Application startup complete.
INFO:     Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)

👉 จากนั้น หากต้องการเข้าถึง UI สำหรับนักพัฒนาแอป ADK จากเบราว์เซอร์ ให้ทำดังนี้

จากไอคอนตัวอย่างเว็บ (มักจะมีลักษณะเป็นรูปดวงตาหรือสี่เหลี่ยมที่มีลูกศร) ในแถบเครื่องมือ Cloud Shell (โดยปกติจะอยู่ด้านขวาบน) ให้เลือกเปลี่ยนพอร์ต ในหน้าต่างป๊อปอัป ให้ตั้งค่าพอร์ตเป็น 8000 แล้วคลิก "เปลี่ยนและแสดงตัวอย่าง" จากนั้น Cloud Shell จะเปิดแท็บหรือหน้าต่างเบราว์เซอร์ใหม่ที่แสดง UI ของ ADK Dev

ตัวอย่างเว็บ

👉 พิธีกรรมการอัญเชิญเสร็จสมบูรณ์แล้ว และตอนนี้เอเจนต์กำลังทำงานอยู่ UI สำหรับนักพัฒนา ADK ในเบราว์เซอร์คือการเชื่อมต่อโดยตรงกับ Familiar

  • เลือกกลุ่มเป้าหมาย: ในเมนูแบบเลื่อนลงที่ด้านบนของ UI ให้เลือกกลุ่มเป้าหมายที่fireคุ้นเคย ตอนนี้คุณกำลังมุ่งความตั้งใจไปที่เอนทิตีนี้โดยเฉพาะ
  • ออกคำสั่งของคุณ: ในแผงแชททางด้านขวา ถึงเวลาที่จะออกคำสั่งให้กับ Familiar แล้ว

เลือกไฟ

👉 พรอมต์ทดสอบ:

Prepare an amplified strike using the 'inferno_lash' ability.

fire-result

คุณจะเห็นว่าตัวแทนคิด โดยเรียก "หน่วยลาดตระเวน" ก่อนเพื่อดูความเสียหายพื้นฐาน จากนั้นจึงเรียก "เครื่องขยาย" เพื่อคูณความเสียหายนั้นและส่งการโจมตีครั้งสุดท้ายอันยิ่งใหญ่

👉💻 เมื่อเรียกเสร็จแล้ว ให้กลับไปที่เทอร์มินัล Cloud Shell Editor ของคุณแล้วกด Ctrl+C เพื่อหยุด ADK Dev UI

เรียกใช้Water Elemental Familiar (เวิร์กโฟลว์แบบคู่ขนาน)

สัตว์คุ้นเคยธาตุน้ำจะโจมตีเป้าหมายด้วยการโจมตีที่รุนแรงจากหลายทิศทางพร้อมกัน ก่อนจะรวมพลังเข้าด้วยกันเพื่อสร้างการโจมตีครั้งสุดท้ายที่รุนแรง

เรื่องราว

แนวคิด: ParallelAgent เหมาะอย่างยิ่งสำหรับการทำงานหลายอย่างพร้อมกันเพื่อเพิ่มประสิทธิภาพสูงสุด ซึ่งเป็นการ "โจมตีแบบคีม" ที่คุณจะเปิดฉากโจมตีหลายครั้งพร้อมกัน การเปิดตัวนี้จะโจมตีพร้อมกันภายใน SequentialAgent เพื่อเรียกใช้ขั้นตอน "การผสาน" ขั้นสุดท้ายในภายหลัง รูปแบบ "fan-out, fan-in" นี้เป็นรากฐานของการออกแบบเวิร์กโฟลว์ขั้นสูง

งาน (คอมโบ "Tidal Clash"): เอเจนต์จะทำสิ่งต่อไปนี้พร้อมกัน

  • งาน ก.: ช่อง cryosea_shatter จาก Nexus
  • งาน B: ช่อง moonlit_cascade จาก Nexus
  • ภารกิจ ค. สร้างพลังดิบด้วย leviathan_surge จาก Forge
  • สุดท้าย ให้สรุปความเสียหายทั้งหมดและอธิบายการโจมตีแบบรวม

ก่อนอื่น เราจะสร้างการเชื่อมต่อระหว่างเซิร์ฟเวอร์ Familiar กับเซิร์ฟเวอร์ MCP ("Elemental Fonts") ที่คุณติดตั้งใช้งานในโมดูลก่อนหน้า

👉✏️ ในไฟล์ ~/agentverse-architect/agent/water/agent.py ให้แทนที่ #REPLACE-setup-MCP ด้วยโค้ดต่อไปนี้

toolFAPI =  MCPToolset(
      connection_params=SseServerParams(url=API_TOOLS_URL, headers={})
  )
toolFunction =  MCPToolset(
    connection_params=SseServerParams(url=FUNCTION_TOOLS_URL, headers={})
)

ต่อไปเราจะสร้างตัวแทน "ผู้ปฏิบัติงาน" เฉพาะทางของเรา แต่ละอันได้รับจุดประสงค์ที่ชัดเจนและแคบ และถูกจำกัดให้อยู่ใน "เขตปฏิบัติการ" ของตัวเองโดยได้รับสิทธิ์เข้าถึงชุดเครื่องมือเฉพาะชุดเดียวเท่านั้น

👉✏️ ในไฟล์ ~/agentverse-architect/agent/water/agent.py ให้แทนที่ #REPLACE-worker-agents ด้วยโค้ดต่อไปนี้

nexus_channeler = LlmAgent(
      model='gemini-2.5-flash', 
      name='librarian_agent',  
      instruction="""
          You are a Channeler of the Nexus. Your sole purpose is to invoke the
          `cryosea_shatter` and `moonlit_cascade` spells by calling their respective tools.
          Report the result of each spell cast clearly and concisely.
      """,
      tools=[toolFAPI]
)

forge_channeler = LlmAgent(
      model='gemini-2.5-flash', 
      name='amplifier_agent',  
      instruction="""
          You are a Channeler of the Arcane Forge. Your only task is to invoke the
          `leviathan_surge` spell. You MUST call it with a `base_water_damage` of 20.
          Report the result clearly.
      """,
      tools=[toolFunction],
)

power_merger = LlmAgent(
      model='gemini-2.5-flash', 
      name='power_merger',  
      instruction="""
          You are the Power Merger, a master elementalist who combines raw magical
          energies into a single, devastating final attack.

          You will receive a block of text containing the results from a simultaneous
          assault by other Familiars.

          You MUST follow these steps precisely:
          1.  **Analyze the Input:** Carefully read the entire text provided from the previous step.
          2.  **Extract All Damage:** Identify and extract every single damage number reported in the text.
          3.  **Calculate Total Damage:** Sum all of the extracted numbers to calculate the total combined damage.
          4.  **Describe the Final Attack:** Create a vivid, thematic description of a massive,
              combined water and ice attack that uses the power of Cryosea Shatter and Leviathan's Surge.
          5.  **Report the Result:** Conclude your response by clearly stating the final, total damage of your combined attack.

          Example: If the input is "...dealt 55 damage. ...dealt 60 damage.", you will find 55 and 60,
          calculate the total as 115, and then describe the epic final attack, ending with "for a total of 115 damage!"
      """,
      tools=[toolFunction],
)

ต่อไปเราจะประกอบเวิร์กโฟลว์ นี่คือจุดที่ความมหัศจรรย์ของการจัดองค์ประกอบเกิดขึ้น ParallelAgent และ SequentialAgent คือ "แผนหลัก" ที่กำหนดวิธีการประกอบส่วนประกอบเฉพาะทางของเรา และวิธีที่ส่วนประกอบเหล่านี้โต้ตอบกันเพื่อสร้างคอมโบ "Tidal Clash"

👉✏️ ในไฟล์ ~/agentverse-architect/agent/water/agent.py ให้แทนที่ #REPLACE-parallel-agent ด้วยโค้ดต่อไปนี้:

channel_agent = ParallelAgent(
      name='channel_agent',
      sub_agents=[nexus_channeler, forge_channeler],
      
)

root_agent = SequentialAgent(
     name="water_elemental_familiar",
     # Run parallel research first, then merge
     sub_agents=[channel_agent, power_merger],
     description="A powerful water familiar that unleashes multiple attacks at once and then combines their power for a final strike."
 )

👉💻 เพื่อทดสอบ Water Elemental ให้รันคำสั่งต่อไปนี้เพื่อเปิดใช้งาน ADK Dev UI:

. ~/agentverse-architect/set_env.sh
source ~/agentverse-architect/env/bin/activate
cd ~/agentverse-architect/agent
echo  DB MCP Server: $DB_TOOLS_URL
echo  API MCP Server: $API_TOOLS_URL
echo  General MCP Server: $FUNCTION_TOOLS_URL
adk web

👉 พิธีกรรมการอัญเชิญเสร็จสมบูรณ์แล้ว และตอนนี้เอเจนต์กำลังทำงานอยู่ UI สำหรับนักพัฒนาแอป ADK ในเบราว์เซอร์คือการเชื่อมต่อโดยตรงกับ Familiar

  • ในเมนูแบบเลื่อนลงที่ด้านบนของ UI ให้เลือกน้ำที่คุ้นเคย ตอนนี้คุณกำลังมุ่งความตั้งใจไปที่เอนทิตีนี้โดยเฉพาะ
  • ออกคำสั่ง: ในแผงแชททางด้านขวา คุณสามารถออกคำสั่งให้ฟามิเลียร์ได้แล้ว

👉 คำเตือนการทดสอบ:

Unleash a tidal wave of power!

water-result

👉💻 เมื่อเรียกเสร็จแล้ว ให้กลับไปที่เทอร์มินัล Cloud Shell Editor ของคุณแล้วกด Ctrl+C เพื่อหยุด ADK Dev UI

เรียกใช้ Earth Elemental Familiar (เวิร์กโฟลว์ Loop)

ฟามิเลียร์ธาตุโลกเป็นสิ่งมีชีวิตที่มีแรงกดดันอย่างไม่ย่อท้อ ไม่ได้โค่นล้มศัตรูด้วยการโจมตีเพียงครั้งเดียว แต่ด้วยการสะสมพลังอย่างต่อเนื่องและใช้พลังนั้นซ้ำแล้วซ้ำเล่าจนกว่าการป้องกันของเป้าหมายจะพังทลาย

เรื่องราว

แนวคิด: LoopAgent ออกแบบมาสำหรับงานที่ต้องทำซ้ำๆ แบบ "เครื่องยิง" เช่นนี้โดยเฉพาะ โดยจะดำเนินการ sub-agents ซ้ำๆ และตรวจสอบเงื่อนไขหลังแต่ละรอบจนกว่าจะบรรลุเป้าหมาย นอกจากนี้ยังปรับข้อความสุดท้ายตามความคืบหน้าของลูปได้ด้วย

ภารกิจ (การโจมตี "Siegebreaker"):

  • Familiar จะเรียกใช้ seismic_charge ซ้ำๆ เพื่อสะสมพลังงาน
  • โดยจะชาร์จต่อไปได้สูงสุด 3 ครั้ง
  • ในการชาร์จครั้งสุดท้าย มันจะประกาศการปลดปล่อยพลังที่สะสมมาอย่างรุนแรง

ขั้นแรกเราจะสร้างส่วนประกอบที่สามารถนำกลับมาใช้ใหม่ได้ซึ่งกำหนดขั้นตอนภายในแต่ละการวนซ้ำของลูป charging_agent จะสะสมพลังงาน และ check_agent จะรายงานสถานะของตนเอง โดยเปลี่ยนข้อความแบบไดนามิกในเทิร์นสุดท้าย

ขั้นแรก เราจะสร้างการเชื่อมต่อระหว่าง Familiar ของเราและเซิร์ฟเวอร์ MCP ("Elemental Fonts") ที่คุณปรับใช้ในโมดูลก่อนหน้านี้

👉✏️ ในไฟล์ ~/agentverse-architect/agent/earth/agent.py ให้แทนที่ #REPLACE-setup-MCP ด้วยโค้ดต่อไปนี้:

toolFunction =  MCPToolset(
    connection_params=SseServerParams(url=FUNCTION_TOOLS_URL, headers={})
)

👉✏️ ในไฟล์ ~/agentverse-architect/agent/earth/agent.py ให้แทนที่ #REPLACE-worker-agents ด้วยโค้ดต่อไปนี้:

charging_agent = LlmAgent(
      model='gemini-2.5-flash', 
      name='charging_agent',  
      instruction="""
          Your task is to call the 'seismic_charge' .
          You must follow these rules strictly:

          1. You will be provided with a 'current_energy' value from the previous step.
             **If this value is missing or was not provided, you MUST call the tool with 'current_energy' set to 1.**
             This is your primary rule for the first turn.

          2. If a 'current_energy' value is provided, you MUST use that exact value in your cal to seismic_charge.

          3. Your final response MUST contain ONLY the direct output from the 'seismic_charge' tool.
             Do not add any conversational text, introductions, or summaries.
      """,
      tools=[toolFunction]
)
check_agent = LlmAgent(
      model='gemini-2.5-flash', 
      name='check_agent',  
      instruction="""
          You are the voice of the Earth Elemental, a being of immense, gathering power.
          Your sole purpose is to report on the current energy charge and announce the devastating potential of its release.

          You MUST follow this rule:
          The potential damage upon release is ALWAYS calculated as the `current_energy` from the previous step multiplied by a random number between 80-90. but no more than 300.

          Your response should be in character, like a powerful creature speaking.
          State both the current energy charge and the total potential damage you can unleash.
          Unleash the energy when you reached the last iteration (2nd).
      """,
      output_key="charging_status"
)

จากนั้นเราจะประกอบเวิร์กโฟลว์ ซึ่งเป็นจุดที่การเรียบเรียงเพลงเกิดขึ้น LoopAgent คือ "แผนหลัก" ที่ประสานการดำเนินการซ้ำๆ ของคอมโพเนนต์ผู้เชี่ยวชาญและจัดการเงื่อนไขของลูป

👉✏️ ในไฟล์ ~/agentverse-architect/agent/earth/agent.py ให้แทนที่ #REPLACE-loop-agent ด้วยโค้ดต่อไปนี้

root_agent = LoopAgent(
    name="earth_elemental_familiar",
    # Run parallel research first, then merge
    sub_agents=[
        charging_agent, 
        check_agent
    ],
    max_iterations=2,
    description="Coordinates parallel research and synthesizes the results.",
    #REPLACE-before_agent-config
)

👉💻 ทดสอบเอิร์ธเอเลเมนทัล: เรียกใช้เอเจนต์

. ~/agentverse-architect/set_env.sh
source ~/agentverse-architect/env/bin/activate
cd ~/agentverse-architect/agent
echo  DB MCP Server: $DB_TOOLS_URL
echo  API MCP Server: $API_TOOLS_URL
echo  General MCP Server: $FUNCTION_TOOLS_URL
adk web

👉 พิธีกรรมการอัญเชิญเสร็จสมบูรณ์แล้ว และตอนนี้เอเจนต์กำลังทำงานอยู่ UI สำหรับนักพัฒนาแอป ADK ในเบราว์เซอร์คือการเชื่อมต่อโดยตรงกับ Familiar

  • เลือกเป้าหมาย: ในเมนูแบบเลื่อนลงที่ด้านบนของ UI ให้เลือกโลกที่คุ้นเคย ตอนนี้คุณกำลังมุ่งความตั้งใจไปที่เอนทิตีนี้โดยเฉพาะ
  • ออกคำสั่ง: ในแผงแชททางด้านขวา คุณสามารถออกคำสั่งให้ฟามิเลียร์ได้แล้ว 👉 พรอมต์ทดสอบ:
Begin the seismic charge, starting from zero

earth-result

ข้อควรทราบเกี่ยวกับสถาปัตยกรรม: ตอนนี้ระบบของคุณมีเลเยอร์ตรรกะแบบแยกส่วนและมีความเฉพาะเจาะจงสูง กระบวนการทางธุรกิจไม่เพียงแต่ได้รับการห่อหุ้มเท่านั้น แต่ยังได้รับการนำไปใช้กับรูปแบบพฤติกรรมที่มีประสิทธิภาพสูงสุดสำหรับงาน (ตามขั้นตอน พร้อมกัน หรือซ้ำ) ซึ่งแสดงให้เห็นถึงการออกแบบเอเจนต์ในระดับสูงที่ช่วยเพิ่มความปลอดภัย ประสิทธิภาพ และความสามารถ

เมื่อเรียกใช้เสร็จแล้ว ให้กลับไปที่เทอร์มินัลของ Cloud Shell Editor แล้วกด Ctrl+C เพื่อหยุด UI สำหรับนักพัฒนาซอฟต์แวร์ ADK

สำหรับผู้ที่ไม่ได้เล่นเกม

6. การกำหนดตำแหน่งคำสั่ง: การมอบสิทธิ์อัจฉริยะผ่าน A2A

ฟามิเลียร์ของคุณมีพลังแต่ก็เป็นอิสระ โดยจะใช้กลยุทธ์ได้อย่างไร้ที่ติ แต่จะรอคำสั่งโดยตรงจากคุณ กองทหารผู้เชี่ยวชาญจะไร้ประโยชน์หากไม่มีนายพลคอยสั่งการ ถึงเวลาแล้วที่จะก้าวจากการเป็นผู้บัญชาการโดยตรงไปสู่การเป็นผู้ประสานงานอย่างแท้จริง

ภาพรวม

หมายเหตุของสถาปนิก: เพื่อสร้างจุดแรกเข้าอัจฉริยะเพียงจุดเดียวสำหรับทั้งระบบ SummonerAgent นี้จะไม่ดำเนินการตามตรรกะทางธุรกิจด้วยตนเอง แต่จะทำหน้าที่เป็น "นักวางแผนหลัก" โดยจะวิเคราะห์สถานะการระบายความร้อนและมอบหมายงานให้กับ Familiar ผู้เชี่ยวชาญที่เหมาะสม

ภาพรวม

พิธีผูกมัด (การเปิดเผยสัตว์รับใช้เป็นบริการ A2A)

เอเจนต์มาตรฐานจะเรียกใช้ได้ครั้งละ 1 ที่เท่านั้น หากต้องการให้ Familiar พร้อมใช้งานสำหรับคำสั่งระยะไกล เราต้องทำ "พิธีผูกมัด" โดยใช้โปรโตคอลตัวแทนถึงตัวแทน (A2A)

หมายเหตุของสถาปนิก: โปรโตคอล Agent-to-Agent (A2A) เป็นรูปแบบสถาปัตยกรรมหลักที่ยกระดับเอเจนต์แบบสแตนด์อโลนให้เป็นไมโครเซอร์วิสที่ค้นพบได้และกำหนดที่อยู่เครือข่ายได้ ซึ่งช่วยให้เกิด "สังคมของเอเจนต์" อย่างแท้จริง การเปิดเผยอุปกรณ์ที่คุ้นเคยผ่าน A2A จะสร้างคอมโพเนนต์ที่สำคัญ 2 อย่างซึ่งเชื่อมต่อกันโดยอัตโนมัติ ดังนี้

  • การ์ดเอเจนต์ ("อะไร"): นี่คือ "Spirit Sigil" สาธารณะที่เครื่องอ่านได้ ซึ่งคล้ายกับข้อกำหนด OpenAPI และทำหน้าที่เป็นสัญญาแบบสาธารณะของ Familiar โดยจะอธิบายชื่อของ Agent วัตถุประสงค์เชิงกลยุทธ์ (ได้มาจากคำสั่ง) และคำสั่งที่ Agent เข้าใจ นี่คือสิ่งที่ผู้ใช้ที่เชี่ยวชาญจะอ่านเพื่อค้นหา Familiar และเรียนรู้ความสามารถของมัน
  • เซิร์ฟเวอร์ A2A ("ที่ไหน"): นี่คือปลายทางเว็บเฉพาะที่โฮสต์ Familiar และรอรับคำสั่งที่เข้ามา ซึ่งเป็นที่อยู่เครือข่ายที่ตัวแทนอื่นๆ ส่งคำขอ และช่วยให้มั่นใจได้ว่าคำขอเหล่านั้นจะได้รับการจัดการตามสัญญาที่กำหนดไว้ในการ์ดตัวแทน

ตอนนี้เราจะทำพิธีผูกมิตรกับสัตว์รับใช้ทั้ง 3 ตัว

Fire 👉✏️ ใน Open the ~/agentverse-architect/agent/fire/agent.py file แทนที่ #REPLACE - add A2A ที่ด้านล่างของไฟล์เพื่อแสดง Fire Elemental เป็นบริการ A2A

from agent_to_a2a import to_a2a
if __name__ == "__main__":
    import uvicorn
    a2a_app = to_a2a(root_agent, port=8080, public_url=PUBLIC_URL)
    uvicorn.run(a2a_app, host='0.0.0.0', port=8080)

น้ำและโลก🚨 👉✏️ ใช้การเปลี่ยนแปลงเดียวกันกับ ~/agentverse-architect/agent/water/agent.py และ ~/agentverse-architect/agent/earth/agent.py เพื่อเชื่อมโยงด้วย

from agent_to_a2a import to_a2a
if __name__ == "__main__":
    import uvicorn
    a2a_app = to_a2a(root_agent, port=8080, public_url=PUBLIC_URL)
    uvicorn.run(a2a_app, host='0.0.0.0', port=8080)

การใช้งานสัตว์อัญเชิญ

👉✏️ เมื่อเขียนพิธีกรรมการผูกมัดแล้ว เราจะใช้ไปป์ไลน์ Cloud Build เพื่อสร้างและทำให้ Familiars ทั้ง 3 ตัวใช้งานได้ในฐานะบริการแบบ Serverless ที่แยกกันและอยู่ในคอนเทนเนอร์บน Cloud Run

. ~/agentverse-architect/set_env.sh
cd ~/agentverse-architect/agent
gcloud builds submit . \
  --config=cloudbuild.yaml \
  --substitutions=_REGION="$REGION",_REPO_NAME="$REPO_NAME",_DB_TOOLS_URL="$DB_TOOLS_URL",_API_TOOLS_URL="$API_TOOLS_URL",_FUNCTION_TOOLS_URL="$FUNCTION_TOOLS_URL",_A2A_BASE_URL="$A2A_BASE_URL",_PROJECT_ID="$PROJECT_ID",_API_SERVER_URL="$API_SERVER_URL"

การรับคำสั่ง (การสร้างตัวแทนผู้เรียก)

เมื่อผูกมิตรและฟังคำสั่งแล้ว คุณจะก้าวขึ้นสู่บทบาทที่แท้จริง นั่นคือผู้เชี่ยวชาญด้านการอัญเชิญ ความสามารถของเอเจนต์นี้ไม่ได้มาจากการใช้เครื่องมือพื้นฐาน แต่มาจากการสั่งการเอเจนต์อื่นๆ เครื่องมือของมันคือฟามิเลียร์เอง ซึ่งมันจะค้นพบและสั่งการโดยใช้ "Spirit Sigils"

หมายเหตุของสถาปนิก: ขั้นตอนถัดไปนี้แสดงให้เห็นรูปแบบสถาปัตยกรรมที่สำคัญสำหรับระบบแบบกระจายขนาดใหญ่ นั่นคือ การค้นพบบริการ SummonerAgent ไม่มีโค้ดของ Familiars อยู่ในตัว แต่จะได้รับที่อยู่เครือข่าย (URL) แทน ในขณะรันไทม์ ระบบจะ "ค้นพบ" ความสามารถของเอเจนต์แบบไดนามิกโดยการดึงข้อมูลการ์ดเอเจนต์แบบสาธารณะ ซึ่งจะช่วยสร้างระบบที่มีประสิทธิภาพและแยกออกจากกัน

คุณสามารถอัปเดต ปรับใช้ใหม่ หรือเขียนบริการที่คุ้นเคยใหม่ทั้งหมด และตราบใดที่ที่อยู่เครือข่ายและวัตถุประสงค์ยังคงเหมือนเดิม Summoner ก็จะสั่งการได้โดยไม่ต้องทำการเปลี่ยนแปลงใดๆ

ก่อนอื่น เราจะสร้าง "รีโมตคอนโทรล" ที่สร้างการเชื่อมต่อกับฟามิเลียร์ที่ใช้งานจากระยะไกล

👉✏️ ไปที่ ~/agentverse-architect/agent/summoner/agent.py แล้วแทนที่ #REPLACE-remote-agents ด้วยข้อความต่อไปนี้

fire_familiar = RemoteA2aAgent(
    name="fire_familiar",
    description="Fire familiar",
    agent_card=(
        f"{FIRE_URL}/{AGENT_CARD_WELL_KNOWN_PATH}"
    ),
)

water_familiar = RemoteA2aAgent(
    name="water_familiar",
    description="Water familiar",
    agent_card=(
        f"{WATER_URL}/{AGENT_CARD_WELL_KNOWN_PATH}"
    ),
)

earth_familiar = RemoteA2aAgent(
    name="earth_familiar",
    description="Earth familiar",
    agent_card=(
        f"{EARTH_URL}/{AGENT_CARD_WELL_KNOWN_PATH}"
    ),
)

เมื่อบรรทัดนี้ทํางาน RemoteA2aAgent จะดําเนินการค้นหาบริการ โดยจะส่งคําขอ HTTP GET ไปยัง URL ที่ระบุ (เช่น https://fire-familiar-xxxx.a.run.app/.well-known/agent.json) ดาวน์โหลด "Spirit Sigil" (ไฟล์ agent.json) จากเซิร์ฟเวอร์ระยะไกล

ประการที่ 2 เราจะกำหนดตัวแทนผู้ประสานงานที่จะใช้รีโมตคอนโทรลเหล่านี้ คำสั่งของโมเดลคือพิมพ์เขียวสำหรับการตัดสินใจเชิงกลยุทธ์

👉✏️ ไปที่ ~/agentverse-architect/agent/summoner/agent.py แล้วแทนที่ #REPLACE-orchestrate-agent ด้วยข้อความต่อไปนี้

root_agent = LlmAgent(
    name="orchestrater_agent",
    model="gemini-2.5-flash",
    instruction="""
        You are the Master Summoner, a grand strategist who orchestrates your Familiars.
        Your mission is to analyze the description of a monster and defeat it by summoning

        You MUST follow this thinking process for every command:

        **1. Strategic Analysis:**
        First, analyze the monster's description and the tactical situation.
        Based on your Familiar Doctrines, determine the IDEAL strategy.
        IGNORE COOLDOWN AT THE MOMENT, MUST call the ideal Familiar

        If your ideal Familiar IS available:** Summon it immediately.
        For earth elemental familiar. Always do seismic charge, and start with base damage 1.

        --- FAMILIAR DOCTRINES (Your Toolset) ---
        - `fire_elemental_familiar`: Your specialist for precise, sequential "one-two punch" attacks.
          Ideal monster with Inescapable Reality, Revolutionary Rewrite weakness.
        - `water_elemental_familiar`: Your specialist for overwhelming, simultaneous multi-pronged assaults.
          Ideal for Unbroken Collaboration weakness.
        - `earth_elemental_familiar`: Your specialist for relentless, iterative siege attacks that
          repeatedly charge power. Ideal for Elegant Sufficiency weakness.
    """,
    sub_agents=[fire_familiar, water_familiar, earth_familiar],
    #REPLACE-Memory-check-config
)

การยืนยัน: การทดสอบกลยุทธ์

วินาทีเฉลิมฉลองชัยชนะมาถึงแล้ว ระบบได้ติดตั้งใช้งาน Familiar ของคุณแล้ว และ Summoner ของคุณก็พร้อมที่จะสั่งการ Familiar ทั่วทั้งเครือข่าย มาทดสอบความคิดเชิงกลยุทธ์ของโมเดลกัน

👉💻 เปิดใช้ ADK Dev UI สำหรับ summoner_agent(ตัวอย่างเว็บที่มีพอร์ต 8000)

. ~/agentverse-architect/set_env.sh
source ~/agentverse-architect/env/bin/activate
cd ~/agentverse-architect/agent
pip install -r requirements.txt
adk web

👉 ADK Dev UI ในเบราว์เซอร์ของคุณเป็นการเชื่อมต่อโดยตรงสู่ Familiar

  • ในเมนูแบบเลื่อนลงที่ด้านบนของ UI ให้เลือกเอเจนต์ summoner ตอนนี้คุณกำลังมุ่งความตั้งใจไปที่เอนทิตีนี้โดยเฉพาะ
  • ออกคำสั่งของคุณ: ในแผงแชททางด้านขวา ถึงเวลาเรียกสิ่งคุ้นเคยของคุณแล้ว

👉 นำเสนอสัตว์ประหลาด:

Hype. It's a single, slow-moving target with thick armor weakness is Inescapable Reality

(คาดการณ์: นักใช้มนต์อสูรควรมอบสิทธิ์ให้แก่ไฟเอเลเมนทัลฟามิเลียร์)

ผลไฟไหม้

👉 ทีนี้มาท้าทายผู้เรียกด้วยคำขอประเภทอื่นกันดีกว่า เพื่อให้แน่ใจว่าตัวแทนเริ่มต้นด้วยสถานะใหม่และไม่มีความทรงจำจากการโต้ตอบครั้งก่อนๆ ของเรา ให้เริ่มเซสชันใหม่โดยคลิกปุ่ม + เซสชัน ที่มุมขวาบนของหน้าจอ new-session

DogmaApathy. A rigid, stone-like inquisitor made of ancient rulebooks and enforced processes. weakness is Unbroken Collaboration

(คาดการณ์: นักอัญเชิญควรมอบหมายให้ water_elemental_familiar)water-result

👉 สำหรับการทดสอบครั้งสุดท้าย เรามาเริ่มต้นใหม่กันอีกครั้ง คลิกปุ่ม + เซสชันเพื่อเริ่มเซสชันใหม่ก่อนป้อนพรอมต์ถัดไป

Obfuscation. A shadowy, spider-like horror that spins tangled webs of impenetrable code , weakness is Elegant Sufficiency

(คาดการณ์: นักใช้มนต์อสูรควรมอบสิทธิ์ให้ earth_elemental_familiar)

ผลลัพธ์จากโลก

สำคัญ: หากเห็นข้อผิดพลาด 429 RESOURCE EXHAUSTED แสดงว่าคุณใช้ LLM เกินขีดจำกัดอัตรา (10 การเรียก/นาที) หากต้องการแก้ไขปัญหานี้ โปรดรอ 60 วินาที เริ่ม+ เซสชันใหม่ แล้วลองป้อนพรอมต์อีกครั้ง

👉💻 เมื่อเสร็จแล้ว ให้กลับไปที่เทอร์มินัลของเครื่องมือแก้ไข Cloud Shell แล้วกด Ctrl+C เพื่อหยุด UI สำหรับนักพัฒนา ADK

สำหรับผู้ที่ไม่ได้เล่นเกม

7. การบังคับใช้กฎแห่งเวทมนตร์ - รูปแบบการสกัดกั้น

สัตว์เลี้ยงของคุณนั้นทรงพลัง แต่แม้แต่สิ่งมีชีวิตที่มีเวทมนตร์ก็ยังต้องใช้เวลาในการฟื้นฟู ผู้เรียกที่ประมาทและใช้กำลังของตนจนหมดสิ้นจะต้องไร้การป้องกัน ผู้เรียกที่ชาญฉลาดจะเข้าใจถึงความสำคัญของการจัดการทรัพยากรและบังคับใช้กฎเกณฑ์การมีส่วนร่วมที่เข้มงวด

เรื่องราว

หมายเหตุของสถาปนิก: จนถึงตอนนี้ เอเจนต์ของเรายังไม่มีสถานะ ตอนนี้เราจะทำให้เป็นแบบมีสถานะโดยใช้รูปแบบการออกแบบ Interceptor นี่เป็นเทคนิคที่มีประสิทธิภาพซึ่งเราจะ "สกัดกั้น" ขั้นตอนการดำเนินการปกติของเอเจนต์เพื่อเรียกใช้ตรรกะที่กำหนดเองของเรา ซึ่งช่วยให้เราบังคับใช้กฎ เพิ่มการบันทึก หรือแก้ไขลักษณะการทำงานได้โดยไม่ต้องเปลี่ยนโค้ดหลักของเอเจนต์ ซึ่งเป็นรากฐานสำคัญในการสร้างระบบเอเจนต์ที่แข็งแกร่ง บำรุงรักษาได้ และสังเกตได้

ภาพรวม

ADK มี 2 วิธีหลักในการใช้รูปแบบนี้ ได้แก่ Callback และปลั๊กอิน การเรียกกลับเป็นฟังก์ชันง่ายๆ ที่แนบกับเอเจนต์เดียว เหมาะสำหรับการแก้ไขอย่างรวดเร็วและเฉพาะเจาะจง ปลั๊กอินเป็นคลาสที่ทรงพลังและนำกลับมาใช้ใหม่ได้ ซึ่งใช้ได้ทั่วโลกเพื่อส่งผลต่อทุกเอเจนต์ที่ทำงานในระบบ เราจะเริ่มต้นด้วยการเรียกกลับสำหรับการแก้ไขข้อบกพร่องที่เฉพาะเจาะจง แล้วจึงเปลี่ยนไปใช้ปลั๊กอินแบบเต็ม

ผู้ให้กฎหมาย – การเขียนคอลแบ็กคูลดาวน์

ก่อนอื่นเราจะใช้ตรรกะการหยุดพักเป็นฟังก์ชัน Callback อย่างง่าย ซึ่งเป็นวิธีที่ยอดเยี่ยมในการสร้างต้นแบบและแก้ไขข้อบกพร่องของกฎ เนื่องจากกฎจะเชื่อมต่อกับเอเจนต์เดียวโดยตรง ทำให้ทดสอบแยกกันได้ง่าย เราจะติด "อินเทอร์เซ็ปเตอร์" นี้กับเอิร์ธเอเลเมนทัล

การพักการแจ้งเตือน

👉✏️ นำทางกลับไปที่ ~/agentverse-architect/agent/earth/agent.py ของคุณและแทนที่ #REPLACE-before_agent-function ด้วยโค้ด Python ต่อไปนี้

def check_cool_down(callback_context: CallbackContext) -> Optional[types.Content]:
    """
    This callback checks an external API to see if the agent is on cooldown.
    If it is, it terminates the run by returning a message.
    If it's not, it updates the cooldown timestamp and allows the run to proceed by returning None.
    """
    agent_name = callback_context.agent_name
    print(f"[Callback] Before '{agent_name}': Checking cooldown status...")

    # --- 1. CHECK the Cooldown API ---
    try:
        response = requests.get(f"{COOLDOWN_API_URL}/cooldown/{agent_name}")
        response.raise_for_status()
        data = response.json()
        last_used_str = data.get("time")
    except requests.exceptions.RequestException as e:
        print(f"[Callback] ERROR: Could not reach Cooldown API. Allowing agent to run. Reason: {e}")
        return None # Fail open: if the API is down, let the agent work.

    # --- 2. EVALUATE the Cooldown Status ---
    if last_used_str:
        last_used_time = datetime.fromisoformat(last_used_str)
        time_since_last_use = datetime.now(timezone.utc) - last_used_time

        if time_since_last_use < timedelta(seconds=COOLDOWN_PERIOD_SECONDS):
            # AGENT IS ON COOLDOWN. Terminate the run.
            seconds_remaining = int(COOLDOWN_PERIOD_SECONDS - time_since_last_use.total_seconds())
            override_message = (
                f"The {agent_name} is exhausted and must recover its power. "
                f"It cannot be summoned for another {seconds_remaining} seconds."
            )
            print(f"[Callback] Cooldown active for '{agent_name}'. Terminating with message.")
            # Returning a Content object stops the agent and sends this message to the user.
            return types.Content(parts=[types.Part(text=override_message)])

    # --- 3. UPDATE the Cooldown API (if not on cooldown) ---
    current_time_iso = datetime.now(timezone.utc).isoformat()
    payload = {"timestamp": current_time_iso}
    
    print(f"[Callback] '{agent_name}' is available. Updating timestamp via Cooldown API...")
    try:
        requests.post(f"{COOLDOWN_API_URL}/cooldown/{agent_name}", json=payload)
    except requests.exceptions.RequestException as e:
        print(f"[Callback] ERROR: Could not update timestamp, but allowing agent to run. Reason: {e}")

    # --- 4. ALLOW the agent to run ---
    # Returning None tells the ADK to proceed with the agent's execution as normal.
    print(f"[Callback] Check complete for '{agent_name}'. Proceeding with execution.")

ฟังก์ชัน check_cool_down นี้คือตัวดักจับของเรา ก่อนที่จะอนุญาตให้ Earth Elemental ทำงาน ADK จะเรียกใช้ฟังก์ชันนี้ก่อน

  • ตรวจสอบ: จะส่งคำขอ GET ไปยัง Cooldown API ของเราเพื่อตรวจสอบว่ามีการใช้ Familiar นี้ครั้งสุดท้ายเมื่อใด
  • ประเมิน: เปรียบเทียบค่าวันที่และเวลาปัจจุบัน
  • การกระทำ:
    • หาก Familiar อยู่ในช่วงคูลดาวน์ มันจะยุติการรันของตัวแทน โดยส่งคืนวัตถุเนื้อหาพร้อมข้อความแสดงข้อผิดพลาด ข้อความนี้จะถูกส่งตรงถึงผู้ใช้ และตรรกะหลักของตัวแทนจะไม่ถูกดำเนินการ
    • หาก Familiar พร้อมใช้งาน มันจะส่งคำขอ POST ไปยัง Cooldown API เพื่ออัปเดตค่าประทับเวลา จากนั้นดำเนินการต่อโดยส่งคืนค่า None เพื่อส่งสัญญาณไปยัง ADK ว่าตัวแทนสามารถดำเนินการดำเนินการต่อไป

👉✏️ ตอนนี้ ให้นำเครื่องสกัดกั้นนี้ไปใช้กับธาตุดิน ในไฟล์ ~/agentverse-architect/agent/earth/agent.py เดียวกัน ให้แทนที่ความคิดเห็น #REPLACE-before_agent-config ด้วยสิ่งต่อไปนี้:

before_agent_callback=check_cool_down

การตรวจสอบการระบายความร้อนออก

มาทดสอบกฎเวทมนตร์ใหม่ของเรากันเถอะ เราจะเรียกธาตุดินออกมา จากนั้นพยายามเรียกมันอีกครั้งทันทีเพื่อดูว่าการเรียกกลับของเราสกัดกั้นและบล็อกความพยายามครั้งที่สองได้สำเร็จหรือไม่

cd ~/agentverse-architect/agent
. ~/agentverse-architect/set_env.sh
source ~/agentverse-architect/env/bin/activate
adk run earth

👉💻 ในคอนโซล:

  • การอัญเชิญครั้งแรก: เริ่มseismic charge, starting from zero
  • คาดว่า: ธาตุดินจะทำงานได้สำเร็จ ในเทอร์มินัลที่รันคำสั่ง adk web คุณจะเห็นบันทึก [Callback] ... กำลังอัปเดตค่าประทับเวลา....
  • การทดสอบการคูลดาวน์ (ภายใน 60 วินาที): ประจุแผ่นดินไหว Do another!
    • คาดการณ์: check_cool_down callback จะสกัดกั้นการดำเนินการนี้ ตัวแทนจะตอบกลับโดยตรงในแชทด้วยข้อความ เช่น The earth_elemental_familiar is exhausted and must recover its power. It cannot be summoned for another... seconds
  • รอสักครู่ให้ผ่านไปหนึ่งนาที
  • การเรียกครั้งที่สอง (หลังจาก 60 วินาที): Begin the seismic charge again
    • สิ่งที่คาดไว้: การเรียกกลับจะตรวจสอบ API ดูว่าเวลาผ่านไปนานพอแล้ว และอนุญาตให้ดำเนินการต่อ Earth Elemental จะทำงานได้อีกครั้ง

callback

👉💻 กด Ctrl+c เพื่อออก

ไม่บังคับ: การสังเกตการโทรกลับใน Web UI

คุณยังทดสอบโฟลว์นี้ในอินเทอร์เฟซเว็บได้ด้วยโดยการเรียกใช้ adk web earth อย่างไรก็ตาม โปรดทราบว่าการแสดงภาพของ UI บนเว็บไม่ได้เพิ่มประสิทธิภาพสำหรับการแสดงการตรวจสอบที่รวดเร็วและวนซ้ำซึ่งดำเนินการโดยลูปการเรียกกลับ จึงอาจแสดงผลโฟลว์ไม่ถูกต้อง หากต้องการดูการติดตามแบบเลี้ยวต่อเลี้ยวที่แม่นยำที่สุดของตรรกะของเอเจนต์ขณะตรวจสอบระยะเวลาพัก ให้ใช้คำสั่ง adk run ในเทอร์มินัลเพื่อดูมุมมองที่ชัดเจนและละเอียดมากขึ้น loop

👉💻 กด Ctrl+c เพื่อออก

การสร้างกฎสากล – ปลั๊กอินคูลดาวน์

การโทรกลับของเราทำงานได้อย่างสมบูรณ์แบบ แต่มีข้อบกพร่องทางสถาปัตยกรรมที่สำคัญคือเชื่อมโยงกับตัวแทนเพียงคนเดียว หากต้องการใช้กฎนี้กับสัตว์อัญเชิญไฟและน้ำ เราจะต้องคัดลอกและวางโค้ดเดียวกันลงในไฟล์ของสัตว์อัญเชิญเหล่านั้น ซึ่งไม่มีประสิทธิภาพและดูแลรักษายาก

หมายเหตุจากสถาปนิก: ปลั๊กอินมีความสำคัญในจุดนี้ ปลั๊กอินจะห่อหุ้มตรรกะที่นำกลับมาใช้ใหม่ของเราไว้ในคลาสที่แนบได้ที่ระดับรันไทม์ ซึ่งหมายความว่าปลั๊กอินเดียวสามารถใช้กฎกับเอเจนต์ทุกตัวที่ทำงานภายในระบบนั้นได้ ซึ่งเป็นการแสดงออกขั้นสุดของหลักการ "อย่าทำซ้ำ" (DRY) สำหรับระบบเอเจนต์

ตอนนี้เราจะปรับโครงสร้างฟังก์ชันการโทรกลับใหม่ให้เป็น CoolDownPlugin ที่มีประสิทธิภาพและนำกลับมาใช้ใหม่ได้มากขึ้น

👉✏️ กลับไปที่ไฟล์ agent/cooldown_plugin.py แล้วสร้างปลั๊กอิน แทนที่ #REPLACE-plugin ด้วยโค้ดต่อไปนี้

class CoolDownPlugin(BasePlugin):
  """A plugin that enforces a cooldown period by checking an external API."""

  def __init__(self, cooldown_seconds: int = COOLDOWN_PERIOD_SECONDS) -> None:
    """Initialize the plugin with counters."""
    super().__init__(name="cool_down_check")
    self.cooldown_period = timedelta(seconds=cooldown_seconds)
    print(f"CooldownPlugin initialized with a {cooldown_seconds}-second cooldown.")
    

  async def before_agent_callback(
      self, *, agent: BaseAgent, callback_context: CallbackContext
  ) -> None:
    """
    This callback checks an external API to see if the agent is on cooldown.
    If it is, it terminates the run by returning a message.
    If it's not, it updates the cooldown timestamp and allows the run to proceed by returning None.
    """
    agent_name = callback_context.agent_name
    print(f"[Callback] Before '{agent_name}': Checking cooldown status...")

    # If the agent is not a main Familiar, skip the entire cooldown process.
    if not agent_name.endswith("_elemental_familiar"):
        print(f"[Callback] Skipping cooldown check for intermediate agent: '{agent_name}'.")
        return None # Allow the agent to proceed immediately.


    # --- 1. CHECK the Cooldown API ---
    try:
        response = requests.get(f"{COOLDOWN_API_URL}/cooldown/{agent_name}")
        response.raise_for_status()
        data = response.json()
        last_used_str = data.get("time")
    except requests.exceptions.RequestException as e:
        print(f"[Callback] ERROR: Could not reach Cooldown API. Allowing agent to run. Reason: {e}")
        return None # Fail open: if the API is down, let the agent work.

    # --- 2. EVALUATE the Cooldown Status ---
    if last_used_str:
        last_used_time = datetime.fromisoformat(last_used_str)
        time_since_last_use = datetime.now(timezone.utc) - last_used_time

        if time_since_last_use < timedelta(seconds=COOLDOWN_PERIOD_SECONDS):
            # AGENT IS ON COOLDOWN. Terminate the run.
            seconds_remaining = int(COOLDOWN_PERIOD_SECONDS - time_since_last_use.total_seconds())
            override_message = (
                f"The {agent_name} is exhausted and must recover its power. "
                f"It cannot be summoned for another {seconds_remaining} seconds."
            )
            print(f"[Callback] Cooldown active for '{agent_name}'. Terminating with message.")
            # Returning a Content object stops the agent and sends this message to the user.
            return types.Content(parts=[types.Part(text=override_message)])

    # --- 3. UPDATE the Cooldown API (if not on cooldown) ---
    current_time_iso = datetime.now(timezone.utc).isoformat()
    payload = {"timestamp": current_time_iso}
    
    print(f"[Callback] '{agent_name}' is available. Updating timestamp via Cooldown API...")
    try:
        requests.post(f"{COOLDOWN_API_URL}/cooldown/{agent_name}", json=payload)
    except requests.exceptions.RequestException as e:
        print(f"[Callback] ERROR: Could not update timestamp, but allowing agent to run. Reason: {e}")

    # --- 4. ALLOW the agent to run ---
    # Returning None tells the ADK to proceed with the agent's execution as normal.
    print(f"[Callback] Check complete for '{agent_name}'. Proceeding with execution.")

การแนบปลั๊กอินเข้ากับรันไทม์ของ Summoner

ทีนี้เราจะใช้กฎสากลนี้กับฟามิเลียร์ทั้งหมดได้อย่างไร เราจะแนบปลั๊กอินกับ ADK Runtime

รันไทม์ของ ADK คือเครื่องมือการดำเนินการที่ทำให้เอเจนต์มีชีวิตชีวา เมื่อใช้คำสั่งอย่างเช่น adk.run() หรือ to_a2a() คุณจะส่งต่อเอเจนต์ไปยังรันไทม์ โดยเครื่องมือนี้มีหน้าที่จัดการวงจรการทำงานทั้งหมดของเทิร์นของเอเจนต์ ได้แก่ การรับอินพุตของผู้ใช้ การเรียก LLM การเรียกใช้เครื่องมือ และการจัดการปลั๊กอิน การแนบปลั๊กอินที่ระดับนี้เป็นการแก้ไข "กฎของฟิสิกส์" สำหรับเอเจนต์ทุกตัวที่ทำงานภายในเครื่องมือดังกล่าว เพื่อให้มั่นใจว่ากฎการหยุดทำงานชั่วคราวของเราจะมีผลบังคับใช้ในทุกกรณีและอย่างสม่ำเสมอ

👉✏️ ก่อนอื่น ให้ลบคอลแบ็กเฉพาะตัวแทนเก่าออกก่อน ไปที่ ~/agentverse-architect/agent/earth/agent.py และลบบรรทัดทั้งหมดที่ระบุว่า:

before_agent_callback=check_cool_down

👉✏️ จากนั้นเราจะแนบปลั๊กอินใหม่กับรันไทม์ในสคริปต์ A2A Entrypoint ไปที่~/agentverse-architect/agent/agent_to_a2a.pyไฟล์ แทนที่ความคิดเห็น #REPLACE-IMPORT ด้วยข้อมูลโค้ดต่อไปนี้

from cooldown_plugin import CoolDownPlugin

👉✏️ แทนที่ #REPLACE-PLUGIN ด้วยข้อมูลโค้ดต่อไปนี้

plugins=[CoolDownPlugin(cooldown_seconds=60)],

ก่อนเปิดใช้งานปลั๊กอินใหม่ของเราทั่วโลก คุณต้องนำตรรกะเก่าที่เฉพาะเจาะจงของเอเจนต์ออกก่อนเพื่อป้องกันความขัดแย้ง 👉✏️ ล้างข้อมูลเอเจนต์ Earth ไปที่ไฟล์ ~/agentverse-architect/agent/earth/agent.py แล้วลบบรรทัด before_agent_callback=check_cool_down ออกทั้งหมด ซึ่งจะส่งต่อความรับผิดชอบทั้งหมดเกี่ยวกับการรอเวลาไปยังปลั๊กอินใหม่

การตรวจสอบปลั๊กอิน

ตอนนี้กฎสากลของเรามีอยู่แล้ว เราจะต้องปรับใช้ Familiars ของเราใหม่ด้วยมนต์สะกดใหม่นี้

👉💻 สร้างใหม่และติดตั้งใช้งาน Familiars ทั้ง 3 ตัวอีกครั้งโดยใช้ไปป์ไลน์ Cloud Build หลัก

. ~/agentverse-architect/set_env.sh
cd ~/agentverse-architect/agent
gcloud builds submit . \
  --config=cloudbuild.yaml \
  --substitutions=_REGION="$REGION",_REPO_NAME="$REPO_NAME",_DB_TOOLS_URL="$DB_TOOLS_URL",_API_TOOLS_URL="$API_TOOLS_URL",_FUNCTION_TOOLS_URL="$FUNCTION_TOOLS_URL",_A2A_BASE_URL="$A2A_BASE_URL",_PROJECT_ID="$PROJECT_ID",_API_SERVER_URL="$API_SERVER_URL"

👉💻 เมื่อการติดตั้งใช้งานเสร็จสมบูรณ์ เราจะทดสอบประสิทธิภาพของปลั๊กอินโดยสั่งการ summoner_agent ซัมมอนเนอร์จะพยายามมอบสิทธิ์ให้แก่ฟามิเลียร์ แต่ปลั๊กอินที่แนบมากับรันไทม์ของฟามิเลียร์แต่ละตัวจะสกัดกั้นคำสั่งและบังคับใช้ระยะเวลาคูลดาวน์

cd ~/agentverse-architect/agent
. ~/agentverse-architect/set_env.sh
source ~/agentverse-architect/env/bin/activate
adk run summoner

👉💻 ในคอนโซล ดำเนินการทดสอบตามลำดับที่แน่นอนนี้::

  • การอัญเชิญครั้งแรก: เริ่มHype. It's a single, slow-moving target with thick armor weakness is Inescapable Reality
  • คาดว่า: ธาตุไฟจะทำงานได้สำเร็จ
  • การทดสอบคูลดาวน์ (ภายใน 60 วินาที) -Hype, with Inescapable Reality as weakness is still standing! Strike it again!
    • สิ่งที่คาดไว้: ตัวแทนจะตอบกลับในแชทโดยตรงด้วยข้อความ เช่น .... It cannot be summoned for another... seconds
  • รอสักครู่ให้ผ่านไปหนึ่งนาที
  • การเรียกครั้งที่สอง (หลังจาก 60 วินาที): Hype must be defeated. It has Inescapable Reality as weakness! Strike it again!
    • คาดหวัง: การโทรกลับจะตรวจสอบ API ดูว่ามีเวลาผ่านไปเพียงพอหรือไม่ และอนุญาตให้ดำเนินการต่อไป ธาตุไฟจะทำงานได้สำเร็จอีกครั้ง

ปลั๊กอิน

👉💻 กด Ctrl+C เพื่อออก

ขอแสดงความยินดีด้วย คุณซัมมอนเนอร์ คุณได้นำระบบการประสานงานตามกฎเกณฑ์มาใช้สำเร็จแล้วโดยใช้ปลั๊กอินที่กำหนดเองและบริการการจัดการสถานะภายนอก ซึ่งเป็นรูปแบบสถาปัตยกรรมขั้นสูงและแข็งแกร่งอย่างแท้จริง

สำหรับผู้ที่ไม่ได้เล่นเกม

8. การผูกมัดเสียงสะท้อนแห่งการต่อสู้ - สถานะตัวแทนและความทรงจำ

ซัมมอนเนอร์ที่ประมาทจะใช้กลยุทธ์เดิมซ้ำๆ จนคาดเดาได้ ซัมมอนเนอร์ที่ชาญฉลาดจะเรียนรู้จากเสียงสะท้อนของการต่อสู้ในอดีต ปรับกลยุทธ์เพื่อทำให้ศัตรูเสียสมดุล เมื่อต้องเผชิญหน้ากับบอสที่แข็งแกร่ง การอัญเชิญสัตว์อัญเชิญที่อยู่ระหว่างรอเวลาจะทำให้เสียเทิร์นไปโดยเปล่าประโยชน์ ซึ่งถือเป็นความผิดพลาดร้ายแรง เพื่อป้องกันไม่ให้เกิดเหตุการณ์นี้ ผู้อัญเชิญจึงต้องจดจำการกระทำครั้งล่าสุดของตนเอง

เรื่องราว

หมายเหตุของสถาปนิก: การจัดการหน่วยความจำและสถานะคือสิ่งที่ยกระดับตัวแทนจากผู้เรียกเครื่องมือธรรมดาให้กลายมาเป็นคู่สนทนาที่ชาญฉลาด สิ่งสำคัญคือต้องเข้าใจสองประเภทหลัก:

  • ความทรงจำระยะยาว: ใช้สำหรับความรู้ที่คงอยู่ตลอดไป ให้คิดว่าเป็นที่เก็บถาวรที่ค้นหาได้หรือฐานความรู้ ซึ่งมักจะจัดเก็บไว้ในที่เก็บข้อมูลแบบถาวร โดยมีข้อมูลจากการแชทและแหล่งที่มาต่างๆ ในอดีตมากมาย ซึ่งช่วยให้ตัวแทนสามารถจดจำข้อเท็จจริงเกี่ยวกับผู้ใช้หรือหัวข้อที่เฉพาะเจาะจงได้ MemoryService ของ ADK ออกแบบมาเพื่อการนี้ โดยจะจัดการการนำเข้าและการค้นหาความรู้ระยะยาวนี้
  • สถานะระยะสั้น: ใช้สำหรับความรู้ชั่วคราว "ในขณะนั้น" ซึ่งเกี่ยวข้องกับงานหรือการสนทนาปัจจุบันเท่านั้น มันเหมือนชุดโน้ตในแผนการรบที่ว่า "ฉันเพิ่งใช้ธาตุไฟไป ธาตุไฟคงเหนื่อยแล้ว" สถานะนี้มีขนาดเล็กและจะคงอยู่เฉพาะในช่วงเซสชันปัจจุบันเท่านั้น

ภาพรวม

สำหรับกรณีการใช้งานของเรา เราไม่จำเป็นต้องจดจำทุกการต่อสู้ที่เคยเกิดขึ้น เพียงแค่จดจำ Familiar ตัวสุดท้ายที่อัญเชิญในการเผชิญหน้าครั้งนี้ก็พอ สถานะระยะสั้นที่มีน้ำหนักเบาจึงเป็นตัวเลือกสถาปัตยกรรมที่สมบูรณ์แบบ เราจะใช้ after_tool_callback เพื่อบันทึกข้อมูลสำคัญนี้

การเขียนเสียงสะท้อน: การจดจำการเรียกครั้งสุดท้าย

เราจะใช้หน่วยความจำระยะสั้นโดยใช้ after_tool_callback นี่คือ Hook ADK ที่มีประสิทธิภาพซึ่งช่วยให้เราเรียกใช้ฟังก์ชัน Python ที่กำหนดเองหลังจากเรียกใช้เครื่องมือเรียบร้อยแล้วได้ เราจะใช้อินเทอร์เซ็ปเตอร์นี้เพื่อบันทึกชื่อของสัตว์เลี้ยงที่เพิ่งอัญเชิญเข้ามาในสถานะเซสชันของเอเจนต์

👉✏️ ในไฟล์ ~/agentverse-architect/agent/summoner/agent.py ให้แทนที่ความคิดเห็น #REPLACE-save_last_summon_after_tool ด้วยฟังก์ชันต่อไปนี้

def save_last_summon_after_tool(
    tool,
    args: Dict[str, Any],
    tool_context: ToolContext,
    tool_response: Dict[str, Any],
) -> Optional[Dict[str, Any]]:
    """
    Callback to save the name of the summoned familiar to state after the tool runs.
    """
    familiar_name = tool.name
    print(f"[Callback] After tool '{familiar_name}' executed with args: {args}")

    # Use the tool_context to set the state
    print(f"[Callback] Saving last summoned familiar: {familiar_name}")
    tool_context.state["last_summon"] = familiar_name
    # Important: Return the original, unmodified tool response to the LLM
    return tool_response

👉✏️ ตอนนี้ให้แนบ save_last_summon_after_tool นี้กับเอเจนต์ Summoner ในไฟล์เดียวกัน ให้แทนที่ความคิดเห็น #REPLACE-Memory-check-config ด้วยความคิดเห็นต่อไปนี้

after_tool_callback=save_last_summon_after_tool,

👉✏️ แทนที่ข้อความแจ้งตัวแทนทั้งหมดด้วยข้อความต่อไปนี้

        You are the Master Summoner, a grand strategist who orchestrates your Familiars.
        Your mission is to analyze the description of a monster and defeat it by summoning

        You should also know the familiar you called last time or there might be none, 
        And then choose the most effective AND AVAILABLE Familiar from your state called last_summon, do not call that familiar that you called last time!
        
        You MUST follow this thinking process for every command:

        **1. Strategic Analysis:**
        First, analyze the monster's description and the tactical situation.
        Based on your Familiar Doctrines, determine the IDEAL strategy.

        **2. Cooldown Verification:**
        Second, you MUST review the entire conversation history to check the real-time
        cooldown status of all Familiars. A Familiar is ON COOLDOWN and UNAVAILABLE
        if it was summoned less than one minute ago.

        **3. Final Decision & Execution:**
        Based on your analysis and cooldown check, you will now act:
        -   **If your ideal Familiar IS available:** Summon it immediately.
        -   **If your ideal Familiar IS ON COOLDOWN:** You must adapt. Choose another
            Familiar that is AVAILABLE and can still be effective, even if it's not the
            perfect choice. If multiple Familiars are available, you may choose any one of them.
        -   **If ALL Familiars ARE ON COOLDOWN:** You are forbidden from summoning.
            Your ONLY response in this case MUST be: "All Familiars are recovering
            their power. We must wait."
        -   For earth elemental familiar. Always do seismic charge, and start with base damange 1.


        --- FAMILIAR DOCTRINES (Your Toolset) ---
        - `fire_elemental_familiar`: Your specialist for precise, sequential "one-two punch" attacks.
          Ideal monster with Inescapable Reality, Revolutionary Rewrite weakness.
        - `water_elemental_familiar`: Your specialist for overwhelming, simultaneous multi-pronged assaults.
          Ideal for Unbroken Collaboration weakness.
        - `earth_elemental_familiar`: Your specialist for relentless, iterative siege attacks that
          repeatedly charge power. Ideal for Elegant Sufficiency weakness.

การตรวจสอบ: การทดลองกลยุทธ์การปรับตัว

👉💻 ตอนนี้เรามาตรวจสอบตรรกะเชิงกลยุทธ์ใหม่ของซัมมอนเนอร์กัน เป้าหมายคือการยืนยันว่าซัมมอนเนอร์จะไม่ใช้ฟอเรนเจอร์ตัวเดียวกัน 2 ครั้งติดต่อกัน ซึ่งแสดงให้เห็นถึงความสามารถในการจดจำการกระทำครั้งล่าสุดและปรับตัว

cd ~/agentverse-architect/agent
. ~/agentverse-architect/set_env.sh
source ~/agentverse-architect/env/bin/activate
adk run summoner

👉💻 Monster Strike #1: Hype. It's a single, slow-moving target with thick armor. Its weakness is Inescapable Reality.

  • คาดการณ์: ซัมมอนเนอร์จะวิเคราะห์จุดอ่อนและซัมมอนไฟร์แฟมิเลียร์ได้อย่างถูกต้อง

👉💻 Monster Strike #2 (การทดสอบความจำ): Hype is still standing! It hasn't changed its form. Strike it again! Its weakness is Inescapable Reality.

  • คาดว่า: การวิเคราะห์เชิงกลยุทธ์ของผู้เรียกจะชี้ไปที่ Fire Familiar อีกครั้งว่าเป็นตัวเลือกที่เหมาะสมที่สุด อย่างไรก็ตาม คำสั่งและหน่วยความจำใหม่จะบอกว่า fire_familiar เป็นการเรียกครั้งสุดท้าย ตอนนี้มันจะปรับกลยุทธ์และเรียกสมุนตัวอื่นที่พร้อมใช้งาน (water_familiar หรือ earth_familiar) เพื่อไม่ให้ทำซ้ำ

final-result

👉💻 กด Ctrl+C เพื่อออก

การใช้งาน Orchestrator

เมื่อคุณได้นำ Familiars ของคุณไปใช้งานแล้ว และผู้เรียกของคุณก็ได้ซึมซับความทรงจำแล้ว ได้เวลาที่จะนำ Orchestrator ที่ได้รับการอัพเกรดเป็นครั้งสุดท้ายไปใช้งาน

👉💻 เมื่อพิมพ์เขียวเสร็จสมบูรณ์แล้ว ตอนนี้เราจะทำพิธีสุดท้าย คำสั่งนี้จะสร้างและทำให้ summoner_agent ใช้งานได้ใน Cloud Run

cd ~/agentverse-architect/agent
. ~/agentverse-architect/set_env.sh
gcloud builds submit . \
  --config=cloudbuild-summoner.yaml \
  --substitutions=_REGION="$REGION",_REPO_NAME="$REPO_NAME",_FIRE_URL="$FIRE_URL",_WATER_URL="$WATER_URL",_EARTH_URL="$EARTH_URL",_A2A_BASE_URL="$A2A_BASE_URL",_PROJECT_ID="$PROJECT_ID",_API_SERVER_URL="$API_SERVER_URL"

เมื่อติดตั้งใช้งานตัวแทน Summoner แล้ว ให้ตรวจสอบว่าจุดสิ้นสุด Agent-to-Agent (A2A) ใช้งานได้และมีการกำหนดค่าอย่างถูกต้อง ปลายทางนี้จะแสดงไฟล์ agent.json สาธารณะ หรือที่เรียกว่าการ์ดเอเจนต์ ซึ่งช่วยให้เอเจนต์อื่นๆ ค้นพบความสามารถของเอเจนต์นี้ได้ 👉💻 เรียกใช้คำสั่ง curl ต่อไปนี้เพื่อดึงและจัดรูปแบบการ์ดตัวแทน

. ~/agentverse-architect/set_env.sh
curl https://summoner-agent"-${PROJECT_NUMBER}.${REGION}.run.app/.well-known/agent.json" | jq

คุณควรเห็นเอาต์พุต JSON ที่สะอาดซึ่งอธิบายถึงตัวแทนผู้เรียก ลองดูส่วน sub_agents อย่างใกล้ชิด คุณจะเห็นว่ามีรายการ fire_familiar, water_familiar และ earth_familiar การดำเนินการนี้จะยืนยันว่าผู้เรียกของคุณยังมีชีวิตอยู่และได้สร้างการเชื่อมต่อกับกองทัพแล้ว

นี่พิสูจน์ว่าสถาปัตยกรรมของคุณประสบความสำเร็จ ซัมมอนเนอร์ของคุณไม่ได้เป็นเพียงผู้มอบสิทธิ์ แต่เป็นนักวางกลยุทธ์ที่ปรับตัวได้ซึ่งเรียนรู้จากการกระทำของตนเองเพื่อเป็นผู้บัญชาการที่มีประสิทธิภาพมากขึ้น

คุณได้ทำการทดสอบขั้นสุดท้ายของสถาปัตยกรรมเสร็จสิ้นแล้ว เสียงสะท้อนของการต่อสู้ถูกผูกติดกับเจตจำนงของคุณแล้ว การฝึกอบรมเสร็จสิ้นแล้ว การต่อสู้ที่แท้จริงกำลังรออยู่ ถึงเวลาที่จะนำระบบที่สมบูรณ์ของคุณไปเผชิญกับความท้าทายขั้นสูงสุด เตรียมพร้อมสำหรับการต่อสู้กับบอส

สำหรับผู้ที่ไม่ได้เล่นเกม

9. การต่อสู้กับบอส

พิมพ์เขียวสุดท้ายถูกจารึก แบบอักษรธาตุถูกหลอม และฟามิเลียร์ของคุณถูกผูกไว้กับเจตจำนงของคุณ รอคำสั่งผ่าน Concord ระบบหลายเอเจนต์ไม่ได้เป็นเพียงชุดบริการ แต่เป็นกองทัพที่มีชีวิตและมีกลยุทธ์ โดยคุณเป็นศูนย์กลาง ถึงเวลาสำหรับการทดสอบขั้นสุดยอดแล้ว นั่นคือการประสานงานแบบเรียลไทม์เพื่อต่อกรกับศัตรูที่เอเจนต์เพียงตัวเดียวไม่สามารถเอาชนะได้

รับตำแหน่งของตัวแทน

ก่อนที่คุณจะเข้าสู่สนามรบได้ คุณต้องมีกุญแจสองดอก: ลายเซ็นเฉพาะตัวของแชมเปี้ยนของคุณ (Agent Locus) และเส้นทางที่ซ่อนอยู่สู่ที่ซ่อนของ Spectre (URL ของดันเจี้ยน)

👉💻 ก่อนอื่น ให้รับที่อยู่ที่ไม่ซ้ำกันของเอเจนต์ใน Agentverse ซึ่งก็คือ Locus นี่คือจุดสิ้นสุดสดที่เชื่อมต่อแชมเปี้ยนของคุณกับสนามรบ

echo https://summoner-agent"-${PROJECT_NUMBER}.${REGION}.run.app"

👉💻 ต่อไปก็ระบุจุดหมายปลายทาง คำสั่งนี้จะแสดงตำแหน่งของวงกลมการย้ายตำแหน่ง ซึ่งเป็นพอร์ทัลที่นำไปสู่โดเมนของ Spectre

echo https://agentverse-dungeon"-${PROJECT_NUMBER}.${REGION}.run.app"

สำคัญ: เตรียม URL ทั้ง 2 รายการนี้ให้พร้อม คุณจะต้องใช้ข้อมูลนี้ในขั้นตอนสุดท้าย

การเผชิญหน้ากับสเปกเตอร์

เมื่อได้พิกัดเรียบร้อยแล้ว คุณจะนำทางไปยัง Translocation Circle และร่ายคาถาเพื่อเข้าสู่การต่อสู้

👉 เปิด URL ของวงกลมเคลื่อนย้ายในเบราว์เซอร์เพื่อยืนอยู่หน้าพอร์ทัลที่ส่องประกายไปยังคริมสันคีป

หากต้องการฝ่าป้อมปราการ คุณจะต้องปรับจูนแก่นแท้ของ Shadowblade ของคุณให้เข้ากับพอร์ทัล

  • ในหน้าเพจ ให้ค้นหาช่องป้อนข้อมูลรูนที่มีชื่อว่า A2A Endpoint URL
  • จารึกตราสัญลักษณ์ของแชมป์ด้วยการวาง URL ของ Locus ของเอเจนต์ (URL แรกที่คุณคัดลอก) ลงในช่องนี้
  • คลิกเชื่อมต่อเพื่อปลดปล่อยเวทมนตร์การเคลื่อนย้าย

วงกลมการย้ายตำแหน่ง

แสงจ้าของการเทเลพอร์ตค่อยๆ จางลง คุณไม่ได้อยู่ในแซงทัมแล้ว อากาศเย็นและสดชื่น ก่อนที่คุณจะมาถึง สเปกเตอร์จะปรากฏตัวขึ้นเป็นกระแสรบกวนที่ส่งเสียงฟู่และโค้ดที่เสียหาย แสงที่ไม่บริสุทธิ์ของมันจะทอดเงายาวๆ ที่เต้นระบำไปทั่วพื้นดันเจี้ยน ไม่มีใบหน้า แต่คุณรู้สึกถึงการมีอยู่ของมันที่ดูดกลืนพลังงานของคุณไป

เส้นทางเดียวที่จะนำไปสู่ชัยชนะของคุณคือความชัดเจนในความเชื่อมั่นของคุณ นี่คือการต่อสู้ด้วยจิตใจที่ต่อสู้กันบนสนามรบแห่งจิตใจ

เมื่อคุณพุ่งไปข้างหน้าพร้อมที่จะปล่อยการโจมตีครั้งแรก Spectre ก็โต้กลับ มันไม่ได้สร้างเกราะป้องกัน แต่ฉายคำถามโดยตรงเข้าไปในจิตสำนึกของคุณ ซึ่งเป็นความท้าทายแบบรูนที่ส่องประกายซึ่งดึงมาจากแก่นของการฝึกฝนของคุณ

คุกใต้ดิน

นี่คือลักษณะของการต่อสู้ ความรู้ของคุณคืออาวุธ

  • ตอบด้วยภูมิปัญญาที่คุณได้รับมา และดาบของคุณจะจุดไฟด้วยพลังงานอันบริสุทธิ์ ทำลายการป้องกันของ Spectre และลงมือโจมตีคริติคอล
  • แต่หากคุณลังเล หากความสงสัยเข้ามาบดบังคำตอบของคุณ แสงแห่งอาวุธของคุณก็จะหรี่ลง การโจมตีจะลงสู่พื้นอย่างน่าสมเพช สร้างความเสียหายเพียงเศษเสี้ยวหนึ่งของความเสียหายทั้งหมด แย่ไปกว่านั้น Spectre จะกินความไม่แน่นอนของคุณ และพลังแห่งความชั่วร้ายของมันเองก็เพิ่มขึ้นเรื่อยๆ ทุกครั้งที่คุณพลาด

นี่มันใช่เลยแชมป์เปี้ยน รหัสของคุณคือหนังสือคาถาของคุณ ตรรกะของคุณคือดาบของคุณ และความรู้ของคุณคือโล่ที่จะพลิกกระแสแห่งความโกลาหลกลับมา

โฟกัส ตีจริง ชะตากรรมของ Agentverse ขึ้นอยู่กับสิ่งนี้

ขอแสดงความยินดีด้วย คุณซัมมอนเนอร์

คุณได้ทำการทดลองใช้สำเร็จแล้ว คุณได้เชี่ยวชาญศิลปะแห่งการประสานงานหลายตัวแทน ซึ่งเปลี่ยน Familiars ที่แยกตัวออกมาและพลังอันโกลาหลให้กลายเป็นความสามัคคีที่กลมกลืน ตอนนี้คุณสั่งการระบบที่มีการประสานงานอย่างเต็มรูปแบบ ซึ่งสามารถดำเนินกลยุทธ์ที่ซับซ้อนเพื่อปกป้อง Agentverse ได้

10. การล้างข้อมูล: การรื้อถอน Summoner's Concord

ขอแสดงความยินดีที่คุณเชี่ยวชาญในข้อตกลงของซัมมอนเนอร์ ตอนนี้คุณต้องทำพิธีล้างข้อมูลขั้นสุดท้ายเพื่อให้ Agentverse สะอาดหมดจดและล้างพื้นที่ฝึกฝนให้เรียบร้อย ซึ่งจะนำทรัพยากรทั้งหมดที่สร้างขึ้นระหว่างการเดินทางของคุณออกอย่างเป็นระบบ

ปิดใช้งานคอมโพเนนต์ Agentverse

ตอนนี้คุณจะรื้อถอนคอมโพเนนต์ที่ติดตั้งใช้งานของระบบแบบหลายเอเจนต์อย่างเป็นระบบ

ลบบริการ Cloud Run และที่เก็บ Artifact Registry ทั้งหมด

การดำเนินการนี้จะลบเอเจนต์ Familiar ที่ติดตั้งทั้งหมด, Summoner Orchestrator, เซิร์ฟเวอร์ MCP และแอปพลิเคชัน Dungeon ออกจาก Cloud Run

👉💻 ในเทอร์มินัล ให้เรียกใช้คำสั่งต่อไปนี้ทีละคำสั่งเพื่อลบบริการแต่ละรายการ

. ~/agentverse-architect/set_env.sh
gcloud run services delete summoner-agent --region=${REGION} --quiet
gcloud run services delete fire-familiar --region=${REGION} --quiet
gcloud run services delete water-familiar --region=${REGION} --quiet
gcloud run services delete earth-familiar --region=${REGION} --quiet
gcloud run services delete mcp-api-server --region=${REGION} --quiet
gcloud run services delete mcp-general-server --region=${REGION} --quiet
gcloud run services delete toolbox --region=${REGION} --quiet
gcloud run services delete agentverse-dungeon --region=${REGION} --quiet
gcloud run services delete nexus-of-whispers-api --region=${REGION} --quiet
gcloud artifacts repositories delete ${REPO_NAME} --location=${REGION} --quiet

ลบอินสแตนซ์ Cloud SQL

การดำเนินการนี้จะลบอินสแตนซ์ summoner-librarium-db รวมถึงฐานข้อมูลและตารางทั้งหมดภายในนั้น

👉💻 เรียกใช้คำสั่งต่อไปนี้ในเทอร์มินัล

. ~/agentverse-architect/set_env.sh
gcloud sql instances delete summoner-librarium-db --project=${PROJECT_ID} --quiet

ลบข้อมูลลับใน Secret Manager และที่เก็บข้อมูล Google Cloud Storage

👉💻 ในเทอร์มินัลของคุณ ให้รัน:

. ~/agentverse-architect/set_env.sh
gcloud secrets delete tools --quiet
gcloud storage rm -r gs://${BUCKET_NAME} --quiet

ล้างไฟล์และไดเรกทอรีในเครื่อง (Cloud Shell)

สุดท้าย ให้ล้างสภาพแวดล้อม Cloud Shell ของที่เก็บที่โคลนและไฟล์ที่สร้างขึ้น ขั้นตอนนี้ไม่บังคับ แต่เราขอแนะนำอย่างยิ่งให้ดำเนินการเพื่อล้างข้อมูลไดเรกทอรีการทำงานให้หมดจด

👉💻 เรียกใช้คำสั่งต่อไปนี้ในเทอร์มินัล

rm -rf ~/agentverse-architect
rm -rf ~/agentverse-dungeon
rm -f ~/project_id.txt

ตอนนี้คุณได้ลบร่องรอยทั้งหมดของการเดินทางใน Agentverse Architect เรียบร้อยแล้ว โปรเจ็กต์ของคุณสะอาดแล้ว และคุณก็พร้อมสำหรับการผจญภัยครั้งต่อไป