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

1. Tawaran

Era pengembangan yang terkotak-kotak telah berakhir. Gelombang evolusi teknologi berikutnya bukanlah tentang kejeniusan yang menyendiri, tetapi tentang penguasaan secara kolaboratif. Membangun agen tunggal yang pintar adalah eksperimen yang menarik. Membangun ekosistem agen yang kuat, aman, dan cerdas—Agentverse sejati—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 realitas operasional berskala penuh. Dalam empat lab yang saling terhubung ini, Anda akan mempelajari cara keterampilan khusus developer, arsitek, engineer data, dan SRE harus bertemu untuk membuat, mengelola, dan menskalakan Agentverse yang efektif.

Tidak ada satu pilar pun yang dapat mendukung Agentverse saja. Desain megah 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 agentik, era yang penuh dengan janji besar, di mana agen cerdas dan otonom bekerja dalam harmoni yang sempurna 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. Static bukanlah virus atau bug; ia adalah perwujudan kekacauan yang memangsa tindakan penciptaan.

Ia memperbesar rasa frustrasi lama ke dalam bentuk yang mengerikan, dan melahirkan Tujuh Hantu Pembangunan. Bila tidak diatasi, The Static dan Spectre-nya akan menghambat kemajuan, mengubah janji Agentverse menjadi tanah tandus penuh utang teknis dan proyek terbengkalai.

Hari ini, kami menyerukan kepada para juara untuk melawan gelombang kekacauan. Kita butuh pahlawan yang bersedia menguasai keahliannya dan bekerja sama untuk melindungi Agentverse. Waktunya telah tiba untuk memilih jalanmu.

Pilih Kelas Anda

Empat jalur berbeda terbentang di hadapan Anda, yang 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 garis depan. Anda adalah pengrajin yang membuat bilah pisau, membuat peralatan, dan menghadapi musuh dalam detail kode yang rumit. Jalan yang Anda tempuh adalah jalan menuju presisi, keterampilan, dan kreasi praktis.
  • The Summoner (Arsitek): Ahli strategi dan orkestrator 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 teguh. Anda membangun benteng, mengelola jalur pasokan listrik, dan memastikan seluruh sistem dapat menahan serangan The Static yang tak terelakkan. Kekuatan Anda adalah fondasi yang membangun kemenangan tim Anda.

Misi Anda

Pelatihan Anda akan dimulai sebagai latihan mandiri. Anda akan berjalan di jalur yang Anda pilih, mempelajari keterampilan unik yang dibutuhkan untuk menguasai peran Anda. Di akhir ujian Anda, Anda akan menghadapi Spectre yang lahir dari The Static—bos mini yang memangsa tantangan spesifik dalam pesawat Anda.

Hanya dengan menguasai peran individu Anda, Anda dapat mempersiapkan diri untuk ujian akhir. Anda kemudian harus membentuk kelompok dengan juara dari kelas lain. Bersama-sama, Anda akan menjelajah ke jantung korupsi untuk menghadapi bos terhebat.

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

Agentverse menanti para pahlawannya. Apakah Anda akan menjawab panggilannya?

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 canggih.

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 agentic yang dapat diskalakan, mudah dikelola, dan aman.
  • Kuasai Alur Kerja Agentik Tingkat Lanjut: Melampaui agen tunggal dan bangun legiun "Familiar" 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 sesungguhnya. Anda akan membuat Agen Orkestrasi utama yang menggunakan protokol Agent-to-Agent (A2A) untuk menemukan dan mendelegasikan tugas kompleks ke Familiars 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 interaksi yang memiliki status. Anda akan menerapkan logika kustom menggunakan sistem Plugin dan Callback ADK yang canggih untuk mengelola batasan dunia nyata seperti timer jeda.
  • 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.
  • Jalankan Penerapan Cloud End-to-End: Ubah seluruh sistem multi-agen Anda dari prototipe lokal menjadi realitas tingkat produksi. Anda akan mempelajari cara mengontainerisasi agen dan orkestrasi Anda dan menyebarkannya sebagai kumpulan layanan mikro yang skalabel dan independen di Google Cloud Run.

3. Menggambar Lingkaran Pemanggilan

