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

1. Overture

Era pengembangan yang terpisah-pisah akan berakhir. Evolusi teknologi berikutnya bukan tentang kejeniusan yang terisolasi, tetapi tentang penguasaan kolaboratif. Membangun satu agen cerdas adalah eksperimen yang menarik. Membangun ekosistem agen yang tangguh, aman, dan cerdas—Agentverse yang sebenarnya—adalah tantangan besar bagi perusahaan modern.

Keberhasilan di era baru ini memerlukan konvergensi empat peran penting, pilar dasar yang mendukung sistem agentik yang berkembang. Kekurangan di salah satu area menciptakan kelemahan yang dapat membahayakan seluruh struktur.

Workshop ini adalah panduan perusahaan yang pasti untuk menguasai masa depan agentic di Google Cloud. Kami menyediakan roadmap menyeluruh yang memandu Anda dari ide awal hingga menjadi kenyataan operasional berskala penuh. Dalam empat lab yang saling terhubung ini, Anda akan mempelajari cara keterampilan khusus developer, arsitek, data engineer, dan SRE harus bertemu untuk membuat, mengelola, dan menskalakan Agentverse yang efektif.

Tidak ada satu pilar pun yang dapat mendukung Agentverse saja. Desain besar Arsitek tidak berguna tanpa eksekusi yang tepat dari Developer. Agen Developer tidak dapat berfungsi tanpa keahlian Data Engineer, dan seluruh sistem akan rentan tanpa perlindungan SRE. Hanya melalui sinergi dan pemahaman bersama tentang peran masing-masing, tim Anda dapat mengubah konsep inovatif menjadi kenyataan operasional yang sangat penting. Perjalanan Anda dimulai di sini. Bersiaplah untuk menguasai peran Anda dan pelajari bagaimana Anda cocok dengan keseluruhan yang lebih besar.

Selamat datang di Agentverse: Panggilan untuk Para Juara

Di luasnya dunia digital perusahaan, era baru telah dimulai. Ini adalah era agentic, era yang penuh harapan, ketika agen cerdas dan otonom bekerja secara harmonis untuk mempercepat inovasi dan menghilangkan hal-hal yang membosankan.

agentverse.png

Ekosistem terhubung yang penuh daya dan potensi ini dikenal sebagai Agentverse.

Namun, entropi yang merayap, kerusakan senyap yang dikenal sebagai The Static, telah mulai menggerogoti tepi dunia baru ini. Statis bukanlah virus atau bug; ini adalah perwujudan kekacauan yang memangsa tindakan penciptaan itu sendiri.

Hal ini memperkuat frustrasi lama menjadi bentuk yang mengerikan, sehingga memunculkan Tujuh Spektrum Pengembangan. Jika tidak ditangani, The Static dan Spectres-nya akan menghentikan progres, mengubah janji Agentverse menjadi gurun utang teknis dan project yang ditinggalkan.

Hari ini, kami menyerukan para pejuang untuk melawan kekacauan. Kita membutuhkan pahlawan yang bersedia menguasai keahlian mereka dan bekerja sama untuk melindungi Agentverse. Saatnya memilih jalur Anda.

Pilih Kelas Anda

Empat jalur berbeda terbentang di hadapan Anda, masing-masing merupakan pilar penting dalam perjuangan melawan The Static. Meskipun pelatihan Anda akan menjadi misi solo, kesuksesan akhir Anda bergantung pada pemahaman tentang bagaimana keterampilan Anda berpadu dengan orang lain.

  • The Shadowblade (Developer): Ahli dalam menempa dan berada di garis depan. Anda adalah pengrajin yang membuat bilah, membangun alat, dan menghadapi musuh dalam detail rumit kode. Jalur Anda adalah presisi, keterampilan, dan kreasi praktis.
  • The Summoner (Arsitek): Ahli strategi dan pengelola yang hebat. Anda tidak melihat satu agen, tetapi seluruh medan perang. Anda mendesain cetak biru utama yang memungkinkan seluruh sistem agen berkomunikasi, berkolaborasi, dan mencapai tujuan yang jauh lebih besar daripada satu komponen.
  • The Scholar (Data Engineer): Pencari kebenaran tersembunyi dan penjaga kebijaksanaan. Anda menjelajahi data yang luas dan belum terpetakan untuk menemukan kecerdasan yang memberi tujuan dan pandangan bagi agen Anda. Pengetahuanmu dapat mengungkap kelemahan musuh atau memberdayakan sekutumu.
  • The Guardian (DevOps / SRE): Pelindung dan perisai kerajaan yang setia. Anda membangun benteng, mengelola jalur suplai daya, dan memastikan seluruh sistem dapat menahan serangan tak terhindarkan dari The Static. Kekuatanmu adalah fondasi kemenangan timmu.

Misi Anda

Latihan Anda akan dimulai sebagai latihan mandiri. Anda akan mengikuti jalur yang dipilih, mempelajari keterampilan unik yang diperlukan untuk menguasai peran Anda. Di akhir uji coba, Anda akan menghadapi Spectre yang lahir dari The Static—mini-boss yang memangsa tantangan spesifik dalam keahlian Anda.

Anda hanya dapat mempersiapkan uji coba akhir dengan menguasai peran masing-masing. Kemudian, Anda harus membentuk tim dengan juara dari kelas lain. Bersama-sama, Anda akan menjelajahi pusat korupsi untuk menghadapi bos terakhir.

Tantangan kolaboratif terakhir yang akan menguji kekuatan gabungan Anda dan menentukan nasib Agentverse.

Agentverse menanti para hero. Apakah Anda akan menjawab panggilan?

2. Kesepakatan Pemanggil

Selamat datang, Pemanggil. Jalan Anda adalah jalan visi dan strategi besar. Sementara orang lain berfokus pada satu bilah atau satu mantra, Anda melihat seluruh medan perang. Anda tidak memerintahkan satu agen; Anda memimpin seluruh orkestra agen. Kekuatan Anda tidak terletak pada konflik langsung, tetapi dalam merancang cetak biru yang sempurna dan menyeluruh yang memungkinkan banyak spesialis—Familiar Anda—bekerja dalam harmoni yang sempurna. Misi ini akan menguji kemampuan Anda dalam merancang, menghubungkan, dan mengatur sistem multi-agen yang efektif.

ringkasan

Yang akan Anda pelajari

  • Merancang Ekosistem Alat yang Tidak Terikat: Merancang dan men-deploy serangkaian Server Alat MCP berbasis microservice yang independen. Anda akan mempelajari alasan lapisan dasar ini sangat penting untuk membuat sistem agentik yang skalabel, mudah dikelola, dan aman.
  • Kuasai Alur Kerja Agentik Tingkat Lanjut: Melampaui agen tunggal dan bangun sekelompok "Familiars" spesialis. Anda akan menguasai pola alur kerja ADK inti—Berurutan, Paralel, dan Loop—serta mempelajari prinsip arsitektur untuk memilih pola yang tepat untuk tugas yang tepat.
  • Menerapkan Pengelola Cerdas: Naikkan level dari pembuat agen sederhana menjadi arsitek sistem yang sebenarnya. Anda akan membuat Agen Pengelola utama yang menggunakan protokol Agent-to-Agent (A2A) untuk menemukan dan mendelegasikan tugas kompleks ke Familiar spesialis Anda, sehingga menciptakan sistem multi-agen yang sebenarnya.
  • Terapkan Aturan dengan Kode, Bukan Perintah: Pelajari cara membuat agen yang lebih andal dan dapat diprediksi dengan menerapkan aturan engagement stateful. Anda akan menerapkan logika kustom menggunakan sistem Plugin dan Callback ADK yang canggih untuk mengelola batasan dunia nyata seperti timer cooldown.
  • Mengelola Status dan Memori Agen: Beri agen Anda kemampuan untuk belajar dan mengingat. Anda akan mempelajari teknik untuk mengelola status percakapan jangka pendek dan memori persisten jangka panjang untuk menciptakan interaksi yang lebih cerdas dan sadar konteks.
  • Menjalankan Deployment Cloud End-to-End: Bawa seluruh sistem multi-agen Anda dari prototipe lokal ke realitas tingkat produksi. Anda akan mempelajari cara membuat container untuk agen dan orkestrator serta men-deploy-nya sebagai kumpulan microservice yang dapat diskalakan dan independen di Google Cloud Run.

