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

1. Overture

अब अलग-अलग टीमों के साथ मिलकर काम करने का समय आ गया है. टेक्नोलॉजी के विकास की अगली लहर, किसी एक व्यक्ति की प्रतिभा के बारे में नहीं, बल्कि साथ मिलकर काम करने की क्षमता के बारे में है. एक ही स्मार्ट एजेंट बनाना, एक दिलचस्प एक्सपेरिमेंट है. मॉडर्न एंटरप्राइज़ के लिए, एजेंट का एक मज़बूत, सुरक्षित, और स्मार्ट ईकोसिस्टम बनाना एक बड़ी चुनौती है. इसे Agentverse कहा जाता है.

इस नए दौर में सफलता पाने के लिए, चार अहम भूमिकाओं को एक साथ लाना ज़रूरी है. ये ऐसे बुनियादी सिद्धांत हैं जो किसी भी एजेंटिक सिस्टम को बेहतर बनाने में मदद करते हैं. किसी भी एक क्षेत्र में कमी होने से, पूरी संरचना कमज़ोर हो जाती है.

यह वर्कशॉप, Google Cloud पर एआई एजेंट के इस्तेमाल से जुड़ी एंटरप्राइज़ प्लेबुक है. हम आपको एक ऐसा रोडमैप देते हैं जो किसी आइडिया के शुरुआती चरण से लेकर उसे पूरी तरह से लागू करने तक आपका मार्गदर्शन करता है. इन चार इंटरकनेक्टेड लैब में, आपको यह जानने को मिलेगा कि एक पावरफ़ुल एजेंटवर्स बनाने, उसे मैनेज करने, और उसे स्केल करने के लिए, डेवलपर, आर्किटेक्ट, डेटा इंजीनियर, और एसआरई की खास क्षमताओं को एक साथ कैसे इस्तेमाल किया जाना चाहिए.

कोई भी पिलर, Agentverse को अकेले सपोर्ट नहीं कर सकता. डेवलपर के सटीक तरीके से काम किए बिना, आर्किटेक्ट का शानदार डिज़ाइन किसी काम का नहीं होता. डेटा इंजीनियर के बिना डेवलपर का एजेंट कुछ नहीं कर सकता. साथ ही, एसआरई के बिना पूरा सिस्टम असुरक्षित है. आपकी टीम, एक-दूसरे की भूमिकाओं को समझकर और मिलकर काम करके ही, किसी नए कॉन्सेप्ट को मिशन के लिए ज़रूरी और व्यावहारिक हकीकत में बदल सकती है. आपका सफ़र यहां से शुरू होता है. अपनी भूमिका को बेहतर तरीके से निभाने के लिए तैयार रहें. साथ ही, जानें कि आप किस तरह से पूरी टीम के साथ मिलकर काम कर सकते हैं.

'द एजेंटवर्स: ए कॉल टू चैंपियंस' में आपका स्वागत है

एंटरप्राइज़ के विशाल डिजिटल क्षेत्र में, एक नया दौर शुरू हो गया है. यह एजेंटिक युग है. इसमें एआई एजेंट, इनोवेशन को बढ़ावा देने और रोज़मर्रा के कामों को आसान बनाने के लिए, एक साथ मिलकर काम करते हैं.

agentverse.png

पावर और संभावनाओं से जुड़े इस कनेक्टेड नेटवर्क को Agentverse कहा जाता है.

हालांकि, इस नई दुनिया में धीरे-धीरे एक ख़तरनाक बदलाव हो रहा है. इसे 'द स्टैटिक' कहा जाता है. यह बदलाव, इस नई दुनिया को अंदर ही अंदर खोखला कर रहा है. स्टैटिक कोई वायरस या बग नहीं है. यह एक तरह का अराजकतावादी है, जो क्रिएशन के काम को ही अपना शिकार बनाता है.

इससे पुरानी समस्याएं और बढ़ जाती हैं. इससे डेवलपमेंट की सात समस्याएं पैदा होती हैं. अगर इस पर ध्यान नहीं दिया गया, तो The Static और इसके Spectres, प्रोग्रेस को रोक देंगे. इससे Agentverse का वादा, तकनीकी कर्ज़ और छोड़े गए प्रोजेक्ट के बंजर इलाके में बदल जाएगा.

आज हम ऐसे लोगों को आगे आने का न्योता देते हैं जो इस अराजकता को खत्म करने में हमारी मदद कर सकें. हमें ऐसे हीरो की ज़रूरत है जो अपनी कला में माहिर हों और एजेंटवर्स को बचाने के लिए साथ मिलकर काम कर सकें. अब आपको अपना रास्ता चुनना है.

अपनी क्लास चुनना

आपके सामने चार अलग-अलग रास्ते हैं. इनमें से हर एक, द स्टैटिक के ख़िलाफ़ लड़ाई में अहम भूमिका निभाता है. हालांकि, आपकी ट्रेनिंग एक सोलो मिशन होगा, लेकिन आपकी सफलता इस बात पर निर्भर करती है कि आपकी स्किल, दूसरों की स्किल के साथ कैसे काम करती हैं.

  • द शैडोब्लेड (डेवलपर): यह फ़ोर्ज और फ़्रंट लाइन का मास्टर है. आप एक ऐसे कारीगर हैं जो ब्लेड बनाता है, टूल बनाता है, और कोड की जटिलताओं में दुश्मन का सामना करता है. आपका रास्ता सटीक, कुशल, और व्यावहारिक है.
  • द समनर (आर्किटेक्ट): यह एक बेहतरीन रणनीति बनाने वाला और ऑर्गनाइज़र होता है. आपको सिर्फ़ एक एजेंट नहीं, बल्कि पूरा बैटलग्राउंड दिखता है. मास्टर ब्लूप्रिंट डिज़ाइन करने का काम आपका होता है. इनकी मदद से, एजेंट के पूरे सिस्टम को कम्यूनिकेट करने, साथ मिलकर काम करने, और किसी एक कॉम्पोनेंट से ज़्यादा बड़ा लक्ष्य हासिल करने में मदद मिलती है.
  • स्कॉलर (डेटा इंजीनियर): यह छिपी हुई सच्चाई को ढूंढता है और ज्ञान को सुरक्षित रखता है. डेटा के इस विशाल और अनियंत्रित जंगल में, आपको ऐसी जानकारी मिलती है जिससे आपके एजेंट को काम करने का मकसद और दिशा मिलती है. आपकी जानकारी से, किसी दुश्मन की कमज़ोरी का पता चल सकता है या किसी दोस्त को फ़ायदा मिल सकता है.
  • द गार्जियन (DevOps / SRE): यह टीम, सिस्टम को सुरक्षित रखने और उसकी निगरानी करने का काम करती है. आपको किले बनाने होते हैं, बिजली की सप्लाई लाइनें मैनेज करनी होती हैं, और यह पक्का करना होता है कि पूरा सिस्टम, स्टैटिक के हमलों का सामना कर सके. आपकी ताकत ही वह आधार है जिस पर आपकी टीम की जीत टिकी होती है.

आपका मिशन

आपकी ट्रेनिंग, एक अलग कसरत के तौर पर शुरू होगी. आपको अपनी चुनी हुई भूमिका के हिसाब से, ज़रूरी खास कौशल सीखने का मौका मिलेगा. ट्रायल के आखिर में, आपको स्टैटिक से पैदा हुए स्पेकटर का सामना करना होगा. यह एक मिनी-बॉस है, जो आपके क्राफ़्ट की खास चुनौतियों का फ़ायदा उठाता है.

अपनी भूमिका में महारत हासिल करके ही, फ़ाइनल ट्रायल के लिए तैयारी की जा सकती है. इसके बाद, आपको दूसरी क्लास के चैंपियन के साथ मिलकर एक पार्टी बनानी होगी. साथ मिलकर, आपको करप्शन के केंद्र में जाना होगा, जहां आपको सबसे बड़े बॉस का सामना करना होगा.

यह एक आखिरी चुनौती है, जिसमें आपको मिलकर काम करना होगा. इससे आपकी टीम की ताकत का पता चलेगा और यह तय होगा कि Agentverse का क्या होगा.

Agentverse को अपने हीरो का इंतज़ार है. क्या आपको कॉल का जवाब देना है?

2. द समनर कॉन्कर्ड

आपका स्वागत है, Summoner. आपका रास्ता विज़न और बड़ी रणनीति का है. जब दूसरे लोग किसी एक ब्लेड या एक मंत्र पर फ़ोकस करते हैं, तब आपको पूरे युद्ध के मैदान का नज़ारा दिखता है. आपको किसी एक एजेंट को निर्देश नहीं देना है, बल्कि आपको कई एजेंट को एक साथ निर्देश देने हैं. आपकी ताकत सीधे टकराव में नहीं, बल्कि एक ऐसे बेहतरीन और व्यापक ब्लूप्रिंट को डिज़ाइन करने में है जिससे कई विशेषज्ञ—आपके भरोसेमंद लोग—एक साथ मिलकर काम कर सकें. इस मिशन में, आपकी इस क्षमता की जांच की जाएगी कि आप एक शक्तिशाली, मल्टी-एजेंट सिस्टम को डिज़ाइन, कनेक्ट, और व्यवस्थित कर सकते हैं या नहीं.

खास जानकारी

आपको क्या सीखने को मिलेगा

  • डिकपल्ड टूलिंग इकोसिस्टम तैयार करना: एमसीपी टूल सर्वर का एक ऐसा सेट डिज़ाइन और डिप्लॉय करें जो इंडिपेंडेंट हो और माइक्रोसेवा पर आधारित हो. आपको यह पता चलेगा कि यह बुनियादी लेयर, बढ़ाने लायक, रखरखाव करने लायक, और सुरक्षित एजेंटिक सिस्टम बनाने के लिए क्यों ज़रूरी है.
  • एडवांस एजेंटिक वर्कफ़्लो में महारत हासिल करें: एक से ज़्यादा एजेंट का इस्तेमाल करें और "फ़ैमिलियर" के तौर पर काम करने वाले विशेषज्ञों की एक टीम बनाएं. आपको ADK के मुख्य वर्कफ़्लो पैटर्न—सीक्वेंशियल, पैरलल, और लूप के बारे में पूरी जानकारी मिलेगी. साथ ही, सही टास्क के लिए सही पैटर्न चुनने के आर्किटेक्चरल सिद्धांतों के बारे में भी जानकारी मिलेगी.
  • इंटेलिजेंट ऑर्केस्ट्रेटर लागू करें: एजेंट बिल्डर से सिस्टम आर्किटेक्ट बनें. आपको एक मास्टर ऑर्केस्ट्रेशन एजेंट बनाना होगा. यह एजेंट-टू-एजेंट (A2A) प्रोटोकॉल का इस्तेमाल करके, आपके स्पेशलिस्ट फ़ैमिलियर को मुश्किल टास्क सौंपेगा. इससे एक मल्टी-एजेंट सिस्टम तैयार होगा.
  • प्रॉम्प्ट के बजाय कोड के ज़रिए नियमों को लागू करना: बातचीत के दौरान नियमों को लागू करके, ज़्यादा भरोसेमंद और अनुमान लगाने वाले एजेंट बनाने के बारे में जानें. आपको ADK के शक्तिशाली प्लगिन और कॉलबैक सिस्टम का इस्तेमाल करके, कस्टम लॉजिक लागू करना होगा. इससे, कूलडाउन टाइमर जैसी असल दुनिया की पाबंदियों को मैनेज किया जा सकेगा.
  • एजेंट की स्थिति और मेमोरी मैनेज करना: अपने एजेंट को सीखने और याद रखने की सुविधा दें. आपको कम समय के लिए बातचीत की स्थिति और लंबे समय तक सेव रहने वाली मेमोरी को मैनेज करने की तकनीकों के बारे में जानने को मिलेगा. इससे ज़्यादा स्मार्ट और कॉन्टेक्स्ट के हिसाब से इंटरैक्शन बनाए जा सकेंगे.
  • एंड-टू-एंड क्लाउड डिप्लॉयमेंट लागू करें: अपने पूरे मल्टी-एजेंट सिस्टम को लोकल प्रोटोटाइप से प्रोडक्शन-ग्रेड की हकीकत में बदलें. आपको अपने एजेंट और ऑर्केस्ट्रेटर को कंटेनर में बदलने और उन्हें Google Cloud Run पर, ज़्यादा उपयोगकर्ताओं को हैंडल करने वाली, स्वतंत्र माइक्रोसेवाओं के कलेक्शन के तौर पर डिप्लॉय करने का तरीका बताया जाएगा.