Selamat datang, Summoner. Sebelum seorang Familiar dapat dipanggil, sebelum perjanjian apa pun dapat dibuat, landasan tempat Anda berdiri harus dipersiapkan. Lingkungan yang liar merupakan undangan menuju kekacauan; seorang Summoner yang baik hanya beroperasi dalam ruang yang disucikan dan diberi wewenang. Tugas pertama kita adalah menggambar lingkaran pemanggilan: untuk mengukir rune kekuatan yang membangkitkan layanan cloud yang diperlukan dan memperoleh cetak biru kuno yang akan memandu pekerjaan kita. Kekuatan seorang Summoner lahir dari persiapan yang cermat.

👉 Klik Aktifkan Cloud Shell di bagian atas konsol Google Cloud (Ini adalah ikon bentuk 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

👉Buka terminal di IDE cloud, Teks alternatif

👉💻 Di terminal, verifikasi bahwa Anda sudah terautentikasi dan proyek telah diatur ke ID proyek Anda menggunakan perintah berikut:

gcloud auth list

👉💻 Kloning proyek 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 penyiapan dari direktori project.

⚠️ Catatan tentang Project ID: Skrip akan menyarankan Project ID default yang dibuat secara acak. Anda dapat menekan Enter untuk menerima default ini.

Namun, jika Anda lebih suka membuat proyek baru tertentu, Anda dapat mengetikkan ID Proyek yang diinginkan saat diminta oleh skrip.

cd ~/agentverse-architect
./init.sh

Skrip akan menangani sisa proses penyiapan secara otomatis.

👉 Langkah Penting Setelah Selesai: Setelah skrip selesai, Anda harus memastikan Konsol Google Cloud Anda melihat project yang benar:

  1. Buka console.cloud.google.com.
  2. Klik menu tarik-turun pemilih proyek di bagian atas halaman.
  3. Klik tab "Semua" (karena proyek baru mungkin belum muncul di "Terbaru").
  4. Pilih ID Proyek yang baru saja Anda konfigurasikan pada langkah init.sh.

03-05-project-all.png

👉💻 Tetapkan ID Proyek yang dibutuhkan:

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 memiliki class lain yang di-deploy di 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 yang 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 Elemental Font yang akan digunakan Familiars untuk mendapatkan kekuatan.

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 Pemanggil: menempa sumber kekuatan yang akan digunakan Familiars Anda untuk mendapatkan kekuatan. Ritual ini dibagi menjadi tiga bagian, yang masing-masing membangkitkan Sumber Elemen—sumber kekuatan stabil dan independen dari jenis tertentu. Anda hanya dapat memulai pekerjaan pemanggilan yang lebih rumit jika ketiga font tersebut aktif.

Story

Catatan Arsitek: Server Model Context Protocol (MCP) adalah komponen dasar dalam sistem agen modern, yang bertindak sebagai jembatan komunikasi standar yang memungkinkan agen menemukan dan menggunakan alat jarak jauh. Dalam ekosistem perkakas kami, kami akan merancang dua jenis server MCP yang berbeda, masing-masing mewakili pola arsitektur yang penting. Untuk menghubungkan ke basis data kami, kami akan menggunakan pendekatan deklaratif dengan Database Toolbox, mendefinisikan alat kami dalam berkas konfigurasi sederhana. Pola ini sangat efisien dan aman untuk mengekspos akses data terstruktur. Namun, saat kita perlu mengimplementasikan logika bisnis khusus atau memanggil API pihak ketiga eksternal, kita akan menggunakan pendekatan imperatif, menulis logika server langkah demi langkah dalam kode. Hal ini memberikan kendali dan fleksibilitas terbaik, yang memungkinkan kami merangkum operasi rumit di balik alat yang sederhana dan dapat digunakan kembali. Seorang arsitek utama harus memahami kedua pola tersebut untuk memilih pendekatan yang tepat bagi setiap komponen, sehingga menciptakan fondasi perkakas yang kuat, aman, dan terukur.

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 bertindak sebagai sumber daya eksternal kami, menawarkan dua titik akhir mantra mentah: /cryosea_shatter dan /moonlit_cascade.

Catatan Arsitek: Anda akan menggunakan pendekatan imperatif yang secara eksplisit mendefinisikan 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 merupakan keterampilan penting bagi seorang arsitek agen.

👉✏️ Arahkan ke direktori ~/agentverse-architect/mcp-servers/api/main.py dan REPLACE #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 tersebut adalah fungsi Python biasa. Di sinilah pekerjaan sesungguhnya terjadi.

👉✏️ Dalam file yang sama ~/agentverse-architect/mcp-servers/api/main.py REPLACE #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.

Menyalakan Arcane Forge (Fungsi Umum Server MCP)

Tidak semua kekuatan berasal dari buku-buku kuno atau bisikan-bisikan yang jauh. Kadang kala, seorang Summoner harus menempa sihirnya sendiri dari kemauan mentah dan logika murni. Arcane Forge adalah sumber kekuatan tersebut—server yang menyediakan fungsi utilitas umum tanpa status.

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. Ini merangkum logika khusus Anda, membuatnya dapat digunakan kembali oleh agen mana pun dalam ekosistem Anda, dan memisahkannya 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 pendekatan mcp.server yang imperatif yang sama seperti pada Nexus digunakan untuk membangun Font of Power kustom ini.

Buat Pipeline Build Master Cloud

Sekarang, kita akan membuat file cloudbuild.yaml di dalam direktori mcp-servers. Berkas ini akan mengatur pembangunan dan penyebaran 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 penerapan selesai.

👉 Anda dapat memverifikasi penerapan dengan menavigasi ke konsol Cloud Run. Anda akan melihat dua instans server MCP baru Anda berjalan, seperti yang ditunjukkan di bawah ini: Teks alternatif

Membangkitkan Pustaka Pengetahuan (Database ToolBox MCP Server)

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

Story

Catatan Arsitek: Untuk itu, kita akan menggunakan Database Toolbox modern dan 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. Kami akan menggunakan skrip pengaturan untuk menangani ini 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. Sekarang Anda dapat memverifikasi konten Grimoire secara langsung.

👉 Pertama, navigasikan ke Cloud SQL Studio untuk database Anda dengan membuka tautan 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 tertera, 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

Konfigurasikan Server MCP ToolBox

Berkas konfigurasi tools.yaml berfungsi sebagai cetak biru untuk server kita, yang memberi tahu Database Toolbox cara yang tepat untuk 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 pada 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 berikut ini

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"

👉✏️ 🚨🚨GANTI

YOUR_PROJECT_ID

dengan ID proyek Anda.

alat: Bagian ini mendefinisikan kemampuan atau fungsi sebenarnya yang akan ditawarkan server kami.

  • lookup-available-ability:: Ini adalah nama alat pertama kami.
  • jenis: postgres-sql: Ini memberi tahu Toolbox bahwa tindakan alat ini adalah mengeksekusi 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. Hal ini penting untuk mengaktifkan kemampuan pemanggilan fungsi agen.
  • statement: Ini adalah kueri SQL mentah yang akan dieksekusi. $1 adalah placeholder aman tempat parameter familiar_name yang disediakan oleh agen akan dimasukkan dengan aman.

👉✏️ Pada ~/agentverse-architect/mcp-servers/db-toolbox yang sama di file tools.yaml, ganti #REPLACE-tools dengan yang 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;

toolset: Bagian ini mengelompokkan masing-masing alat kami menjadi satu.

  • summoner-librarium:: Kami membuat seperangkat alat dengan nama yang sama dengan sumber kami. Ketika agen diagnostik kita terhubung kemudian, ia dapat meminta untuk memuat semua alat dari perangkat summoner-librarium dalam satu perintah yang efisien.

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

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

Menerapkan Perpustakaan

Sekarang kita akan menggunakan Librarium. Alih-alih membangun kontainer sendiri, kami akan menggunakan citra kontainer resmi yang telah dibangun sebelumnya dari Google dan menyediakan konfigurasi tools.yaml kami secara aman ke dalamnya menggunakan Secret Manager. Ini adalah praktik terbaik untuk keamanan dan pemeliharaan.

👉💻 Buat rahasia dari file tools.yaml

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

👉💻 Terapkan kontainer kotak peralatan 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" \
    --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: Perintah ini secara aman memasang rahasia alat kita sebagai file bernama tools.yaml di dalam kontainer yang sedang berjalan.
  • --args: Kami menginstruksikan wadah kotak peralatan untuk menggunakan berkas rahasia yang dipasang sebagai konfigurasinya.

👉 Untuk mengonfirmasi bahwa kotak peralatan Anda telah berhasil diterapkan, navigasikan ke konsol Cloud Run. Anda akan melihat layanan summoner-toolbox tercantum dengan tanda centang hijau, yang menunjukkan 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 rahasia menggunakan perintah berikut dan menerapkannya lagi.

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

Librarium of Knowledge(Database ToolBox MCP Server) sekarang aktif dan dapat diakses di cloud. Server MCP ini menggunakan apa yang kami sebut Desain Deklaratif yang mendeskripsikan apa yang Anda inginkan, dan kotak peralatan membangun server untuk Anda.

Verifikasi: Ujian Sang Magang

👉💻 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

👉💻 Pada alat pengujian baris cmd, uji ketiga font tersebut:

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, Summoner. Tiga Font Elemen 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 Familiar: Alur Kerja Domain Inti

Elemental Fonts dibuat dengan kekuatan mentah yang tak tertandingi. 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 kombo pukulan satu-dua yang presisi. Yang lain akan mengalahkan musuh dengan serangan serentak yang memiliki banyak arah. Sepertiga akan menjadi mesin pengepungan yang gigih, menerapkan tekanan hingga targetnya hancur.

Story

Untuk merangkum proses, logika bisnis, dan tindakan yang disediakan oleh server MCP ke dalam agen alur kerja khusus dan otonom. 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 pekerjaan yang tepat.

ringkasan

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

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

Panggil Familiar Fire Elemental (Alur Kerja Berurutan)

Serangan Familiar Elemen Api merupakan kombinasi tepat dua bagian: serangan terarah yang diikuti oleh penyalaan 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 (Kombo "Serangan yang Diperkuat"):

  • Langkah 1: Agen akan terlebih dahulu melihat 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.

👉✏️ Pada 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={})
)