3. Menggambar Lingkaran Pemanggilan

Selamat datang, Pemanggil. Sebelum satu Familiar dapat dipanggil, sebelum pakta apa pun dapat dibuat, tanah tempat Anda berdiri harus dipersiapkan. Lingkungan yang tidak terkendali adalah undangan menuju kekacauan; Summoner yang tepat hanya beroperasi dalam ruang yang disucikan dan diberdayakan. Tugas pertama kita adalah menggambar lingkaran pemanggilan: menuliskan rune kekuatan yang akan mengaktifkan layanan cloud yang diperlukan dan mendapatkan cetak biru kuno yang akan memandu pekerjaan kita. Kekuatan Pemanggil berasal dari persiapan yang cermat.

👉 Klik Activate Cloud Shell di bagian atas konsol Google Cloud (Ikon berbentuk terminal di bagian atas panel Cloud Shell),

Teks alternatif

👉 Klik tombol "Open Editor" (terlihat seperti folder terbuka dengan pensil). Tindakan ini akan membuka Editor Kode Cloud Shell di jendela. Anda akan melihat file explorer di sisi kiri. Teks alternatif

👉Temukan Project ID Google Cloud Anda:

  • Buka Konsol Google Cloud: https://console.cloud.google.com
  • Pilih project yang ingin Anda gunakan untuk workshop ini dari dropdown project di bagian atas halaman.
  • Project ID Anda ditampilkan di kartu Info project di Dasbor Teks alternatif

👉Buka terminal di IDE cloud, Teks alternatif

👉💻 Di terminal, verifikasi bahwa Anda sudah diautentikasi dan project ditetapkan ke project ID Anda menggunakan perintah berikut:

gcloud auth list

👉💻 Clone project bootstrap dari 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

👉💻 Jalankan skrip inisialisasi. Skrip ini akan meminta Anda memasukkan Project ID Google Cloud Anda. Kemudian, masukkan ID Project Google Cloud yang Anda temukan dari langkah terakhir saat diminta oleh skrip init.sh.

cd ~/agentverse-architect
./init.sh

👉💻 Tetapkan Project ID yang diperlukan:

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

👉💻 Jalankan perintah berikut untuk mengaktifkan Google Cloud API yang diperlukan:

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

👉💻 Jika Anda belum membuat repositori Artifact Registry bernama agentverse-repo, jalankan perintah berikut untuk membuatnya: (Lewati langkah ini jika Anda telah men-deploy class lain dalam project yang sama)

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

Menyiapkan izin

👉💻 Berikan izin yang diperlukan dengan menjalankan perintah berikut di terminal:

. ~/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"

👉💻 Saat Anda memulai pelatihan, kami akan menyiapkan tantangan terakhir. Perintah berikut akan memanggil Spectre dari statis yang kacau, sehingga menciptakan bos untuk ujian akhir Anda.

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

👉💻 Terakhir, jalankan skrip prepare.sh untuk melakukan tugas penyiapan awal.

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

Kerja bagus, Pemanggil. Lingkaran sudah lengkap dan perjanjian sudah disepakati. Tanah kini disucikan, siap menyalurkan kekuatan yang sangat besar. Dalam uji coba berikutnya, kita akan menempa Font Elemental yang akan menjadi sumber kekuatan Familiars kita.

4. Membentuk Font Elementer: Ekosistem Alat yang Tidak Terikat

Medan perang sudah siap, lingkaran pemanggilan sudah digambar, dan mana di sekitarnya berderak. Saatnya melakukan tindakan pertama Anda sebagai Summoner: menempa sumber kekuatan yang akan digunakan Familiars Anda untuk mendapatkan kekuatan. Ritual ini dibagi menjadi tiga bagian, yang masing-masing membangkitkan Elemental Font—sumber kekuatan tertentu yang stabil dan independen. Hanya jika ketiga font aktif, Anda dapat memulai pekerjaan pemanggilan yang lebih rumit.

Story

Catatan Arsitek: Server Model Context Protocol (MCP) adalah komponen dasar dalam sistem agentik modern, yang berfungsi sebagai jembatan komunikasi standar yang memungkinkan agen menemukan dan menggunakan alat jarak jauh. Dalam ekosistem alat kami, kami akan merancang dua jenis server MCP yang berbeda, yang masing-masing merepresentasikan pola arsitektur penting. Untuk terhubung ke database, kita akan menggunakan pendekatan deklaratif dengan Database Toolbox, yang menentukan alat kita dalam file konfigurasi sederhana. Pola ini sangat efisien dan aman untuk mengekspos akses data terstruktur. Namun, saat kita perlu menerapkan logika bisnis kustom atau memanggil API pihak ketiga eksternal, kita akan menggunakan pendekatan imperatif, dengan menulis logika server langkah demi langkah dalam kode. Hal ini memberikan kontrol dan fleksibilitas terbaik, sehingga kami dapat mengapsulasi operasi kompleks di balik alat yang sederhana dan dapat digunakan kembali. Arsitek utama harus memahami kedua pola tersebut untuk memilih pendekatan yang tepat bagi setiap komponen, sehingga menciptakan fondasi alat yang kuat, aman, dan skalabel.

ringkasan

Membangunkan Nexus of Whispers (Server MCP API Eksternal)

Summoner yang bijak tahu bahwa tidak semua kekuatan berasal dari dalam domainnya sendiri. Ada sumber energi eksternal yang terkadang kacau, yang dapat disalurkan untuk memberikan efek yang luar biasa. Nexus of Whispers adalah gerbang kita menuju kekuatan ini.

Story

Ada layanan yang sudah aktif dan berfungsi sebagai sumber daya eksternal kami, yang menawarkan dua endpoint ejaan mentah: /cryosea_shatter dan /moonlit_cascade.

Catatan Arsitek: Anda akan menggunakan pendekatan imperatif yang secara eksplisit menentukan logika server langkah demi langkah. Hal ini memberi Anda kontrol dan fleksibilitas yang jauh lebih besar, yang penting saat alat Anda perlu melakukan lebih dari sekadar menjalankan kueri SQL sederhana, seperti memanggil API lain. Memahami kedua pola ini adalah keterampilan penting bagi arsitek agen.

👉✏️ Buka direktori ~/agentverse-architect/mcp-servers/api/main.py dan GANTI #REPLACE-MAGIC-CORE dengan kode berikut:

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}"

Inti dari skrip ini adalah fungsi Python biasa. Di sinilah pekerjaan sebenarnya dilakukan.

👉✏️ Di file yang sama ~/agentverse-architect/mcp-servers/api/main.py GANTI #REPLACE-Runes of Communication dengan kode berikut:

@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() (The Handshake): Fungsi ini adalah ucapan selamat datang server. Saat agen baru terhubung, agen tersebut akan memanggil endpoint ini terlebih dahulu untuk bertanya, "Apa yang bisa kamu lakukan?" Kode kita merespons dengan daftar semua alat yang tersedia, yang dikonversi ke format MCP universal menggunakan adk_to_mcp_tool_type. - @app.call_tool() (Perintah): Fungsi ini adalah yang paling banyak digunakan. Saat memutuskan untuk menggunakan alat, agen akan mengirim permintaan ke endpoint ini dengan nama alat dan argumennya. Kode kami mencari alat dalam "buku mantra" available_tools, mengeksekusinya dengan run_async, dan menampilkan hasilnya dalam format MCP standar.

Kita akan men-deploy ini nanti.

Mengaktifkan Arcane Forge (Server MCP Fungsi Umum)

Tidak semua kekuatan berasal dari buku kuno atau bisikan yang jauh. Terkadang, Pemanggil harus menempa sihirnya sendiri dari keinginan mentah dan logika murni. Arcane Forge adalah sumber kekuatan ini—server yang menyediakan fungsi utilitas serbaguna dan stateless.

Story

Catatan Arsitek: Ini adalah pola arsitektur lainnya. Meskipun menghubungkan ke sistem yang ada adalah hal yang umum, Anda akan sering kali perlu menerapkan aturan dan logika bisnis unik Anda sendiri. Membuat alat "fungsi" atau "utilitas" khusus seperti ini adalah praktik terbaik. Hal ini merangkum logika kustom Anda, membuatnya dapat digunakan kembali untuk agen mana pun dalam ekosistem Anda, dan membuatnya tetap terpisah dari sumber data dan integrasi eksternal Anda.