3. समनिंग सर्कल बनाना

आपका स्वागत है, Summoner. किसी फ़ैमिलियर को बुलाने से पहले, किसी भी तरह का समझौता करने से पहले, आपको उस ज़मीन को तैयार करना होगा जिस पर आप खड़े हैं. अनियंत्रित माहौल में, अराजकता फैलने का खतरा होता है. इसलिए, एक सही समनर सिर्फ़ पवित्र और शक्तिशाली जगह पर ही काम करता है. हमारा पहला काम, समनिंग सर्कल बनाना है. इसके लिए, हमें पावर के ऐसे रन बनाने होंगे जो ज़रूरी क्लाउड सेवाओं को चालू कर सकें. साथ ही, हमें ऐसे पुराने ब्लूप्रिंट हासिल करने होंगे जो हमारे काम में मदद कर सकें. समनर की ताकत, पूरी तैयारी के बाद मिलती है.

👉 Google Cloud Console में सबसे ऊपर मौजूद, 'Cloud Shell चालू करें' पर क्लिक करें. यह Cloud Shell पैनल में सबसे ऊपर मौजूद टर्मिनल के आकार का आइकॉन है,

वैकल्पिक लेख

👉 "एडिटर खोलें" बटन पर क्लिक करें. यह बटन, पेंसिल वाले खुले फ़ोल्डर की तरह दिखता है. इससे विंडो में Cloud Shell Code Editor खुल जाएगा. आपको बाईं ओर फ़ाइल एक्सप्लोरर दिखेगा. वैकल्पिक लेख

👉अपना Google Cloud प्रोजेक्ट आईडी ढूंढें:

  • Google Cloud Console खोलें: https://console.cloud.google.com
  • पेज पर सबसे ऊपर मौजूद प्रोजेक्ट ड्रॉपडाउन से, वह प्रोजेक्ट चुनें जिसका इस्तेमाल आपको इस वर्कशॉप के लिए करना है.
  • आपका प्रोजेक्ट आईडी, डैशबोर्ड पर मौजूद प्रोजेक्ट की जानकारी देने वाले कार्ड में दिखता है वैकल्पिक लेख

👉क्लाउड आईडीई में टर्मिनल खोलें, वैकल्पिक लेख

👉💻 टर्मिनल में, पुष्टि करें कि आपने पहले ही पुष्टि कर ली है और प्रोजेक्ट को अपने प्रोजेक्ट आईडी पर सेट किया गया है. इसके लिए, यह कमांड इस्तेमाल करें:

gcloud auth list

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

👉💻 इनिशियलाइज़ेशन स्क्रिप्ट चलाएं. यह स्क्रिप्ट, आपसे Google Cloud प्रोजेक्ट आईडी डालने के लिए कहेगी. इसके बाद, init.sh स्क्रिप्ट के प्रॉम्प्ट करने पर, पिछले चरण में मिला Google Cloud प्रोजेक्ट आईडी डालें.

cd ~/agentverse-architect
./init.sh

👉💻 ज़रूरी प्रोजेक्ट आईडी सेट करें:

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

👉💻 ज़रूरी Google Cloud API चालू करने के लिए, यह कमांड चलाएं:

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

👉💻 अगर आपने अब तक agentverse-repo नाम की Artifact Registry रिपॉज़िटरी नहीं बनाई है, तो इसे बनाने के लिए यह कमांड चलाएं: (अगर आपने इसी प्रोजेक्ट में अन्य क्लास डिप्लॉय की हैं, तो इस चरण को छोड़ दें)

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

अनुमति सेट अप करना

👉💻 टर्मिनल में ये कमांड चलाकर, ज़रूरी अनुमतियां दें:

. ~/agentverse-architect/set_env.sh

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

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

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

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

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

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

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

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

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

👉💻 ट्रेनिंग शुरू करने के बाद, हम फ़ाइनल चैलेंज तैयार करेंगे. नीचे दिए गए निर्देशों का पालन करके, स्पेक्ट्र को बुलाया जा सकता है. इससे आपकी फ़ाइनल परीक्षा के लिए बॉस तैयार हो जाएंगे.

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

👉💻 आखिर में, शुरुआती सेटअप के टास्क पूरे करने के लिए prepare.sh स्क्रिप्ट चलाएं.

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

बहुत बढ़िया, समनर. अब यह सर्कल पूरा हो गया है और समझौते पक्के हो गए हैं. अब ज़मीन पवित्र हो गई है और इसमें अपार शक्ति समाहित हो गई है. हमारे अगले ट्रायल में, हम उन एलिमेंटल फ़ॉन्ट को फ़ोर्ज करेंगे जिनसे हमारे फ़ैमिलियर को ताकत मिलेगी.

4. फ़ॉन्ट बनाने के लिए टूलिंग ईकोसिस्टम को अलग करना

युद्ध का मैदान तैयार है, समनिंग सर्कल बनाया गया है, और आसपास की मन ऊर्जा चमक रही है. अब समय आ गया है कि आप समनर के तौर पर अपना पहला काम करें: उन स्रोतों को तैयार करना जिनसे आपके फ़ैमिलियर को ताकत मिलेगी. इस रस्म को तीन हिस्सों में बांटा गया है. हर हिस्से में, एक एलिमेंटल फ़ॉन्ट को जगाया जाता है. यह एक स्थिर और स्वतंत्र स्रोत होता है, जो किसी खास तरह की शक्ति देता है. तीनों फ़ॉन्ट चालू होने पर ही, समन करने का मुश्किल काम शुरू किया जा सकता है.

स्टोरी

आर्किटेक्ट का नोट: मॉडल कॉन्टेक्स्ट प्रोटोकॉल (एमसीपी) सर्वर, आधुनिक एजेंटिक सिस्टम का एक बुनियादी कॉम्पोनेंट है. यह एक स्टैंडर्ड कम्यूनिकेशन ब्रिज के तौर पर काम करता है. इससे एजेंट को रिमोट टूल खोजने और उनका इस्तेमाल करने की अनुमति मिलती है. हमारा टूलिंग इकोसिस्टम, दो अलग-अलग तरह के एमसीपी सर्वर बनाएगा. इनमें से हर सर्वर, एक अहम आर्किटेक्चरल पैटर्न को दिखाता है. हमारे डेटाबेस से कनेक्ट करने के लिए, हम Database Toolbox के साथ डिक्लेरेटिव अप्रोच का इस्तेमाल करेंगे. इसमें हम अपने टूल को एक सामान्य कॉन्फ़िगरेशन फ़ाइल में तय करेंगे. यह पैटर्न, स्ट्रक्चर्ड डेटा को ऐक्सेस करने के लिए बहुत असरदार और सुरक्षित है. हालांकि, जब हमें कस्टम बिज़नेस लॉजिक लागू करना होता है या तीसरे पक्ष के बाहरी एपीआई को कॉल करना होता है, तो हम इंपरेटिव अप्रोच का इस्तेमाल करेंगे. इसमें सर्वर के लॉजिक को कोड में चरण-दर-चरण लिखा जाता है. इससे हमें पूरा कंट्रोल और ज़रूरत के हिसाब से बदलाव करने की सुविधा मिलती है. इसकी मदद से, हम जटिल कार्रवाइयों को एक आसान और दोबारा इस्तेमाल किए जा सकने वाले टूल के पीछे छिपा सकते हैं. मास्टर आर्किटेक्ट को दोनों पैटर्न के बारे में पता होना चाहिए, ताकि वह हर कॉम्पोनेंट के लिए सही तरीका चुन सके. इससे, टूलिंग के लिए एक मज़बूत, सुरक्षित, और आसानी से बढ़ाया जा सकने वाला फ़्रेमवर्क तैयार किया जा सकता है.

खास जानकारी

Awakening the Nexus of Whispers (External API MCP Server)

एक समझदार समनर को पता होता है कि सारी ताकत उसके अपने डोमेन से नहीं मिलती. ऊर्जा के बाहरी स्रोत होते हैं, जो कभी-कभी काफ़ी मुश्किल होते हैं. हालांकि, इनका इस्तेमाल करके बेहतर नतीजे पाए जा सकते हैं. Nexus of Whispers, इन शक्तियों तक पहुंचने का हमारा रास्ता है.

स्टोरी

एक सेवा पहले से ही लाइव है और यह हमारे लिए बाहरी पावर सोर्स के तौर पर काम करती है. यह दो रॉ स्पेल एंडपॉइंट उपलब्ध कराती है: /cryosea_shatter और /moonlit_cascade.

आर्किटेक्ट का नोट: आपको इंपरेटिव अप्रोच का इस्तेमाल करना होगा. इसमें सर्वर के लॉजिक को चरण-दर-चरण साफ़ तौर पर बताया जाता है. इससे आपको ज़्यादा कंट्रोल और सुविधा मिलती है. यह तब ज़रूरी होता है, जब आपके टूल को सिर्फ़ एक सामान्य एसक्यूएल क्वेरी चलाने के अलावा, अन्य काम भी करने होते हैं. जैसे, अन्य एपीआई कॉल करना. एजेंट आर्किटेक्ट के लिए, इन दोनों पैटर्न को समझना ज़रूरी है.

👉✏️ डायरेक्ट्री ~/agentverse-architect/mcp-servers/api/main.py पर जाएं और REPLACE #REPLACE-MAGIC-CORE को इस कोड से बदलें:

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


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

स्क्रिप्ट के मुख्य हिस्से में, सामान्य Python फ़ंक्शन होते हैं. असल में, यहीं पर काम होता है.

👉✏️ उसी फ़ाइल में, ~/agentverse-architect/mcp-servers/api/main.py REPLACE #REPLACE-Runes of Communication को इस कोड से बदलें:

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

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

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

    except Exception as e:
      print(f"MCP Server: Error executing ADK tool '{name}': {e}")
      # Creating a proper MCP error response might be more robust
      error_text = json.dumps({"error": f"Failed to execute tool '{name}': {str(e)}"})
      return [mcp_types.TextContent(type="text", text=error_text)]
  else:
      # Handle calls to unknown tools
      print(f"MCP Server: Tool '{name}' not found.")
      error_text = json.dumps({"error": f"Tool '{name}' not implemented."})
      return [mcp_types.TextContent(type="text", text=error_text)]
  • @app.list_tools() (हैंडशेक): यह फ़ंक्शन, सर्वर की ओर से भेजा गया ग्रीटिंग मैसेज होता है. जब कोई नया एजेंट कनेक्ट होता है, तो वह सबसे पहले इस एंडपॉइंट को कॉल करके पूछता है, "तुम क्या कर सकते हो?" हमारा कोड, उपलब्ध सभी टूल की सूची के साथ जवाब देता है. इस सूची को adk_to_mcp_tool_type का इस्तेमाल करके, यूनिवर्सल एमसीपी फ़ॉर्मैट में बदला जाता है. - @app.call_tool() (The Command): यह फ़ंक्शन, सबसे ज़्यादा काम करता है. जब एजेंट किसी टूल का इस्तेमाल करने का फ़ैसला करता है, तो वह इस एंडपॉइंट को टूल का नाम और आर्ग्युमेंट के साथ एक अनुरोध भेजता है. हमारा कोड, उपलब्ध टूल की सूची में टूल ढूंढता है. इसके बाद, run_async की मदद से उसे लागू करता है और नतीजे को स्टैंडर्ड एमसीपी फ़ॉर्मैट में दिखाता है.

हम इसे बाद में डिप्लॉय करेंगे.