Berikutnya, kami membuat agen "pekerja" spesialis kami. Masing-masing diberi tujuan yang sempit dan terdefinisi dengan baik dan dibatasi pada "wilayah operasionalnya" sendiri dengan hanya diberikan akses ke satu perangkat 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-agen ini adalah komponen-komponen modular yang dapat digunakan kembali. Secara teori, Anda dapat menggunakan scout_agent ini dalam alur kerja yang sepenuhnya berbeda yang perlu menanyakan basis data. Dengan memisahkan tanggung jawab mereka, kami menciptakan komponen-komponen yang fleksibel. Ini adalah prinsip inti dari desain berbasis komponen dan layanan mikro.

Selanjutnya, kita akan menyusun Alur Kerja. Di sinilah keajaiban komposisi terjadi. SequentialAgent adalah "rencana induk" yang mendefinisikan bagaimana komponen spesialis kami dirakit dan bagaimana mereka berinteraksi.

👉✏️ Pada 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 Elemental Api, jalankan perintah berikut akan meluncurkan UI ADK DEV:

. ~/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 ADK Web Server telah dimulai, seperti 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 ADK Dev UI dari browser Anda:

Dari ikon pratinjau Web (seringkali tampak seperti mata atau persegi dengan panah) di bilah alat Cloud Shell (biasanya di kanan atas), pilih Ubah port. Di jendela pop-up, tetapkan port ke 8000, lalu klik "Ubah dan Pratinjau". Cloud Shell kemudian akan membuka tab atau jendela browser baru yang menampilkan ADK Dev UI.