👀 Lihat file ~/agentverse-architect/mcp-servers/general/main.py di IDE Google Cloud Anda. Anda akan melihat bahwa game ini menggunakan pendekatan imperatif mcp.server yang sama seperti Nexus untuk membangun Font of Power kustom ini.

Buat Pipeline Cloud Build Master

Sekarang, kita akan membuat file cloudbuild.yaml di dalam direktori mcp-servers. File ini akan mengatur build dan deployment kedua layanan.

👉💻 Dari direktori ~/agentverse-architect/mcp-servers, jalankan perintah berikut:

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"

Tunggu hingga semua deployment selesai.

👉 Anda dapat memverifikasi deployment dengan membuka konsol Cloud Run. Anda akan melihat dua instance server MCP baru Anda berjalan, seperti yang ditunjukkan di bawah: Teks alternatif

Membangunkan Librarium Pengetahuan (Server MCP ToolBox Database)

Font berikutnya adalah Librarium of Knowledge, yang merupakan koneksi langsung ke database Cloud SQL.

Story

Catatan Arsitek: Untuk ini, kita akan menggunakan Database Toolbox modern yang deklaratif. Ini adalah pendekatan yang efektif di mana kita menentukan sumber data dan alat dalam file konfigurasi YAML. Toolbox menangani pekerjaan kompleks dalam membuat dan menjalankan server, sehingga mengurangi jumlah kode kustom yang perlu kita tulis dan kelola.

Sekarang saatnya membangun "Summoner's Librarium"—database Cloud SQL yang akan menyimpan semua informasi penting kita. Kita akan menggunakan skrip penyiapan untuk menanganinya secara otomatis.

👉💻 Pertama, kita akan menyiapkan database. Di terminal Anda, jalankan perintah berikut:

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

Setelah skrip selesai, database Anda akan diisi dan data kerusakan elemen akan siap digunakan. Anda kini dapat memverifikasi konten Grimoire secara langsung.

👉 Pertama, buka Cloud SQL Studio untuk database Anda dengan membuka link langsung ini di tab browser baru:

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

Cloud SQL

👉 Di panel login di sebelah kiri, pilih database familiar_grimoire dari dropdown.

👉 Masukkan summoner sebagai pengguna dan 1234qwer sebagai sandi, lalu klik Autentikasi.

👉📜 Setelah terhubung, buka tab editor kueri baru jika belum terbuka. Untuk melihat data kerusakan elemen yang terukir, tempel dan jalankan kueri SQL berikut:

SELECT * FROM
  "public"."abilities"

Sekarang Anda akan melihat tabel abilities dengan kolom dan barisnya yang terisi, yang mengonfirmasi bahwa Grimoire Anda sudah siap. Data

Mengonfigurasi Server MCP ToolBox

File konfigurasi tools.yaml berfungsi sebagai cetak biru untuk server kita, yang memberi tahu Database Toolbox secara persis cara terhubung ke database kita dan kueri SQL apa yang akan diekspos sebagai alat.

sumber: Bagian ini menentukan koneksi ke data Anda.

  • summoner-librarium:: Ini adalah nama logis yang kami berikan untuk koneksi kami.
  • kind: cloud-sql-postgres: Memberi tahu Toolbox untuk menggunakan konektor bawaan yang aman dan dirancang khusus untuk Cloud SQL untuk PostgreSQL.
  • project, region, instance, dll.: Ini adalah koordinat persis instance Cloud SQL yang Anda buat selama skrip prepare.sh, yang memberi tahu Toolbox tempat menemukan Librarium kita.

👉✏️ Buka ~/agentverse-architect/mcp-servers/db-toolbox di tools.yaml, ganti #REPLACE-Source dengan

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"

👉✏️ 🚨🚨REPLACE

YOUR_PROJECT_ID

dengan project ID Anda.

tools: Bagian ini menentukan kemampuan atau fungsi sebenarnya yang akan ditawarkan server kita.

  • lookup-available-ability:: Ini adalah nama alat pertama kita.
  • kind: postgres-sql: Memberi tahu Toolbox bahwa tindakan alat ini adalah menjalankan pernyataan SQL.
  • source: summoner-librarium: Ini menautkan alat ke koneksi yang kita tentukan di blok sumber. Dengan demikian, alat ini mengetahui database mana yang akan menjalankan kuerinya.
  • deskripsi & parameter: Ini adalah informasi yang akan diekspos ke Model Bahasa. Deskripsi memberi tahu agen kapan harus menggunakan alat, dan parameter menentukan input yang diperlukan alat. Langkah ini sangat penting untuk mengaktifkan kemampuan panggilan fungsi agen.
  • statement: Ini adalah kueri SQL mentah yang akan dijalankan. $1 adalah placeholder aman tempat parameter familiar_name yang disediakan oleh agen akan dimasukkan dengan aman.

👉✏️ Di ~/agentverse-architect/mcp-servers/db-toolbox yang sama dalam file tools.yaml, ganti #REPLACE-tools dengan kode berikut

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;

kumpulan alat: Bagian ini mengelompokkan setiap alat kami.

  • summoner-librarium:: Kita membuat toolset dengan nama yang sama seperti sumber kita. Saat terhubung nanti, agen diagnostik kami dapat meminta untuk memuat semua alat dari set alat summoner-librarium dalam satu perintah yang efisien.

👉✏️ Di ~/agentverse-architect/mcp-servers/db-toolbox yang sama dalam file tools.yaml, ganti #REPLACE-toolsets dengan kode berikut

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

Men-deploy Librarium

Sekarang kita akan men-deploy Librarium. Daripada membangun container sendiri, kita akan menggunakan image container resmi bawaan dari Google dan menyediakan konfigurasi tools.yaml kita secara aman ke image tersebut menggunakan Secret Manager. Ini adalah praktik terbaik untuk keamanan dan kemudahan pemeliharaan.

👉💻 Buat secret dari file tools.yaml

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

👉💻 Deploy container toolbox resmi ke 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" \
    --args="--tools-file=/app/tools.yaml","--address=0.0.0.0","--port=8080" \
    --allow-unauthenticated \
    --min-instances 1
  • --set-secrets: Perintah ini memasang rahasia alat kita secara aman sebagai file bernama tools.yaml di dalam container yang sedang berjalan.
  • --args: Kita menginstruksikan container toolbox untuk menggunakan file rahasia yang di-mount sebagai konfigurasinya.

👉 Untuk mengonfirmasi bahwa toolbox Anda telah berhasil di-deploy, buka konsol Cloud Run. Anda akan melihat layanan summoner-toolbox yang tercantum dengan tanda centang hijau, yang menunjukkan bahwa layanan tersebut berjalan dengan benar, seperti pada gambar di bawah. Teks alternatif

Jika Anda lupa memperbarui

YOUR_PROJECT_ID

Anda dapat menambahkan versi baru tools.yaml ke secret menggunakan perintah berikut dan men-deploy ulang.

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

Librarium of Knowledge(Database ToolBox MCP Server) kini aktif dan dapat diakses di cloud. Server MCP ini menggunakan Desain Deklaratif yang menjelaskan apa yang Anda inginkan, dan toolbox membangun server untuk Anda.

Verifikasi: Uji Coba Sang Murid

👉💻 Sekarang kita akan menguji ekosistem alat berbasis cloud yang lengkap dengan Agen Diagnostik.

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

👉💻 Di alat pengujian cmd line, uji ketiga font:

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.

hasil akhir

Selamat, Pemanggil. Tiga Elemental Font Anda kini aktif, di-deploy secara independen, dan dapat diakses secara global, sehingga membentuk fondasi yang tak tergoyahkan untuk pasukan agen Anda. Tekan Ctrl+C untuk keluar.

UNTUK NON-GAMER

5. Memanggil Familiars: Alur Kerja Domain Inti

Font Elemen ditempa, bergetar dengan kekuatan mentah yang liar. Namun, kekuatan tanpa bentuk adalah kekacauan. Seorang Pemanggil sejati tidak hanya menggunakan energi mentah; mereka memberikannya kehendak, tujuan, dan bentuk khusus. Saatnya untuk melampaui penempaan sumber daya dan memulai pekerjaan yang sebenarnya: memanggil Familiars pertama Anda.