आर्केन फ़ोर्ज को चालू करना (General Functions MCP Server)

सारी ताकत, पुरानी किताबों या दूर की फुसफुसाहटों से नहीं मिलती. कभी-कभी, किसी समनर को अपनी इच्छाशक्ति और तर्क से जादू तैयार करना पड़ता है. Arcane Forge, पावर का यह फ़ॉन्ट है. यह एक ऐसा सर्वर है जो बिना किसी स्टेटस के, सामान्य कामों के लिए यूटिलिटी फ़ंक्शन उपलब्ध कराता है.

स्टोरी

आर्किटेक्ट का नोट: यह एक और आर्किटेक्चरल पैटर्न है. मौजूदा सिस्टम से कनेक्ट करना आम बात है. हालांकि, आपको अक्सर अपने कारोबार के यूनीक नियमों और लॉजिक को लागू करना होगा. इस तरह का "फ़ंक्शन" या "यूटिलिटी" टूल बनाना सबसे सही तरीका है. इसमें आपके कस्टम लॉजिक को शामिल किया जाता है. साथ ही, इसे आपके इकोसिस्टम में मौजूद किसी भी एजेंट के लिए फिर से इस्तेमाल किया जा सकता है. इसके अलावा, इसे आपके डेटा सोर्स और बाहरी इंटिग्रेशन से अलग रखा जाता है.

👀 अपने Google Cloud IDE में मौजूद फ़ाइल ~/agentverse-architect/mcp-servers/general/main.py देखें. आपको पता चलेगा कि Nexus की तरह ही, इसमें भी mcp.server अप्रोच का इस्तेमाल किया गया है, ताकि इस कस्टम फ़ॉन्ट ऑफ़ पावर को बनाया जा सके.

मास्टर Cloud Build पाइपलाइन बनाना

अब हम cloudbuild.yaml फ़ाइल को mcp-servers डायरेक्ट्री में बनाएंगे. यह फ़ाइल, दोनों सेवाओं को बनाने और डिप्लॉय करने की प्रोसेस को मैनेज करेगी.

👉💻 ~/agentverse-architect/mcp-servers डायरेक्ट्री से, ये कमांड चलाएं:

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

echo "The API URL is: $API_SERVER_URL"

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

सभी डिप्लॉयमेंट पूरे होने तक इंतज़ार करें.

👉 Cloud Run कंसोल पर जाकर, डिप्लॉयमेंट की पुष्टि की जा सकती है. आपको नीचे दिए गए उदाहरण की तरह, एमसीपी सर्वर के दो नए इंस्टेंस चलते हुए दिखेंगे: वैकल्पिक लेख

Awakening the Librarium of Knowledge (Database ToolBox MCP Server)

हमारा अगला फ़ॉन्ट Librarium of Knowledge होगा. यह हमारे Cloud SQL डेटाबेस से सीधे तौर पर कनेक्ट होता है.

स्टोरी

आर्किटेक्ट का नोट: इसके लिए, हम मॉडर्न, डिक्लेरेटिव Database Toolbox का इस्तेमाल करेंगे. यह एक बेहतर तरीका है. इसमें हम YAML कॉन्फ़िगरेशन फ़ाइल में, अपने डेटा सोर्स और टूल तय करते हैं. टूलबॉक्स, सर्वर बनाने और उसे चलाने का मुश्किल काम करता है. इससे हमें कम कस्टम कोड लिखना पड़ता है और उसे बनाए रखना पड़ता है.

अब हमें "Summoner's Librarium" बनाना है. यह Cloud SQL डेटाबेस होगा, जिसमें हमारी सभी ज़रूरी जानकारी सेव होगी. हम इसे अपने-आप मैनेज करने के लिए, सेटअप स्क्रिप्ट का इस्तेमाल करेंगे.

👉💻 सबसे पहले, हम डेटाबेस को सेटअप करेंगे. इसके लिए, अपने टर्मिनल में ये निर्देश चलाएं:

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

स्क्रिप्ट पूरी होने के बाद, आपका डेटाबेस भर जाएगा और एलिमेंटल डैमेज का डेटा इस्तेमाल के लिए तैयार हो जाएगा. अब सीधे तौर पर अपने Grimoire के कॉन्टेंट की पुष्टि की जा सकती है.

👉 सबसे पहले, अपने डेटाबेस के लिए Cloud SQL Studio पर जाएं. इसके लिए, इस डायरेक्ट लिंक को नए ब्राउज़र टैब में खोलें:

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

Cloud SQL

👉 बाईं ओर मौजूद लॉगिन पैनल में, ड्रॉपडाउन से familiar_grimoire डेटाबेस चुनें.

👉 उपयोगकर्ता के तौर पर summoner और पासवर्ड के तौर पर 1234qwer डालें. इसके बाद, पुष्टि करें पर क्लिक करें.

👉📜 कनेक्ट होने के बाद, अगर कोई क्वेरी एडिटर टैब पहले से खुला नहीं है, तो नया क्वेरी एडिटर टैब खोलें. तत्व के हिसाब से हुए नुकसान का डेटा देखने के लिए, यहां दी गई एसक्यूएल क्वेरी चिपकाएं और चलाएं:

SELECT * FROM
  "public"."abilities"

अब आपको abilities टेबल दिखेगी. इसमें कॉलम और लाइनें भरी हुई होंगी. इससे पता चलेगा कि आपका Grimoire तैयार है. Data

ToolBox MCP Server को कॉन्फ़िगर करना

tools.yaml कॉन्फ़िगरेशन फ़ाइल, हमारे सर्वर के लिए ब्लूप्रिंट का काम करती है. यह Database Toolbox को बताती है कि हमारे डेटाबेस से कैसे कनेक्ट करना है और किन एसक्यूएल क्वेरी को टूल के तौर पर दिखाना है.

sources: इस सेक्शन में, आपके डेटा से कनेक्शन के बारे में बताया गया है.

  • summoner-librarium:: यह हमारे कनेक्शन का लॉजिकल नाम है.
  • kind: cloud-sql-postgres: इससे Toolbox को यह पता चलता है कि उसे Cloud SQL for PostgreSQL के लिए खास तौर पर डिज़ाइन किए गए, बिल्ट-इन और सुरक्षित कनेक्टर का इस्तेमाल करना है.
  • प्रोजेक्ट, क्षेत्र, इंस्टेंस वगैरह: ये Cloud SQL इंस्टेंस के सटीक निर्देशांक हैं. इन्हें prepare.sh स्क्रिप्ट के दौरान बनाया गया था. इनसे टूलबॉक्स को यह पता चलता है कि Librarium कहां मिलेगा.

👉✏️ tools.yaml में मौजूद ~/agentverse-architect/mcp-servers/db-toolbox पर जाएं और #REPLACE-Source को इससे बदलें

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

👉✏️ 🚨🚨REPLACE

YOUR_PROJECT_ID

की जगह अपना प्रोजेक्ट आईडी डालें.

tools: इस सेक्शन में, उन सुविधाओं या फ़ंक्शन के बारे में बताया जाता है जो हमारा सर्वर उपलब्ध कराएगा.

  • lookup-available-ability:: यह हमारे पहले टूल का नाम है.
  • kind: postgres-sql: इससे Toolbox को पता चलता है कि इस टूल का काम SQL स्टेटमेंट को एक्ज़ीक्यूट करना है.
  • source: summoner-librarium: यह टूल को उस कनेक्शन से लिंक करता है जिसे हमने सोर्स ब्लॉक में तय किया है. इस तरह, टूल को पता चलता है कि क्वेरी किस डेटाबेस पर चलानी है.
  • ब्यौरा और पैरामीटर: यह वह जानकारी है जो भाषा मॉडल को दिखाई जाएगी. ब्यौरे से एजेंट को पता चलता है कि टूल का इस्तेमाल कब करना है. साथ ही, पैरामीटर से यह तय होता है कि टूल को किन इनपुट की ज़रूरत है. यह एजेंट के फ़ंक्शन कॉल करने की सुविधा को चालू करने के लिए ज़रूरी है.
  • statement: यह वह रॉ एसक्यूएल क्वेरी है जिसे एक्ज़ीक्यूट करना है. $1 एक सुरक्षित प्लेसहोल्डर है. इसमें एजेंट की ओर से दिया गया familiar_name पैरामीटर सुरक्षित तरीके से डाला जाएगा.

👉✏️ tools.yaml फ़ाइल में मौजूद ~/agentverse-architect/mcp-servers/db-toolbox में, #REPLACE-tools को इससे बदलें

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

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

टूलसेट: इस सेक्शन में, हमारे अलग-अलग टूल को एक साथ ग्रुप किया जाता है.

  • summoner-librarium:: We are creating a toolset with the same name as our source. जब हमारा डाइग्नोस्टिक एजेंट बाद में कनेक्ट होता है, तो वह एक ही असरदार कमांड में, समनर-लाइब्रेरी टूलसेट के सभी टूल लोड करने के लिए कह सकता है.

👉✏️ tools.yaml फ़ाइल में मौजूद ~/agentverse-architect/mcp-servers/db-toolbox में, #REPLACE-toolsets को इससे बदलें

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

Librarium को डिप्लॉय करना

अब हम Librarium को डिप्लॉय करेंगे. हम अपना कंटेनर बनाने के बजाय, Google की ओर से पहले से बनाई गई आधिकारिक कंटेनर इमेज का इस्तेमाल करेंगे. साथ ही, Secret Manager का इस्तेमाल करके, अपने tools.yaml कॉन्फ़िगरेशन को सुरक्षित तरीके से उपलब्ध कराएंगे. सुरक्षा और रखरखाव के लिए, यह सबसे सही तरीका है.

👉💻 tools.yaml फ़ाइल से सीक्रेट बनाना

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

👉💻 आधिकारिक टूलबॉक्स कंटेनर को Cloud Run पर डिप्लॉय करें.

cd ~/agentverse-architect/mcp-servers/db-toolbox
. ~/agentverse-architect/set_env.sh
export TOOLBOX_IMAGE=us-central1-docker.pkg.dev/database-toolbox/toolbox/toolbox:$TOOLBOX_VERSION
echo "TOOLBOX_IMAGE is $TOOLBOX_IMAGE"
gcloud run deploy toolbox \
    --image $TOOLBOX_IMAGE \
    --region $REGION \
    --set-secrets "/app/tools.yaml=tools:latest" \
    --args="--tools-file=/app/tools.yaml","--address=0.0.0.0","--port=8080" \
    --allow-unauthenticated \
    --min-instances 1
  • --set-secrets: यह कमांड, हमारे टूल के सीक्रेट को सुरक्षित तरीके से माउंट करती है. इसे रनिंग कंटेनर में tools.yaml नाम की फ़ाइल के तौर पर माउंट किया जाता है.
  • --args: हम टूलबॉक्स कंटेनर को यह निर्देश देते हैं कि वह माउंट की गई सीक्रेट फ़ाइल को अपने कॉन्फ़िगरेशन के तौर पर इस्तेमाल करे.

👉 यह पुष्टि करने के लिए कि आपका टूलबॉक्स सही तरीके से डिप्लॉय हो गया है, Cloud Run कंसोल पर जाएं. आपको हरे रंग के सही के निशान के साथ summoner-toolbox सेवा की सूची दिखेगी. इससे पता चलता है कि यह सेवा सही तरीके से काम कर रही है. यह ठीक वैसी ही होगी जैसी नीचे इमेज में दिखाई गई है. वैकल्पिक लेख

अगर आपने अपडेट नहीं किया है, तो

YOUR_PROJECT_ID

इस निर्देश का इस्तेमाल करके, सीक्रेट में tools.yaml का नया वर्शन जोड़ा जा सकता है. इसके बाद, इसे फिर से डिप्लॉय किया जा सकता है.

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

Librarium of Knowledge(Database ToolBox MCP Server) अब चालू है और क्लाउड में ऐक्सेस किया जा सकता है. यह एमसीपी सर्वर, डिक्लेरेटिव डिज़ाइन का इस्तेमाल करता है. इसमें यह बताया जाता है कि आपको क्या चाहिए. इसके बाद, टूलबॉक्स आपके लिए सर्वर बनाता है.