pratinjau 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 fire yang sudah dikenal. Sekarang Anda memfokuskan keinginan Anda pada entitas tertentu ini.
  • Berikan Perintah Anda: Di panel obrolan di sebelah kanan, saatnya memberi perintah pada Familiar.

pilih api

👉 Perintah Pengujian:

Prepare an amplified strike using the 'inferno_lash' ability.

hasil kebakaran

Anda akan melihat agen tersebut berpikir, pertama-tama memanggil "pengintai" untuk mencari tahu kerusakan dasar, lalu "penguat" untuk melipatgandakannya dan memberikan pukulan terakhir yang dahsyat.

👉💻 Setelah Anda selesai memanggil, kembali ke terminal Cloud Shell Editor Anda 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 "Benturan Pasang"): Agen akan secara bersamaan:

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

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

👉✏️ Pada 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" spesialis kita. Masing-masing diberi tujuan yang sempit dan terdefinisi dengan baik dan dibatasi pada "wilayah operasionalnya" sendiri dengan hanya diberikan akses ke satu perangkat 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 merakit komponen khusus kami dan cara berinteraksi untuk membentuk kombo "Tidal Clash".

👉✏️ Pada 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 Elemental Air, jalankan perintah berikut untuk meluncurkan 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

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

  • Pada menu tarik-turun di bagian atas UI, pilih air yang familiar. Anda sekarang memfokuskan keinginan Anda pada entitas spesifik ini.
  • Berikan Perintah Anda: Di panel obrolan di sebelah kanan, saatnya memberi perintah pada Familiar.

👉 Petunjuk Uji:

Unleash a tidal wave of power!

hasil air

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

Panggil Familiar Earth Elemental (Alur Kerja Loop)