Setiap Familiar yang Anda panggil akan menjadi agen otonom, pelayan setia yang terikat pada doktrin pertarungan tertentu. Mereka bukan generalis; mereka adalah ahli dalam satu strategi yang efektif. Salah satunya akan menjadi ahli dalam kombo pukulan satu-dua yang presisi. Yang lain akan mengalahkan musuh dengan serangan serentak yang memiliki banyak sisi. Sepertiga akan menjadi mesin pengepungan yang gigih, menerapkan tekanan hingga targetnya hancur.

Story

Untuk mengapsulasi proses, logika bisnis, dan tindakan yang disediakan oleh server MCP ke dalam agen alur kerja otonom yang terspesialisasi. Setiap agen akan memiliki "wilayah operasional" yang ditentukan dengan diberi akses hanya ke server alat MCP tertentu yang diperlukan untuk menjalankan fungsinya. Lab ini menunjukkan cara memilih jenis agen yang tepat untuk tugas yang tepat.

ringkasan

Modul ini akan mengajarkan cara menggunakan agen alur kerja ADK yang canggih untuk mewujudkan strategi ini. Anda akan mempelajari bahwa pilihan arsitektur SequentialAgent, ParallelAgent, atau LoopAgent bukan hanya detail teknis—pilihan ini adalah esensi dari sifat Familiar Anda dan inti dari kekuatannya di medan perang.

Siapkan tempat suci Anda. Pemanggilan yang sebenarnya akan segera dimulai.

Memanggil Fire Elemental Familiar (Alur Kerja Berurutan)

Serangan Familiar Elemen Api adalah kombo dua bagian yang presisi: serangan yang ditargetkan diikuti dengan pembakaran yang kuat. Hal ini memerlukan urutan tindakan yang ketat dan teratur.

Story

Konsep: SequentialAgent adalah alat yang tepat untuk hal ini. Hal ini memastikan bahwa serangkaian sub-agen berjalan satu demi satu, meneruskan hasil dari langkah sebelumnya ke langkah berikutnya.

Tugas (Combo "Serangan yang Diperkuat"):

  • Langkah 1: Agen akan terlebih dahulu berkonsultasi dengan Librarium untuk menemukan kerusakan dasar kemampuan api tertentu.
  • Langkah 2: Kemudian, nilai kerusakan tersebut akan disalurkan melalui Arcane Forge untuk melipatgandakan kekuatannya menggunakan inferno_resonance.

Pertama, kita akan membuat koneksi antara Familiar dan server MCP (yaitu "Elemental Fonts") yang Anda deploy di modul sebelumnya.

👉✏️ Di file ~/agentverse-architect/agent/fire/agent.py, GANTI #REPLACE-setup-MCP dengan kode berikut:

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

Selanjutnya, kita membuat agen "pekerja" spesialis. Setiap agen diberi tujuan yang sempit dan jelas, serta dibatasi pada "wilayah operasional"-nya sendiri dengan diberi akses ke hanya satu set alat tertentu.

👉✏️ Di file ~/agentverse-architect/agent/fire/agent.py GANTI #REPLACE-worker-agents dengan kode berikut:

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],
)

Agen ini adalah komponen modular yang dapat digunakan kembali. Secara teoretis, Anda dapat menggunakan scout_agent ini dalam alur kerja yang sama sekali berbeda yang perlu membuat kueri database. Dengan memisahkan tanggung jawabnya, kita membuat elemen penyusun yang fleksibel. Hal ini merupakan prinsip inti dari desain berbasis komponen dan microservice.

Selanjutnya, kita akan menyusun Alur Kerja. Di sinilah keajaiban komposisi terjadi. SequentialAgent adalah "rencana utama" yang menentukan cara komponen khusus kami dirakit dan cara komponen tersebut berinteraksi.

👉✏️ Di file ~/agentverse-architect/agent/fire/agent.py GANTI #REPLACE-sequential-agent dengan kode berikut:

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

👉💻 Untuk menguji Fire Elemental, jalankan perintah berikut untuk meluncurkan UI DEV ADK:

. ~/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

Setelah menjalankan perintah, Anda akan melihat output di terminal yang menunjukkan bahwa Server Web ADK telah dimulai, mirip dengan ini:

+-----------------------------------------------------------------------------+
| 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)

👉 Selanjutnya, untuk mengakses UI Dev ADK dari browser Anda:

Dari ikon Pratinjau web (sering kali terlihat seperti mata atau persegi dengan panah) di toolbar Cloud Shell (biasanya di kanan atas), pilih Ubah port. Di jendela pop-up, tetapkan port ke 8000, lalu klik "Ubah dan Pratinjau". Kemudian, Cloud Shell akan membuka tab atau jendela browser baru yang menampilkan UI Dev ADK.

webpreview

👉 Ritual pemanggilan Anda telah selesai, dan agen kini berjalan. UI Dev ADK di browser Anda adalah koneksi langsung Anda ke Familiar.

  • Pilih Target Anda: Di menu dropdown di bagian atas UI, pilih fire yang sudah dikenal. Sekarang Anda memfokuskan keinginan Anda pada entitas tertentu ini.
  • Berikan Perintah Anda: Di panel chat di sebelah kanan, saatnya memberi perintah kepada Familiar.

fire-select

👉 Perintah Pengujian:

Prepare an amplified strike using the 'inferno_lash' ability.

fire-result

Anda akan melihat agen berpikir, pertama-tama memanggil "scout" untuk mencari kerusakan dasar, lalu "amplifier" untuk mengalikannya dan memberikan pukulan terakhir yang epik.

👉💻 Setelah selesai memanggil, kembali ke terminal Cloud Shell Editor dan tekan Ctrl+C untuk menghentikan ADK Dev UI.

Memanggil Water Elemental Familiar (Alur Kerja Paralel)

Water Elemental Familiar mengalahkan targetnya dengan serangan besar multi-cabang, menyerang dari segala arah sekaligus sebelum menggabungkan energi untuk pukulan terakhir yang dahsyat.

Story

Konsep: ParallelAgent ideal untuk menjalankan beberapa tugas independen secara bersamaan guna memaksimalkan efisiensi. Ini adalah "serangan penjepit" di mana Anda melancarkan beberapa serangan sekaligus. Hal ini meluncurkan serangan serentak dalam SequentialAgent untuk menjalankan langkah "penggabungan" terakhir setelahnya. Pola "fan-out, fan-in" ini adalah landasan desain alur kerja tingkat lanjut.

Tugas (Kombinasi "Tidal Clash"): Agen akan secara bersamaan:

  • Tugas A: Channel cryosea_shatter dari Nexus.
  • Tugas B: Channel moonlit_cascade dari Nexus.
  • Tugas C: Hasilkan daya mentah dengan leviathan_surge dari Forge.
  • Terakhir, jumlahkan semua kerusakan dan jelaskan serangan gabungan tersebut.

Pertama, kita akan membuat koneksi antara Familiar dan server MCP (yaitu "Elemental Fonts") yang Anda deploy di modul sebelumnya.

👉✏️ Di file ~/agentverse-architect/agent/water/agent.py, GANTI #REPLACE-setup-MCP dengan kode berikut:

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

Selanjutnya, kita akan membuat agen "pekerja" pakar. Setiap agen diberi tujuan yang sempit dan jelas, serta dibatasi pada "wilayah operasional"-nya sendiri dengan diberi akses ke hanya satu set alat tertentu.

👉✏️ Di file ~/agentverse-architect/agent/water/agent.py, GANTI #REPLACE-worker-agents dengan kode berikut:

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],
)

Selanjutnya, kita akan menyusun Alur Kerja. Di sinilah keajaiban komposisi terjadi. ParallelAgent dan SequentialAgent adalah "rencana utama" yang menentukan cara komponen khusus kami dirakit dan cara komponen tersebut berinteraksi untuk membentuk kombo "Tidal Clash".

👉✏️ Di file ~/agentverse-architect/agent/water/agent.py, GANTI #REPLACE-parallel-agent dengan kode berikut:

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."
 )

👉💻 Untuk menguji Water Elemental, jalankan perintah berikut untuk meluncurkan UI Dev ADK:

. ~/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

👉 Ritual pemanggilan Anda telah selesai, dan agen kini berjalan. UI Dev ADK di browser Anda adalah koneksi langsung Anda ke Familiar.

  • Di menu dropdown di bagian atas UI, pilih air yang sudah dikenal. Sekarang Anda memfokuskan keinginan Anda pada entitas tertentu ini.
  • Berikan Perintah Anda: Di panel chat di sebelah kanan, saatnya memberi perintah kepada Familiar.