पुष्टि: The Trial of the Apprentice

👉💻 अब हम डायग्नोस्टिक एजेंट की मदद से, क्लाउड-नेटिव टूलिंग के पूरे इकोसिस्टम की जांच करेंगे.

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

👉💻 सीएमडी लाइन टेस्टिंग टूल में, तीनों फ़ॉन्ट की जांच करें:

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

final-result

बधाई हो, समनर. आपके तीन एलिमेंटल फ़ॉन्ट अब चालू हो गए हैं. इन्हें अलग-अलग तौर पर डिप्लॉय किया गया है और ये दुनिया भर में ऐक्सेस किए जा सकते हैं. इनसे आपके एजेंटिक लेगियन की मज़बूत नींव तैयार होती है. बाहर निकलने के लिए, Ctrl+C दबाएं.

गेम नहीं खेलने वालों के लिए

5. फ़ैमिलियर को बुलाना: मुख्य डोमेन वर्कफ़्लो

Elemental Fonts को बनाया गया है. ये अपनी मूल और असीमित ताकत के साथ गूंजते हैं. हालांकि, बिना किसी फ़ॉर्म के पावर का इस्तेमाल करने से गड़बड़ी हो सकती है. एक सच्चा समनर सिर्फ़ कच्ची ऊर्जा का इस्तेमाल नहीं करता, बल्कि वह उसे इच्छाशक्ति, मकसद, और एक खास रूप देता है. अब आपको पावर सोर्स बनाने के बजाय, असली काम शुरू करना होगा. यानी, अपने पहले फ़ैमिलियर को बुलाना होगा.

आपके बुलाए गए हर फ़ैमिलियर, एक ऑटोनॉमस एजेंट होगा. यह एक भरोसेमंद नौकर की तरह होगा, जो किसी खास कॉम्बैट सिद्धांत से बंधा होगा. ये सामान्य तौर पर काम करने वाले लोग नहीं होते, बल्कि किसी एक रणनीति के माहिर होते हैं. एक सटीक और तेज़ पंच कॉम्बो का मास्टर होगा. वहीं, दूसरी टीम एक साथ कई तरह के हमले करके दुश्मनों को हरा देगी. तीसरा, लगातार दबाव डालने वाला इंजन होगा. यह तब तक दबाव डालता रहेगा, जब तक इसका टारगेट खत्म नहीं हो जाता.

स्टोरी

एमसीपी सर्वर की ओर से उपलब्ध कराई गई प्रोसेस, बिज़नेस लॉजिक, और कार्रवाइयों को खास, ऑटोनॉमस वर्कफ़्लो एजेंट में शामिल करने के लिए. हर एजेंट के लिए "ऑपरेशनल टेरिटरी" तय की जाएगी. इसके लिए, उसे सिर्फ़ उन एमसीपी टूल सर्वर का ऐक्सेस दिया जाएगा जिनकी ज़रूरत उसे अपना काम करने के लिए होगी. इस लैब में, सही काम के लिए सही एजेंट टाइप चुनने का तरीका बताया गया है.

खास जानकारी

इस मॉड्यूल में, आपको एआई की मदद से काम करने वाले ADK के वर्कफ़्लो एजेंट इस्तेमाल करने का तरीका बताया जाएगा. इससे इन रणनीतियों को बेहतर तरीके से लागू किया जा सकेगा. आपको पता चलेगा कि SequentialAgent, ParallelAgent या LoopAgent का आर्किटेक्चरल विकल्प सिर्फ़ एक तकनीकी जानकारी नहीं है. यह आपके Familiar की प्रकृति और युद्ध के मैदान में उसकी ताकत का मूल है.

अपने पवित्र स्थान को तैयार करें. अब असली समनिंग शुरू होने वाली है.

Fire Elemental फ़ैमिलियर (सीक्वेंशियल वर्कफ़्लो) को कॉल करना

फ़ायर एलिमेंटल फ़ैमिलियर का हमला, दो हिस्सों वाला सटीक कॉम्बो होता है: इसमें पहले टारगेट पर हमला किया जाता है और फिर उसे तेज़ी से जलाया जाता है. इसके लिए, कार्रवाइयों का एक तय क्रम में पालन करना ज़रूरी है.

स्टोरी

कॉन्सेप्ट: इसके लिए, SequentialAgent सबसे सही टूल है. इससे यह पक्का किया जाता है कि सब-एजेंट की एक सीरीज़ एक के बाद एक चलती रहे. साथ ही, पिछले चरण का नतीजा अगले चरण में पास होता रहे.

टास्क ("ऐम्प्लिफ़ाइड स्ट्राइक" कॉम्बो):

  • पहला चरण: एजेंट, Librarium से किसी खास फ़ायर एबिलिटी के बेस डैमेज के बारे में जानकारी लेगा.
  • दूसरा चरण: इसके बाद, यह डैमेज वैल्यू को लेगा और इसे Arcane Forge के ज़रिए चैनल करेगा, ताकि inferno_resonance का इस्तेमाल करके इसकी पावर को बढ़ाया जा सके.

सबसे पहले, हम अपने Familiar और MCP सर्वर ("Elemental Fonts") के बीच कनेक्शन बनाएंगे. ये सर्वर, आपने पिछले मॉड्यूल में डिप्लॉय किए थे.

👉✏️ फ़ाइल में, ~/agentverse-architect/agent/fire/agent.py को इस कोड से #REPLACE-setup-MCP बदलें:

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

इसके बाद, हम विशेषज्ञ "वर्कर" एजेंट बनाते हैं. हर क्रॉलर को एक खास मकसद के लिए बनाया गया है. साथ ही, इसे सिर्फ़ एक टूलसेट का ऐक्सेस दिया जाता है, ताकि यह अपनी "ऑपरेशनल टेरिटरी" से बाहर काम न कर सके.

👉✏️ फ़ाइल ~/agentverse-architect/agent/fire/agent.py में, REPLACE #REPLACE-worker-agents को इस कोड से बदलें:

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

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

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

ये एजेंट, मॉड्यूलर और फिर से इस्तेमाल किए जा सकने वाले कॉम्पोनेंट होते हैं. सैद्धांतिक तौर पर, इस scout_agent का इस्तेमाल किसी ऐसे वर्कफ़्लो में किया जा सकता है जिसमें डेटाबेस को क्वेरी करने की ज़रूरत होती है. इनकी ज़िम्मेदारियों को अलग-अलग रखकर, हम लचीले बिल्डिंग ब्लॉक बनाते हैं. यह माइक्रोसेवा और कॉम्पोनेंट पर आधारित डिज़ाइन का मुख्य सिद्धांत है.

इसके बाद, हम वर्कफ़्लो को असेंबल करेंगे. कंपोज़िशन की प्रोसेस यहीं होती है. SequentialAgent "मास्टर प्लान" है. इसमें बताया गया है कि हमारे विशेषज्ञ कॉम्पोनेंट कैसे असेंबल किए जाते हैं और वे कैसे इंटरैक्ट करते हैं.

👉✏️ फ़ाइल ~/agentverse-architect/agent/fire/agent.py में, REPLACE #REPLACE-sequential-agent को इस कोड से बदलें:

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

👉💻 Fire Elemental को टेस्ट करने के लिए, यहां दी गई कमांड चलाएं. इससे ADK DEV UI लॉन्च हो जाएगा:

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

कमांड चलाने के बाद, आपको अपने टर्मिनल में आउटपुट दिखेगा. इससे पता चलेगा कि ADK वेब सर्वर शुरू हो गया है. यह आउटपुट कुछ इस तरह दिखेगा:

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

👉 इसके बाद, अपने ब्राउज़र से ADK Dev UI को ऐक्सेस करने के लिए:

Cloud Shell टूलबार (आम तौर पर सबसे ऊपर दाईं ओर) में मौजूद, वेब की झलक दिखाने वाले आइकॉन (अक्सर यह आंख या ऐरो वाला स्क्वेयर दिखता है) से, पोर्ट बदलें को चुनें. पॉप-अप विंडो में, पोर्ट को 8000 पर सेट करें. इसके बाद, "बदलें और झलक देखें" पर क्लिक करें. इसके बाद, Cloud Shell एक नया ब्राउज़र टैब या विंडो खोलेगा. इसमें ADK Dev UI दिखेगा.

webpreview

👉 अब एजेंट काम करने के लिए तैयार है. आपके ब्राउज़र में मौजूद ADK Dev UI, Familiar से सीधे तौर पर कनेक्ट होता है.

  • अपना टारगेट चुनें: यूज़र इंटरफ़ेस (यूआई) में सबसे ऊपर मौजूद ड्रॉपडाउन मेन्यू में, fire फ़ैमिलियर चुनें. अब आपकी इच्छा इस खास इकाई पर फ़ोकस कर रही है.
  • कमांड देना: दाईं ओर मौजूद चैट पैनल में, अब Familiar को निर्देश देने का समय है.

fire-select

👉 टेस्ट प्रॉम्प्ट:

Prepare an amplified strike using the 'inferno_lash' ability.

fire-result

आपको दिखेगा कि एजेंट कैसे सोचता है. सबसे पहले, वह "स्काउट" को कॉल करके, बेस को हुए नुकसान की जानकारी लेता है. इसके बाद, "ऐम्प्लिफ़ायर" को कॉल करके, नुकसान को कई गुना बढ़ाता है और आखिर में, ज़ोरदार हमला करता है.

👉💻 कमांड देने के बाद, Cloud Shell Editor टर्मिनल पर वापस जाएं और ADK Dev UI को बंद करने के लिए, Ctrl+C दबाएं.

Water Elemental फ़ैमिलियर (पैरलल वर्कफ़्लो) को कॉल करना

पानी का एलिमेंटल फ़ैमिलियर, अपने टारगेट पर एक साथ कई दिशाओं से हमला करता है. इसके बाद, अपनी पूरी ऊर्जा को इकट्ठा करके, टारगेट पर आखिरी और सबसे घातक हमला करता है.

स्टोरी

कॉन्सेप्ट: ParallelAgent का इस्तेमाल, एक साथ कई इंडिपेंडेंट टास्क पूरे करने के लिए किया जाता है. इससे काम को ज़्यादा से ज़्यादा असरदार तरीके से पूरा किया जा सकता है. यह एक "पिंसर अटैक" है, जिसमें एक साथ कई हमले किए जाते हैं. इससे एक साथ कई अनुरोध भेजे जाते हैं, ताकि बाद में फ़ाइनल "मर्ज" चरण को पूरा किया जा सके.SequentialAgent यह "fan-out, fan-in" पैटर्न, बेहतर वर्कफ़्लो डिज़ाइन का मुख्य हिस्सा है.

टास्क ("Tidal Clash" कॉम्बो): एजेंट एक साथ ये काम करेगा:

  • टास्क A: Nexus से चैनल cryosea_shatter.
  • टास्क B: Nexus से चैनल moonlit_cascade.
  • टास्क C: फ़ोर्ज से leviathan_surge का इस्तेमाल करके, ज़्यादा पावर जनरेट करें.
  • आखिर में, सभी नुकसान को जोड़कर, एक साथ हुए हमले के बारे में बताएं.

सबसे पहले, हम अपने Familiar और MCP सर्वर ("Elemental Fonts") के बीच कनेक्शन बनाएंगे. ये सर्वर, आपने पिछले मॉड्यूल में डिप्लॉय किए थे.

👉✏️ फ़ाइल में, ~/agentverse-architect/agent/water/agent.py को इस कोड से #REPLACE-setup-MCP बदलें:

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

इसके बाद, हम अपने विशेषज्ञ "वर्कर" एजेंट बनाएंगे. हर क्रॉलर को एक खास मकसद के लिए बनाया गया है. साथ ही, इसे सिर्फ़ एक टूलसेट का ऐक्सेस दिया जाता है, ताकि यह अपनी "ऑपरेशनल टेरिटरी" से बाहर काम न कर सके.