Hewan Pendamping Elemen Bumi adalah makhluk dengan tekanan yang tak henti-hentinya. 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 "mesin pengepungan" berulang seperti ini. Ia akan berulang kali mengeksekusi sub-agents, memeriksa kondisi setelah setiap siklus, hingga suatu tujuan tercapai. Ia juga dapat menyesuaikan pesan akhir berdasarkan kemajuan putaran.

Tugas (Serangan "Siegebreaker"):

  • Familiar akan berulang kali memanggil seismic_charge untuk mengumpulkan energi.
  • Pengisian daya akan terus dilakukan hingga maksimal 3 kali.
  • Pada serangan terakhir, ia akan mengumumkan pelepasan dahsyat dari kekuatan yang terkumpul.

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

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

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

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

👉✏️ Pada 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.

👉✏️ Pada 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
)

👉💻 Uji Elemental Bumi: 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: Pada menu tarik-turun di bagian atas UI, pilih bumi yang familiar. Anda sekarang memfokuskan keinginan Anda pada entitas spesifik ini.
  • Berikan Perintah Anda: Di panel obrolan di sebelah kanan, saatnya memberi perintah pada Familiar. 👉 Petunjuk Uji:
Begin the seismic charge, starting from zero

hasil bumi

Kesimpulan Arsitektur: Sistem Anda sekarang memiliki lapisan logika yang sangat terspesialisasi dan modular. Proses bisnis tidak hanya dienkapsulasi, tetapi juga diimplementasikan dengan pola perilaku yang paling efisien untuk pekerjaan tersebut (prosedural, bersamaan, atau berulang). Hal ini menunjukkan tingkat desain agentik yang canggih, yang meningkatkan keamanan, efisiensi, dan kemampuan.

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

UNTUK NON-GAMER

6. Menetapkan Locus Perintah: Delegasi Cerdas melalui A2A

Familiar Anda kuat namun mandiri. Mereka menjalankan strategi mereka dengan sempurna tetapi menunggu perintah langsung Anda. Sekelompok spesialis tidak ada gunanya tanpa seorang jenderal yang memimpin mereka. Sudah saatnya untuk naik pangkat dari seorang komandan langsung menjadi seorang Orkestrator sejati.

ringkasan

Catatan Arsitek: Untuk membuat titik masuk tunggal dan cerdas untuk keseluruhan 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 Familiar sebagai Layanan A2A)

Agen standar hanya dapat dijalankan di satu tempat dalam satu waktu. Untuk membuat Familiar kita tersedia untuk perintah jarak jauh, kita harus melakukan "ritual pengikatan" menggunakan protokol Agen-ke-Agen (A2A).

Catatan Arsitek: Protokol Agen-ke-Agen (A2A) adalah pola arsitektur inti yang meningkatkan agen mandiri menjadi layanan mikro yang dapat ditemukan dan dialamatkan ke jaringan, sehingga memungkinkan "masyarakat agen" yang sesungguhnya. Mengekspos Familiar melalui A2A secara otomatis menciptakan dua komponen penting yang saling berhubungan:

  • Kartu Agen ("Apa"): Ini adalah "Sigil Roh" publik yang dapat dibaca mesin—seperti spesifikasi OpenAPI—yang berfungsi sebagai kontrak publik Familiar. Ia menguraikan nama agen, tujuan strategisnya (berasal dari instruksinya), dan perintah yang dipahaminya. Inilah yang dibaca oleh seorang Master Summoner untuk menemukan Familiar dan mempelajari kemampuannya.
  • Server A2A (The "Where"): Ini adalah endpoint web khusus yang menghosting Familiar dan memproses perintah yang 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.

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

Menyebarkan Familiar Terikat

👉✏️ Dengan ritual pengikatan yang telah dijelaskan, kami akan menggunakan alur kerja Cloud Build untuk membentuk dan menerapkan tiga Familiar kami sebagai layanan serverless yang independen dan terkontainerisasi pada 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 tidak berasal dari penggunaan alat-alat dasar, tetapi dari memerintah agen lain. Alatnya adalah Familiar itu sendiri, yang akan ditemukan dan diperintah menggunakan "Sigil Roh" mereka.

Catatan Arsitek: Langkah berikutnya ini menunjukkan pola arsitektur penting untuk sistem terdistribusi skala besar: Penemuan Layanan. SummonerAgent tidak memiliki kode Familiars yang terintegrasi di dalamnya. Sebagai gantinya, model akan diberi alamat jaringan (URL) mereka. 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 "kendali jarak jauh" yang membuat koneksi ke Familiar jarak jauh yang kita sebarkan.