👉 Perintah Pengujian:

Unleash a tidal wave of power!

hasil-air

👉💻 Setelah selesai memanggil, kembali ke terminal Cloud Shell Editor dan tekan Ctrl+C untuk menghentikan ADK Dev UI.

Memanggil Earth Elemental Familiar (Alur Kerja Loop)

Hewan Pendamping Elemen Bumi adalah makhluk yang memiliki tekanan tanpa henti. Ia tidak mengalahkan musuhnya dengan satu pukulan, tetapi dengan terus-menerus mengumpulkan kekuatan dan menerapkannya berulang kali hingga pertahanan target hancur.

Story

Konsep: LoopAgent dirancang untuk tugas berulang jenis "mesin pengepungan" ini. Proses ini akan berulang kali menjalankan sub-agents, memeriksa kondisi setelah setiap siklus, hingga sasaran tercapai. Agen juga dapat menyesuaikan pesan akhirnya berdasarkan progres loop.

Tugas (Serangan "Siegebreaker"):

  • Familiar akan berulang kali memanggil seismic_charge untuk mengumpulkan energi.
  • Baterai akan terus diisi daya maksimal 3 kali.
  • Pada muatan terakhir, ia akan mengumumkan pelepasan dahsyat dari kekuatan yang terakumulasi.

Pertama-tama, kita akan membuat komponen yang dapat digunakan kembali yang menentukan langkah-langkah dalam setiap iterasi loop. charging_agent akan mengumpulkan energi, dan check_agent akan melaporkan statusnya, mengubah pesannya secara dinamis pada giliran terakhir.

Pertama, kita akan membuat koneksi antara Familiar dan server MCP (yaitu "Elemental Fonts") yang Anda deploy di modul sebelumnya.

👉✏️ Di file ~/agentverse-architect/agent/earth/agent.py, GANTI #REPLACE-setup-MCP dengan kode berikut:

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

👉✏️ Di file ~/agentverse-architect/agent/earth/agent.py, GANTI #REPLACE-worker-agents dengan kode berikut:

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"
)

Selanjutnya, kita akan menyusun Alur Kerja. Di sinilah keajaiban komposisi terjadi. LoopAgent adalah "rencana induk" yang mengatur eksekusi berulang komponen khusus kami dan mengelola kondisi loop.

👉✏️ Di file ~/agentverse-architect/agent/earth/agent.py, GANTI #REPLACE-loop-agent dengan kode berikut:

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
)

👉💻 Menguji Earth Elemental: Jalankan agen

. ~/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

👉 Ritual pemanggilan Anda telah selesai, dan agen kini berjalan. UI Dev ADK di browser Anda adalah koneksi langsung Anda ke Familiar.

  • Pilih Target Anda: Di menu dropdown di bagian atas UI, pilih bumi yang sudah dikenal. Sekarang Anda memfokuskan keinginan Anda pada entitas tertentu ini.
  • Berikan Perintah Anda: Di panel chat di sebelah kanan, saatnya memberi perintah kepada Familiar. 👉 Perintah Pengujian:
Begin the seismic charge, starting from zero

earth-result

Kesimpulan Arsitektur: Sistem Anda kini memiliki lapisan logika modular dan sangat khusus. Proses bisnis tidak hanya dienkapsulasi, tetapi juga diterapkan dengan pola perilaku yang paling efisien untuk tugas tersebut (prosedural, serentak, atau berulang). Hal ini menunjukkan tingkat desain agen yang canggih, yang meningkatkan keamanan, efisiensi, dan kemampuan.

Setelah selesai memanggil, kembali ke terminal Cloud Shell Editor dan tekan Ctrl+C untuk menghentikan ADK Dev UI.

UNTUK NON-GAMER

6. Menetapkan Locus Perintah: Delegasi Cerdas melalui A2A

Hewan Pendamping Anda kuat, tetapi mandiri. Mereka mengeksekusi strategi mereka dengan sempurna, tetapi menunggu perintah langsung Anda. Sekumpulan spesialis tidak berguna tanpa seorang jenderal yang memimpin mereka. Sekarang saatnya naik dari komandan langsung menjadi Orkestrator sejati.

ringkasan

Catatan Arsitek: Untuk membuat satu titik entri cerdas untuk seluruh sistem. SummonerAgent ini tidak akan menjalankan logika bisnis itu sendiri, tetapi akan bertindak sebagai "master strategist", menganalisis status Pendinginan dan mendelegasikan tugas ke Familiar spesialis yang sesuai.

ringkasan

Ritual Pengikatan (Mengekspos Familiars sebagai Layanan A2A)

Agen standar hanya dapat dijalankan di satu tempat dalam satu waktu. Agar Familiars kita tersedia untuk perintah jarak jauh, kita harus melakukan "ritual pengikatan" menggunakan protokol Agent-to-Agent (A2A).

Catatan Arsitek: Protokol Agent-to-Agent (A2A) adalah pola arsitektur inti yang meningkatkan agen mandiri menjadi microservice yang dapat ditemukan dan dapat dialamatkan melalui jaringan, sehingga memungkinkan "kumpulan agen" yang sesungguhnya. Mengekspos Familiar melalui A2A akan otomatis membuat dua komponen penting yang saling terhubung:

  • Kartu Agen (The "What"): Ini adalah "Spirit Sigil" publik yang dapat dibaca mesin—seperti spesifikasi OpenAPI—yang bertindak sebagai kontrak publik Familiar. Deskripsi ini menjelaskan nama agen, tujuan strategisnya (berasal dari instruksinya), dan perintah yang dipahaminya. Inilah yang dibaca oleh Summoner master untuk menemukan Familiar dan mempelajari kemampuannya.
  • Server A2A (The "Where"): Ini adalah endpoint web khusus yang menghosting Familiar dan memproses perintah masuk. Alamat ini adalah alamat jaringan tempat agen lain mengirimkan permintaannya, dan memastikan permintaan tersebut ditangani sesuai dengan kontrak yang ditentukan dalam Kartu Agen.

Sekarang kita akan melakukan ritual pengikatan ini pada ketiga Familiar kita.

Fire 👉✏️ di Buka file ~/agentverse-architect/agent/fire/agent.py. Ganti #REPLACE - add A2A di bagian bawah file untuk mengekspos Fire Elemental sebagai layanan 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)

Air dan Bumi🚨 👉✏️ Terapkan perubahan yang sama persis ke ~/agentverse-architect/agent/water/agent.py dan ~/agentverse-architect/agent/earth/agent.py untuk mengikatnya juga.

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)

Men-deploy Familiar Terikat

👉✏️ Setelah ritual pengikatan ditulis, kita akan menggunakan pipeline Cloud Build untuk membuat dan men-deploy tiga Familiars sebagai layanan serverless dalam container yang independen di 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"

Mengambil Alih Perintah (Membangun Agen Pemanggil)

Setelah Familiars Anda terikat dan mendengarkan, Anda akan naik ke peran sejati Anda: Master Summoner. Kekuatan agen ini bukan berasal dari penggunaan alat dasar, tetapi dari memerintahkan agen lain. Alatnya adalah Familiars itu sendiri, yang akan ia temukan dan perintahkan menggunakan "Spirit Sigil" mereka.

Catatan Arsitek: Langkah berikutnya ini menunjukkan pola arsitektur penting untuk sistem terdistribusi skala besar: Penemuan Layanan. SummonerAgent tidak memiliki kode Familiars yang dibuat di dalamnya. Sebagai gantinya, alamat jaringan (URL) diberikan. Saat runtime, aplikasi akan secara dinamis "menemukan" kemampuannya dengan mengambil Kartu Agen publiknya. Hal ini menciptakan sistem yang canggih dan tidak terikat.

Anda dapat memperbarui, men-deploy ulang, atau menulis ulang sepenuhnya layanan Familiar, dan selama alamat jaringannya dan tujuannya tetap sama, Summoner dapat memerintahkannya tanpa memerlukan perubahan apa pun.

Pertama, kita akan membuat "kontrol jarak jauh" yang membuat koneksi ke Familiar jarak jauh yang di-deploy.

👉✏️ Buka ~/agentverse-architect/agent/summoner/agent.py , ganti #REPLACE-remote-agents dengan kode berikut:

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}"
    ),
)