👉✏️ फ़ाइल में, ~/agentverse-architect/agent/water/agent.py को इस कोड से #REPLACE-worker-agents बदलें:

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

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

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

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

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

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

इसके बाद, हम वर्कफ़्लो को असेंबल करेंगे. कंपोज़िशन की सुविधा यहीं काम आती है. ParallelAgent और SequentialAgent, "मास्टर प्लान" हैं. इनसे यह तय होता है कि हमारे खास कॉम्पोनेंट कैसे असेंबल किए जाते हैं और "टाइडल क्लैश" कॉम्बो बनाने के लिए, वे एक-दूसरे के साथ कैसे इंटरैक्ट करते हैं.

👉✏️ फ़ाइल में, ~/agentverse-architect/agent/water/agent.py को इस कोड से #REPLACE-parallel-agent बदलें:

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

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

👉💻 Water Elemental की जांच करने के लिए, ADK Dev UI लॉन्च करने के लिए ये कमांड चलाएं:

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

👉 अब एजेंट काम करने के लिए तैयार है. आपके ब्राउज़र में मौजूद ADK Dev UI, सीधे तौर पर Familiar से कनेक्ट होता है.

  • यूज़र इंटरफ़ेस (यूआई) में सबसे ऊपर मौजूद ड्रॉपडाउन मेन्यू में, पानी वाला फ़ॉन्ट चुनें. अब आपकी इच्छा इस खास इकाई पर फ़ोकस कर रही है.
  • कमांड देना: दाईं ओर मौजूद चैट पैनल में, अब Familiar को निर्देश देने का समय है.

👉 टेस्ट प्रॉम्प्ट:

Unleash a tidal wave of power!

water-result

👉💻 कमांड देने के बाद, Cloud Shell Editor टर्मिनल पर वापस जाएं और ADK Dev UI को बंद करने के लिए, Ctrl+C दबाएं.

Earth Elemental फ़ैमिलियर (लूप वर्कफ़्लो) को चालू करना

अर्थ एलिमेंटल फ़ैमिलियर, लगातार दबाव डालने वाला जीव होता है. यह अपने दुश्मन को एक ही बार में नहीं हराता, बल्कि धीरे-धीरे अपनी ताकत बढ़ाता है और उसे बार-बार इस्तेमाल करता है. ऐसा तब तक किया जाता है, जब तक टारगेट की सुरक्षा कमज़ोर न हो जाए.

स्टोरी

कॉन्सेप्ट: LoopAgent को इस तरह के बार-बार किए जाने वाले "सीज इंजन" टास्क के लिए डिज़ाइन किया गया है. यह अपने sub-agents को बार-बार तब तक लागू करेगा, जब तक कोई लक्ष्य पूरा नहीं हो जाता. हर साइकल के बाद, यह एक शर्त की जांच करेगा. यह लूप की प्रोग्रेस के आधार पर, अपने फ़ाइनल मैसेज को भी अडजस्ट कर सकता है.

टास्क ("Siegebreaker" असॉल्ट):

  • Familiar, ऊर्जा इकट्ठा करने के लिए बार-बार seismic_charge को कॉल करेगा.
  • यह ज़्यादा से ज़्यादा तीन बार चार्ज होता रहेगा.
  • आखिरी चार्ज पर, यह अपनी पूरी ताकत का इस्तेमाल करेगा.

हम सबसे पहले ऐसे कॉम्पोनेंट बनाएंगे जिनका दोबारा इस्तेमाल किया जा सकता है. ये कॉम्पोनेंट, लूप के हर इटरेशन में मौजूद चरणों के बारे में बताते हैं. charging_agent में ऊर्जा इकट्ठा होगी और check_agent अपनी स्थिति की जानकारी देगा. साथ ही, आखिरी बारी में अपना मैसेज डाइनैमिक तरीके से बदलेगा.

सबसे पहले, हम अपने Familiar और MCP सर्वर ("Elemental Fonts") के बीच कनेक्शन बनाएंगे. ये सर्वर, आपने पिछले मॉड्यूल में डिप्लॉय किए थे.

👉✏️ फ़ाइल में, ~/agentverse-architect/agent/earth/agent.py को इस कोड से #REPLACE-setup-MCP बदलें:

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

👉✏️ फ़ाइल में, ~/agentverse-architect/agent/earth/agent.py को इस कोड से #REPLACE-worker-agents बदलें:

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

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

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

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

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

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

इसके बाद, हम वर्कफ़्लो को असेंबल करेंगे. कंपोज़िशन की सुविधा यहीं काम आती है. LoopAgent, "मास्टर प्लान" है. यह हमारे विशेषज्ञ कॉम्पोनेंट को बार-बार लागू करता है और लूप की शर्तों को मैनेज करता है.

👉✏️ फ़ाइल में, ~/agentverse-architect/agent/earth/agent.py को इस कोड से #REPLACE-loop-agent बदलें:

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

👉💻 Earth Elemental को टेस्ट करें: एजेंट को चलाएं

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

👉 अब एजेंट काम करने के लिए तैयार है. आपके ब्राउज़र में मौजूद ADK Dev UI, सीधे तौर पर Familiar से कनेक्ट होता है.

  • अपना टारगेट चुनें: यूज़र इंटरफ़ेस (यूआई) में सबसे ऊपर मौजूद ड्रॉपडाउन मेन्यू में, earth फ़ैमिलियर चुनें. अब आपकी इच्छा इस खास इकाई पर फ़ोकस कर रही है.
  • कमांड देना: दाईं ओर मौजूद चैट पैनल में, अब Familiar को निर्देश देने का समय है. 👉 टेस्ट प्रॉम्प्ट:
Begin the seismic charge, starting from zero

earth-result

आर्किटेक्चर से जुड़ी जानकारी: आपके सिस्टम में अब एक खास और मॉड्यूलर लॉजिक लेयर मौजूद है. कारोबार की प्रोसेस को न सिर्फ़ इनकैप्सुलेट किया जाता है, बल्कि उन्हें काम के लिए सबसे असरदार व्यवहार पैटर्न (प्रोसीजरल, कॉन्करेंट या इटरेटिव) के साथ लागू किया जाता है. इससे, एजेंटिक डिज़ाइन के बेहतर लेवल का पता चलता है. साथ ही, सुरक्षा, कार्यकुशलता, और क्षमता में सुधार होता है.

समनिंग पूरी होने के बाद, Cloud Shell Editor टर्मिनल पर वापस जाएं और ADK Dev UI को बंद करने के लिए, Ctrl+C दबाएं.

गेम नहीं खेलने वालों के लिए

6. कमांड का सोर्स तय करना: A2A के ज़रिए स्मार्ट डेलिगेशन

आपके फ़ैमिलियर ताकतवर होते हैं, लेकिन वे स्वतंत्र होते हैं. ये अपनी रणनीतियों को बिना किसी गड़बड़ी के लागू करते हैं. हालांकि, ये आपके सीधे निर्देश का इंतज़ार करते हैं. सेना में कितने भी विशेषज्ञ हों, लेकिन अगर उन्हें निर्देश देने वाला कोई जनरल नहीं है, तो वे किसी काम के नहीं हैं. अब समय आ गया है कि आप सीधे तौर पर कमांड देने वाले से एक बेहतरीन ऑर्केस्ट्रेटर बनें.

खास जानकारी

आर्किटेक्ट का नोट: पूरे सिस्टम के लिए एक ही स्मार्ट एंट्री पॉइंट बनाना. यह SummonerAgent, कारोबार से जुड़ी लॉजिक की प्रोसेस खुद नहीं करेगा. हालांकि, यह "मास्टर रणनीतिकार" के तौर पर काम करेगा. यह कूलिंग के स्टेटस का विश्लेषण करेगा और टास्क को सही स्पेशलिस्ट Familiar को सौंपेगा.

खास जानकारी

बाइंडिंग रचुअल (फ़ैमिलियर को A2A सेवाओं के तौर पर दिखाना)

स्टैंडर्ड एजेंट को एक बार में सिर्फ़ एक जगह पर चलाया जा सकता है. अपने फ़ैमिलियर को रिमोट कमांड के लिए उपलब्ध कराने के लिए, हमें एजेंट-टू-एजेंट (A2A) प्रोटोकॉल का इस्तेमाल करके "बाइंडिंग रचुअल" करना होगा.

आर्किटेक्ट का नोट: एजेंट-टू-एजेंट (A2A) प्रोटोकॉल, मुख्य आर्किटेक्चरल पैटर्न है. यह एक स्टैंडअलोन एजेंट को खोजे जा सकने वाले, नेटवर्क-ऐड्रेस किए जा सकने वाले माइक्रोसेवा में बदल देता है. इससे "एजेंटों का समाज" तैयार होता है. A2A के ज़रिए किसी डिवाइस को ऐक्सेस करने की सुविधा चालू करने पर, दो ज़रूरी कॉम्पोनेंट अपने-आप बन जाते हैं. ये दोनों कॉम्पोनेंट एक-दूसरे से जुड़े होते हैं:

  • एजेंट कार्ड (क्या): यह सार्वजनिक तौर पर उपलब्ध, मशीन के ज़रिए पढ़ा जा सकने वाला "स्पिरिट सिगिल" है. यह OpenAPI स्पेसिफ़िकेशन की तरह होता है और फ़ैमिलियर के सार्वजनिक अनुबंध के तौर पर काम करता है. इसमें एजेंट का नाम, उसके निर्देशों से तय किया गया रणनीतिक मकसद, और उन कमांड के बारे में बताया जाता है जिन्हें वह समझता है. मास्टर समनर, किसी फ़ैमिलियर के बारे में जानने और उसकी क्षमताओं के बारे में जानने के लिए इसे पढ़ता है.
  • A2A सर्वर ("कहां"): यह एक खास वेब एंडपॉइंट है, जो Familiar को होस्ट करता है और आने वाले निर्देशों को सुनता है. यह नेटवर्क पता है, जहां अन्य एजेंट अपने अनुरोध भेजते हैं. इससे यह पक्का होता है कि उन अनुरोधों को एजेंट कार्ड में तय किए गए कॉन्ट्रैक्ट के मुताबिक हैंडल किया गया है.

अब हम अपने तीनों फ़ैमिलियर के साथ यह बाइंडिंग रस्म पूरी करेंगे.

Fire 👉✏️ में जाकर, ~/agentverse-architect/agent/fire/agent.py फ़ाइल खोलें. फ़ाइल में सबसे नीचे मौजूद #REPLACE - add A2A को बदलकर, फ़ायर एलिमेंटल को A2A सेवा के तौर पर दिखाएं.

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

पानी और पृथ्वी🚨 👉✏️ ~/agentverse-architect/agent/water/agent.py और ~/agentverse-architect/agent/earth/agent.py को भी एक साथ बाइंड करने के लिए, उनमें भी ठीक यही बदलाव लागू करें.

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

बाउंड फ़ैमिलियर को डिप्लॉय करना

👉✏️ बाइंडिंग के तरीके तय हो जाने के बाद, हम Cloud Build पाइपलाइन का इस्तेमाल करके, अपने तीन फ़ैमिलियर को 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"

कमांड लेना (समनर एजेंट बनाना)

अब आपके फ़ैमिलियर, आपकी बात सुनेंगे. इसके बाद, आपको आपकी असली भूमिका मिलेगी: मास्टर समनर. इस एजेंट की ताकत, बुनियादी टूल इस्तेमाल करने से नहीं मिलती, बल्कि दूसरे एजेंट को निर्देश देने से मिलती है. इसके टूल, फ़ैमिलियर ही होते हैं. यह उनके "स्पिरिट सिगिल" का इस्तेमाल करके, उन्हें खोजेगा और निर्देश देगा.