👉✏️ 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 dijalankan, RemoteA2aAgent melakukan tindakan penemuan layanan: membuat permintaan HTTP GET ke URL yang disediakan (misalnya, https://fire-familiar-xxxx.a.run.app/.well-known/agent.json). Ia mengunduh "Spirit Sigil" (file agent.json) dari server jarak jauh.

Kedua, kita akan mendefinisikan agen pengatur yang akan menggunakan kendali jarak jauh ini. Petunjuknya adalah cetak biru untuk pengambilan keputusan strategisnya.

👉✏️ Buka ~/agentverse-architect/agent/summoner/agent.py , ganti #REPLACE-orchestrate-agent dengan yang 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 telah di-deploy, dan Summoner Anda siap memerintahkan mereka di seluruh jaringan. Mari kita uji kemampuan berpikir strategisnya.

👉💻 Luncurkan ADK Dev UI 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.

  • Pada menu tarik-turun di bagian atas UI, pilih agen summoner. Anda sekarang memfokuskan keinginan Anda pada entitas spesifik ini.
  • Berikan Perintah Anda: Di panel chat di sebelah kanan, saatnya memanggil roh peliharaan Anda.

👉 Hadirkan Monster:

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

(Diharapkan: Pemanggil harus mendelegasikan ke fire_elemental_familiar.)

hasil kebakaran

👉 Sekarang, mari tantang Summoner dengan jenis permintaan yang berbeda. Untuk memastikan agen memulai dengan keadaan bersih dan tanpa ingatan tentang interaksi sebelumnya, mulailah sesi baru dengan mengklik tombol + Sesi di sudut kanan atas layar. sesi baru

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

(Diharapkan: Pemanggil harus mendelegasikan ke water_elemental_familiar.)hasil air

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

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

(Diharapkan: Pemanggil harus mendelegasikan ke earth_elemental_familiar.)

hasil bumi

Penting: Jika Anda melihat kesalahan 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 Anda selesai memanggil, kembali ke terminal Cloud Shell Editor Anda dan tekan Ctrl+C untuk menghentikan ADK Dev UI.

UNTUK NON-GAMER

7. Menerapkan Hukum Sihir – Pola Interceptor

Hewan peliharaan Anda sangat kuat, tetapi bahkan makhluk ajaib pun memerlukan waktu untuk pulih. Pemanggil yang ceroboh dan menghabiskan 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 – Menuliskan panggilan balik Cooldown

Pertama-tama kita akan menerapkan logika pendinginan kita sebagai fungsi panggilan balik sederhana. Ini adalah cara terbaik untuk membuat prototipe dan men-debug suatu aturan karena aturan tersebut dilampirkan langsung ke satu agen, sehingga memudahkan pengujian secara terpisah. Kita akan memasang "pencegat" ini ke Elemental Bumi kita.

Periode tunggu

👉✏️ Navigasi 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 pencegat kami. Sebelum Earth Elemental diizinkan untuk berjalan, ADK akan menjalankan fungsi ini terlebih dahulu.

  • Periksa: Ia membuat permintaan GET ke Cooldown API kita untuk memeriksa kapan terakhir kali Familiar ini digunakan.
  • Evaluasi: Membandingkan stempel waktu dengan waktu saat ini.
  • Tindakan:
    • Jika Familiar sedang dalam masa tunggu, 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, ia membuat permintaan POST ke Cooldown API untuk memperbarui stempel waktu, lalu melanjutkan dengan mengembalikan None, memberi sinyal ke ADK bahwa agen dapat melanjutkan eksekusinya.

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

before_agent_callback=check_cool_down

Memverifikasi periode tunggu

Mari kita uji hukum sihir baru kita. Kita akan memanggil Elemental Tanah, lalu segera mencoba memanggilnya lagi untuk melihat apakah panggilan balik kita berhasil mencegat dan memblokir percobaan kedua.

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

👉💻 Di konsol:

  • Pemanggilan 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 Pendinginan (dalam 60 detik): Muatan seismik Do another!
    • Diharapkan: check_cool_down callback akan mencegat ini. Agen akan merespons langsung di obrolan dengan pesan seperti: The earth_elemental_familiar is exhausted and must recover its power. It cannot be summoned for another... seconds.
  • Tunggu hingga satu menit berlalu.
  • Pemanggilan Kedua (setelah 60 detik): Begin the seismic charge again.
    • Yang diharapkan: Panggilan balik akan memeriksa API, memastikan waktu yang cukup telah berlalu, dan mengizinkan tindakan untuk dilanjutkan. Earth Elemental akan berhasil berjalan lagi.

callback

👉💻 Tekan Ctrl+c untuk keluar.

Opsional: Mengamati Panggilan Balik 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 cepat dan berulang yang dilakukan oleh loop panggilan balik, sehingga mungkin tidak menyajikan alur secara akurat. Untuk melihat jejak logika agen yang paling tepat, langkah demi langkah saat memeriksa waktu tunggu, menggunakan perintah adk run di terminal Anda akan memberikan tampilan yang lebih jelas dan terperinci. loop

👉💻 Tekan Ctrl+c untuk keluar.

Menciptakan Hukum Universal – Plugin Cooldown

Panggilan balik kami berfungsi sempurna tetapi memiliki kelemahan arsitektur utama: ia terikat pada satu agen. Jika kita ingin menerapkan aturan ini pada Familiar Api dan Air, kita harus menyalin dan menempel kode yang sama ke dalam berkas mereka. Ini tidak efisien dan sulit dipertahankan.

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 ke semua Familiar kita? Kita akan melampirkan plugin ke ADK Runtime.

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, mari kita hapus panggilan balik lama yang khusus untuk 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 dalam 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, sangat penting untuk menghapus logika lama yang spesifik untuk agen guna mencegah konflik. 👉✏️ Bersihkan agen Bumi. Buka file ~/agentverse-architect/agent/earth/agent.py berikut dan hapus baris before_agent_callback=check_cool_down sepenuhnya. Ini menyerahkan semua tanggung jawab pendinginan ke plugin baru.

Memverifikasi Plugin

Sekarang hukum universal kita sudah berlaku, kita harus mengerahkan kembali Familiar kita dengan pesona baru ini.

👉💻 Bangun ulang dan deploy ulang ketiga Familiar 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. Pemanggil akan mencoba mendelegasikan ke Familiar, tetapi plugin yang terpasang ke runtime setiap Familiar akan mencegat perintah dan menerapkan periode tunggu.

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

👉💻 Di konsol,lakukan urutan pengujian yang persis 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 Pendinginan (dalam 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 hingga satu menit berlalu.
  • 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, Summoner. Anda telah berhasil menerapkan sistem orkestrasi berbasis aturan menggunakan plugin khusus dan layanan manajemen status eksternal—pola arsitektur yang benar-benar canggih dan tangguh.

UNTUK NON-GAMER

8. Mengikat Gema Pertempuran - Status & Memori Agen

Pemanggil yang ceroboh akan mengulangi strategi yang sama, sehingga mudah diprediksi. Seorang Summoner yang bijak belajar dari gema pertempuran masa lalu, menyesuaikan taktik mereka 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: Ini untuk pengetahuan persisten yang akan bertahan selamanya. Anggap saja sebagai arsip yang dapat dicari atau basis pengetahuan, yang sering disimpan dalam penyimpanan permanen. 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: Ini untuk pengetahuan sementara, "saat ini" yang hanya relevan dengan tugas atau percakapan saat ini. Ini seperti catatan rencana pertempuran: "Saya baru saja menggunakan Elemental Api, jadi mungkin sudah lelah." Status ini ringan dan hanya ada selama 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 khusus ini. Oleh karena itu, Status Jangka Pendek ringan adalah pilihan arsitektur yang tepat. Kami akan menggunakan after_tool_callback untuk menyimpan informasi penting ini.

Menulis Gema: Mengingat Panggilan Terakhir

Kami akan mengimplementasikan memori jangka pendek kami menggunakan after_tool_callback. Ini adalah kait ADK yang kuat yang memungkinkan kita menjalankan fungsi Python kustom setelah suatu alat berhasil dijalankan. Kami akan menggunakan interceptor ini untuk merekam nama Familiar yang baru saja dipanggil ke status sesi agen.

👉✏️ Di file ~/agentverse-architect/agent/summoner/agent.py Anda, 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. Dalam berkas yang sama, ganti komentar #REPLACE-Memory-check-config dengan yang 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 memastikan bahwa Summoner tidak akan menggunakan Familiar yang sama dua kali berturut-turut, menunjukkan kemampuannya untuk mengingat tindakan terakhirnya dan beradaptasi.

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

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

  • Yang Diharapkan: Pemanggil akan menganalisis kelemahan dan memanggil fire_familiar dengan benar.

👉💻 Monster Strike #2 (Tes Memori): Hype is still standing! It hasn't changed its form. Strike it again! Its weakness is Inescapable Reality.

  • Yang diharapkan: Analisis strategis Summoner akan kembali menunjuk pada Fire Familiar sebagai pilihan ideal. Namun, instruksi dan memori barunya akan memberitahunya bahwa fire_familiar adalah last_summon. Untuk menghindari terulangnya hal yang sama, ia sekarang akan menyesuaikan strateginya dan memanggil salah satu Familiar lain yang tersedia (baik water_familiar maupun earth_familiar).

hasil akhir

👉💻 Tekan Ctrl+C untuk keluar.

Menyebarkan Orchestrator

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

👉💻 Setelah cetak biru selesai, sekarang kita akan melakukan ritual terakhir. Perintah ini akan membangun dan menyebarkan 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 menjelaskan 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.

Ini membuktikan 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

Cetak biru terakhir telah ditulis, Font Elemental telah ditempa, dan Familiar Anda terikat pada keinginan Anda, menunggu perintah Anda melalui Concord. Sistem multi-agen Anda bukan sekadar kumpulan layanan; ia adalah pasukan strategis yang hidup, dengan Anda sebagai pusatnya. Waktunya telah tiba untuk ujian pamungkas—orkestrasi langsung melawan musuh yang tidak dapat dikalahkan oleh satu agen pun.

Dapatkan Lokus Agen Anda

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

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

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

👉💻 Berikutnya, tentukan tujuannya. Perintah ini mengungkap lokasi Lingkaran Translokasi, portal menuju wilayah kekuasaan Spectre.

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

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

Menghadapi Hantu

Setelah koordinat diamankan, Anda sekarang akan menavigasi ke Lingkaran Translokasi dan mengucapkan mantra untuk maju ke pertempuran.

👉 Buka URL Lingkaran Translokasi di peramban 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 Lokus 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 berdesir 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 tenaga, yang sepenuhnya tertuju pada Anda.

Satu-satunya jalan Anda menuju kemenangan terletak pada kejelasan keyakinan Anda. Ini adalah pertarungan kemauan, yang terjadi di medan perang pikiran.

Saat Anda menerjang maju, siap melancarkan serangan pertama, Spectre membalas. Ia tidak mengangkat perisai, tetapi memproyeksikan pertanyaan langsung ke dalam kesadaran Anda—tantangan berkilauan dan rahasia yang diambil dari inti pelatihan Anda.

Dungeon

Begitulah sifat pertarungannya. Pengetahuan Anda adalah senjata Anda.

  • Jawablah dengan kebijaksanaan yang telah kau peroleh, dan pedangmu 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 Anda adalah buku mantra Anda, logika Anda adalah pedang Anda, dan pengetahuan Anda adalah perisai yang akan membalikkan gelombang kekacauan.

Fokus. Tembak dengan akurat. Nasib Agentverse bergantung padanya.

Selamat, Summoner.

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

10. Pembersihan: Membongkar Kesepakatan Pemanggil

Selamat telah menguasai Kesepakatan Pemanggil! Untuk memastikan Agentverse Anda tetap bersih dan tempat latihan Anda bersih, Anda sekarang harus melakukan ritual pembersihan akhir. Ini akan secara sistematis menghapus semua sumber daya yang dibuat selama perjalanan Anda.

Nonaktifkan Komponen Agentverse

Anda sekarang akan secara sistematis membongkar komponen-komponen yang diterapkan pada sistem multi-agen Anda.

Hapus Semua Layanan Cloud Run dan Repositori Registri Artefak

Ini menghapus semua agen Familiar yang disebarkan, Summoner Orchestrator, server MCP, dan aplikasi Dungeon dari Cloud Run.

👉💻 Di terminal Anda, 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 Instans Cloud SQL

Ini akan menghapus instans summoner-librarium-db, termasuk basis datanya dan semua tabel di dalamnya.

👉💻 Di terminal Anda, jalankan:

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

Hapus Secret Manager Secret dan Bucket Google Cloud Storage

👉💻 Di terminal Anda, jalankan:

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

Bersihkan File dan Direktori Lokal (Cloud Shell)

Terakhir, bersihkan lingkungan Cloud Shell Anda dari repositori kloning dan file yang dibuat. 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 membersihkan semua jejak perjalanan Agentverse Architect Anda. Proyek Anda bersih, dan Anda siap untuk petualangan berikutnya.