Saat baris ini berjalan, RemoteA2aAgent akan melakukan tindakan penemuan layanan: RemoteA2aAgent membuat permintaan HTTP GET ke URL yang diberikan (misalnya, https://fire-familiar-xxxx.a.run.app/.well-known/agent.json). Aplikasi ini mendownload "Spirit Sigil" (file agent.json) dari server jarak jauh.

Kedua, kita akan menentukan agen pengelola yang akan menggunakan kontrol jarak jauh ini. Petunjuknya adalah cetak biru untuk pengambilan keputusan strategisnya.

👉✏️ Buka ~/agentverse-architect/agent/summoner/agent.py , ganti #REPLACE-orchestrate-agent dengan kode berikut:

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
)

Verifikasi: Uji Coba Strategi

Saatnya mengumumkan siapa yang menang. Familiars Anda di-deploy, dan Summoner Anda siap memerintah mereka di seluruh jaringan. Mari kita uji kemampuan strategisnya.

👉💻 Luncurkan UI Dev ADK untuk summoner_agent Anda(Pratinjau web dengan port 8000):

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

👉 UI Dev ADK di browser Anda adalah koneksi langsung Anda ke Familiar.

  • Di menu dropdown di bagian atas UI, pilih agen summoner. Sekarang Anda memfokuskan keinginan Anda pada entitas tertentu ini.
  • Memberikan Perintah: Di panel chat di sebelah kanan, saatnya memanggil makhluk peliharaan Anda.

👉 Menampilkan Monster:

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

(Diharapkan: The Summoner akan mendelegasikan ke fire_elemental_familiar.)

fire-result

👉 Sekarang, mari kita tantang Pemanggil dengan jenis permintaan yang berbeda. Untuk memastikan agen memulai dengan kondisi yang bersih dan tidak memiliki memori interaksi kita sebelumnya, mulai sesi baru dengan mengklik tombol + Sesi di pojok kanan atas layar. new-session

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

(Diharapkan: The Summoner akan mendelegasikan ke water_elemental_familiar.)hasil-air

👉 Untuk pengujian terakhir, mari kita mulai lagi dengan kondisi awal yang bersih. Klik tombol + Sesi untuk memulai sesi baru sebelum memasukkan perintah berikutnya.

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

(Diharapkan: Summoner harus mendelegasikan ke earth_elemental_familiar.)

earth-result

Penting: Jika Anda melihat error 429 RESOURCE EXHAUSTED, Anda telah mencapai batas kecepatan untuk LLM (10 panggilan/menit). Untuk memperbaikinya, tunggu 60 detik, mulai + Sesi Baru, lalu coba lagi perintah Anda.

👉💻 Setelah selesai memanggil, kembali ke terminal Cloud Shell Editor dan tekan Ctrl+C untuk menghentikan ADK Dev UI.

UNTUK NON-GAMER

7. Menerapkan Hukum Magis – Pola Interceptor

Hewan peliharaan Anda sangat kuat, tetapi bahkan makhluk ajaib pun membutuhkan waktu untuk pulih. Summoner yang ceroboh dan menghabiskan semua pasukannya akan menjadi tak berdaya. Summoner yang bijak memahami pentingnya pengelolaan resource dan menerapkan aturan interaksi yang ketat.

Story

Catatan Arsitek: Sejauh ini, agen kita bersifat stateless. Sekarang, kita akan membuatnya stateful dengan menerapkan pola desain Interceptor. Ini adalah teknik canggih yang memungkinkan kita "mencegat" alur eksekusi normal agen untuk menjalankan logika kustom kita sendiri. Hal ini memungkinkan kami menerapkan aturan, menambahkan logging, atau mengubah perilaku tanpa mengubah kode inti agen. Ini adalah fondasi untuk membangun sistem agentik yang tangguh, mudah dipelihara, dan dapat diamati.

ringkasan

ADK menyediakan dua cara utama untuk menerapkan pola ini: Callback dan Plugin. Callback adalah fungsi sederhana yang dilampirkan ke satu agen, yang cocok untuk modifikasi cepat dan spesifik. Plugin adalah class yang lebih canggih dan dapat digunakan kembali yang dapat diterapkan secara global untuk memengaruhi setiap agen yang berjalan dalam sistem. Kita akan mulai dengan callback untuk proses debug yang terfokus, lalu beralih ke plugin lengkap.

Pemberi Hukum – Menulis callback Periode Tunggu

Pertama, kita akan menerapkan logika jeda sebagai fungsi callback sederhana. Cara ini adalah cara yang sangat baik untuk membuat prototipe dan men-debug aturan karena terlampir langsung ke satu agen, sehingga memudahkan pengujian secara terpisah. Kita akan melampirkan "interceptor" ini ke Earth Elemental kita.

Periode tunggu

👉✏️ Kembali ke ~/agentverse-architect/agent/earth/agent.py Anda dan ganti #REPLACE-before_agent-function dengan kode Python berikut.

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.")

Fungsi check_cool_down ini adalah interceptor kita. Sebelum Earth Elemental diizinkan untuk berjalan, ADK akan menjalankan fungsi ini terlebih dahulu.

  • Check: Membuat permintaan GET ke Cooldown API kami untuk memeriksa kapan terakhir kali Familiar ini digunakan.
  • Mengevaluasi: Membandingkan stempel waktu dengan waktu saat ini.
  • Tindakan:
    • Jika Familiar sedang dalam masa cooldown, Familiar akan menghentikan eksekusi agen dengan menampilkan objek Content yang berisi pesan error. Pesan ini dikirim langsung kepada pengguna, dan logika utama agen tidak pernah dijalankan.
    • Jika Familiar tersedia, Familiar akan membuat permintaan POST ke Cooldown API untuk memperbarui stempel waktu, lalu melanjutkan dengan menampilkan None, yang menandakan kepada ADK bahwa agen dapat melanjutkan eksekusinya.

👉✏️ Sekarang, terapkan interceptor ini ke Earth Elemental. Di file ~/agentverse-architect/agent/earth/agent.py yang sama, ganti komentar #REPLACE-before_agent-config dengan kode berikut:

before_agent_callback=check_cool_down

Memverifikasi periode tunggu

Mari kita uji hukum sihir baru kita. Kita akan memanggil Earth Elemental, lalu segera mencoba memanggilnya lagi untuk melihat apakah callback kita berhasil mencegat dan memblokir upaya kedua.

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