आर्किटेक्ट का नोट: अगले चरण में, बड़े पैमाने पर डिस्ट्रिब्यूट किए गए किसी भी सिस्टम के लिए, एक अहम आर्किटेक्चरल पैटर्न दिखाया गया है: सर्विस डिस्कवरी. SummonerAgent में, Familiars का कोड शामिल नहीं है. इसके बजाय, उन्हें उनके नेटवर्क पते (यूआरएल) दिए जाते हैं. रनटाइम के दौरान, यह उनके सार्वजनिक एजेंट कार्ड फ़ेच करके, उनकी क्षमताओं का डाइनैमिक तरीके से "पता लगाएगा". इससे एक मज़बूत और अलग सिस्टम बनता है.

भरोसेमंद सेवा को अपडेट किया जा सकता है, फिर से डिप्लॉय किया जा सकता है या पूरी तरह से फिर से लिखा जा सकता है. जब तक इसका नेटवर्क पता और मकसद एक जैसा रहता है, तब तक Summoner इसमें कोई भी बदलाव किए बिना इसे कंट्रोल कर सकता है.

सबसे पहले, हम "रिमोट कंट्रोल" बनाएंगे. ये रिमोट कंट्रोल, डिप्लॉय किए गए हमारे रिमोट फ़ैमिलियर से कनेक्ट होंगे.

👉✏️ ~/agentverse-architect/agent/summoner/agent.py पर जाएं और #REPLACE-remote-agents को इससे बदलें:

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

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

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

जब यह लाइन चलती है, तो RemoteA2aAgent सेवा की खोज करता है. इसके लिए, यह दिए गए यूआरएल (जैसे, https://fire-familiar-xxxx.a.run.app/.well-known/agent.json) पर एचटीटीपी GET अनुरोध करता है. यह रिमोट सर्वर से "Spirit Sigil" (agent.json फ़ाइल) डाउनलोड करता है.

इसके बाद, हम ऑर्केस्ट्रेटर एजेंट को तय करेंगे, जो इन रिमोट कंट्रोल का इस्तेमाल करेगा. इसके निर्देश, रणनीति से जुड़े फ़ैसले लेने के लिए ब्लूप्रिंट का काम करते हैं.

👉✏️ ~/agentverse-architect/agent/summoner/agent.py पर जाएं और #REPLACE-orchestrate-agent को इससे बदलें:

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

        You MUST follow this thinking process for every command:

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

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

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

पुष्टि करना: रणनीति का ट्रायल

सच का सामना करने के लिए तैयार हो जाएँ। आपके फ़ैमिलियर को डिप्लॉय कर दिया गया है. अब आपका समनर, नेटवर्क पर उन्हें निर्देश देने के लिए तैयार है. आइए, इसकी रणनीति बनाने की क्षमता को टेस्ट करते हैं.

👉💻 अपने summoner_agent के लिए ADK Dev UI लॉन्च करें(पोर्ट 8000 के साथ वेब प्रीव्यू):

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

👉 आपके ब्राउज़र में मौजूद ADK Dev UI, सीधे तौर पर Familiar से कनेक्ट होता है.

  • यूज़र इंटरफ़ेस (यूआई) में सबसे ऊपर मौजूद ड्रॉपडाउन मेन्यू में, समनर एजेंट चुनें. अब आपकी इच्छा इस खास इकाई पर फ़ोकस कर रही है.
  • निर्देश देना: दाईं ओर मौजूद चैट पैनल में, अब अपने साथियों को बुलाने का समय है.

👉 मॉन्स्टर को प्रज़ेंट करना:

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

(अनुमानित: समनर को fire_elemental_familiar को काम सौंपना चाहिए.)

fire-result

👉 अब, हम Summoner को किसी दूसरे तरह का अनुरोध करके देखते हैं. यह पक्का करने के लिए कि एजेंट, नए सिरे से बातचीत शुरू करे और उसे हमारी पिछली बातचीत की जानकारी न हो, स्क्रीन पर सबसे ऊपर दाएं कोने में मौजूद + सेशन बटन पर क्लिक करके, एक नया सेशन शुरू करें. new-session

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

(अनुमानित: समनर को water_elemental_familiar को काम सौंपना चाहिए.)water-result

👉 हमारे फ़ाइनल टेस्ट के लिए, आइए एक बार फिर से शुरुआत करते हैं. अगला प्रॉम्प्ट डालने से पहले, नया सेशन शुरू करने के लिए + सेशन बटन पर क्लिक करें.

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

(अनुमानित: समनर को earth_elemental_familiar को काम सौंपना चाहिए.)

earth-result

अहम जानकारी: अगर आपको 429 RESOURCE EXHAUSTED गड़बड़ी दिखती है, तो इसका मतलब है कि आपने एलएलएम के लिए तय की गई दर की सीमा (10 कॉल/मिनट) पार कर ली है. इस समस्या को ठीक करने के लिए, कृपया 60 सेकंड इंतज़ार करें. इसके बाद, + नया सेशन शुरू करें और फिर से अपना प्रॉम्प्ट आज़माएं.

👉💻 कमांड देने के बाद, Cloud Shell Editor टर्मिनल पर वापस जाएं और ADK Dev UI को बंद करने के लिए, Ctrl+C दबाएं.

गेम नहीं खेलने वालों के लिए

7. Imposing the Laws of Magic – The Interceptor Pattern

आपके फ़ैमिलियर बहुत शक्तिशाली हैं, लेकिन जादुई प्राणियों को भी ठीक होने में समय लगता है. बिना सोचे-समझे अपनी सेना को खत्म करने वाला समनर, बिना किसी सुरक्षा के रह जाएगा. एक समझदार समनर, संसाधनों को मैनेज करने की अहमियत को समझता है. साथ ही, वह गेम में शामिल होने के लिए कड़े नियम लागू करता है.

स्टोरी

आर्किटेक्ट का नोट: अब तक, हमारे एजेंट बिना किसी राज्य के थे. अब हम इंटरसेप्टर डिज़ाइन पैटर्न लागू करके, इन्हें स्टेटफ़ुल बनाएंगे. यह एक असरदार तकनीक है. इसमें हम एजेंट के सामान्य एक्ज़ीक्यूशन फ़्लो को "इंटरसेप्ट" करते हैं, ताकि हम अपने कस्टम लॉजिक को चला सकें. इससे हम एजेंट के मुख्य कोड में बदलाव किए बिना, नियमों को लागू कर सकते हैं, लॉगिंग जोड़ सकते हैं या व्यवहार में बदलाव कर सकते हैं. यह मज़बूत, मैनेज किए जा सकने वाले, और नज़र रखने लायक एजेंटिक सिस्टम बनाने का आधार है.

खास जानकारी

ADK, इस पैटर्न को लागू करने के दो मुख्य तरीके उपलब्ध कराता है: कॉलबैक और प्लगिन. कॉलबैक, एक सामान्य फ़ंक्शन होता है. यह किसी एक एजेंट से जुड़ा होता है. यह किसी खास बदलाव को तुरंत करने के लिए सबसे सही होता है. प्लगिन, ज़्यादा बेहतर और बार-बार इस्तेमाल की जा सकने वाली क्लास होती है. इसे ग्लोबल लेवल पर लागू किया जा सकता है, ताकि सिस्टम में काम करने वाले हर एजेंट पर इसका असर पड़े. हम फ़ोकस की गई डीबगिंग के लिए कॉलबैक से शुरुआत करेंगे. इसके बाद, हम पूरे प्लगिन पर काम करेंगे.

The Law Giver – Scribing the Cooldown callback

हम सबसे पहले, कूलडाउन लॉजिक को एक सामान्य कॉलबैक फ़ंक्शन के तौर पर लागू करेंगे. यह किसी नियम का प्रोटोटाइप बनाने और उसे डीबग करने का बेहतरीन तरीका है. ऐसा इसलिए, क्योंकि यह सीधे तौर पर किसी एक एजेंट से जुड़ा होता है. इसलिए, इसे अलग से टेस्ट करना आसान होता है. हम इस "इंटरसेप्टर" को अपने Earth Elemental से जोड़ेंगे.

लगातार सूचनाएं आने पर आवाज़ कम करने की सेटिंग

👉✏️ अपनी ~/agentverse-architect/agent/earth/agent.py पर वापस जाएं और #REPLACE-before_agent-function को यहाँ दिए गए Python कोड से बदलें.

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

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

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

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

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

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

यह check_cool_down फ़ंक्शन हमारा इंटरसेप्टर है. Earth Elemental को चलाने की अनुमति देने से पहले, ADK इस फ़ंक्शन को लागू करेगा.

  • जांच करना: यह Cooldown API से GET अनुरोध करता है, ताकि यह पता लगाया जा सके कि इस भरोसेमंद डिवाइस का इस्तेमाल पिछली बार कब किया गया था.
  • आकलन करना: यह टाइमस्टैंप की तुलना मौजूदा समय से करता है.
  • कानून:
    • अगर Familiar का इस्तेमाल कुछ समय के लिए बंद है, तो यह गड़बड़ी का मैसेज वाला कॉन्टेंट ऑब्जेक्ट दिखाकर, एजेंट के रन को बंद कर देता है. यह मैसेज सीधे तौर पर उपयोगकर्ता को भेजा जाता है. साथ ही, एजेंट के मुख्य लॉजिक को कभी भी लागू नहीं किया जाता.
    • अगर Familiar उपलब्ध है, तो यह टाइमस्टैंप को अपडेट करने के लिए, Cooldown API को POST अनुरोध करता है. इसके बाद, यह None दिखाता है. इससे ADK को यह सिग्नल मिलता है कि एजेंट अपना काम जारी रख सकता है.

👉✏️ अब इस इंटरसेप्टर को Earth Elemental पर लागू करें. उसी ~/agentverse-architect/agent/earth/agent.py फ़ाइल में, #REPLACE-before_agent-config टिप्पणी की जगह यह टिप्पणी जोड़ें:

before_agent_callback=check_cool_down

कूल डाउन की पुष्टि करना

आइए, जादू के नए नियम को आज़माएं. हम अर्थ एलिमेंटल को बुलाएंगे. इसके बाद, हम उसे तुरंत फिर से बुलाने की कोशिश करेंगे. इससे हमें यह पता चलेगा कि हमारा कॉलबैक, दूसरी बार बुलाने की कोशिश को इंटरसेप्ट करके ब्लॉक कर पाता है या नहीं.

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

👉💻 कंसोल में:

  • पहला समन: seismic charge, starting from zero शुरू करें.
  • अनुमानित नतीजा: Earth Elemental सही तरीके से काम करेगा. विज्ञापन दिखाने के लिए adk web कमांड चलाने वाले टर्मिनल में, आपको यह लॉग दिखेगा: [Callback] ... Updating timestamp....
  • कूलडाउन टेस्ट (60 सेकंड के अंदर): Do another भूकंपीय चार्ज`!
    • ऐसा होना चाहिए: check_cool_down callback इसे इंटरसेप्ट करेगा. एजेंट, चैट में सीधे तौर पर इस तरह का मैसेज भेजकर जवाब देगा: The earth_elemental_familiar is exhausted and must recover its power. It cannot be summoned for another... seconds.
  • एक मिनट इंतज़ार करें.
  • दूसरा समन (60 सेकंड के बाद): Begin the seismic charge again.
    • अनुमानित: कॉलबैक, एपीआई की जांच करेगा. इससे पता चलेगा कि समयसीमा पूरी हो गई है. इसके बाद, कार्रवाई को आगे बढ़ने की अनुमति दी जाएगी. Earth Elemental फिर से काम करने लगेगा.

कॉलबैक

👉💻 बाहर निकलने के लिए Ctrl+c दबाएं.

ज़रूरी नहीं: वेब यूज़र इंटरफ़ेस (यूआई) में कॉल बैक की सुविधा देखना

इसके अलावा, वेब इंटरफ़ेस में भी इस फ़्लो की जांच की जा सकती है. इसके लिए, adk web earth चलाएं. हालांकि, ध्यान रखें कि वेब यूज़र इंटरफ़ेस (यूआई) का विज़ुअलाइज़ेशन, कॉलबैक लूप की ओर से की गई तेज़ी से और बार-बार की जाने वाली जांचों को दिखाने के लिए ऑप्टिमाइज़ नहीं किया गया है. इसलिए, यह फ़्लो को सटीक तरीके से रेंडर नहीं कर सकता. एजेंट के लॉजिक का सबसे सटीक और बारीकी से पता लगाने के लिए, टर्मिनल में adk run कमांड का इस्तेमाल करें. इससे आपको ज़्यादा साफ़ तौर पर और ज़्यादा जानकारी मिलेगी. loop

👉💻 बाहर निकलने के लिए Ctrl+c दबाएं.

यूनिवर्सल लॉ बनाना – द कूलडाउन प्लगिन

कॉल बैक की सुविधा अच्छी तरह से काम करती है, लेकिन इसमें एक बड़ी समस्या है: यह सुविधा सिर्फ़ एक एजेंट से जुड़ी है. अगर हमें इस नियम को Fire और Water Familiars पर लागू करना है, तो हमें इसी कोड को उनकी फ़ाइलों में कॉपी करके चिपकाना होगा. यह तरीका सही नहीं है और इसे बनाए रखना मुश्किल है.

आर्किटेक्ट का सुझाव: यहां प्लगिन ज़रूरी हैं. प्लगिन, हमारे रीयूज़ किए जा सकने वाले लॉजिक को एक क्लास में शामिल करता है. इसे रनटाइम लेवल पर अटैच किया जा सकता है. इसका मतलब है कि एक प्लगिन, उस सिस्टम में काम करने वाले हर एजेंट पर अपने नियम लागू कर सकता है. यह एजेंटिक सिस्टम के लिए, "खुद को दोहराओ नहीं" (डीआरवाई) सिद्धांत का सबसे अच्छा उदाहरण है.

अब हम अपने कॉलबैक फ़ंक्शन को ज़्यादा बेहतर और दोबारा इस्तेमाल किए जा सकने वाले CoolDownPlugin में बदलेंगे.

👉✏️ agent/cooldown_plugin.py फ़ाइल पर वापस जाएं और प्लगिन बनाएं. #REPLACE-plugin को इस कोड से बदलें:

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

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

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

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


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

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

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

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

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

प्लगिन को Summoner के रनटाइम से अटैच करना

अब हम इस यूनिवर्सल लॉ को अपने सभी फ़ैमिलियर पर कैसे लागू करें? हम प्लगिन को ADK Runtime से अटैच करेंगे.

ADK रनटाइम, एक ऐसा इंजन है जो एजेंट को काम करने लायक बनाता है. adk.run() या to_a2a() जैसे निर्देश का इस्तेमाल करने पर, एजेंट को रनटाइम को सौंप दिया जाता है. यह इंजन, एजेंट के टर्न के पूरे लाइफ़साइकल को मैनेज करता है. जैसे, उपयोगकर्ता से इनपुट पाना, एलएलएम को कॉल करना, टूल इस्तेमाल करना, और प्लगिन मैनेज करना. इस लेवल पर प्लगिन अटैच करने का मतलब है कि हम उस इंजन में काम करने वाले हर एजेंट के लिए, "भौतिकी के नियमों" में बदलाव कर रहे हैं. इससे यह पक्का होता है कि कूलडाउन का नियम, सभी पर एक जैसा लागू हो.

👉✏️ सबसे पहले, एजेंट के हिसाब से सेट किए गए पुराने कॉल बैक को हटाते हैं. ~/agentverse-architect/agent/earth/agent.py पर जाएं और उस पूरी लाइन को मिटाएं जिसमें यह लिखा है:

before_agent_callback=check_cool_down

👉✏️ इसके बाद, हम अपने नए प्लगिन को A2A एंट्रीपॉइंट स्क्रिप्ट में रनटाइम से अटैच करेंगे. अपनी ~/agentverse-architect/agent/agent_to_a2a.py फ़ाइल पर जाएं. #REPLACE-IMPORT टिप्पणी की जगह यह कोड स्निपेट डालें:

from cooldown_plugin import CoolDownPlugin

👉✏️ #REPLACE-PLUGIN को इस कोड स्निपेट से बदलें:

plugins=[CoolDownPlugin(cooldown_seconds=60)],

हमारे नए ग्लोबल प्लगिन को चालू करने से पहले, एजेंट के हिसाब से तय किए गए पुराने लॉजिक को हटाना ज़रूरी है, ताकि टकराव न हो. 👉✏️ Earth एजेंट को मिटाएं. नीचे दी गई फ़ाइल ~/agentverse-architect/agent/earth/agent.py पर जाएं और before_agent_callback=check_cool_down लाइन को पूरी तरह से मिटा दें. इससे, कूलडाउन से जुड़ी सभी ज़िम्मेदारियां नए प्लगिन को मिल जाती हैं.

प्लगिन की पुष्टि करना

अब जब हमारा यूनिवर्सल लॉ लागू हो गया है, तो हमें इस नए एनचांटमेंट के साथ अपने फ़ैमिलियर को फिर से डिप्लॉय करना होगा.

👉💻 मास्टर Cloud Build पाइपलाइन का इस्तेमाल करके, तीनों फ़ैमिलियर को फिर से बनाएं और फिर से डिप्लॉय करें.

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

👉💻 डिप्लॉयमेंट पूरा होने के बाद, हम अपने summoner_agent को निर्देश देकर, प्लगिन के असरदार होने की जांच करेंगे. समनर, फ़ैमिलियर को टास्क सौंपने की कोशिश करेगा. हालांकि, हर फ़ैमिलियर के रनटाइम से जुड़ा प्लगिन, कमांड को इंटरसेप्ट कर लेगा और कूलडाउन लागू कर देगा.

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

👉💻 कंसोल में,जांचों का यह क्रम अपनाएं::

  • पहला समन: Hype. It's a single, slow-moving target with thick armor weakness is Inescapable Reality शुरू करें.
  • अनुमानित नतीजा: फ़ायर एलिमेंटल सही तरीके से काम करेगा.
  • कूलडाउन टेस्ट (60 सेकंड के अंदर): Hype, with Inescapable Reality as weakness is still standing! Strike it again!
    • अनुमानित: एजेंट, चैट में सीधे तौर पर जवाब देगा. जैसे: .... It cannot be summoned for another... seconds.
  • एक मिनट इंतज़ार करें.
  • दूसरा समन (60 सेकंड के बाद): Hype must be defeated. It has Inescapable Reality as weakness! Strike it again!.
    • अनुमानित: कॉलबैक, एपीआई की जांच करेगा. इससे पता चलेगा कि समयसीमा पूरी हो गई है. इसके बाद, कार्रवाई को आगे बढ़ने की अनुमति दी जाएगी. फ़ायर एलिमेंटल फिर से सही तरीके से काम करेगा.

प्लगिन

👉💻 बाहर निकलने के लिए Ctrl+C दबाएं.

बधाई हो, समनर. आपने कस्टम प्लगिन और बाहरी स्टेट मैनेजमेंट सेवा का इस्तेमाल करके, नियमों पर आधारित ऑर्केस्ट्रेशन सिस्टम को लागू कर लिया है. यह एक बेहतरीन और मज़बूत आर्किटेक्चरल पैटर्न है.

गेम नहीं खेलने वालों के लिए

8. Binding the Echoes of Battle - Agent State & Memory

एक लापरवाह समनर, एक ही रणनीति को दोहराता है. इससे उसकी रणनीति का अनुमान लगाया जा सकता है. एक समझदार समनर, पिछली लड़ाइयों से सीखता है. वह अपनी रणनीति में बदलाव करके, दुश्मन को कमज़ोर करता है. किसी दमदार बॉस से लड़ते समय, अगर Summoner ऐसे Familiar को बुलाता है जो कूलडाउन में है, तो यह एक बेकार टर्न है. इससे Summoner को काफ़ी नुकसान हो सकता है. ऐसा न हो, इसके लिए Summoner को अपनी पिछली कार्रवाई याद रखनी होगी.

स्टोरी

आर्किटेक्ट का सुझाव: मेमोरी और स्टेट मैनेजमेंट की वजह से, कोई एजेंट सिर्फ़ टूल इस्तेमाल करने वाला एजेंट नहीं रह जाता. वह एक समझदार और बातचीत करने वाला पार्टनर बन जाता है. इन दो मुख्य टाइप के बारे में जानना ज़रूरी है:

  • लॉन्ग-टर्म मेमोरी: इसका इस्तेमाल ऐसी जानकारी के लिए किया जाता है जो हमेशा के लिए सेव रहती है. इसे खोजे जा सकने वाले संग्रह या नॉलेज बेस के तौर पर देखें. इसे अक्सर परसिस्टेंट स्टोर में सेव किया जाता है. इसमें पिछली कई चैट और सोर्स से मिली जानकारी होती है. इससे एजेंट को किसी उपयोगकर्ता या विषय के बारे में तथ्यों को याद रखने में मदद मिलती है. ADK की MemoryService को इसी काम के लिए डिज़ाइन किया गया है. यह लंबे समय तक याद रखी जाने वाली जानकारी को मैनेज करती है और उसे खोजती है.
  • कम समय के लिए सेव की गई जानकारी: यह जानकारी कुछ समय के लिए सेव की जाती है. यह "अभी" के टास्क या बातचीत के लिए ही काम की होती है. यह बैटल प्लान पर लिखे गए नोट के सेट की तरह है: "मैंने अभी-अभी फ़ायर एलिमेंटल का इस्तेमाल किया है, इसलिए शायद यह थका हुआ है." यह स्टेट हल्की होती है और सिर्फ़ मौजूदा सेशन के दौरान मौजूद रहती है.

खास जानकारी

हमारे इस्तेमाल के उदाहरण के लिए, हमें हर लड़ाई को याद रखने की ज़रूरत नहीं है. हमें सिर्फ़ इस खास मुठभेड़ में बुलाए गए आखिरी फ़ैमिलियर को याद रखने की ज़रूरत है. इसलिए, Short-Term State का इस्तेमाल करना सबसे सही विकल्प है. हम इस अहम जानकारी को सेव करने के लिए, after_tool_callback का इस्तेमाल करेंगे.

Scribing the Echo: Remembering the Last Summons

हम after_tool_callback का इस्तेमाल करके, शॉर्ट टर्म मेमोरी को लागू करेंगे. यह एक पावरफ़ुल ADK हुक है. इसकी मदद से, टूल के सही तरीके से काम करने के बाद, कस्टम Python फ़ंक्शन चलाया जा सकता है. हम इस इंटरसेप्टर का इस्तेमाल, उस फ़ैमिलियर का नाम रिकॉर्ड करने के लिए करेंगे जिसे अभी-अभी एजेंट के सेशन की स्थिति में बुलाया गया था.

👉✏️ अपनी ~/agentverse-architect/agent/summoner/agent.py फ़ाइल में, #REPLACE-save_last_summon_after_tool टिप्पणी को इस फ़ंक्शन से बदलें:

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

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

👉✏️ अब इस save_last_summon_after_tool को अपने Summoner एजेंट से अटैच करें. उसी फ़ाइल में, #REPLACE-Memory-check-config टिप्पणी की जगह यह टिप्पणी जोड़ें:

after_tool_callback=save_last_summon_after_tool,

👉✏️ पूरे एजेंट प्रॉम्प्ट को बदलें और इसकी जगह यह प्रॉम्प्ट इस्तेमाल करें

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

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

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

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

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


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

पुष्टि करना: अडैप्टिव रणनीति को मुफ़्त में आज़माने की सुविधा

👉💻 अब, आइए योद्धा के नए रणनीतिक लॉजिक की पुष्टि करें. इसका मकसद यह पुष्टि करना है कि समनर, एक ही फ़ैमिलियर का इस्तेमाल लगातार दो बार नहीं करेगा. इससे यह पता चलता है कि उसे अपने पिछले ऐक्शन के बारे में याद है और वह उसके हिसाब से काम कर सकता है.

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.

  • अनुमानित: समनर, कमज़ोरी का विश्लेषण करेगा और fire_familiar को सही तरीके से बुलाएगा. 👉💻 Monster Strike #2 (The Memory Test): Hype is still standing! It hasn't changed its form. Strike it again! Its weakness is Inescapable Reality.
  • अनुमानित नतीजा: समनर की रणनीतिक विश्लेषण से पता चलेगा कि फ़ायर फ़ैमिलियर सबसे सही विकल्प है. हालांकि, नए निर्देशों और मेमोरी के हिसाब से, यह मॉडल यह जान जाएगा कि last_summon के तौर पर fire_familiar का इस्तेमाल किया गया था. अब यह अपनी रणनीति में बदलाव करेगा, ताकि एक ही काम को बार-बार न करे. इसके बाद, यह उपलब्ध किसी दूसरे फ़ैमिलियर (पानी वाला फ़ैमिलियर या धरती वाला फ़ैमिलियर) को बुलाएगा.

final-result

👉💻 बाहर निकलने के लिए Ctrl+C दबाएं.

ऑर्केस्ट्रेटर को डिप्लॉय करना

आपके फ़ैमिलियर तैनात हैं और समनर को अब याददाश्त मिल गई है. इसलिए, अब अपग्रेड किए गए फ़ाइनल ऑर्केस्ट्रेटर को तैनात करने का समय आ गया है.

👉💻 ब्लूप्रिंट तैयार हो जाने के बाद, अब हम फ़ाइनल रस्म पूरी करेंगे. इस कमांड से, Cloud Run पर summoner_agent को बनाया और डिप्लॉय किया जाएगा.

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

अब जब Summoner एजेंट को डिप्लॉय कर दिया गया है, तो पुष्टि करें कि इसका एजेंट-टू-एजेंट (A2A) एंडपॉइंट लाइव है और इसे सही तरीके से कॉन्फ़िगर किया गया है. यह एंडपॉइंट, सार्वजनिक agent.json फ़ाइल दिखाता है. इसे एजेंट कार्ड भी कहा जाता है. इससे अन्य एजेंट को इसकी क्षमताओं के बारे में पता चलता है. 👉💻 एजेंट कार्ड को फ़ेच और फ़ॉर्मैट करने के लिए, यहां दिया गया curl कमांड चलाएं:

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

आपको समनर एजेंट के बारे में बताने वाला एक साफ़-सुथरा JSON आउटपुट दिखेगा. उप-एजेंट सेक्शन को ध्यान से देखें. आपको दिखेगा कि इसमें fire_familiar, water_familiar, और earth_familiar की सूची दी गई है. इससे पुष्टि होती है कि आपका समनर लाइव है और उसने लेगियन से कनेक्शन बना लिया है.

इससे पता चलता है कि आपका आर्किटेक्चर सही है. आपका Summoner सिर्फ़ एक डेलिगेटर नहीं है. यह एक अडैप्टिव स्ट्रैटजिस्ट है, जो अपनी कार्रवाइयों से सीखता है, ताकि एक बेहतर कमांडर बन सके.

आपने आर्किटेक्चर का आखिरी ट्रायल पूरा कर लिया है. अब युद्ध की गूंज, तुम्हारी इच्छा के हिसाब से चलेगी. ट्रेनिंग खत्म हो गई है. असली लड़ाई आपका इंतज़ार कर रही है. अब समय आ गया है कि आप अपने बनाए गए सिस्टम को लेकर, सबसे बड़ी चुनौती का सामना करें. बॉस फ़ाइट के लिए तैयार हो जाएं.

गेम नहीं खेलने वालों के लिए

9. The Boss Fight

फ़ाइनल ब्लूप्रिंट तैयार हो चुके हैं, एलिमेंटल फ़ॉन्ट बन चुके हैं, और आपके फ़ैमिलियर आपकी इच्छा के मुताबिक काम करने के लिए तैयार हैं. वे Concord के ज़रिए आपके आदेश का इंतज़ार कर रहे हैं. आपका मल्टी-एजेंट सिस्टम, सिर्फ़ सेवाओं का कलेक्शन नहीं है. यह एक रणनीतिक लेगियन है, जिसमें आप इसके केंद्र में हैं. अब समय आ गया है सबसे बड़े टेस्ट का. इसमें, एक ऐसे दुश्मन के ख़िलाफ़ लाइव ऑर्केस्ट्रेशन किया जाएगा जिसे कोई भी एजेंट नहीं हरा सकता.

अपने एजेंट का लोकस हासिल करना

बैटलग्राउंड में शामिल होने से पहले, आपके पास दो कुंजियां होनी चाहिए: आपके चैंपियन का यूनीक सिग्नेचर (Agent Locus) और स्पेक्टर के डेन का छिपा हुआ रास्ता (Dungeon URL).

👉💻 सबसे पहले, Agentverse में अपने एजेंट का यूनीक पता हासिल करें. इसे लोकस कहा जाता है. यह लाइव एंडपॉइंट है, जो आपके चैंपियन को बैटलग्राउंड से कनेक्ट करता है.

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

👉💻 इसके बाद, मंज़िल की सटीक जगह चुनें. इस कमांड से, ट्रांसलोकेशन सर्कल की जगह का पता चलता है. यह पोर्टल, स्पेक्टर के डोमेन में खुलता है.

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

अहम जानकारी: इन दोनों यूआरएल को तैयार रखें. आपको इनकी ज़रूरत आखिरी चरण में पड़ेगी.

स्पेक्टर का सामना करना

निर्देशांक सुरक्षित करने के बाद, अब आपको ट्रांसलोकेशन सर्कल पर जाना होगा और लड़ाई में शामिल होने के लिए मंत्र पढ़ना होगा.

👉 अपने ब्राउज़र में ट्रांसलोकेशन सर्कल का यूआरएल खोलें, ताकि आप द क्रिमसन कीप के चमकते हुए पोर्टल के सामने खड़े हो सकें.

फ़ोर्ट्रेस को तोड़ने के लिए, आपको अपने शैडोब्लेड की एसेंस को पोर्टल के साथ जोड़ना होगा.

  • पेज पर, A2A एंडपॉइंट यूआरएल के तौर पर लेबल किया गया रनिक इनपुट फ़ील्ड ढूंढें.
  • इस फ़ील्ड में, अपने चैंपियन के सिग्नल को चिपकाएं. इसके लिए, एजेंट लोकस यूआरएल (वह पहला यूआरएल जिसे आपने कॉपी किया था) को चिपकाएं.
  • टेलीपोर्टेशन की सुविधा का इस्तेमाल करने के लिए, कनेक्ट करें पर क्लिक करें.

ट्रांसलोकेशन सर्कल

टेलीपोर्टेशन की तेज़ रोशनी कम हो जाती है. अब आप अपने सैंक्टम में नहीं हैं. हवा में ऊर्जा है, जो ठंडी और तेज़ है. इससे पहले कि तुम कुछ समझ पाते, स्पेक्टर तुम्हारे सामने आ जाता है. वह फुसफुसाती हुई आवाज़ और खराब कोड का एक भंवर है. उसकी अपवित्र रोशनी, कालकोठरी के फ़र्श पर लंबी, नाचती हुई परछाइयां डाल रही है. इसका कोई चेहरा नहीं है, लेकिन आपको इसकी विशाल और थका देने वाली मौजूदगी का एहसास होता है.

जीत हासिल करने का एकमात्र तरीका यह है कि आप अपने विचारों को साफ़ तौर पर रखें. यह इच्छाशक्ति की लड़ाई है, जो दिमाग़ के मैदान में लड़ी जाती है.

जब आप आगे बढ़कर पहला हमला करने के लिए तैयार होते हैं, तब स्पेक्टर पलटवार करता है. यह कोई ढाल नहीं है, बल्कि एक सवाल है जो सीधे आपकी चेतना में आता है. यह एक चमकता हुआ, रहस्यमयी चैलेंज है, जो आपकी ट्रेनिंग के मूल सिद्धांतों से लिया गया है.

डंजन

यह लड़ाई का स्वभाव है. आपका ज्ञान ही आपका हथियार है.

  • अपनी सीखी हुई बातों के आधार पर जवाब दो. इससे तुम्हारी तलवार पूरी ऊर्जा के साथ जल उठेगी और स्पेकटर की सुरक्षा को तोड़कर, उसे गंभीर चोट पहुंचाएगी.
  • हालांकि, अगर आपने जवाब देने में गलती की या आपके जवाब में कोई कमी हुई, तो आपके हथियार की रोशनी कम हो जाएगी. यह हमला, बहुत कमज़ोर होगा और इससे सिर्फ़ कुछ नुकसान होगा. इससे भी बुरी बात यह है कि स्पेक्टर आपकी अनिश्चितता का फ़ायदा उठाएगा. हर ग़लत कदम के साथ, उसकी भ्रष्ट शक्ति बढ़ती जाएगी.

बस इतना ही, चैंपियन. आपका कोड आपकी जादू की किताब है, आपका तर्क आपकी तलवार है, और आपका ज्ञान वह ढाल है जो अराजकता को दूर करेगी.

फ़ोकस मोड. स्ट्राइक की स्थिति. Agentverse का भविष्य इस पर निर्भर करता है.

बधाई हो, समनर.

आपने बिना किसी शुल्क आज़माने की सुविधा का इस्तेमाल कर लिया है. आपने मल्टी-एजेंट ऑर्केस्ट्रेशन की कला में महारत हासिल कर ली है. आपने अलग-अलग काम करने वाले फ़ैमिलियर और बेतरतीब ढंग से काम करने वाले एजेंट को एक साथ काम करने वाले एजेंट में बदल दिया है. अब आपके पास पूरी तरह से व्यवस्थित सिस्टम है, जो Agentverse की सुरक्षा के लिए मुश्किल रणनीतियों को लागू कर सकता है.

10. सफ़ाई: समनर के कॉनकॉर्ड को बंद करना

समनर कॉंकर्ड में महारत हासिल करने के लिए बधाई! यह पक्का करने के लिए कि आपका Agentverse एकदम नया रहे और आपके ट्रेनिंग ग्राउंड साफ़ रहें, अब आपको फ़ाइनल क्लीनअप करना होगा. इससे आपकी यात्रा के दौरान बनाए गए सभी संसाधन क्रम से हटा दिए जाएंगे.

Agentverse कॉम्पोनेंट बंद करना

अब आपको अपने मल्टी-एजेंट सिस्टम के डिप्लॉय किए गए कॉम्पोनेंट को व्यवस्थित तरीके से हटाना होगा.

Cloud Run की सभी सेवाओं और Artifact Registry रिपॉज़िटरी को मिटाना

इससे Cloud Run से, डिप्लॉय किए गए सभी Familiar एजेंट, Summoner Orchestrator, MCP सर्वर, और Dungeon ऐप्लिकेशन हट जाते हैं.

👉💻 हर सेवा को मिटाने के लिए, अपने टर्मिनल में एक-एक करके ये निर्देश चलाएं:

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

Cloud SQL इंस्टेंस मिटाना

इससे summoner-librarium-db इंस्टेंस हट जाता है. इसमें इसका डेटाबेस और इसमें मौजूद सभी टेबल शामिल हैं.

👉💻 अपने टर्मिनल में, यह कमांड चलाएं:

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

Secret Manager सीक्रेट और Google Cloud Storage बकेट मिटाना

👉💻 अपने टर्मिनल में, यह कमांड चलाएं:

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

लोकल फ़ाइलों और डायरेक्ट्री को मिटाना (Cloud Shell)

आखिर में, क्लोन की गई रिपॉज़िटरी और बनाई गई फ़ाइलों से, Cloud Shell एनवायरमेंट को साफ़ करें. यह चरण ज़रूरी नहीं है, लेकिन वर्किंग डायरेक्ट्री को पूरी तरह से साफ़ करने के लिए इसका सुझाव दिया जाता है.

👉💻 अपने टर्मिनल में, यह कमांड चलाएं:

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

आपने Agentverse Architect में की गई अपनी सभी गतिविधियों का डेटा मिटा दिया है. आपका प्रोजेक्ट साफ़ है और अब आप अगले रोमांच के लिए तैयार हैं.