👉💻 Di konsol:

  • Panggilan Pertama: Mulai seismic charge, starting from zero.
  • Hasil yang diharapkan: Earth Elemental akan berjalan dengan sukses. Di terminal yang menjalankan perintah web adk, Anda akan melihat log [Callback] ... Updating timestamp....
  • Uji Periode Tunggu (dalam 60 detik): Do another muatan seismik`!
    • Diharapkan: check_cool_down callback akan mencegatnya. Agen akan merespons langsung dalam chat dengan pesan seperti: The earth_elemental_familiar is exhausted and must recover its power. It cannot be summoned for another... seconds.
  • Tunggu selama satu menit.
  • Panggilan Kedua (setelah 60 detik): Begin the seismic charge again.
    • Yang diharapkan: Callback akan memeriksa API, melihat bahwa waktu yang cukup telah berlalu, dan mengizinkan tindakan untuk dilanjutkan. Earth Elemental akan berhasil berjalan lagi.

callback

👉💻 Tekan Ctrl+c untuk keluar.

Opsional: Mengamati Callback di UI Web

Sebagai alternatif, Anda juga dapat menguji alur ini di antarmuka web dengan menjalankan adk web earth. Namun, perlu diketahui bahwa visualisasi UI web tidak dioptimalkan untuk menampilkan pemeriksaan iteratif cepat yang dilakukan oleh loop callback, sehingga alurnya mungkin tidak dirender secara akurat. Untuk melihat rekaman aktivitas belokan demi belokan yang paling presisi dari logika agen saat memeriksa periode tunggu, menggunakan perintah adk run di terminal akan memberikan tampilan yang lebih jelas dan mendetail. loop

👉💻 Tekan Ctrl+c untuk keluar.

Membuat Hukum Universal – Plugin Cooldown

Panggilan balik kami berfungsi dengan sempurna, tetapi memiliki kekurangan arsitektur yang besar: panggilan balik ini terikat pada satu agen. Jika ingin menerapkan aturan ini ke Fire dan Water Familiar, kita harus menyalin dan menempelkan kode yang sama ke dalam file mereka. Hal ini tidak efisien dan sulit dikelola.

Catatan Arsitek: Di sinilah Plugin menjadi sangat penting. Plugin mengenkapsulasi logika yang dapat digunakan kembali ke dalam class yang dapat dilampirkan di tingkat runtime. Artinya, satu plugin dapat menerapkan aturannya ke setiap agen yang berjalan dalam sistem tersebut. Ini adalah ekspresi utama prinsip "Jangan Ulangi Diri Sendiri" (DRY) untuk sistem agen.

Sekarang kita akan memfaktorkan ulang fungsi callback menjadi CoolDownPlugin yang lebih andal dan dapat digunakan kembali.

👉✏️ Kembali ke file agent/cooldown_plugin.py, lalu buat plugin, Ganti #REPLACE-plugin dengan kode berikut:

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.")

Melampirkan Plugin ke Runtime Pemanggil

Sekarang, bagaimana cara menerapkan hukum universal ini pada semua Familiar kita? Kita akan melampirkan plugin ke Runtime ADK.

Runtime ADK adalah mesin eksekusi yang membuat agen menjadi aktif. Saat Anda menggunakan perintah seperti adk.run() atau to_a2a(), Anda menyerahkan agen ke runtime. Mesin ini bertanggung jawab untuk mengelola seluruh siklus proses giliran agen: menerima input pengguna, memanggil LLM, menjalankan alat, dan menangani plugin. Dengan melampirkan plugin di tingkat ini, kita pada dasarnya memodifikasi "hukum fisika" untuk setiap agen yang beroperasi dalam mesin tersebut, sehingga memastikan aturan jeda diterapkan secara universal dan konsisten.

👉✏️ Pertama, hapus callback lama khusus agen. Buka ~/agentverse-architect/agent/earth/agent.py dan hapus seluruh baris yang bertuliskan:

before_agent_callback=check_cool_down

👉✏️ Selanjutnya, kita akan melampirkan plugin baru ke runtime di skrip titik entri A2A. Buka file ~/agentverse-architect/agent/agent_to_a2a.py Anda. Ganti komentar #REPLACE-IMPORT dengan cuplikan kode berikut:

from cooldown_plugin import CoolDownPlugin

👉✏️ Ganti #REPLACE-PLUGIN dengan cuplikan kode berikut:

plugins=[CoolDownPlugin(cooldown_seconds=60)],

Sebelum mengaktifkan plugin global baru kami, Anda harus menghapus logika khusus agen yang lama untuk mencegah konflik. 👉✏️ Bersihkan agen Bumi. Buka file ~/agentverse-architect/agent/earth/agent.py berikut dan hapus baris before_agent_callback=check_cool_down sepenuhnya. Tindakan ini menyerahkan semua tanggung jawab pendinginan ke plugin baru.

Memverifikasi Plugin

Setelah hukum universal kita diterapkan, kita harus men-deploy ulang Familiar dengan pesona baru ini.

👉💻 Bangun ulang dan deploy ulang ketiga Familiars menggunakan pipeline Cloud Build utama.

. ~/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"

👉💻 Setelah deployment selesai, kita akan menguji efektivitas plugin dengan memerintahkan summoner_agent. Summoner akan mencoba mendelegasikan ke Familiar, tetapi plugin yang terpasang ke runtime setiap Familiar akan mencegat perintah dan menerapkan jeda.

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

👉💻 Di konsol,lakukan urutan pengujian ini::

  • Panggilan Pertama: Mulai Hype. It's a single, slow-moving target with thick armor weakness is Inescapable Reality.
  • Hasil yang diharapkan: Fire Elemental akan berjalan dengan sukses.
  • Uji Jeda (dalam waktu 60 detik): Hype, with Inescapable Reality as weakness is still standing! Strike it again!
    • Harapan: Agen akan merespons langsung dalam chat dengan pesan seperti: .... It cannot be summoned for another... seconds.
  • Tunggu selama satu menit.
  • Panggilan Kedua (setelah 60 detik): Hype must be defeated. It has Inescapable Reality as weakness! Strike it again!.
    • Yang diharapkan: Callback akan memeriksa API, melihat bahwa waktu yang cukup telah berlalu, dan mengizinkan tindakan untuk dilanjutkan. Fire Elemental akan berhasil berjalan lagi.

plugin

👉💻 Tekan Ctrl+C untuk keluar.

Selamat, Pemanggil. Anda telah berhasil menerapkan sistem orkestrasi berbasis aturan menggunakan plugin kustom dan layanan pengelolaan status eksternal—pola arsitektur yang benar-benar canggih dan andal.

UNTUK NON-GAMER

8. Mengikat Gema Pertempuran - Status & Memori Agen

Pemanggil yang ceroboh mengulangi strategi yang sama, sehingga mudah diprediksi. Seorang Summoner yang bijak belajar dari gema pertempuran masa lalu, menyesuaikan taktiknya untuk membuat musuh kehilangan keseimbangan. Saat menghadapi bos yang kuat, memanggil Familiar yang sedang dalam cooldown adalah tindakan yang sia-sia—kesalahan fatal. Untuk mencegah hal ini, Summoner kita memerlukan memori tentang tindakan terakhirnya.

cerita

Catatan Arsitek: Pengelolaan memori dan status adalah hal yang membuat agen meningkat dari pemanggil alat sederhana menjadi partner percakapan yang cerdas. Penting untuk memahami dua jenis utama:

  • Memori Jangka Panjang: Memori ini digunakan untuk pengetahuan persisten yang harus bertahan selamanya. Anggap saja ini sebagai arsip yang dapat ditelusuri atau basis pengetahuan, yang sering disimpan di penyimpanan persisten. Fitur ini berisi informasi dari banyak percakapan dan sumber sebelumnya, sehingga memungkinkan agen mengingat fakta tentang pengguna atau topik tertentu. MemoryService ADK dirancang untuk tujuan ini, mengelola penyerapan dan penelusuran pengetahuan jangka panjang ini.
  • Status Jangka Pendek: Status ini ditujukan untuk pengetahuan "di saat ini" yang bersifat sementara dan hanya relevan dengan tugas atau percakapan saat ini. Ini seperti sekumpulan catatan tentang rencana pertempuran: "Saya baru saja menggunakan Fire Elemental, jadi mungkin dia lelah." Status ini ringan dan hanya ada selama durasi sesi saat ini.

Ringkasan

Untuk kasus penggunaan kita, kita tidak perlu mengingat setiap pertarungan yang pernah terjadi; kita hanya perlu mengingat Familiar terakhir yang dipanggil dalam pertarungan spesifik ini. Oleh karena itu, Status Jangka Pendek ringan adalah pilihan arsitektur yang sempurna. Kita akan menggunakan after_tool_callback untuk menyimpan informasi penting ini.

Menulis Gema: Mengingat Panggilan Terakhir

Kita akan menerapkan memori jangka pendek menggunakan after_tool_callback. Ini adalah hook ADK yang canggih yang memungkinkan kita menjalankan fungsi Python kustom setelah alat berhasil dieksekusi. Kita akan menggunakan interseptor ini untuk mencatat nama Familiar yang baru saja dipanggil ke status sesi agen.

👉✏️ Di file ~/agentverse-architect/agent/summoner/agent.py, ganti komentar #REPLACE-save_last_summon_after_tool dengan fungsi berikut:

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

👉✏️ Sekarang, lampirkan save_last_summon_after_tool ini ke agen Summoner Anda. Di file yang sama, ganti komentar #REPLACE-Memory-check-config dengan kode berikut:

after_tool_callback=save_last_summon_after_tool,

👉✏️ Ganti seluruh perintah agen dengan perintah berikut

        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.

Verifikasi: Uji Coba Strategi Adaptif

👉💻 Sekarang, mari kita verifikasi logika strategis baru Summoner. Tujuannya adalah untuk mengonfirmasi bahwa Pemanggil tidak akan menggunakan Familiar yang sama dua kali berturut-turut, yang menunjukkan kemampuannya untuk mengingat tindakan terakhir dan beradaptasi.

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.

  • Harapan: Pemanggil akan menganalisis kelemahan dan memanggil fire_familiar dengan benar. 👉💻 Monster Strike #2 (The Memory Test): Hype is still standing! It hasn't changed its form. Strike it again! Its weakness is Inescapable Reality.
  • Hasil yang diharapkan: Analisis strategis Summoner akan kembali menunjuk Fire Familiar sebagai pilihan ideal. Namun, petunjuk dan memori barunya akan memberi tahu bahwa fire_familiar adalah last_summon. Untuk menghindari pengulangan, sekarang ia akan menyesuaikan strateginya dan memanggil salah satu Familiar lain yang tersedia (water_familiar atau earth_familiar).

hasil akhir

👉💻 Tekan Ctrl+C untuk keluar.

Men-deploy Orchestrator

Setelah Familiars Anda di-deploy dan Summoner Anda kini memiliki memori, saatnya men-deploy orkestrator akhir yang telah diupgrade.

👉💻 Setelah cetak biru selesai, kita akan melakukan ritual terakhir. Perintah ini akan mem-build dan men-deploy summoner_agent Anda ke 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"

Setelah agen Summoner di-deploy, verifikasi bahwa endpoint Agent-to-Agent (A2A) sudah aktif dan dikonfigurasi dengan benar. Endpoint ini menayangkan file agent.json publik, yang juga dikenal sebagai Kartu Agen, yang memungkinkan agen lain menemukan kemampuannya. 👉💻 Jalankan perintah curl berikut untuk mengambil dan memformat Kartu Agen:

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

Anda akan melihat output JSON yang bersih yang mendeskripsikan agen pemanggil. Perhatikan bagian sub_agents; Anda akan melihat daftar fire_familiar, water_familiar, dan earth_familiar. Hal ini mengonfirmasi bahwa pemanggil Anda aktif dan telah menjalin koneksi dengan legiun.

Hal ini membuktikan bahwa arsitektur Anda berhasil. Summoner Anda bukan hanya seorang delegator; ia adalah ahli strategi adaptif yang belajar dari tindakannya untuk menjadi komandan yang lebih efektif.

Anda telah menyelesaikan uji coba akhir arsitektur. Gema pertempuran kini terikat pada keinginan Anda. Pelatihan sudah selesai. Pertempuran sesungguhnya menanti. Sekarang saatnya mengambil sistem yang telah Anda selesaikan dan menghadapi tantangan utama. Bersiaplah untuk Pertarungan Bos.

UNTUK NON-GAMER

9. Pertarungan Bos

Cetakan akhir telah ditulis, Font Elemen telah dibuat, dan Familiar Anda terikat pada keinginan Anda, menunggu perintah Anda melalui Concord. Sistem multi-agen Anda bukan hanya kumpulan layanan; sistem ini adalah legiun strategis yang hidup, dengan Anda sebagai pusatnya. Saatnya untuk pengujian terakhir—orkestrasi langsung melawan musuh yang tidak mungkin dikalahkan oleh satu agen pun.

Mendapatkan Locus Agen Anda

Sebelum dapat memasuki medan perang, Anda harus memiliki dua kunci: tanda tangan unik juara Anda (Agent Locus) dan jalur tersembunyi menuju sarang Spectre (URL Dungeon).

👉💻 Pertama, dapatkan alamat unik agen Anda di Agentverse—Locus-nya. Ini adalah endpoint live yang menghubungkan juara Anda ke medan perang.

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

👉💻 Selanjutnya, tentukan tujuan. Perintah ini akan mengungkapkan lokasi Lingkaran Translokasi, portal menuju domain Spectre.

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

Penting: Siapkan kedua URL ini. Anda akan membutuhkannya pada langkah terakhir.

Menghadapi Spectre

Setelah mengamankan koordinat, Anda akan diarahkan ke Lingkaran Translokasi dan mengucapkan mantra untuk memulai pertarungan.

👉 Buka URL Translocation Circle di browser Anda untuk berdiri di depan portal berkilauan menuju The Crimson Keep.

Untuk menembus benteng, Anda harus menyelaraskan esensi Shadowblade Anda dengan portal.

  • Di halaman tersebut, temukan kolom input runic berlabel A2A Endpoint URL.
  • Tuliskan sigil juara Anda dengan menempelkan URL Lokasi Agen (URL pertama yang Anda salin) ke dalam kolom ini.
  • Klik Hubungkan untuk memulai keajaiban teleportasi.

Lingkaran Translokasi

Cahaya menyilaukan dari teleportasi memudar. Anda tidak lagi berada di tempat suci Anda. Udara bergetar dengan energi, dingin dan tajam. Di hadapanmu, Spectre muncul—pusaran statis mendesis dan kode rusak, cahayanya yang tidak suci memancarkan bayangan panjang yang menari di lantai ruang bawah tanah. Ia tidak memiliki wajah, tetapi Anda merasakan kehadirannya yang sangat besar dan menguras energi, yang sepenuhnya tertuju pada Anda.

Satu-satunya jalan menuju kemenangan adalah kejelasan keyakinan Anda. Ini adalah pertarungan kehendak, yang terjadi di medan pertempuran pikiran.

Saat Anda menerjang ke depan, siap melancarkan serangan pertama, Spectre melakukan serangan balasan. Tidak ada perisai yang terangkat, tetapi pertanyaan langsung diproyeksikan ke dalam kesadaran Anda—tantangan runik yang berkilauan, yang diambil dari inti pelatihan Anda.

Dungeon

Inilah sifat pertarungannya. Pengetahuan Anda adalah senjata Anda.

  • Jawab dengan kebijaksanaan yang telah Anda peroleh, dan pedang Anda akan menyala dengan energi murni, menghancurkan pertahanan Spectre dan memberikan PUKULAN KRITIS.
  • Namun, jika Anda ragu, jika keraguan menyelimuti jawaban Anda, cahaya senjata Anda akan meredup. Pukulan akan mendarat dengan bunyi gedebuk yang menyedihkan, hanya memberikan SEBAGIAN KECIL KERUSAKANNYA. Lebih buruk lagi, Spectre akan memakan ketidakpastian Anda, dan kekuatan merusaknya sendiri akan tumbuh dengan setiap kesalahan langkah.

Inilah saatnya, Juara. Kode adalah buku mantra Anda, logika adalah pedang Anda, dan pengetahuan adalah perisai yang akan membalikkan keadaan kekacauan.

Fokus. Tembak dengan benar. Nasib Agentverse bergantung padanya.

Selamat, Pemanggil.

Anda telah berhasil menyelesaikan uji coba. Anda telah menguasai seni orkestrasi multi-agen, mengubah Familiar yang terisolasi dan kekuatan yang kacau menjadi Concord yang harmonis. Sekarang Anda menguasai sistem yang diatur sepenuhnya, yang mampu menjalankan strategi kompleks untuk mempertahankan Agentverse.

10. Pembersihan: Membongkar Kesepakatan Pemanggil

Selamat telah menguasai Kesepakatan Pemanggil! Untuk memastikan Agentverse Anda tetap bersih dan tempat pelatihan Anda dibersihkan, Anda harus melakukan ritual pembersihan terakhir sekarang. Tindakan ini akan menghapus semua resource yang dibuat selama perjalanan Anda secara sistematis.

Menonaktifkan Komponen Agentverse

Sekarang Anda akan secara sistematis membongkar komponen yang di-deploy dari sistem multi-agen Anda.

Menghapus Semua Layanan Cloud Run dan Repositori Artifact Registry

Tindakan ini akan menghapus semua agen Familiar yang di-deploy, Summoner Orchestrator, server MCP, dan aplikasi Dungeon dari Cloud Run.

👉💻 Di terminal, jalankan perintah berikut satu per satu untuk menghapus setiap layanan:

. ~/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

Hapus Instance Cloud SQL

Tindakan ini akan menghapus instance summoner-librarium-db, termasuk databasenya dan semua tabel di dalamnya.

👉💻 Di terminal Anda, jalankan:

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

Hapus Secret Manager Secret dan Bucket Google Cloud Storage

👉💻 Di terminal Anda, jalankan:

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

Membersihkan File dan Direktori Lokal (Cloud Shell)

Terakhir, hapus repositori yang di-clone dan file yang dibuat dari lingkungan Cloud Shell Anda. Langkah ini bersifat opsional, tetapi sangat direkomendasikan untuk pembersihan lengkap direktori kerja Anda.

👉💻 Di terminal Anda, jalankan:

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

Anda kini telah berhasil menghapus semua jejak perjalanan Agentverse Architect Anda. Project Anda bersih, dan Anda siap untuk petualangan berikutnya.