1. आपको क्या सीखने को मिलेगा
आपका स्वागत है! आज हम एक शानदार सफ़र पर निकलने वाले हैं. आइए, InstaVibe के बारे में सोचकर शुरुआत करते हैं. यह एक लोकप्रिय सोशल इवेंट प्लैटफ़ॉर्म है. हालांकि, यह सुविधा कारगर है, लेकिन हम जानते हैं कि कुछ लोगों के लिए, ग्रुप में की जाने वाली गतिविधियों की प्लानिंग करना मुश्किल हो सकता है. मान लें कि आपको यह पता लगाना है कि आपके सभी दोस्तों की दिलचस्पी किस चीज़ में है. इसके बाद, आपको इवेंट या जगहों के लिए कई विकल्पों में से सही विकल्प चुनना है. आखिर में, आपको सभी चीज़ों को व्यवस्थित करना है. यह बहुत ज़्यादा है! हम एआई और खास तौर पर, इंटेलिजेंट एजेंट को इसी जगह पर इस्तेमाल कर सकते हैं, ताकि बेहतर नतीजे मिल सकें.
हमारा मकसद एक ऐसा सिस्टम बनाना है जिसमें ये एजेंट, मुश्किल काम आसानी से कर सकें. जैसे, उपयोगकर्ता और उसके दोस्त की पसंद को समझने के लिए, स्मार्ट तरीके से ‘सुनना’. इसके बाद, उनकी पसंद के हिसाब से शानदार गतिविधियों के सुझाव देना. हमारा मकसद, InstaVibe पर सोशल प्लानिंग को आसान और मज़ेदार बनाना है. इन स्मार्ट असिस्टेंट को बनाने के लिए, हमें सही टूल का इस्तेमाल करके एक मज़बूत बुनियादी ढांचा तैयार करना होगा.
आपको यह कॉन्सेप्ट दिखेगा:
Google के ADK की बुनियादी बातें: Google के एजेंट डेवलपमेंट किट (ADK) का इस्तेमाल करके, अपना पहला इंटेलिजेंट एजेंट बनाने की बुनियादी बातें जानें. ज़रूरी कॉम्पोनेंट, एजेंट की लाइफ़साइकल, और फ़्रेमवर्क में पहले से मौजूद टूल का असरदार तरीके से इस्तेमाल करने का तरीका जानें.
मॉडल कॉन्टेक्स्ट प्रोटोकॉल (एमसीपी) की मदद से, एजेंट की क्षमताओं को बढ़ाना: अपने एजेंट को कस्टम टूल और कॉन्टेक्स्ट से लैस करना सीखें. इससे वे खास टास्क पूरे कर पाएंगे और खास जानकारी ऐक्सेस कर पाएंगे. मॉडल कॉन्टेक्स्ट प्रोटोकॉल (एमसीपी) के कॉन्सेप्ट के बारे में जानकारी दें. इस कॉन्टेक्स्ट को उपलब्ध कराने के लिए, एमसीपी सर्वर को सेट अप करने का तरीका जानें.
एजेंट इंटरैक्शन और ऑर्केस्ट्रेशन डिज़ाइन करना: एजेंट ऑर्केस्ट्रेशन को समझने के लिए, सिंगल एजेंट से आगे बढ़ें. आसान क्रम वाले वर्कफ़्लो से लेकर लूप, शर्त के हिसाब से लॉजिक, और पैरलल प्रोसेसिंग वाले मुश्किल स्थितियों तक के इंटरैक्शन पैटर्न डिज़ाइन करें. मॉड्यूलर टास्क मैनेज करने के लिए, एडीके फ़्रेमवर्क में सब-एजेंट का कॉन्सेप्ट पेश किया गया है.
साथ मिलकर काम करने वाले मल्टी-एजेंट सिस्टम बनाना: जानें कि ऐसे सिस्टम कैसे बनाए जाते हैं जिनमें कई एजेंट मिलकर मुश्किल लक्ष्यों को हासिल करते हैं. एजेंट-टू-एजेंट (A2A) कम्यूनिकेशन प्रोटोकॉल के बारे में जानें और इसे लागू करें. इससे अलग-अलग एजेंट (जो अलग-अलग मशीनों या सेवाओं पर चल रहे हैं) के बीच भरोसेमंद तरीके से इंटरैक्ट करने का एक स्टैंडर्ड तरीका तय किया जा सकता है.
Google Cloud पर एजेंटों को प्रोडक्शन के लिए तैयार करना: अपने एजेंट ऐप्लिकेशन को डेवलपमेंट एनवायरमेंट से क्लाउड पर ले जाएं. Google Cloud Platform (GCP) पर, एक से ज़्यादा एजेंट वाले ऐसे सिस्टम को डिज़ाइन और डिप्लॉय करने के सबसे सही तरीके जानें जो आसानी से स्केल किए जा सकें और मज़बूत हों. Cloud Run जैसी GCP सेवाओं का इस्तेमाल करने के बारे में अहम जानकारी पाएं. साथ ही, अपने एजेंट को होस्ट और मैनेज करने के लिए, Google Agent Engine की नई सुविधाओं के बारे में जानें.
2. आर्किटेक्चर
InstaVibe की मदद से, एआई की मदद से सोशल मीडिया पर पोस्ट करने की प्लानिंग करना
सोशल लिसनिंग क्या है?
सोशल मीडिया पर लोगों की बातचीत को मॉनिटर करने की प्रोसेस को सोशल लिसनिंग कहते हैं. इसमें सोशल मीडिया, फ़ोरम, और समाचार साइटों जैसे प्लैटफ़ॉर्म पर होने वाली डिजिटल बातचीत को मॉनिटर किया जाता है. इससे यह समझने में मदद मिलती है कि लोग किसी विषय, ब्रैंड या इंडस्ट्री के बारे में क्या कह रहे हैं. इससे लोगों की भावनाओं, रुझानों, और उपयोगकर्ता की ज़रूरतों के बारे में अहम जानकारी मिलती है. इस वर्कशॉप में, हम एजेंट पर आधारित सिस्टम में इस कॉन्सेप्ट का इस्तेमाल करेंगे.
InstaVibe की टीम में आपका स्वागत है
मान लें कि आप "InstaVibe" नाम के एक सफल स्टार्टअप में काम करते हैं. यह स्टार्टअप, युवाओं को टारगेट करने वाला एक लोकप्रिय सोशल इवेंट प्लैटफ़ॉर्म है. सब कुछ ठीक चल रहा है. हालांकि, कई टेक्नोलॉजी कंपनियों की तरह, आपकी टीम पर भी निवेशकों का दबाव है कि वह एआई का इस्तेमाल करके नए-नए इनोवेशन करे. आपने यह भी देखा है कि कुछ उपयोगकर्ता, अन्य उपयोगकर्ताओं की तरह ऐप्लिकेशन का इस्तेमाल नहीं कर रहे हैं. ऐसा हो सकता है कि वे ग्रुप ऐक्टिविटी शुरू करने में कम दिलचस्पी रखते हों या उन्हें प्लान बनाने में मुश्किल हो रही हो. आपकी कंपनी के लिए, इसका मतलब है कि इस अहम उपयोगकर्ता ग्रुप के बीच प्लैटफ़ॉर्म का इस्तेमाल कम हो रहा है.
आपकी टीम की रिसर्च से पता चलता है कि एआई की मदद से, इन उपयोगकर्ताओं के अनुभव को बेहतर बनाया जा सकता है. इसका मकसद, उपयोगकर्ता और उसके दोस्तों की दिलचस्पी के हिसाब से, उन्हें काम की गतिविधियों के सुझाव देकर, सामाजिक गतिविधियों की योजना बनाने की प्रोसेस को आसान बनाना है. आपको और आपके साथियों को यह सवाल परेशान कर रहा होगा कि एआई एजेंट, दिलचस्पी का पता लगाने, गतिविधि से जुड़ी रिसर्च करने, और शुरुआती समन्वय जैसे कामों को कैसे अपने-आप पूरा कर सकते हैं. इन कामों में अक्सर बहुत समय लगता है.
एजेंट पर आधारित समाधान (प्रोटोटाइप कॉन्सेप्ट)
आपको मल्टी-एजेंट सिस्टम की मदद से, प्रोटोटाइप फ़ीचर डेवलप करने का सुझाव देना है. यहां कॉन्सेप्ट के बारे में बताया गया है:
- सोशल प्रोफ़ाइलिंग एजेंट: यह एजेंट, सोशल लिसनिंग की तकनीकों का इस्तेमाल करता है. इससे उपयोगकर्ता के कनेक्शन, इंटरैक्शन, और उपयोगकर्ता की प्राथमिकताओं से जुड़ी संभावित सार्वजनिक रुझानों का विश्लेषण किया जाता है. इसका मकसद, एक जैसी दिलचस्पी और गतिविधियों की सही विशेषताओं (जैसे, शांत जगहों पर इकट्ठा होने की प्राथमिकताएं, खास शौक) की पहचान करना है.
- इवेंट प्लान करने वाला एजेंट: यह एजेंट, सोशल प्रोफ़ाइलिंग एजेंट से मिली अहम जानकारी का इस्तेमाल करके, खास इवेंट, जगहों या आइडिया के लिए ऑनलाइन संसाधनों को खोजता है. ये संसाधन, पहचान की गई शर्तों (जैसे कि जगह, दिलचस्पी) के मुताबिक होते हैं.
- प्लेटफ़ॉर्म इंटरैक्शन एजेंट (एमसीपी का इस्तेमाल करता है): यह एजेंट, गतिविधि की योजना बनाने वाले एजेंट से फ़ाइनल किया गया प्लान लेता है. इसका मुख्य काम, पहले से तय किए गए एमसीपी (मॉडल कॉन्टेक्स्ट प्रोटोकॉल) टूल का इस्तेमाल करके, सीधे तौर पर InstaVibe प्लैटफ़ॉर्म के साथ इंटरैक्ट करना है. इस टूल की मदद से एजेंट, इवेंट का सुझाव दे सकता है और प्लान के बारे में बताने वाली पोस्ट बना सकता है.
- ऑर्केस्ट्रेटर एजेंट: यह एजेंट, सेंट्रल कोऑर्डिनेटर के तौर पर काम करता है. इसे InstaVibe प्लैटफ़ॉर्म से उपयोगकर्ता का शुरुआती अनुरोध मिलता है.साथ ही, यह अनुरोध के मुख्य मकसद को समझता है. जैसे, "मेरे और मेरे दोस्तों के लिए एक इवेंट प्लान करो"), और फिर खास कामों को सही क्रम में, उनसे जुड़े एजेंट को सौंपता है. यह एजेंट के बीच जानकारी के फ़्लो को मैनेज करता है. साथ ही, यह पक्का करता है कि उपयोगकर्ता को फ़ाइनल नतीजा वापस मिल जाए.
मुख्य आर्किटेक्चरल एलिमेंट और टेक्नोलॉजी
Google Cloud Platform (GCP):
- Vertex AI:
- Gemini मॉडल: इससे आपको Google के बेहतरीन लार्ज लैंग्वेज मॉडल (एलएलएम) का ऐक्सेस मिलता है. जैसे, Gemini. ये मॉडल, हमारे एजेंट को रीज़निंग और फ़ैसले लेने की सुविधा देते हैं.
- Vertex AI Agent Engine: यह एक मैनेज की गई सेवा है. इसका इस्तेमाल, ऑर्केस्ट्रेटर एजेंट को डिप्लॉय, होस्ट, और स्केल करने के लिए किया जाता है. इससे प्रोडक्शन को आसान बनाया जाता है और बुनियादी ढांचे की जटिलताओं को कम किया जाता है.
- Cloud Run: कंटेनर के साथ बने ऐप्लिकेशन को डिप्लॉय करने के लिए, बिना सर्वर वाला प्लैटफ़ॉर्म. हम इसका इस्तेमाल इन कामों के लिए करते हैं:
- InstaVibe के मुख्य वेब ऐप्लिकेशन को होस्ट करना.
- A2A की सुविधा वाले एजेंट (प्लानर, सोशल प्रोफ़ाइलिंग, प्लैटफ़ॉर्म इंटरैक्शन) को इंडिपेंडेंट माइक्रोसेवाओं के तौर पर डिप्लॉय करें.
- एमसीपी टूल सर्वर चलाएं, ताकि एजेंटों के लिए InstaVibe के इंटरनल एपीआई उपलब्ध कराए जा सकें.
- Spanner: यह पूरी तरह से मैनेज किया जाने वाला, दुनिया भर में डिस्ट्रिब्यूट किया जाने वाला, और पूरी तरह से काम करने वाला रिलेशनल डेटाबेस है. इस वर्कशॉप में, हम इसकी क्षमताओं का इस्तेमाल ग्राफ़ डेटाबेस के तौर पर करेंगे. इसके लिए, हम इसके GRAPH DDL और क्वेरी सुविधाओं का इस्तेमाल करेंगे. इससे हमें ये काम करने में मदद मिलेगी:
- जटिल सोशल रिलेशनशिप (उपयोगकर्ता, दोस्ती, इवेंट में शामिल होना, पोस्ट) को मॉडल और सेव करना.
- सोशल प्रोफ़ाइलिंग एजेंट के लिए, इन संबंधों की क्वेरी को आसानी से चालू करें.
- Artifact Registry: यह पूरी तरह से मैनेज की जाने वाली सेवा है. इसका इस्तेमाल कंटेनर इमेज को सेव करने, मैनेज करने, और सुरक्षित रखने के लिए किया जाता है.
- Cloud Build: यह एक ऐसी सेवा है जो Google Cloud पर आपकी बिल्ड प्रोसेस को पूरा करती है. हम इसका इस्तेमाल, एजेंट और ऐप्लिकेशन के सोर्स कोड से Docker कंटेनर इमेज अपने-आप बनाने के लिए करते हैं.
- Cloud Storage: इसका इस्तेमाल Cloud Build जैसी सेवाएं, बिल्ड आर्टफ़ैक्ट को सेव करने के लिए करती हैं. साथ ही, Agent Engine इसका इस्तेमाल अपनी ऑपरेशनल ज़रूरतों के लिए करता है.
- कोर एजेंट फ़्रेमवर्क और प्रोटोकॉल:
- Google का एजेंट डेवलपमेंट किट (एडीके): यह इनके लिए प्राइमरी फ़्रेमवर्क है:
- हर इंटेलिजेंट एजेंट के लिए, मुख्य लॉजिक, व्यवहार, और निर्देश सेट तय करना.
- एजेंट के लाइफ़साइकल, स्थिति, और मेमोरी को मैनेज करना. इसमें शॉर्ट-टर्म सेशन की स्थिति और संभावित रूप से लॉन्ग-टर्म नॉलेज शामिल है.
- ऐसे टूल (जैसे, Google Search या कस्टम-बिल्ट टूल) इंटिग्रेट करना जिन्हें एजेंट, दुनिया के साथ इंटरैक्ट करने के लिए इस्तेमाल कर सकते हैं.
- मल्टी-एजेंट वर्कफ़्लो को व्यवस्थित करना. इसमें सब-एजेंट को क्रम से, लूप में, और पैरलल तरीके से एक्ज़ीक्यूट करना शामिल है.
- एजेंट-टू-एजेंट (A2A) कम्यूनिकेशन प्रोटोकॉल: यह एक ओपन स्टैंडर्ड है. इससे ये काम किए जा सकते हैं:
- अलग-अलग एआई एजेंट के बीच सीधे तौर पर, स्टैंडर्ड तरीके से बातचीत और सहयोग करना. भले ही, वे अलग-अलग सेवाओं के तौर पर काम कर रहे हों या अलग-अलग मशीनों पर चल रहे हों.
- एजेंट, एक-दूसरे की क्षमताओं के बारे में जान सकते हैं (एजेंट कार्ड के ज़रिए) और टास्क सौंप सकते हैं. यह हमारे Orchestrator एजेंट के लिए ज़रूरी है, ताकि वह Planner, Social, और Platform एजेंट के साथ इंटरैक्ट कर सके.
- A2A Python Library (a2a-python): यह एक ऐसी लाइब्रेरी है जिसका इस्तेमाल, हमारे ADK एजेंट को A2A प्रोटोकॉल के बारे में बताने के लिए किया जाता है. यह सर्वर-साइड कॉम्पोनेंट उपलब्ध कराता है, ताकि:
- हमारे एजेंटों को A2A के मुताबिक सर्वर के तौर पर दिखाना.
- डिस्कवरी के लिए, "एजेंट कार्ड" दिखाने की सुविधा अपने-आप मैनेज होती है.
- दूसरे एजेंट (जैसे, Orchestrator) से टास्क के अनुरोध पाना और उन्हें मैनेज करना.
- मॉडल कॉन्टेक्स्ट प्रोटोकॉल (एमसीपी): यह एक ओपन स्टैंडर्ड है. इसकी मदद से एजेंट ये काम कर सकते हैं:
- मानक तरीके से बाहरी टूल, डेटा सोर्स, और सिस्टम से कनेक्ट करना और उनका इस्तेमाल करना.
- हमारा प्लैटफ़ॉर्म इंटरैक्शन एजेंट, एमसीपी सर्वर से कम्यूनिकेट करने के लिए एमसीपी क्लाइंट का इस्तेमाल करता है. यह एमसीपी सर्वर, InstaVibe प्लैटफ़ॉर्म के मौजूदा एपीआई के साथ इंटरैक्ट करने के लिए टूल उपलब्ध कराता है.
- Google का एजेंट डेवलपमेंट किट (एडीके): यह इनके लिए प्राइमरी फ़्रेमवर्क है:
- डीबग करने वाले टूल:
- A2A इंस्पेक्टर: A2A इंस्पेक्टर, वेब पर आधारित एक डीबगिंग टूल है. इसका इस्तेमाल इस पूरी वर्कशॉप में किया जाता है. इसकी मदद से, A2A की सुविधा वाले एजेंट से कनेक्ट किया जाता है, उनकी जांच की जाती है, और उनसे इंटरैक्ट किया जाता है. यह फ़ाइनल प्रोडक्शन आर्किटेक्चर का हिस्सा नहीं है, लेकिन यह हमारे डेवलपमेंट वर्कफ़्लो का एक ज़रूरी हिस्सा है. यह सुविधा उपलब्ध है:
- एजेंट कार्ड व्यूअर: इसका इस्तेमाल, एजेंट की सार्वजनिक तौर पर उपलब्ध क्षमताओं को फ़ेच करने और उनकी पुष्टि करने के लिए किया जाता है.
- लाइव चैट इंटरफ़ेस: इससे डिप्लॉय किए गए एजेंट को सीधे मैसेज भेजे जा सकते हैं, ताकि तुरंत जांच की जा सके.
- डीबग कंसोल: इंस्पेक्टर और एजेंट के बीच भेजे और पाए गए रॉ JSON-RPC मैसेज देखने के लिए.
- A2A इंस्पेक्टर: A2A इंस्पेक्टर, वेब पर आधारित एक डीबगिंग टूल है. इसका इस्तेमाल इस पूरी वर्कशॉप में किया जाता है. इसकी मदद से, A2A की सुविधा वाले एजेंट से कनेक्ट किया जाता है, उनकी जांच की जाती है, और उनसे इंटरैक्ट किया जाता है. यह फ़ाइनल प्रोडक्शन आर्किटेक्चर का हिस्सा नहीं है, लेकिन यह हमारे डेवलपमेंट वर्कफ़्लो का एक ज़रूरी हिस्सा है. यह सुविधा उपलब्ध है:
- लैंग्वेज मॉडल (एलएलएम): सिस्टम के "दिमाग":
- Google के Gemini मॉडल: हम खास तौर पर gemini-2.0-flash जैसे वर्शन का इस्तेमाल करते हैं. इन मॉडल को इनके लिए चुना गया है:
- रीज़निंग और निर्देशों का पालन करने की बेहतर क्षमता: ये मॉडल, मुश्किल प्रॉम्प्ट को समझ सकते हैं, निर्देशों का पालन कर सकते हैं, और टास्क के बारे में तर्क दे सकते हैं. इसलिए, ये एजेंट को फ़ैसले लेने में मदद कर सकते हैं.
- टूल का इस्तेमाल (फ़ंक्शन कॉलिंग): Gemini मॉडल, यह तय करने में बेहतर होते हैं कि ADK के ज़रिए उपलब्ध कराए गए टूल का इस्तेमाल कब और कैसे करना है. इससे एजेंट, जानकारी इकट्ठा कर पाते हैं या कार्रवाइयां कर पाते हैं.
- बेहतर परफ़ॉर्मेंस (फ़्लैश मॉडल): "फ़्लैश" वैरिएंट, परफ़ॉर्मेंस और लागत के मामले में बेहतर विकल्प हैं. ये ऐसे कई इंटरैक्टिव एजेंट टास्क के लिए सही हैं जिनमें तुरंत जवाब देने की ज़रूरत होती है.
- Google के Gemini मॉडल: हम खास तौर पर gemini-2.0-flash जैसे वर्शन का इस्तेमाल करते हैं. इन मॉडल को इनके लिए चुना गया है:
क्या आपको Google Cloud क्रेडिट चाहिए?
3. शुरू करने से पहले
👉Google Cloud Console में सबसे ऊपर मौजूद, Cloud Shell चालू करें पर क्लिक करें (यह Cloud Shell पैनल में सबसे ऊपर मौजूद टर्मिनल के आकार का आइकॉन है),
👉 "एडिटर खोलें" बटन पर क्लिक करें. यह बटन, पेंसिल वाले खुले फ़ोल्डर की तरह दिखता है. इससे विंडो में Cloud Shell Code Editor खुल जाएगा. आपको बाईं ओर फ़ाइल एक्सप्लोरर दिखेगा.
👉नीचे दिए गए स्टेटस बार में, Cloud Code से साइन इन करें बटन पर क्लिक करें. निर्देशों के मुताबिक, प्लग इन को अनुमति दें. अगर आपको स्टेटस बार में Cloud Code - no project दिखता है, तो उसे चुनें. इसके बाद, ड्रॉप डाउन में ‘Select a Google Cloud Project' चुनें. इसके बाद, बनाए गए प्रोजेक्ट की सूची में से कोई Google Cloud प्रोजेक्ट चुनें.
👉 अपना Google Cloud प्रोजेक्ट आईडी ढूंढें:
- Google Cloud Console खोलें: https://console.cloud.google.com
- पेज पर सबसे ऊपर मौजूद प्रोजेक्ट ड्रॉपडाउन से, वह प्रोजेक्ट चुनें जिसका इस्तेमाल आपको इस वर्कशॉप के लिए करना है.
- आपका प्रोजेक्ट आईडी, डैशबोर्ड पर मौजूद प्रोजेक्ट की जानकारी देने वाले कार्ड में दिखता है
👉क्लाउड आईडीई में टर्मिनल खोलें,
👉💻 टर्मिनल में, पुष्टि करें कि आपने पहले ही पुष्टि कर ली है और प्रोजेक्ट को अपने प्रोजेक्ट आईडी पर सेट किया गया है. इसके लिए, यह कमांड इस्तेमाल करें:
gcloud auth list
👉💻 GitHub से instavibe-bootstrap
प्रोजेक्ट का क्लोन बनाएं:
git clone -b adk-1.2.1-a2a-0.2.7 https://github.com/weimeilin79/instavibe-bootstrap.git
chmod +x ~/instavibe-bootstrap/init.sh
chmod +x ~/instavibe-bootstrap/set_env.sh
प्रोजेक्ट के स्ट्रक्चर को समझना
बनाना शुरू करने से पहले, आइए कुछ समय के लिए उस instavibe-bootstrap
प्रोजेक्ट के लेआउट को समझें जिसे आपने अभी क्लोन किया है. इससे आपको यह जानने में मदद मिलेगी कि वर्कशॉप के दौरान, फ़ाइलों को कहां ढूंढना है और उनमें बदलाव कैसे करना है.
instavibe-bootstrap/
├── agents/
│ ├── orchestrate/
│ ├── planner/
│ ├── platform_mcp_client/
│ └── social/
├── instavibe/
│ ├── static/
│ └── templates/
├── tools/
│ └── instavibe/
├── utils/
├── init.sh
└── set_env.sh
यहां मुख्य डायरेक्ट्री के बारे में बताया गया है:
agents/
: यह हमारे एआई सिस्टम का मुख्य हिस्सा है. हर सबडायरेक्ट्री (planner/, social/, वगैरह) में, किसी खास इंटेलिजेंट एजेंट का सोर्स कोड होता है.agent.py
: यह हर एजेंट के फ़ोल्डर में मौजूद मुख्य फ़ाइल होती है. इसमें एजेंट का लॉजिक होता है.a2a_server.py
: यह फ़ाइल, ADK एजेंट को एजेंट-टू-एजेंट (A2A) सर्वर के साथ रैप करती है.Dockerfile
: इससे यह तय होता है कि Cloud Run या Agent Engine पर एजेंट को डिप्लॉय करने के लिए, कंटेनर इमेज कैसे बनाई जाए.
instavibe/
: इस डायरेक्ट्री में, InstaVibe वेब ऐप्लिकेशन का पूरा सोर्स कोड होता है.tools/
: यह डायरेक्ट्री, बाहरी टूल बनाने के लिए है. हमारे एजेंट इन टूल का इस्तेमाल कर सकते हैं.instavibe/
में मॉडल कॉन्टेक्स्ट प्रोटोकॉल (एमसीपी) सर्वर होता है.
इस मॉड्यूलर स्ट्रक्चर में, वेब ऐप्लिकेशन को अलग-अलग एआई कॉम्पोनेंट से अलग किया जाता है. इससे पूरे सिस्टम को मैनेज करना, टेस्ट करना, और डिप्लॉय करना आसान हो जाता है.
👉💻 स्क्रिप्ट को शुरू करें:
यह स्क्रिप्ट, आपसे Google Cloud प्रोजेक्ट आईडी डालने के लिए कहेगी.
init.sh
स्क्रिप्ट के प्रॉम्प्ट करने पर, पिछले चरण में मिला Google Cloud प्रोजेक्ट आईडी डालें:
cd ~/instavibe-bootstrap
./init.sh
👉💻 ज़रूरी प्रोजेक्ट आईडी सेट करें:
gcloud config set project $(cat ~/project_id.txt) --quiet
👉💻 ज़रूरी Google Cloud API चालू करने के लिए, यह कमांड चलाएं:
gcloud services enable run.googleapis.com \
cloudfunctions.googleapis.com \
cloudbuild.googleapis.com \
artifactregistry.googleapis.com \
spanner.googleapis.com \
apikeys.googleapis.com \
iam.googleapis.com \
compute.googleapis.com \
aiplatform.googleapis.com \
cloudresourcemanager.googleapis.com \
maps-backend.googleapis.com
👉💻 ज़रूरी सभी एनवायरमेंट वैरिएबल सेट करें:
export PROJECT_ID=$(gcloud config get project)
export PROJECT_NUMBER=$(gcloud projects describe ${PROJECT_ID} --format="value(projectNumber)")
export SERVICE_ACCOUNT_NAME=$(gcloud compute project-info describe --format="value(defaultServiceAccount)")
export SPANNER_INSTANCE_ID="instavibe-graph-instance"
export SPANNER_DATABASE_ID="graphdb"
export GOOGLE_CLOUD_PROJECT=$(gcloud config get project)
export GOOGLE_GENAI_USE_VERTEXAI=TRUE
export GOOGLE_CLOUD_LOCATION="us-central1"
अनुमति सेट अप करना
👉💻 अनुमतियां दें. टर्मिनल में, यह कमांड चलाएं :
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:$SERVICE_ACCOUNT_NAME" \
--role="roles/spanner.admin"
# Spanner Database User
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:$SERVICE_ACCOUNT_NAME" \
--role="roles/spanner.databaseUser"
# Artifact Registry Admin
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:$SERVICE_ACCOUNT_NAME" \
--role="roles/artifactregistry.admin"
# Cloud Build Editor
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:$SERVICE_ACCOUNT_NAME" \
--role="roles/cloudbuild.builds.editor"
# Cloud Run Admin
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:$SERVICE_ACCOUNT_NAME" \
--role="roles/run.admin"
# IAM Service Account User
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:$SERVICE_ACCOUNT_NAME" \
--role="roles/iam.serviceAccountUser"
# Vertex AI User
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:$SERVICE_ACCOUNT_NAME" \
--role="roles/aiplatform.user"
# Logging Writer (to allow writing logs)
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/logging.viewer"
👉 IAM कंसोल में जाकर, नतीजे की पुष्टि करें
👉💻 Artifact Registry रिपॉज़िटरी बनाने के लिए, टर्मिनल में ये कमांड चलाएं. हमारे एजेंट, MCP सर्वर, और InstaVibe ऐप्लिकेशन के लिए सभी Docker इमेज, Cloud Run या Agent Engine पर डिप्लॉय करने से पहले यहां सेव की जाती हैं.
export REPO_NAME="introveally-repo"
gcloud artifacts repositories create $REPO_NAME \
--repository-format=docker \
--location=us-central1 \
--description="Docker repository for InstaVibe workshop"
एपीआई पासकोड के लिए, मैप प्लैटफ़ॉर्म सेट अप करना
InstaVibe ऐप्लिकेशन में Google Maps की सेवाओं का इस्तेमाल करने के लिए, आपको एक एपीआई पासकोड बनाना होगा. साथ ही, उसे सही तरीके से सीमित करना होगा.
👉 नए टैब में, एपीआई और सेवाएं > क्रेडेंशियल पर जाएं. "क्रेडेंशियल" पेज पर, सबसे ऊपर मौजूद + CREATE CREDENTIALS बटन पर क्लिक करें. ड्रॉपडाउन मेन्यू से एपीआई पासकोड चुनें.
👉 आपको एक डायलॉग बॉक्स दिखेगा, जिसमें आपकी नई एपीआई कुंजी दिखेगी. आपको इसकी ज़रूरत बाद में ऐप्लिकेशन कॉन्फ़िगरेशन के लिए होगी.
👉 "एपीआई पासकोड बनाया गया" डायलॉग बॉक्स में, बंद करें पर क्लिक करें.
👉 आपको अपनी नई एपीआई पासकोड की सूची दिखेगी. उदाहरण के लिए, "एपीआई पासकोड 1"). दाईं ओर मौजूद तीन बिंदुओं पर क्लिक करें. इसके बाद, "एपीआई कुंजी को सीमित करें और उसका नाम बदलें" पेज खोलने के लिए, एपीआई कुंजी में बदलाव करें को चुनें.
👉 सबसे ऊपर मौजूद 'नाम' फ़ील्ड में, डिफ़ॉल्ट नाम को बदलकर यह नाम डालें: Maps Platform API पासकोड (🚨🚨अहम जानकारी🚨🚨 कृपया इस नाम का इस्तेमाल करें!)
Maps Platform API Key
👉 "ऐप्लिकेशन से जुड़ी पाबंदियां" सेक्शन में जाकर, पक्का करें कि कोई नहीं चुना गया हो.
👉 "एपीआई पर पाबंदियां" सेक्शन में जाकर, 'कुंजी पर पाबंदी लगाएं' रेडियो बटन को चुनें.
👉 Select APIs ड्रॉपडाउन मेन्यू पर क्लिक करें. दिखने वाले खोज बॉक्स में, Maps JavaScript API
टाइप करें और सूची से इसे चुनें.
👉 ठीक है पर क्लिक करें.
👉 पेज पर सबसे नीचे मौजूद, 'सेव करें' बटन पर क्लिक करें.
आपने "Maps Platform API Key" नाम का एपीआई पासकोड बना लिया है. साथ ही, आपने इसे सिर्फ़ "Maps JavaScript API" के इस्तेमाल के लिए सीमित कर दिया है. इसके अलावा, आपने यह भी पक्का कर लिया है कि आपके प्रोजेक्ट के लिए एपीआई चालू है.
4. ग्राफ़ डेटाबेस सेटअप करना
इंटेलिजेंट एजेंट बनाने से पहले, हमें InstaVibe सोशल नेटवर्क में मौजूद रिच कनेक्शन को सेव करने और समझने का तरीका चाहिए. ऐसे में, ग्राफ़ डेटाबेस का इस्तेमाल किया जाता है. पारंपरिक रिलेशनल डेटाबेस, डेटा को लाइनों और कॉलम वाली टेबल में सेव करते हैं. हालांकि, ग्राफ़ डेटाबेस को खास तौर पर नोड (जैसे, लोग, इवेंट या पोस्ट) और उन्हें जोड़ने वाले संबंधों (किनारे) के हिसाब से डेटा को दिखाने और क्वेरी करने के लिए डिज़ाइन किया गया है. जैसे, दोस्ती, इवेंट में शामिल होना या ज़िक्र करना. यह स्ट्रक्चर, सोशल मीडिया ऐप्लिकेशन के लिए बहुत काम का है. ऐसा इसलिए, क्योंकि यह असल ज़िंदगी के सोशल नेटवर्क के स्ट्रक्चर जैसा होता है. इससे यह समझने में आसानी होती है कि अलग-अलग इकाइयां एक-दूसरे से कैसे जुड़ी हुई हैं.
हम इस ग्राफ़ डेटाबेस को Google Cloud Spanner का इस्तेमाल करके लागू कर रहे हैं. Spanner को मुख्य रूप से, दुनिया भर में इस्तेमाल किया जाने वाला रिलेशनल डेटाबेस माना जाता है. हालांकि, यह हमें रिलेशनल टेबल के ऊपर सीधे तौर पर ग्राफ़ स्ट्रक्चर को तय करने और क्वेरी करने की सुविधा भी देता है.
इससे हमें Spanner की स्केलेबिलिटी, लेन-देन की स्थिरता, और जाने-पहचाने SQL इंटरफ़ेस के साथ-साथ, ग्राफ़ क्वेरी की एक्सप्रेसिव पावर के फ़ायदे मिलते हैं. इससे, एआई की मदद से काम करने वाली सुविधाओं के लिए ज़रूरी जटिल सोशल डायनामिक का विश्लेषण किया जा सकता है.
👉💻 Cloud Shell IDE टर्मिनल में. Google Cloud पर ज़रूरी इंफ़्रास्ट्रक्चर सेट अप करें. हम Spanner इंस्टेंस बनाकर शुरुआत करेंगे. यह हमारे डेटाबेस के लिए एक डेडीकेटेड कंटेनर के तौर पर काम करता है. इंस्टेंस तैयार होने के बाद, हम इसमें Spanner डेटाबेस बनाएंगे. इसमें हमारी सभी टेबल और InstaVibe का ग्राफ़ डेटा होगा:
. ~/instavibe-bootstrap/set_env.sh
gcloud spanner instances create $SPANNER_INSTANCE_ID \
--config=regional-us-central1 \
--description="GraphDB Instance InstaVibe" \
--processing-units=100 \
--edition=ENTERPRISE
gcloud spanner databases create $SPANNER_DATABASE_ID \
--instance=$SPANNER_INSTANCE_ID \
--database-dialect=GOOGLE_STANDARD_SQL
👉💻 डिफ़ॉल्ट सेवा खाते को Spanner का रीड/राइट ऐक्सेस देना
echo "Granting Spanner read/write access to ${SERVICE_ACCOUNT_NAME} for database ${SPANNER_DATABASE_ID}..."
gcloud spanner databases add-iam-policy-binding ${SPANNER_DATABASE_ID} \
--instance=${SPANNER_INSTANCE_ID} \
--member="serviceAccount:${SERVICE_ACCOUNT_NAME}" \
--role="roles/spanner.databaseUser" \
--project=${PROJECT_ID}
👉💻 अभी. हम Python का वर्चुअल एनवायरमेंट सेट अप करेंगे. इसके बाद, ज़रूरी Python पैकेज इंस्टॉल करेंगे. फिर, Spanner में Graph Database का स्कीमा सेट अप करेंगे. इसके बाद, उसमें शुरुआती डेटा लोड करेंगे और setup.py
स्क्रिप्ट चलाएंगे.
. ~/instavibe-bootstrap/set_env.sh
cd ~/instavibe-bootstrap
python -m venv env
source env/bin/activate
pip install -r requirements.txt
cd instavibe
python setup.py
👉 नए ब्राउज़र टैब में, Google Cloud Console पर जाएं. इसके बाद, Spanner पर जाएं. आपको अपने Spanner इंस्टेंस की सूची दिखेगी. instavibe-graph-instance
पर क्लिक करें. 👉 उदाहरण के लिए, इंस्टेंस की खास जानकारी वाले पेज पर, आपको उस इंस्टेंस में मौजूद डेटाबेस की सूची दिखेगी.
graphdb
पर क्लिक करें
👉 अपने डेटाबेस के बाईं ओर मौजूद नेविगेशन पैनल में, Spanner Studio पर क्लिक करें
👉 क्वेरी एडिटर (बिना टाइटल वाली क्वेरी टैब) में, यह Graph SQL क्वेरी चिपकाएं. इस क्वेरी से, सभी Person नोड और अन्य Person नोड के साथ उनके सीधे तौर पर जुड़े Friendship नोड का पता चलेगा. इसके बाद, नतीजा देखने के लिए चलाएं पर क्लिक करें.
Graph SocialGraph
MATCH result_paths = ((p:Person)-[f:Friendship]-(friend:Person))
RETURN SAFE_TO_JSON(result_paths) AS result_paths
👉 उसी क्वेरी एडिटर में, पिछले डीडीएल को बदलकर, एक ही इवेंट में शामिल हुए लोगों को खोजें. इसका मतलब है कि शेयर की गई गतिविधि के ज़रिए, अप्रत्यक्ष रूप से कनेक्ट किए गए लोगों को खोजें.
Graph SocialGraph
MATCH result_paths = (p1:Person)-[:Attended]->(e:Event)<-[:Attended]-(p2:Person)
WHERE p1.person_id < p2.person_id
RETURN SAFE_TO_JSON(result_paths) AS result_paths
👉 इस क्वेरी में, अलग तरह के कनेक्शन के बारे में बताया गया है. इसमें किसी व्यक्ति के दोस्तों की लिखी गई पोस्ट में शामिल लोगों के बारे में जानकारी मिलती है. इसके लिए, क्वेरी एडिटर में यह क्वेरी चलाई जाती है.
Graph SocialGraph
MATCH result_paths = (user:Person {name: "Alice"})-[:Friendship]-(friend:Person)-[:Wrote]->(post:Post)-[:Mentioned]->(mentioned_person:Person)
WHERE user <> mentioned_person AND friend <> mentioned_person -- Avoid self-mentions or friend mentioning themselves in their own post if not intended
RETURN SAFE_TO_JSON(result_paths) AS result_paths
इन क्वेरी से, हमारे InstaVibe ऐप्लिकेशन के लिए, Spanner को ग्राफ़ डेटाबेस के तौर पर इस्तेमाल करने की सुविधा के बारे में जानकारी मिलती है. हम अपने सोशल डेटा को एक-दूसरे से जुड़े ग्राफ़ के तौर पर मॉडल करते हैं. इससे, हम संबंधों और गतिविधियों का बेहतर तरीके से विश्लेषण कर पाते हैं. यह हमारे एआई एजेंट के लिए ज़रूरी होगा, ताकि वे उपयोगकर्ता के संदर्भ को समझ सकें, उनकी रुचियों का पता लगा सकें, और आखिर में उन्हें सोशल प्लानिंग में बेहतर तरीके से मदद कर सकें.
अब हमारा बुनियादी डेटा स्ट्रक्चर तैयार हो गया है और इसकी जांच भी हो गई है. इसलिए, आइए अब हम InstaVibe के मौजूदा ऐप्लिकेशन पर ध्यान दें. हमारे एजेंट इसी ऐप्लिकेशन का इस्तेमाल करेंगे.
5. InstaVibe की मौजूदा स्थिति
हमारे एआई एजेंट कहां काम करेंगे, यह समझने के लिए हमें सबसे पहले मौजूदा InstaVibe वेब ऐप्लिकेशन को डिप्लॉय और चलाना होगा. यह ऐप्लिकेशन, यूज़र इंटरफ़ेस और बुनियादी सुविधाएं उपलब्ध कराता है. ये सुविधाएं, पहले से सेट अप किए गए Spanner ग्राफ़ डेटाबेस से कनेक्ट होती हैं.
InstaVibe ऐप्लिकेशन, Google Maps का इस्तेमाल करता है. इससे वह इवेंट की ज़्यादा जानकारी वाले पेजों पर, इवेंट की जगहों को विज़ुअल तौर पर दिखा पाता है. इस सुविधा को चालू करने के लिए, ऐप्लिकेशन को उस एपीआई कुंजी की ज़रूरत होती है जिसे हमने पहले बनाया था. नीचे दी गई स्क्रिप्ट, असाइन किए गए डिसप्ले नेम ("Maps Platform API Key") का इस्तेमाल करके, असली कुंजी स्ट्रिंग को वापस लाएगी.
👉💻 Cloud Shell IDE पर वापस जाएं. नीचे दी गई स्क्रिप्ट चलाएं. इसके बाद, आउटपुट को ध्यान से देखें. पक्का करें कि दिखाया गया GOOGLE_MAPS_API_KEY, उस कुंजी से मेल खाता हो जिसे आपने पहले Google Cloud Console में बनाया और कॉपी किया था.
. ~/instavibe-bootstrap/set_env.sh
export KEY_DISPLAY_NAME="Maps Platform API Key"
GOOGLE_MAPS_KEY_ID=$(gcloud services api-keys list \
--project="${PROJECT_ID}" \
--filter="displayName='${KEY_DISPLAY_NAME}'" \
--format="value(uid)" \
--limit=1)
GOOGLE_MAPS_API_KEY=$(gcloud services api-keys get-key-string "${GOOGLE_MAPS_KEY_ID}" \
--project="${PROJECT_ID}" \
--format="value(keyString)")
echo "${GOOGLE_MAPS_API_KEY}" > ~/mapkey.txt
echo "Retrieved GOOGLE_MAPS_API_KEY: ${GOOGLE_MAPS_API_KEY}"
👉💻 अब, InstaVibe वेब ऐप्लिकेशन के लिए कंटेनर इमेज बनाते हैं और इसे Artifact Registry की रिपॉज़िटरी में पुश करते हैं.
. ~/instavibe-bootstrap/set_env.sh
cd ~/instavibe-bootstrap/instavibe/
export IMAGE_TAG="latest"
export APP_FOLDER_NAME="instavibe"
export IMAGE_NAME="instavibe-webapp"
export IMAGE_PATH="${REGION}-docker.pkg.dev/${PROJECT_ID}/${REPO_NAME}/${IMAGE_NAME}:${IMAGE_TAG}"
export SERVICE_NAME="instavibe"
gcloud builds submit . \
--tag=${IMAGE_PATH} \
--project=${PROJECT_ID}
👉💻 InstaVibe के नए बिल्ड की वेब ऐप्लिकेशन इमेज को Cloud Run पर डिप्लॉय करें
. ~/instavibe-bootstrap/set_env.sh
cd ~/instavibe-bootstrap/instavibe/
export IMAGE_TAG="latest"
export APP_FOLDER_NAME="instavibe"
export IMAGE_NAME="instavibe-webapp"
export IMAGE_PATH="${REGION}-docker.pkg.dev/${PROJECT_ID}/${REPO_NAME}/${IMAGE_NAME}:${IMAGE_TAG}"
export SERVICE_NAME="instavibe"
gcloud run deploy ${SERVICE_NAME} \
--image=${IMAGE_PATH} \
--platform=managed \
--region=${REGION} \
--allow-unauthenticated \
--set-env-vars="SPANNER_INSTANCE_ID=${SPANNER_INSTANCE_ID}" \
--set-env-vars="SPANNER_DATABASE_ID=${SPANNER_DATABASE_ID}" \
--set-env-vars="APP_HOST=0.0.0.0" \
--set-env-vars="APP_PORT=8080" \
--set-env-vars="GOOGLE_CLOUD_LOCATION=${REGION}" \
--set-env-vars="GOOGLE_CLOUD_PROJECT=${PROJECT_ID}" \
--set-env-vars="GOOGLE_MAPS_API_KEY=${GOOGLE_MAPS_API_KEY}" \
--project=${PROJECT_ID} \
--min-instances=1
डिप्लॉयमेंट पूरा होने के बाद, Cloud Run के लॉग में, चल रहे InstaVibe ऐप्लिकेशन का सार्वजनिक यूआरएल दिखना चाहिए.
इस यूआरएल को Google Cloud Console में Cloud Run सेक्शन पर जाकर भी ढूंढा जा सकता है. इसके लिए, instavibe सेवा को चुनें.
InstaVibe प्लैटफ़ॉर्म के बारे में जानने के लिए, अब उस यूआरएल को अपने वेब ब्राउज़र में खोलें. हमने जो ग्राफ़ डेटाबेस सेट अप किया है उसकी मदद से, पोस्ट, इवेंट, और उपयोगकर्ता कनेक्शन देखें.
अब हमारा टारगेट ऐप्लिकेशन चल रहा है. इसलिए, आइए इसकी क्षमताओं को बेहतर बनाने के लिए, पहला इंटेलिजेंट एजेंट बनाना शुरू करें.
6. ADK के साथ बेसिक एजेंट,इवेंट प्लानर
ADK फ़्रेमवर्क
Google के ADK फ़्रेमवर्क के बारे में जानकारी अब हमारा फ़ाउंडेशन (InstaVibe ऐप्लिकेशन और डेटाबेस) सेट हो गया है. इसलिए, हम Google के Agent Development Kit (ADK) का इस्तेमाल करके, अपना पहला इंटेलिजेंट एजेंट बनाना शुरू कर सकते हैं.
एजेंट डेवलपमेंट किट (एडीके) एक फ़्लेक्सिबल और मॉड्यूलर फ़्रेमवर्क है. इसे खास तौर पर एआई एजेंट डेवलप और डिप्लॉय करने के लिए डिज़ाइन किया गया है. इसे इस तरह से डिज़ाइन किया गया है कि एजेंट डेवलपमेंट, पारंपरिक सॉफ़्टवेयर डेवलपमेंट की तरह लगे. इसका मकसद, डेवलपर के लिए एजेंटिक आर्किटेक्चर को बनाना, डिप्लॉय करना, और व्यवस्थित करना आसान बनाना है. ये आर्किटेक्चर, एक ही मकसद वाले आसान टास्क से लेकर कई एजेंट वाले मुश्किल वर्कफ़्लो तक, सभी को मैनेज कर सकते हैं.
एडीके, मुख्य रूप से Agent
के कॉन्सेप्ट पर आधारित है.इसमें निर्देश और कॉन्फ़िगरेशन शामिल होते हैं. जैसे, चुना गया भाषा मॉडल (उदाहरण के लिए, Gemini), और Tools
का एक सेट होता है. Gemini, इन Tools
का इस्तेमाल करके कार्रवाइयां कर सकता है या जानकारी इकट्ठा कर सकता है.
हमारा शुरुआती एजेंट, "इवेंट प्लानर" होगा. इसका मुख्य मकसद, लोगों से उनकी सामाजिक गतिविधियों (जगह, तारीख, और दिलचस्पी के हिसाब से) के अनुरोध लेना और उनके हिसाब से क्रिएटिव सुझाव देना है. सुझावों को काम का बनाने और उन्हें मौजूदा जानकारी (जैसे, उस वीकेंड पर होने वाले खास इवेंट) के आधार पर देने के लिए, हम ADK के बिल्ट-इन टूल में से किसी एक का इस्तेमाल करेंगे: Google Search. इससे एजेंट को वेब पर रीयल-टाइम में मिले नतीजों के आधार पर जवाब देने की सुविधा मिलती है. साथ ही, उपयोगकर्ता की खोज से मिलते-जुलते स्थानों, इवेंट, और गतिविधियों के बारे में नई जानकारी मिलती है.
👉📝 Cloud Shell IDE में वापस जाएं. इसके बाद, एजेंट बनाने के लिए ~/instavibe-bootstrap/agents/planner/agent.py
में यह प्रॉम्प्ट और निर्देश जोड़ें
from google.adk.agents import Agent
from google.adk.tools import google_search
root_agent = Agent(
name="planner_agent",
model="gemini-2.0-flash",
description="Agent tasked with generating creative and fun dating plan suggestions",
instruction="""
You are a specialized AI assistant tasked with generating creative and fun plan suggestions.
Request:
For the upcoming weekend, specifically from **[START_DATE_YYYY-MM-DD]** to **[END_DATE_YYYY-MM-DD]**, in the location specified as **[TARGET_LOCATION_NAME_OR_CITY_STATE]** (if latitude/longitude are provided, use these: Lat: **[TARGET_LATITUDE]**, Lon: **[TARGET_LONGITUDE]**), please generate a distinct dating plan suggestions.
Constraints and Guidelines for Suggestions:
1. Creativity & Fun: Plans should be engaging, memorable, and offer a good experience for a date.
2. Budget: All generated plans should aim for a moderate budget (conceptually "$$"), meaning they should be affordable yet offer good value, without being overly cheap or extravagant. This budget level should be *reflected in the choice of activities and venues*, but **do not** explicitly state "Budget: $$" in the `plan_description`.
3. Interest Alignment:
Consider the following user interests: **[COMMA_SEPARATED_LIST_OF_INTERESTS, e.g., outdoors, arts & culture, foodie, nightlife, unique local events, live music, active/sports]**. Tailor suggestions specifically to these where possible. The plan should *embody* these interests.
Fallback: If specific events or venues perfectly matching all listed user interests cannot be found for the specified weekend, you should create a creative and fun generic dating plan that is still appealing, suitable for the location, and adheres to the moderate budget. This plan should still sound exciting and fun, even if it's more general.
4. Current & Specific: Prioritize finding specific, current events, festivals, pop-ups, or unique local venues operating or happening during the specified weekend dates. If exact current events cannot be found, suggest appealing evergreen options or implement the fallback generic plan.
5. Location Details: For each place or event mentioned within a plan, you MUST provide its name, precise latitude, precise longitude, and a brief, helpful description.
6. Maximum Activities: The plan must contain a maximum of 3 distinct activities.
RETURN PLAN in MARKDOWN FORMAT
""",
tools=[google_search]
)
इस तरह, हमने अपना पहला एजेंट तय कर लिया है! ADK की सबसे अच्छी बात यह है कि इसे इस्तेमाल करना आसान है और इसमें काम के टूल मिलते हैं. इनमें से सबसे काम का टूल, ADK Dev UI है. इसकी मदद से, अपने एजेंट की इंटरैक्टिव तरीके से जांच की जा सकती है. साथ ही, इसके जवाबों को रीयल-टाइम में देखा जा सकता है.
👉💻 चलिए, इसे शुरू करते हैं. इन कमांड से, ADK DEV UI लॉन्च होगा:
. ~/instavibe-bootstrap/set_env.sh
source ~/instavibe-bootstrap/env/bin/activate
cd ~/instavibe-bootstrap/agents
sed -i "s|^\(O\?GOOGLE_CLOUD_PROJECT\)=.*|GOOGLE_CLOUD_PROJECT=${PROJECT_ID}|" ~/instavibe-bootstrap/agents/planner/.env
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 दिखेगा.
आपके ब्राउज़र में ADK Dev UI खुलने के बाद: यूज़र इंटरफ़ेस (यूआई) के सबसे ऊपर दाईं ओर मौजूद ड्रॉपडाउन मेन्यू में, प्लानर को उस एजेंट के तौर पर चुनें जिससे आपको इंटरैक्ट करना है. अब दाईं ओर मौजूद चैट डायलॉग में, एजेंट को कोई टास्क दें. उदाहरण के लिए, एजेंट से बातचीत करना:
Search and plan something in Seattle for me this weekend
This weekend and I enjoy food and anime
तारीख का सुझाव दें (आपकी प्राथमिकता)
July 12 2025
आपको दिखेगा कि एजेंट आपके अनुरोध को प्रोसेस कर रहा है और Google Search के नतीजों के आधार पर आपको एक प्लान दे रहा है.
किसी एजेंट से बातचीत करना एक बात है, लेकिन हमें कैसे पता चलेगा कि वह लगातार उम्मीद के मुताबिक काम कर रहा है या नहीं. खास तौर पर, जब हम बदलाव करते हैं?
सॉफ़्टवेयर की टेस्टिंग के पारंपरिक तरीके, एआई एजेंट के लिए अक्सर कारगर नहीं होते. इसकी वजह यह है कि एआई एजेंट, जनरेटिव और नॉन-डिटरमिनिस्टिक होते हैं. एक बेहतरीन डेमो से लेकर भरोसेमंद प्रोडक्शन एजेंट तक पहुंचने के लिए, आकलन की एक मज़बूत रणनीति का होना ज़रूरी है. जनरेटिव मॉडल के फ़ाइनल आउटपुट की जांच करने के बजाय, किसी एजेंट का आकलन करने में अक्सर यह आकलन करना शामिल होता है कि वह फ़ैसले कैसे लेता है. साथ ही, अलग-अलग स्थितियों में टूल का सही तरीके से इस्तेमाल करने या निर्देशों का पालन करने की उसकी क्षमता का आकलन करना भी शामिल होता है. ADK में, इस काम में मदद करने वाली सुविधाएं उपलब्ध हैं.
👉 ADK Dev UI में, बाईं ओर मौजूद नेविगेशन में "Eval" टैब पर क्लिक करें. आपको plan_eval
नाम की पहले से लोड की गई टेस्ट फ़ाइल दिखेगी. इस फ़ाइल में, प्लानर एजेंट की जांच करने के लिए पहले से तय किए गए इनपुट और शर्तें शामिल हैं.
👉 कोई परिदृश्य चुनें, जैसे कि "बोस्टन" और आकलन करें बटन पर क्लिक करें. इसके बाद, दिखने वाली पॉप-अप विंडो में, मैच स्कोर को 0.3 पर सेट करें. इसके बाद, 'शुरू करें' पर क्लिक करें.
इससे एजेंट को टेस्ट इनपुट के साथ एक्ज़ीक्यूट किया जाएगा. साथ ही, यह देखा जाएगा कि इसका आउटपुट, तय की गई शर्तों के मुताबिक है या नहीं. इससे आपको अपने एजेंट की परफ़ॉर्मेंस को व्यवस्थित तरीके से टेस्ट करने का तरीका मिलता है.
👉 अब देखते हैं कि ज़्यादा सख्त थ्रेशोल्ड के साथ क्या होता है. "nyc" परिदृश्य चुनें और Run Evaluation पर फिर से क्लिक करें. इस बार, मैच स्कोर को डिफ़ॉल्ट वैल्यू (जवाब का मैच स्कोर: 0.7) पर छोड़ दें और 'शुरू करें' पर क्लिक करें. आपको दिखेगा कि नतीजा 'फ़ेल' है. ऐसा इसलिए होता है, क्योंकि एजेंट का क्रिएटिव आउटपुट, पहले से तय किए गए "गोल्डन" जवाब से पूरी तरह मेल नहीं खाता.
👉 यह जांच क्यों पूरी नहीं हुई, यह जानने के लिए "nyc" लाइन में मौजूद फ़ेल आइकॉन पर क्लिक करें. यूज़र इंटरफ़ेस (यूआई) में अब एजेंट से मिले जवाब और टेस्ट केस से मिले जवाब की तुलना, एक साथ दिखाई जाती है. यह व्यू, डीबग करने के लिए ज़रूरी है. इससे आपको यह पता चलता है कि एजेंट का आउटपुट कहां अलग है. साथ ही, इसके हिसाब से एजेंट को निर्देश दिए जा सकते हैं.
यूज़र इंटरफ़ेस (यूआई) और आकलन को एक्सप्लोर करने के बाद, अपने Cloud Shell Editor टर्मिनल पर वापस जाएं और ADK Dev UI को बंद करने के लिए, Ctrl+C
दबाएं.
फ़्री-फ़ॉर्म टेक्स्ट आउटपुट एक अच्छा विकल्प है. हालांकि, InstaVibe जैसे ऐप्लिकेशन के लिए, एजेंट के सुझावों का आसानी से इस्तेमाल करने के लिए, स्ट्रक्चर्ड डेटा (जैसे कि JSON) ज़्यादा फ़ायदेमंद होता है. आइए, हम अपने एजेंट में बदलाव करके, उसे एक जैसे JSON फ़ॉर्मैट में प्लान दिखाने के लिए कहें.
👉📝 ~/instavibe-bootstrap/agents/planner/agent.py
में, वह लाइन ढूंढें जिसमें फ़िलहाल एजेंट के निर्देश वाली स्ट्रिंग में RETURN PLAN in MARKDOWN FORMAT
लिखा है. उस लाइन को यहां दिए गए JSON स्ट्रक्चर से बदलें:
Return your response *exclusively* as a single JSON object. This object should contain a top-level key, "fun_plans", which holds a plan objects. Each plan object in the list must strictly adhere to the following structure:
--json--
{
"plan_description": "A summary of the overall plan, consisting of **exactly three sentences**. Craft these sentences in a friendly, enthusiastic, and conversational tone, as if you're suggesting this awesome idea to a close friend. Make it sound exciting and personal, highlighting the positive aspects and appeal of the plan without explicitly mentioning budget or listing interest categories.",
"locations_and_activities": [
{
"name": "Name of the specific place or event",
"latitude": 0.000000, // Replace with actual latitude
"longitude": 0.000000, // Replace with actual longitude
"description": "A brief description of this place/event, why it's suitable for the date, and any specific details for the weekend (e.g., opening hours, event time)."
}
// Add more location/activity objects here if the plan involves multiple stops/parts
]
}
आपने एजेंट के निर्देशों को अपडेट करके, खास तौर पर JSON आउटपुट का अनुरोध किया है. अब इस बदलाव की पुष्टि करते हैं.
👉💻 ADK Dev UI को फिर से लॉन्च करने के लिए, पहले की तरह ही यह निर्देश दें: Relaunch
. ~/instavibe-bootstrap/set_env.sh
source ~/instavibe-bootstrap/env/bin/activate
cd ~/instavibe-bootstrap/agents
adk web
अगर आपने पहले से ही टैब खोला हुआ है, तो टैब को रीफ़्रेश करें. इसके अलावा, अपने ब्राउज़र में ADK Dev UI खोलने के लिए, पहले की तरह ही इन चरणों का पालन करें. इसके लिए, Cloud Shell में पोर्ट 8000 पर वेब प्रीव्यू का इस्तेमाल करें. यूज़र इंटरफ़ेस (यूआई) लोड होने के बाद, पक्का करें कि प्लानर एजेंट चुना गया हो.
👉 इस बार, इसे कोई दूसरा अनुरोध करके देखते हैं. चैट डायलॉग में, यह डालें:
Plan an event Boston this weekend with art and coffee
एजेंट के जवाब को ध्यान से पढ़ें. अब आपको सिर्फ़ बातचीत वाला टेक्स्ट जवाब नहीं दिखेगा. इसके बजाय, आपको एक ऐसा जवाब दिखेगा जिसे JSON ऑब्जेक्ट के तौर पर फ़ॉर्मैट किया गया है. यह जवाब, निर्देशों में बताए गए स्ट्रक्चर से मेल खाता है. इसमें fun_plans, plan_description, locations_and_activities वगैरह शामिल हैं. इससे पुष्टि होती है कि एजेंट अब ऐसा स्ट्रक्चर्ड आउटपुट जनरेट कर सकता है जिसका इस्तेमाल हमारा InstaVibe ऐप्लिकेशन प्रोग्राम के हिसाब से कर सकता है.
JSON आउटपुट की पुष्टि करने के बाद, Cloud Shell टर्मिनल पर वापस जाएं और ADK Dev UI को रोकने के लिए, Ctrl+C
दबाएं.
ADK कॉम्पोनेंट
ADK Dev UI, इंटरैक्टिव टेस्टिंग के लिए बहुत अच्छा है. हालांकि, हमें अक्सर अपने एजेंट को प्रोग्राम के हिसाब से चलाना पड़ता है. ऐसा शायद किसी बड़े ऐप्लिकेशन या बैकएंड सेवा के हिस्से के तौर पर किया जाता है. इसके काम करने के तरीके को समझने के लिए, आइए रनटाइम और कॉन्टेक्स्ट मैनेजमेंट से जुड़े कुछ मुख्य ADK कॉन्सेप्ट देखें.
बातचीत को ज़्यादा फ़ायदेमंद और कई चरणों में पूरा करने के लिए, एजेंट को संदर्भ समझना होता है. इसके लिए, उसे यह याद रखना होता है कि बातचीत में क्या कहा गया और क्या किया गया, ताकि बातचीत को जारी रखा जा सके. ADK, Session, State, और Memory के ज़रिए, इस कॉन्टेक्स्ट को मैनेज करने के लिए स्ट्रक्चर्ड तरीके उपलब्ध कराता है:
- सेशन: जब कोई उपयोगकर्ता किसी एजेंट के साथ इंटरैक्ट करना शुरू करता है, तब एक सेशन बनता है. इसे किसी एक चैट थ्रेड के कंटेनर के तौर पर समझें. इसमें एक यूनीक आईडी, इंटरैक्शन (इवेंट) का इतिहास, मौजूदा वर्किंग डेटा (स्टेट), और मेटाडेटा होता है. जैसे, आखिरी अपडेट का समय.
- स्टेट: यह एजेंट की कम समय के लिए काम करने वाली मेमोरी होती है. यह मेमोरी, एक सेशन के दौरान काम करती है. यह एक ऐसा डिक्शनरी ऑब्जेक्ट है जिसमें बदलाव किया जा सकता है.इसमें एजेंट, मौजूदा टास्क को पूरा करने के लिए ज़रूरी अस्थायी जानकारी सेव कर सकता है. जैसे, अब तक इकट्ठा की गई उपयोगकर्ता की प्राथमिकताएं, टूल कॉल से मिले इंटरमीडिएट नतीजे.
- मेमोरी: इससे पता चलता है कि एजेंट, अलग-अलग सेशन में लंबे समय तक जानकारी याद रख सकता है या बाहरी नॉलेज बेस को ऐक्सेस कर सकता है. सेशन और स्टेट, बातचीत को तुरंत हैंडल करते हैं. वहीं, मेमोरी (इसे अक्सर MemoryService मैनेज करता है) की मदद से एजेंट, पिछली बातचीत या स्ट्रक्चर्ड डेटा सोर्स से जानकारी पा सकता है. इससे उसे ज़्यादा जानकारी मिलती है. (ध्यान दें: हमारा सामान्य क्लाइंट, आसानी से इस्तेमाल करने के लिए इन-मेमोरी सेवाओं का इस्तेमाल करता है. इसका मतलब है कि स्क्रिप्ट के चलने के दौरान ही मेमोरी/स्टेट बनी रहती है).
- इवेंट: किसी सेशन में होने वाले हर इंटरैक्शन (उपयोगकर्ता का मैसेज, एजेंट का जवाब, टूल इस्तेमाल करने का अनुरोध, टूल का नतीजा, स्थिति में बदलाव, गड़बड़ी) को एक ऐसे इवेंट के तौर पर रिकॉर्ड किया जाता है जिसे बदला नहीं जा सकता. इससे, समय के हिसाब से लॉग तैयार होता है. इसमें बातचीत की ट्रांसक्रिप्ट और कार्रवाई का इतिहास शामिल होता है.
इसलिए, जब कोई एजेंट चलता है, तो इन्हें कैसे मैनेज किया जाता है? यह काम रनर का होता है.
- रनर: रनर, ADK की ओर से उपलब्ध कराया गया मुख्य एक्ज़ीक्यूशन इंजन है. आपको एजेंट और उसके इस्तेमाल किए जाने वाले टूल तय करने होते हैं. इसके बाद, Runner उपयोगकर्ता के अनुरोध को पूरा करने की प्रोसेस को मैनेज करता है. यह सेशन को मैनेज करता है, इवेंट के फ़्लो को हैंडल करता है, स्थिति को अपडेट करता है, बुनियादी भाषा मॉडल को चालू करता है, टूल कॉल को कोऑर्डिनेट करता है, और MemoryService के साथ इंटरैक्ट भी कर सकता है. इसे एक कंडक्टर के तौर पर समझें, जो यह पक्का करता है कि सभी अलग-अलग हिस्से एक साथ सही तरीके से काम करें.
हम Runner का इस्तेमाल करके, अपने एजेंट को एक स्टैंडअलोन Python ऐप्लिकेशन के तौर पर चला सकते हैं. यह Dev UI से पूरी तरह से अलग होता है.
आइए, हम अपने प्लानर एजेंट को प्रोग्राम के हिसाब से शुरू करने के लिए, एक सामान्य क्लाइंट स्क्रिप्ट बनाते हैं.
👉📝 फ़ाइल ~/instavibe-bootstrap/agents/planner/planner_client.py
में, मौजूदा इंपोर्ट के नीचे यह Python कोड जोड़ें. planner_client.py
में, इंपोर्ट के नीचे यह जोड़ें:
async def async_main():
session_service = InMemorySessionService()
session = await session_service.create_session(
state={}, app_name='planner_app', user_id='user_dc'
)
query = "Plan Something for me in San Francisco this weekend on wine and fashion "
print(f"User Query: '{query}'")
content = types.Content(role='user', parts=[types.Part(text=query)])
root_agent = agent.root_agent
runner = Runner(
app_name='planner_app',
agent=root_agent,
session_service=session_service,
)
print("Running agent...")
events_async = runner.run_async(
session_id=session.id, user_id=session.user_id, new_message=content
)
async for event in events_async:
print(f"Event received: {event}")
if __name__ == '__main__':
try:
asyncio.run(async_main())
except Exception as e:
print(f"An error occurred: {e}")
यह कोड, सेशन और आर्टफ़ैक्ट मैनेजमेंट के लिए इन-मेमोरी सेवाएं सेट अप करता है. इस उदाहरण में, इसे आसान रखा गया है. यह कोड एक सेशन बनाता है, उपयोगकर्ता की क्वेरी तय करता है, हमारे एजेंट के साथ रनर को कॉन्फ़िगर करता है, और फिर एजेंट को एसिंक्रोनस तरीके से चलाता है. साथ ही, एक्ज़ीक्यूशन के दौरान जनरेट हुए हर इवेंट को प्रिंट करता है.
👉💻 अब इस क्लाइंट स्क्रिप्ट को अपने टर्मिनल से लागू करें:
. ~/instavibe-bootstrap/set_env.sh
source ~/instavibe-bootstrap/env/bin/activate
cd ~/instavibe-bootstrap/agents
python -m planner.planner_client
👀 आउटपुट देखें. आपको सिर्फ़ फ़ाइनल JSON प्लान के बजाय, एजेंट के एक्ज़ीक्यूशन फ़्लो के दौरान जनरेट किए गए हर इवेंट ऑब्जेक्ट का ज़्यादा जानकारी वाला स्ट्रक्चर दिखेगा. इसमें उपयोगकर्ता के मैसेज से जुड़ा शुरुआती इवेंट, टूल कॉल (जैसे कि Google Search) से जुड़े संभावित इवेंट, और आखिर में, मॉडल के जवाब से जुड़ा इवेंट शामिल होता है. इस इवेंट में JSON प्लान शामिल होता है. यह इवेंट स्ट्रीम, डीबग करने और ADK रनटाइम में होने वाली चरण-दर-चरण प्रोसेसिंग को समझने के लिए बहुत उपयोगी है.
Running agent...
Event received: content=Content(parts=[Part(video_metadata=None, thought=None, code_execution_result=None, executable_code=None, file_data=None, function_call=None, function_response=None, inline_data=None, text='```json\n{\n "fun_plans": [\n {\n "plan_description": "Embark on a stylish adventure through Hayes Valley,
...(turncated)
, offering a variety of fashion styles to browse and enjoy."\n }\n ]\n }\n ]\n}\n```')], role='model') grounding_metadata=GroundingMetadata(grounding_chunks=[GroundingChunk(retrieved_context=None, web=GroundingChunkWeb(domain='islands.com', title='islands.com', uri='http
...(turncated)
QyTpPV7jS6wUt-Ix7GuP2mC9J4eY_8Km6Vv44liF9cb2VSs='))], grounding_supports=[GroundingSupport(confide
...(turncated)
>\n', sdk_blob=None), web_search_queries=['..e']) partial=None turn_complete=None error_code=None error_message=None interrupted=None custom_metadata=None invocation_id='e-04d97b8b-9021-47a5-ab41-17b5cbb4bf03' author='location_search_agent' actions=EventActions(skip_summarization=None, state_delta={}, artifact_delta={}, transfer_to_agent=None, escalate=None, requested_auth_configs={}) long_running_tool_ids=None branch=None id='CInHdkKw' timestamp=1746978846.232674
अगर स्क्रिप्ट लगातार चलती रहती है या रुक जाती है, तो आपको Ctrl+C
दबाकर इसे मैन्युअल तरीके से बंद करना पड़ सकता है.
7. Platform Interaction Agent - interact with MCP Server
ADK, हमारे एजेंट को स्ट्रक्चर करने में मदद करता है. हालांकि, उन्हें असल दुनिया में कार्रवाइयां करने के लिए, अक्सर बाहरी सिस्टम या एपीआई के साथ इंटरैक्ट करने की ज़रूरत होती है.
मॉडल कॉन्टेक्स्ट प्रोटोकॉल (एमसीपी)
मॉडल कॉन्टेक्स्ट प्रोटोकॉल (एमसीपी) एक ओपन स्टैंडर्ड है. इसे इस तरह से डिज़ाइन किया गया है कि एआई ऐप्लिकेशन, जैसे कि एजेंट, बाहरी डेटा सोर्स, टूल, और सिस्टम से कैसे कनेक्ट होते हैं. इसका मकसद, हर एआई ऐप्लिकेशन और डेटा सोर्स के कॉम्बिनेशन के लिए कस्टम इंटिग्रेशन की ज़रूरत को खत्म करना है. इसके लिए, यह एक यूनिवर्सल इंटरफ़ेस उपलब्ध कराता है. एमसीपी, क्लाइंट-सर्वर आर्किटेक्चर का इस्तेमाल करता है. इसमें एमसीपी क्लाइंट, एआई ऐप्लिकेशन (होस्ट) में मौजूद होते हैं. ये एमसीपी सर्वर से कनेक्शन मैनेज करते हैं. ये सर्वर, बाहरी प्रोग्राम होते हैं. ये कुछ खास फ़ंक्शन उपलब्ध कराते हैं. जैसे, स्थानीय डेटा को ऐक्सेस करना, एपीआई के ज़रिए रिमोट सेवाओं के साथ इंटरैक्ट करना या पहले से तय किए गए प्रॉम्प्ट उपलब्ध कराना. इससे एआई मॉडल को मौजूदा जानकारी ऐक्सेस करने और अपनी शुरुआती ट्रेनिंग से आगे बढ़कर टास्क पूरे करने में मदद मिलती है. इस स्ट्रक्चर की मदद से, एआई मॉडल स्टैंडर्ड तरीके से बाहरी क्षमताओं को खोज सकते हैं और उनके साथ इंटरैक्ट कर सकते हैं. इससे इंटिग्रेशन आसान हो जाते हैं और उन्हें ज़्यादा बेहतर तरीके से स्केल किया जा सकता है.
InstaVibe MCP सर्वर बनाना और उसे डिप्लॉय करना
हमारे एजेंट को InstaVibe प्लैटफ़ॉर्म के साथ इंटरैक्ट करना होगा.खास तौर पर, प्लैटफ़ॉर्म के मौजूदा एपीआई का इस्तेमाल करके पोस्ट बनाने और इवेंट रजिस्टर करने के लिए. InstaVibe ऐप्लिकेशन, स्टैंडर्ड एचटीटीपी एंडपॉइंट के ज़रिए पहले से ही ये सुविधाएं उपलब्ध कराता है:
एंडपॉइंट | URL | एचटीटीपी मेथड | ब्यौरा |
पोस्ट बनाएं | api/posts | पोस्ट करें | नई पोस्ट जोड़ने के लिए एपीआई एंडपॉइंट. JSON बॉडी की ज़रूरत है: |
इवेंट बनाएं | api/events | पोस्ट करें | नया इवेंट और उसमें शामिल होने वाले लोगों को जोड़ने के लिए एपीआई एंडपॉइंट (आसान स्कीमा). |
एमसीपी के ज़रिए हमारे एजेंट को ये सुविधाएं उपलब्ध कराने के लिए, हमें सबसे पहले आसान Python फ़ंक्शन बनाने होंगे. ये फ़ंक्शन, एपीआई कॉल के लिए रैपर के तौर पर काम करते हैं. ये फ़ंक्शन, एचटीटीपी अनुरोध के लॉजिक को हैंडल करेंगे.
👉 सबसे पहले, पोस्ट बनाने के लिए रैपर फ़ंक्शन लागू करते हैं. फ़ाइल ~/instavibe-bootstrap/tools/instavibe/instavibe.py
खोलें और #REPLACE ME CREATE POST
टिप्पणी को इस Python कोड से बदलें:
def create_post(author_name: str, text: str, sentiment: str, base_url: str = BASE_URL):
"""
Sends a POST request to the /posts endpoint to create a new post.
Args:
author_name (str): The name of the post's author.
text (str): The content of the post.
sentiment (str): The sentiment associated with the post (e.g., 'positive', 'negative', 'neutral').
base_url (str, optional): The base URL of the API. Defaults to BASE_URL.
Returns:
dict: The JSON response from the API if the request is successful.
Returns None if an error occurs.
Raises:
requests.exceptions.RequestException: If there's an issue with the network request (e.g., connection error, timeout).
"""
url = f"{base_url}/posts"
headers = {"Content-Type": "application/json"}
payload = {
"author_name": author_name,
"text": text,
"sentiment": sentiment
}
try:
response = requests.post(url, headers=headers, json=payload)
response.raise_for_status() # Raise an exception for bad status codes (4xx or 5xx)
print(f"Successfully created post. Status Code: {response.status_code}")
return response.json()
except requests.exceptions.RequestException as e:
print(f"Error creating post: {e}")
# Optionally re-raise the exception if the caller needs to handle it
# raise e
return None
except json.JSONDecodeError:
print(f"Error decoding JSON response from {url}. Response text: {response.text}")
return None
👉📝 इसके बाद, हम इवेंट बनाने वाले एपीआई के लिए रैपर फ़ंक्शन बनाएंगे. उसी ~/instavibe-bootstrap/tools/instavibe/instavibe.py
फ़ाइल में, #REPLACE ME CREATE EVENTS
टिप्पणी को इस कोड से बदलें:
def create_event(event_name: str, description: str, event_date: str, locations: list, attendee_names: list[str], base_url: str = BASE_URL):
"""
Sends a POST request to the /events endpoint to create a new event registration.
Args:
event_name (str): The name of the event.
description (str): The detailed description of the event.
event_date (str): The date and time of the event (ISO 8601 format recommended, e.g., "2025-06-10T09:00:00Z").
locations (list): A list of location dictionaries. Each dictionary should contain:
'name' (str), 'description' (str, optional),
'latitude' (float), 'longitude' (float),
'address' (str, optional).
attendee_names (list[str]): A list of names of the people attending the event.
base_url (str, optional): The base URL of the API. Defaults to BASE_URL.
Returns:
dict: The JSON response from the API if the request is successful.
Returns None if an error occurs.
Raises:
requests.exceptions.RequestException: If there's an issue with the network request (e.g., connection error, timeout).
"""
url = f"{base_url}/events"
headers = {"Content-Type": "application/json"}
payload = {
"event_name": event_name,
"description": description,
"event_date": event_date,
"locations": locations,
"attendee_names": attendee_names,
}
try:
response = requests.post(url, headers=headers, json=payload)
response.raise_for_status() # Raise an exception for bad status codes (4xx or 5xx)
print(f"Successfully created event registration. Status Code: {response.status_code}")
return response.json()
except requests.exceptions.RequestException as e:
print(f"Error creating event registration: {e}")
# Optionally re-raise the exception if the caller needs to handle it
# raise e
return None
except json.JSONDecodeError:
print(f"Error decoding JSON response from {url}. Response text: {response.text}")
return None
जैसा कि आप देख सकते हैं, ये फ़ंक्शन मौजूदा InstaVibe API के चारों ओर सीधे तौर पर रैपर हैं. अगर आपके पास पहले से ही अपनी सेवाओं के लिए एपीआई हैं, तो इस पैटर्न का इस्तेमाल किया जा सकता है. इससे, रैपर बनाकर एजेंट के लिए टूल के तौर पर उनकी सुविधाओं को आसानी से उपलब्ध कराया जा सकता है.
MCP सर्वर लागू करना
अब हमारे पास Python फ़ंक्शन हैं, जो कार्रवाइयां करते हैं (InstaVibe API को कॉल करना). इसलिए, हमें MCP सर्वर कॉम्पोनेंट बनाना होगा. यह सर्वर, इन फ़ंक्शन को एमसीपी स्टैंडर्ड के मुताबिक "टूल" के तौर पर दिखाएगा. इससे एमसीपी क्लाइंट (जैसे कि हमारे एजेंट) इन्हें ढूंढकर इस्तेमाल कर पाएंगे.
आम तौर पर, एमसीपी सर्वर दो मुख्य फ़ंक्शन लागू करता है:
- list_tools: यह क्लाइंट को सर्वर पर उपलब्ध टूल ढूंढने की अनुमति देता है. साथ ही, उनके नाम, ब्यौरे, और ज़रूरी पैरामीटर जैसे मेटाडेटा उपलब्ध कराता है. इन्हें अक्सर JSON स्कीमा का इस्तेमाल करके तय किया जाता है
- call_tool: यह क्लाइंट के अनुरोध किए गए किसी टूल को लागू करता है. साथ ही, टूल का नाम और आर्ग्युमेंट पाता है और उससे जुड़ी कार्रवाई करता है. जैसे, हमारे मामले में किसी एपीआई के साथ इंटरैक्ट करना
एमसीपी सर्वर का इस्तेमाल, एआई मॉडल को असल दुनिया के डेटा और कार्रवाइयों का ऐक्सेस देने के लिए किया जाता है. इससे ईमेल भेजने, प्रोजेक्ट मैनेजमेंट सिस्टम में टास्क बनाने, डेटाबेस खोजने या अलग-अलग सॉफ़्टवेयर और वेब सेवाओं के साथ इंटरैक्ट करने जैसे काम किए जा सकते हैं. शुरुआत में, लागू करने के दौरान अक्सर लोकल सर्वर पर फ़ोकस किया जाता था. ये सर्वर, स्टैंडर्ड इनपुट/आउटपुट (stdio) के ज़रिए कम्यूनिकेट करते थे, ताकि इसे आसानी से समझा जा सके. खास तौर पर, डेवलपमेंट या "स्टूडियो" एनवायरमेंट में. हालांकि, रिमोट सर्वर की ओर बढ़ने से, एचटीटीपी जैसे प्रोटोकॉल का इस्तेमाल किया जा सकता है. साथ ही, सर्वर-सेंट इवेंट (एसएसई) का इस्तेमाल किया जा सकता है. इससे, बड़े पैमाने पर इसे अपनाने और एंटरप्राइज़ के इस्तेमाल के मामलों के लिए यह ज़्यादा फ़ायदेमंद होता है.
रिमोट आर्किटेक्चर में, नेटवर्क कम्यूनिकेशन लेयर के बावजूद कई फ़ायदे मिलते हैं: इससे कई एआई क्लाइंट, एक ही सर्वर का ऐक्सेस शेयर कर सकते हैं. साथ ही, टूल के मैनेजमेंट और अपडेट को केंद्रीकृत किया जा सकता है. इसके अलावा, संवेदनशील डेटा और एपीआई कुंजियों को सर्वर साइड पर रखकर सुरक्षा को बेहतर बनाया जा सकता है. ऐसा इसलिए, क्योंकि इन्हें कई क्लाइंट मशीनों पर डिस्ट्रिब्यूट नहीं किया जाता. साथ ही, एआई मॉडल को बाहरी सिस्टम इंटिग्रेशन की खास बातों से अलग किया जाता है. इससे पूरा इकोसिस्टम, हर एआई इंस्टेंस को अपने डायरेक्ट इंटिग्रेशन मैनेज करने की ज़रूरत के मुकाबले ज़्यादा स्केलेबल, सुरक्षित, और रखरखाव करने में आसान हो जाता है.
हमारा एमसीपी सर्वर, कम्यूनिकेशन के लिए एचटीटीपी और सर्वर-सेंट इवेंट (एसएसई) का इस्तेमाल करेगा. यह लंबे समय तक चलने वाले टूल एक्ज़ीक्यूशन और एंटरप्राइज़ के इस्तेमाल के लिए सबसे सही है.
👉📝 सबसे पहले, list_tools एंडपॉइंट लागू करते हैं. फ़ाइल ~/instavibe-bootstrap/tools/instavibe/mcp_server.py
खोलें और #REPLACE ME - LIST TOOLS
टिप्पणी को इस कोड से बदलें. :
@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
mcp_tool_schema_event = adk_to_mcp_tool_type(event_tool)
mcp_tool_schema_post = adk_to_mcp_tool_type(post_tool)
print(f"MCP Server: Received list_tools request. \n MCP Server: Advertising tool: {mcp_tool_schema_event.name} and {mcp_tool_schema_post}")
return [mcp_tool_schema_event,mcp_tool_schema_post]
यह फ़ंक्शन, टूल (create_event, create_post) के बारे में बताता है और कनेक्ट किए गए क्लाइंट को उनके बारे में जानकारी देता है.
👉📝 इसके बाद, call_tool
एंडपॉइंट लागू करें. यह क्लाइंट से मिले अनुरोधों को पूरा करता है. उसी ~/instavibe-bootstrap/tools/instavibe/mcp_server.py
फ़ाइल में, #REPLACE ME - CALL TOOLS
टिप्पणी की जगह यह कोड डालें.
@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)]
यह फ़ंक्शन, टूल का नाम और आर्ग्युमेंट लेता है. इसके बाद, यह उस Python रैपर फ़ंक्शन को ढूंढता है जिसे हमने पहले तय किया था. फिर, यह उसे लागू करता है और नतीजा दिखाता है
👉💻 एमसीपी सर्वर लॉजिक तय करने के बाद, अब हमें इसे कंटेनर के तौर पर पैकेज करना होगा. इसके लिए, टर्मिनल में यह स्क्रिप्ट चलाएं, ताकि Cloud Build का इस्तेमाल करके Docker इमेज बनाई जा सके:
. ~/instavibe-bootstrap/set_env.sh
cd ~/instavibe-bootstrap/tools/instavibe
export IMAGE_TAG="latest"
export MCP_IMAGE_NAME="mcp-tool-server"
export IMAGE_PATH="${REGION}-docker.pkg.dev/${PROJECT_ID}/${REPO_NAME}/${MCP_IMAGE_NAME}:${IMAGE_TAG}"
export SERVICE_NAME="mcp-tool-server"
export INSTAVIBE_BASE_URL=$(gcloud run services list --platform=managed --region=us-central1 --format='value(URL)' | grep instavibe)/api
gcloud builds submit . \
--tag=${IMAGE_PATH} \
--project=${PROJECT_ID}
👉💻 इसके बाद, इमेज को Google Cloud Run पर सेवा के तौर पर डिप्लॉय करें.
. ~/instavibe-bootstrap/set_env.sh
cd ~/instavibe-bootstrap/tools/instavibe
export IMAGE_TAG="latest"
export MCP_IMAGE_NAME="mcp-tool-server"
export IMAGE_PATH="${REGION}-docker.pkg.dev/${PROJECT_ID}/${REPO_NAME}/${MCP_IMAGE_NAME}:${IMAGE_TAG}"
export SERVICE_NAME="mcp-tool-server"
export INSTAVIBE_BASE_URL=$(gcloud run services list --platform=managed --region=us-central1 --format='value(URL)' | grep instavibe)/api
gcloud run deploy ${SERVICE_NAME} \
--image=${IMAGE_PATH} \
--platform=managed \
--region=${REGION} \
--allow-unauthenticated \
--set-env-vars="INSTAVIBE_BASE_URL=${INSTAVIBE_BASE_URL}" \
--set-env-vars="APP_HOST=0.0.0.0" \
--set-env-vars="APP_PORT=8080" \
--set-env-vars="GOOGLE_GENAI_USE_VERTEXAI=TRUE" \
--set-env-vars="GOOGLE_CLOUD_LOCATION=${REGION}" \
--set-env-vars="GOOGLE_CLOUD_PROJECT=${PROJECT_ID}" \
--project=${PROJECT_ID} \
--min-instances=1
👉💻 डिप्लॉयमेंट पूरा होने के बाद, MCP सर्वर चालू हो जाएगा. इसे सार्वजनिक यूआरएल के ज़रिए ऐक्सेस किया जा सकेगा. हमें इस यूआरएल को कैप्चर करना होगा, ताकि हमारा एजेंट (एमसीपी क्लाइंट के तौर पर काम करने वाला) जान सके कि उसे कहां कनेक्ट करना है.
export MCP_SERVER_URL=$(gcloud run services list --platform=managed --region=us-central1 --format='value(URL)' | grep mcp-tool-server)/sse
अब आपको Google Cloud Console के Cloud Run सेक्शन में, mcp-tool-server सेवा "चालू है" के तौर पर दिखनी चाहिए.
एमसीपी सर्वर को डिप्लॉय करने और उसका यूआरएल कैप्चर करने के बाद, अब हम ऐसे एजेंट को लागू कर सकते हैं जो एमसीपी क्लाइंट के तौर पर काम करेगा और इस सर्वर से उपलब्ध कराए गए टूल का इस्तेमाल करेगा.
8. प्लैटफ़ॉर्म इंटरैक्शन एजेंट (एमसीपी का इस्तेमाल करता है)
MCP क्लाइंट MCP क्लाइंट, एआई ऐप्लिकेशन या एजेंट में मौजूद एक कॉम्पोनेंट होता है. यह एआई मॉडल और एक या उससे ज़्यादा MCP सर्वर के बीच इंटरफ़ेस का काम करता है. हमारे लागू करने के तरीके में, इस क्लाइंट को सीधे तौर पर हमारे एजेंट में इंटिग्रेट किया जाएगा. इस क्लाइंट का मुख्य काम, एमसीपी सर्वर के साथ कम्यूनिकेट करना है. इससे list_tools
फ़ंक्शन के ज़रिए उपलब्ध टूल के बारे में पता चलता है. इसके बाद, call_tool
फ़ंक्शन का इस्तेमाल करके, खास टूल को लागू करने का अनुरोध किया जाता है. साथ ही, एआई मॉडल या कॉल को व्यवस्थित करने वाले एजेंट से मिले ज़रूरी आर्ग्युमेंट पास किए जाते हैं.
अब हम ऐसा एजेंट बनाएंगे जो एमसीपी क्लाइंट के तौर पर काम करेगा. ADK फ़्रेमवर्क में काम करने वाला यह एजेंट, अभी-अभी डिप्लॉय किए गए mcp-tool-server
के साथ कम्यूनिकेट करने के लिए ज़िम्मेदार होगा.
👉 सबसे पहले, हमें एजेंट की परिभाषा में बदलाव करना होगा, ताकि चालू एमसीपी सर्वर से टूल को डाइनैमिक तरीके से फ़ेच किया जा सके. agents/platform_mcp_client/agent.py
में, #REPLACE ME - FETCH TOOLS
को इससे बदलें:
"""Gets tools from the File System MCP Server."""
tools = MCPToolset(
connection_params=SseServerParams(url=MCP_SERVER_URL, headers={})
)
यह कोड, MCPToolset.from_server तरीके का इस्तेमाल करके MCP_SERVER_URL से कनेक्ट होता है. इसे हमने पहले एनवायरमेंट वैरिएबल के तौर पर सेट किया था. साथ ही, यह उपलब्ध टूल की सूची को वापस पाता है.
इसके बाद, हमें ADK एजेंट की परिभाषा को यह बताना होगा कि इन डाइनैमिक तौर पर फ़ेच किए गए टूल का इस्तेमाल कैसे करना है.
👉 agents/platform_mcp_client/agent.py
में, #REPLACE ME - SET TOOLs
की जगह यह डालें:
tools=[tools],
👉💻 अब, ADK Dev UI का इस्तेमाल करके, इस एजेंट को स्थानीय तौर पर टेस्ट करते हैं. इससे यह पता चलेगा कि यह MCP सर्वर से सही तरीके से कनेक्ट हो सकता है या नहीं. साथ ही, यह भी पता चलेगा कि यह हमारे चालू InstaVibe ऐप्लिकेशन के साथ इंटरैक्ट करने के लिए टूल का इस्तेमाल कर सकता है या नहीं.
. ~/instavibe-bootstrap/set_env.sh
source ~/instavibe-bootstrap/env/bin/activate
export MCP_SERVER_URL=$(gcloud run services list --platform=managed --region=us-central1 --format='value(URL)' | grep mcp-tool-server)/sse
cd ~/instavibe-bootstrap/agents
sed -i "s|^\(O\?GOOGLE_CLOUD_PROJECT\)=.*|GOOGLE_CLOUD_PROJECT=${PROJECT_ID}|" ~/instavibe-bootstrap/agents/platform_mcp_client/.env
sed -i "s|^\(O\?MCP_SERVER_URL\)=.*|MCP_SERVER_URL=${MCP_SERVER_URL}|" ~/instavibe-bootstrap/agents/platform_mcp_client/.env
adk web
अपने ब्राउज़र में ADK Dev UI को फिर से खोलें. इसके लिए, Cloud Shell के वेब प्रीव्यू का इस्तेमाल करें. यह पोर्ट 8000 पर उपलब्ध है. इस बार, सबसे ऊपर दाईं ओर मौजूद ड्रॉपडाउन में, platform_mcp_client
एजेंट को चुनें.
आइए, create_post टूल को टेस्ट करते हैं. चैट डायलॉग में, यह अनुरोध डालें:
Create a post saying "Y'all I just got the cutest lil void baby 😭✨ Naming him Abyss bc he's deep, mysterious, and lowkey chaotic 🔥🖤 #VoidCat #NewRoomie" I'm Julia
एजेंट को इस अनुरोध को प्रोसेस करना चाहिए. साथ ही, यह पता लगाना चाहिए कि create_post टूल का इस्तेमाल करना है या नहीं. इसके बाद, उसे MCP सर्वर से कम्यूनिकेट करना चाहिए. यह सर्वर, InstaVibe API को कॉल करता है.
👉 पुष्टि करने का तरीका: एजेंट के कार्रवाई की पुष्टि करने के बाद, उस टैब को खोलें जहां InstaVibe ऐप्लिकेशन चल रहा है. इसके अलावा, उसे रीफ़्रेश भी किया जा सकता है. आपको मुख्य फ़ीड में "Julia" की नई पोस्ट दिखनी चाहिए!
👉💻 अगर आपको Instavibe का लिंक चाहिए, तो इस स्क्रिप्ट को अलग टर्मिनल में चलाएं:
gcloud run services list --platform=managed --region=us-central1 --format='value(URL)' | grep instavibe
👉📝 अब, create_event टूल को टेस्ट करते हैं. चैट डायलॉग में, यहां दिया गया मल्टी-लाइन अनुरोध डालें:
Hey, can you set up an event for Hannah and George and me, and I'm Julia? Let's call it 'Mexico City Culinary & Art Day'.
here are more info
{"event_name": "Mexico City Culinary & Art Day",
"description": "A vibrant day in Mexico City for Hannah and George, starting with lunch at one of the city's best taco spots in the hip Condesa neighborhood, followed by an inspiring afternoon exploring the Museo Soumaya's stunning art collection.",
"event_date": "2025-10-17T12:00:00-06:00",
"locations": [
{
"name": "El Tizoncito",
"description": "Considered one of the original creators of tacos al pastor, El Tizoncito offers a legendary taco experience in the heart of Condesa. Their flavorful meats, house salsas, and casual vibe make it a must-visit for foodies.",
"latitude": 19.412179,
"longitude": -99.171308,
"address": "Av. Tamaulipas 122, Hipódromo, Cuauhtémoc, 06100 Ciudad de México, CDMX, Mexico"
},
{
"name": "Museo Soumaya",
"description": "An architectural icon in Mexico City, Museo Soumaya houses over 66,000 works of art, including pieces by Rodin, Dalí, and Rivera. The striking silver structure is a cultural landmark and a visual feast inside and out.",
"latitude": 19.440056,
"longitude": -99.204281,
"address": "Plaza Carso, Blvd. Miguel de Cervantes Saavedra 303, Granada, Miguel Hidalgo, 11529 Ciudad de México, CDMX, Mexico"
}
],
"attendee_names": ["Hannah", "George", Julia],
}
इसके बाद, एजेंट को एमसीपी सर्वर के ज़रिए सही टूल का इस्तेमाल करना चाहिए. Events टैब में, किसी इवेंट पर क्लिक करें. आपको इवेंट के एक्ज़ीक्यूशन की पूरी जानकारी, चरण-दर-चरण दिखेगी.
👉 पुष्टि करने का चरण: InstaVibe ऐप्लिकेशन पर वापस जाएं और "इवेंट" सेक्शन (या इसके जैसा कोई अन्य सेक्शन) पर जाएं. अब आपको "मेक्सिको सिटी में खाना और कला का दिन" इवेंट की सूची दिखेगी.
इससे पता चलता है कि एमसीपी की मदद से, हमारा एजेंट स्टैंडर्ड तरीके से बाहरी टूल (इस मामले में, InstaVibe के एपीआई) का इस्तेमाल कैसे कर सकता है.
दोनों कार्रवाइयों की पुष्टि करने के बाद, Cloud Shell टर्मिनल पर वापस जाएं और ADK Dev UI को रोकने के लिए Ctrl+C
दबाएं.
9. ADK में वर्कफ़्लो एजेंट और मल्टी-एजेंट
फ़िलहाल, हमारे एजेंट आउटिंग प्लान कर सकते हैं और प्लैटफ़ॉर्म से इंटरैक्ट कर सकते हैं. हालांकि, लोगों की दिलचस्पी के हिसाब से प्लान बनाने के लिए, उपयोगकर्ता के सोशल सर्कल को समझना ज़रूरी है. जो लोग व्यस्त रहते हैं और अपने दोस्तों की गतिविधियों पर ज़्यादा ध्यान नहीं देते उनके लिए, इस कॉन्टेक्स्ट को मैन्युअल तरीके से इकट्ठा करना मुश्किल होता है. इस समस्या को हल करने के लिए, हम सोशल प्रोफ़ाइलिंग एजेंट बनाएंगे. यह एजेंट, हमारे Spanner Graph Database का इस्तेमाल करके, दोस्तों की गतिविधियों और उनकी दिलचस्पी का विश्लेषण करेगा. इससे, ज़्यादा काम के सुझाव दिए जा सकेंगे.
सबसे पहले, हमें इस एजेंट के लिए ऐसे टूल चाहिए जिनकी मदद से वह ग्राफ़ डेटा को ऐक्सेस कर सके.
👉📝 फ़ाइल ~/instavibe-bootstrap/agents/social/instavibe.py
के आखिर में, यहां दिए गए Python फ़ंक्शन जोड़ें:
def get_person_attended_events(person_id: str)-> list[dict]:
"""
Fetches events attended by a specific person using Graph Query.
Args:
person_id (str): The ID of the person whose posts to fetch.
Returns: list[dict] or None.
"""
if not db_instance: return None
graph_sql = """
Graph SocialGraph
MATCH (p:Person)-[att:Attended]->(e:Event)
WHERE p.person_id = @person_id
RETURN e.event_id, e.name, e.event_date, att.attendance_time
ORDER BY e.event_date DESC
"""
params = {"person_id": person_id}
param_types_map = {"person_id": param_types.STRING}
fields = ["event_id", "name", "event_date", "attendance_time"]
results = run_graph_query( graph_sql, params=params, param_types=param_types_map, expected_fields=fields)
if results is None: return None
for event in results:
if isinstance(event.get('event_date'), datetime):
event['event_date'] = event['event_date'].isoformat()
if isinstance(event.get('attendance_time'), datetime):
event['attendance_time'] = event['attendance_time'].isoformat()
return results
def get_person_id_by_name( name: str) -> str:
"""
Fetches the person_id for a given name using SQL.
Args:
name (str): The name of the person to search for.
Returns:
str or None: The person_id if found, otherwise None.
Returns the ID of the *first* match if names are duplicated.
"""
if not db_instance: return None
sql = """
SELECT person_id
FROM Person
WHERE name = @name
LIMIT 1 -- Return only the first match in case of duplicate names
"""
params = {"name": name}
param_types_map = {"name": param_types.STRING}
fields = ["person_id"]
# Use the standard SQL query helper
results = run_sql_query( sql, params=params, param_types=param_types_map, expected_fields=fields)
if results: # Check if the list is not empty
return results[0].get('person_id') # Return the ID from the first dictionary
else:
return None # Name not found
def get_person_posts( person_id: str)-> list[dict]:
"""
Fetches posts written by a specific person using Graph Query.
Args:
person_id (str): The ID of the person whose posts to fetch.
Returns:
list[dict] or None: List of post dictionaries with ISO date strings,
or None if an error occurs.
"""
if not db_instance: return None
# Graph Query: Find the specific Person node, follow 'Wrote' edge to Post nodes
graph_sql = """
Graph SocialGraph
MATCH (author:Person)-[w:Wrote]->(post:Post)
WHERE author.person_id = @person_id
RETURN post.post_id, post.author_id, post.text, post.sentiment, post.post_timestamp, author.name AS author_name
ORDER BY post.post_timestamp DESC
"""
# Parameters now include person_id and limit
params = {
"person_id": person_id
}
param_types_map = {
"person_id": param_types.STRING
}
# Fields returned remain the same
fields = ["post_id", "author_id", "text", "sentiment", "post_timestamp", "author_name"]
results = run_graph_query(graph_sql, params=params, param_types=param_types_map, expected_fields=fields)
if results is None:
return None
# Convert datetime objects to ISO format strings
for post in results:
if isinstance(post.get('post_timestamp'), datetime):
post['post_timestamp'] = post['post_timestamp'].isoformat()
return results
def get_person_friends( person_id: str)-> list[dict]:
"""
Fetches friends for a specific person using Graph Query.
Args:
person_id (str): The ID of the person whose posts to fetch.
Returns: list[dict] or None.
"""
if not db_instance: return None
graph_sql = """
Graph SocialGraph
MATCH (p:Person {person_id: @person_id})-[f:Friendship]-(friend:Person)
RETURN DISTINCT friend.person_id, friend.name
ORDER BY friend.name
"""
params = {"person_id": person_id}
param_types_map = {"person_id": param_types.STRING}
fields = ["person_id", "name"]
results = run_graph_query( graph_sql, params=params, param_types=param_types_map, expected_fields=fields)
return results
अब, हम अपने एजेंट को स्ट्रक्चर करने के तरीके के बारे में बात करते हैं. एक से ज़्यादा दोस्तों की प्रोफ़ाइलों का विश्लेषण करने और फिर नतीजों की खास जानकारी देने में कई चरण शामिल होते हैं. यह ADK की मल्टी-एजेंट क्षमताओं का इस्तेमाल करने के लिए सबसे सही उदाहरण है. खास तौर पर, वर्कफ़्लो एजेंट.
Google के ADK में, वर्कफ़्लो एजेंट खुद टास्क पूरे नहीं करता. इसके बजाय, वह अन्य एजेंट को मैनेज करता है. इन एजेंट को सब-एजेंट कहा जाता है. इससे मॉड्यूलर डिज़ाइन तैयार किया जा सकता है. साथ ही, मुश्किल समस्याओं को खास कॉम्पोनेंट में बांटा जा सकता है. ADK में, वर्कफ़्लो के बिल्ट-इन टाइप उपलब्ध होते हैं. जैसे,
- सीक्वेंशियल (एक के बाद एक)
- पैरलल (एक साथ कई काम करना)
- और लूप (बार-बार एक्ज़ीक्यूट करना)
सोशल प्रोफ़ाइलिंग के टास्क के लिए, हमारा डिज़ाइन एक लूप एजेंट का इस्तेमाल करता है, ताकि बार-बार होने वाले वर्कफ़्लो को बनाया जा सके. इसका मकसद एक बार में सिर्फ़ एक व्यक्ति के डेटा को प्रोसेस करना है: profile_agent
डेटा इकट्ठा करता है, summary_agent
विश्लेषण को अपडेट करता है, और check_agent
यह तय करता है कि हमें फिर से लूप करना चाहिए या नहीं.
आइए, इस वर्कफ़्लो के लिए ज़रूरी सब-एजेंट तय करते हैं.
👉📝 ~/instavibe-bootstrap/agents/social/agent.py
में, #REPLACE FOR profile_agent
को इससे बदलें:
profile_agent = LlmAgent(
name="profile_agent",
model="gemini-2.5-flash",
description=(
"Agent to answer questions about the this person social profile. Provide the person's profile using their name, make sure to fetch the id before getting other data."
),
instruction=(
"You are a helpful agent to answer questions about the this person social profile. You'll be given a list of names, provide the person's profile using their name, make sure to fetch the id before getting other data. Get one person at a time, start with the first one on the list, and skip if already provided. return this person's result"
),
tools=[get_person_posts,get_person_friends,get_person_id_by_name,get_person_attended_events],
)
इसके बाद, एजेंट इकट्ठा की गई प्रोफ़ाइल की जानकारी लेता है. यह जानकारी, लूप के सभी वर्शन से इकट्ठा की जाती है. इसके बाद, एजेंट फ़ाइनल जवाब जनरेट करता है. अगर कई लोगों की प्रोफ़ाइल का विश्लेषण किया गया है, तो एजेंट यह भी बताता है कि उनमें क्या समानताएं हैं.
👉📝 उसी ~/instavibe-bootstrap/agents/social/agent.py
में, #REPLACE FOR summary_agent
की जगह यह डालें:
summary_agent = LlmAgent(
name="summary_agent",
model="gemini-2.5-flash",
description=(
"Generate a comprehensive social summary as a single, cohesive paragraph. This summary should cover the activities, posts, friend networks, and event participation of one or more individuals. If multiple profiles are analyzed, the paragraph must also identify and integrate any common ground found between them."
),
instruction=(
"""
Your primary task is to synthesize social profile information into a single, comprehensive paragraph.
**Input Scope & Default Behavior:**
* If specific individuals are named by the user, focus your analysis on them.
* **If no individuals are specified, or if the request is general, assume the user wants an analysis of *all relevant profiles available in the current dataset/context*.**
**For each profile (whether specified or determined by default), you must analyze:**
1. **Post Analysis:**
* Systematically review their posts (e.g., content, topics, frequency, engagement).
* Identify recurring themes, primary interests, and expressed sentiments.
2. **Friendship Relationship Analysis:**
* Examine their connections/friends list.
* Identify key relationships, mutual friends (especially if comparing multiple profiles), and the general structure of their social network.
3. **Event Participation Analysis:**
* Investigate their past (and if available, upcoming) event participation.
* Note the types of events, frequency of attendance, and any notable roles (e.g., organizer, speaker).
**Output Generation (Single Paragraph):**
* **Your entire output must be a single, cohesive summary paragraph.**
* **If analyzing a single profile:** This paragraph will detail their activities, interests, and social connections based on the post, friend, and event analysis.
* **If analyzing multiple profiles:** This paragraph will synthesize the key findings regarding posts, friends, and events for each individual. Crucially, it must then seamlessly integrate or conclude with an identification and description of the common ground found between them (e.g., shared interests from posts, overlapping event attendance, mutual friends). The aim is a unified narrative within this single paragraph.
**Key Considerations:**
* Base your summary strictly on the available data.
* If data for a specific category (posts, friends, events) is missing or sparse for a profile, you may briefly acknowledge this within the narrative if relevant.
"""
),
output_key="summary"
)
हमें यह तय करने का तरीका चाहिए कि लूप कब बंद होना चाहिए. इसका मतलब है कि जब अनुरोध की गई सभी प्रोफ़ाइलों की खास जानकारी मिल जाए, तब लूप बंद हो जाना चाहिए
👉📝 उसी ~/instavibe-bootstrap/agents/social/agent.py
में, #REPLACE FOR check_agent
की जगह यह डालें:
check_agent = LlmAgent(
name="check_agent",
model="gemini-2.5-flash",
description=(
"Check if everyone's social profile are summarized and has been generated. Output 'completed' or 'pending'."
),
output_key="summary_status"
)
हम एक आसान प्रोग्रामैटिक चेक (CheckCondition) जोड़ते हैं. यह summary_status
को साफ़ तौर पर देखता है. यह State में सेव होता है. इसे check_agent
से वापस लाया जाता है. यह Loop Agent को बताता है कि जारी रखना है (escalate=False) या रोकना है (escalate=True).
👉📝 उसी ~/instavibe-bootstrap/agents/social/agent.py
में, फ़ाइल के सबसे ऊपर मौजूद #REPLACE FOR CheckCondition
को इससे बदलें:
class CheckCondition(BaseAgent):
async def _run_async_impl(self, ctx: InvocationContext) -> AsyncGenerator[Event, None]:
#log.info(f"Checking status: {ctx.session.state.get("summary_status", "fail")}")
log.info(f"Summary: {ctx.session.state.get("summary")}")
status = ctx.session.state.get("summary_status", "fail").strip()
is_done = (status == "completed")
yield Event(author=self.name, actions=EventActions(escalate=is_done))
लूप के नतीजों के लिए स्थिति और कॉलबैक
Google के ADK में, स्टेट एक अहम कॉन्सेप्ट है. यह किसी एजेंट के एक्ज़ीक्यूशन के दौरान उसकी मेमोरी या वर्किंग डेटा को दिखाता है. यह एक ऐसा कॉन्टेक्स्ट होता है जो लगातार बना रहता है. इसमें वह जानकारी होती है जिसे एजेंट को अलग-अलग चरणों, टूल कॉल या इंटरैक्शन के दौरान बनाए रखना होता है. इस स्थिति में, बीच के नतीजे, उपयोगकर्ता की जानकारी, आगे की कार्रवाइयों के लिए पैरामीटर या कोई भी ऐसा डेटा सेव किया जा सकता है जिसे एजेंट को किसी टास्क को पूरा करने के दौरान याद रखना होता है.
हमारे उदाहरण में, Loop Agent के दोहराने पर, summary_agent
और check_agent
अपने आउटपुट (summary और summary_status) को एजेंट के स्टेट में सेव करते हैं. इससे जानकारी को कई बार दोहराया जा सकता है. हालांकि, लूप एजेंट के खत्म होने पर, वह अपने-आप जवाब नहीं देता है.
ADK में कॉलबैक की मदद से, हम कस्टम लॉजिक को शामिल कर सकते हैं. इसे एजेंट की लाइफ़साइकल के दौरान किसी खास पॉइंट पर या कुछ इवेंट के जवाब में लागू किया जा सकता है. जैसे, टूल कॉल पूरा होने पर या एजेंट के काम पूरा करने से पहले. इनसे एजेंट के व्यवहार को पसंद के मुताबिक बनाया जा सकता है. साथ ही, इनसे डाइनैमिक तरीके से नतीजे प्रोसेस किए जा सकते हैं.
हम एक ऐसे after_agent_callback
का इस्तेमाल करेंगे जो लूप के खत्म होने पर चलता है. ऐसा इसलिए, क्योंकि CheckCondition बढ़ गया है. यह कॉलबैक modify_output_after_agent
, स्थिति से फ़ाइनल जवाब को वापस लाता है और उसे एजेंट के फ़ाइनल आउटपुट मैसेज के तौर पर फ़ॉर्मैट करता है.
👉📝 उसी ~/instavibe-bootstrap/agents/social/agent.py
में, #REPLACE FOR modify_output_after_agent
को follow से बदलें:
def modify_output_after_agent(callback_context: CallbackContext) -> Optional[types.Content]:
agent_name = callback_context.agent_name
invocation_id = callback_context.invocation_id
current_state = callback_context.state.to_dict()
current_user_content = callback_context.user_content
print(f"[Callback] Exiting agent: {agent_name} (Inv: {invocation_id})")
print(f"[Callback] Current summary_status: {current_state.get("summary_status")}")
print(f"[Callback] Current Content: {current_user_content}")
status = current_state.get("summary_status").strip()
is_done = (status == "completed")
# Retrieve the final summary from the state
final_summary = current_state.get("summary")
print(f"[Callback] final_summary: {final_summary}")
if final_summary and is_done and isinstance(final_summary, str):
log.info(f"[Callback] Found final summary, constructing output Content.")
# Construct the final output Content object to be sent back
return types.Content(role="model", parts=[types.Part(text=final_summary.strip())])
else:
log.warning("[Callback] No final summary found in state or it's not a string.")
# Optionally return a default message or None if no summary was generated
return None
रूट लूप एजेंट तय करना
आखिर में, हम मुख्य LoopAgent को तय करते हैं. यह हर लूप इटरेशन में सब-एजेंट को क्रम से व्यवस्थित करता है (profile_agent -> summary_agent -> check_agent -> CheckCondition). यह इस क्रम को max_iterations बार तक दोहराएगा या तब तक दोहराएगा, जब तक CheckCondition सिग्नल पूरा नहीं हो जाता. after_agent_callback से यह पक्का किया जाता है कि जवाब में खास जानकारी शामिल हो.
👉📝 उसी ~/instavibe-bootstrap/agents/social/agent.py
में, #REPLACE FOR root_agent
को follow से बदलें:
root_agent = LoopAgent(
name="InteractivePipeline",
sub_agents=[
profile_agent,
summary_agent,
check_agent,
CheckCondition(name="Checker")
],
description="Find everyone's social profile on events, post and friends",
max_iterations=10,
after_agent_callback=modify_output_after_agent
)
आइए, ADK Dev UI का इस्तेमाल करके इस मल्टी-एजेंट वर्कफ़्लो की जांच करें.
👉💻 ADK वेब सर्वर लॉन्च करें:
. ~/instavibe-bootstrap/set_env.sh
source ~/instavibe-bootstrap/env/bin/activate
cd ~/instavibe-bootstrap/agents
sed -i "s|^\(O\?GOOGLE_CLOUD_PROJECT\)=.*|GOOGLE_CLOUD_PROJECT=${PROJECT_ID}|" ~/instavibe-bootstrap/agents/social/.env
adk web
ADK Dev UI खोलें (वेब प्रीव्यू के ज़रिए पोर्ट 8000). एजेंट के ड्रॉपडाउन मेन्यू (सबसे ऊपर दाईं ओर) में, सोशल एजेंट चुनें.
👉 अब इसे कई लोगों की प्रोफ़ाइल बनाने का टास्क दें. चैट डायलॉग में, यह डालें:
Tell me about Mike and Bob
एजेंट के जवाब देने के बाद (इसमें लूपिंग और कई एलएलएम कॉल की वजह से थोड़ा समय लग सकता है), सिर्फ़ चैट के फ़ाइनल आउटपुट को न देखें. ADK Dev UI के बाईं ओर मौजूद पैनल में, इवेंट टैब पर जाएं.
👉 पुष्टि करने का तरीका: इवेंट टैब में, आपको इवेंट के लागू होने की पूरी जानकारी सिलसिलेवार तरीके से दिखेगी.
यह देखने के बाद कि एजेंट हर सब-एजेंट को कैसे शुरू करता है, आपको यह तय करना होगा कि फ़्लो को कहां से कहां तक जाना चाहिए. जैसे, profile_agent -> summary_agent -> check_agent. हर इटरेशन में चेकर. हालांकि, असल में हम एजेंट की ‘सेल्फ़-ऑप्टिमाइज़ेशन' सुविधा को काम करते हुए देखते हैं.
ऐसा इसलिए है, क्योंकि मॉडल पूरे अनुरोध को देखता है. जैसे, ‘प्रोफ़ाइल माइक और बॉब'), तो यह अक्सर सबसे सही पाथ चुनता है. साथ ही, यह ज़रूरी डेटा को कई बार इकट्ठा करने के बजाय, एक ही बार में इकट्ठा कर लेता है. आपको हर चरण के लिए इनपुट, आउटपुट, और स्थितियां दिख सकती हैं. इनमें profile_agent के किए गए टूल कॉल भी शामिल हैं
और check_agent और CheckCondition से स्टेटस अपडेट.
इस विज़ुअल ट्रेस से यह समझने और डीबग करने में मदद मिलती है कि मल्टी-एजेंट वर्कफ़्लो कैसे काम करता है. यह तब तक काम करता है, जब तक कि फ़ाइनल जवाब जनरेट नहीं हो जाता और उसे कॉलबैक के ज़रिए वापस नहीं भेज दिया जाता.
चैट के जवाब और इवेंट ट्रेस की जानकारी देखने के बाद, Cloud Shell टर्मिनल पर वापस जाएं. इसके बाद, ADK Dev UI को बंद करने के लिए, Ctrl+C
दबाएं.
10. एजेंट-टू-एजेंट (A2A) कम्यूनिकेशन
अब तक, हमने खास एजेंट बनाए हैं. हालांकि, ये एजेंट अलग-अलग काम करते हैं या एक ही मशीन पर पहले से तय किए गए वर्कफ़्लो के हिसाब से काम करते हैं. अलग-अलग जगहों पर काम करने वाले और साथ मिलकर काम करने वाले मल्टी-एजेंट सिस्टम बनाने के लिए, हमें ऐसा तरीका चाहिए जिससे एजेंट एक-दूसरे को ढूंढ सकें और आपस में असरदार तरीके से बातचीत कर सकें. ये एजेंट, अलग-अलग सेवाओं के तौर पर काम कर सकते हैं. ऐसे में, एजेंट-टू-एजेंट (A2A) प्रोटोकॉल काम आता है.
A2A प्रोटोकॉल एक ओपन स्टैंडर्ड है. इसे खास तौर पर, एआई एजेंट के बीच इंटरऑपरेबल कम्यूनिकेशन के लिए डिज़ाइन किया गया है. एमसीपी, एजेंट से टूल के इंटरैक्शन पर फ़ोकस करता है. वहीं, ए2ए, एजेंट से एजेंट के इंटरैक्शन पर फ़ोकस करता है. इससे एजेंट ये काम कर सकते हैं:
- खोजें: अन्य एजेंट ढूंढें और स्टैंडर्ड एजेंट कार्ड के ज़रिए उनकी क्षमताओं के बारे में जानें.
- कम्यूनिकेट करना: सुरक्षित तरीके से मैसेज और डेटा का आदान-प्रदान करना.
- साथ मिलकर काम करना: मुश्किल लक्ष्यों को हासिल करने के लिए, टास्क सौंपें और कार्रवाइयों को मैनेज करें.
A2A प्रोटोकॉल, "एजेंट कार्ड" जैसे तरीकों से इस कम्यूनिकेशन को आसान बनाता है. एजेंट, इन कार्ड का इस्तेमाल करके अपनी क्षमताओं और कनेक्शन की जानकारी का विज्ञापन कर सकते हैं.
A2A, जाने-पहचाने वेब स्टैंडर्ड (एचटीटीपी, एसएसई, JSON-RPC) का इस्तेमाल करता है. साथ ही, अक्सर क्लाइंट-सर्वर मॉडल का इस्तेमाल करता है. इसमें एक एजेंट (क्लाइंट), दूसरे एजेंट (रिमोट एजेंट/सर्वर) को टास्क भेजता है. स्टैंडर्डाइजेशन, मॉड्यूलर और स्केलेबल सिस्टम बनाने के लिए ज़रूरी है. इससे अलग-अलग एजेंट एक साथ काम कर सकते हैं.
InstaVibe Agents के लिए A2A की सुविधा चालू करना
हमारे मौजूदा Planner, Platform Interaction, और Social एजेंट को A2A के ज़रिए अन्य एजेंट के लिए ऐक्सेस किया जा सकता है. इसके लिए, हमें हर एजेंट को A2A Server कॉम्पोनेंट के साथ रैप करना होगा. यह सर्वर:
- एजेंट कार्ड दिखाना: एचटीटीपी एंडपॉइंट के ज़रिए, एजेंट की क्षमताओं की स्टैंडर्ड जानकारी दिखाएं.
- टास्क के लिए सुनें(अनुरोध वाले मैसेज): A2A प्रोटोकॉल के मुताबिक, अन्य एजेंट (A2A क्लाइंट) से आने वाले टास्क के अनुरोधों को स्वीकार करें.
- टास्क (अनुरोध वाले मैसेज) पूरे करने की सुविधा मैनेज करना: मिले हुए टास्क को प्रोसेस करने के लिए, एआई डेवलपमेंट किट (एडीके) के एजेंट लॉजिक को सौंपना.
Planner Agent (A2A की सुविधा चालू है)
आइए, Planner Agent में A2A सर्वर लेयर जोड़कर शुरू करें.
A2A सर्वर के स्टार्टअप लॉजिक को तय करें. यह कोड, AgentCard (एजेंट के बारे में सार्वजनिक जानकारी) को तय करता है. साथ ही, A2AServer को कॉन्फ़िगर करता है और उसे शुरू करता है. इसके बाद, इसे PlatformAgentExecutor से लिंक करता है.
👉📝 ~/instavibe-bootstrap/agents/planner/a2a_server.py
के आखिर में यह कोड जोड़ें:
class PlannerAgent:
"""An agent to help user planning a event with its desire location."""
SUPPORTED_CONTENT_TYPES = ["text", "text/plain"]
def __init__(self):
self._agent = self._build_agent()
self.runner = Runner(
app_name=self._agent.name,
agent=self._agent,
artifact_service=InMemoryArtifactService(),
session_service=InMemorySessionService(),
memory_service=InMemoryMemoryService(),
)
capabilities = AgentCapabilities(streaming=True)
skill = AgentSkill(
id="event_planner",
name="Event planner",
description="""
This agent generates multiple fun plan suggestions tailored to your specified location, dates, and interests,
all designed for a moderate budget. It delivers detailed itineraries,
including precise venue information (name, latitude, longitude, and description), in a structured JSON format.
""",
tags=["instavibe"],
examples=["What about Bostona MA this weekend?"],
)
self.agent_card = AgentCard(
name="Event Planner Agent",
description="""
This agent generates multiple fun plan suggestions tailored to your specified location, dates, and interests,
all designed for a moderate budget. It delivers detailed itineraries,
including precise venue information (name, latitude, longitude, and description), in a structured JSON format.
""",
url=f"{PUBLIC_URL}",
version="1.0.0",
defaultInputModes=PlannerAgent.SUPPORTED_CONTENT_TYPES,
defaultOutputModes=PlannerAgent.SUPPORTED_CONTENT_TYPES,
capabilities=capabilities,
skills=[skill],
)
def get_processing_message(self) -> str:
return "Processing the planning request..."
def _build_agent(self) -> LlmAgent:
"""Builds the LLM agent for the night out planning agent."""
return agent.root_agent
if __name__ == '__main__':
try:
plannerAgent = PlannerAgent()
request_handler = DefaultRequestHandler(
agent_executor=PlannerAgentExecutor(plannerAgent.runner,plannerAgent.agent_card),
task_store=InMemoryTaskStore(),
)
server = A2AStarletteApplication(
agent_card=plannerAgent.agent_card,
http_handler=request_handler,
)
logger.info(f"Attempting to start server with Agent Card: {plannerAgent.agent_card.name}")
logger.info(f"Server object created: {server}")
uvicorn.run(server.build(), host='0.0.0.0', port=port)
except Exception as e:
logger.error(f"An error occurred during server startup: {e}")
exit(1)
👉💻 आइए, तुरंत जांच करते हैं कि A2A सर्वर, स्थानीय तौर पर सही तरीके से शुरू होता है या नहीं. साथ ही, यह अपने एजेंट कार्ड को दिखाता है या नहीं. अपने पहले टर्मिनल में यह कमांड चलाएं:
. ~/instavibe-bootstrap/set_env.sh
source ~/instavibe-bootstrap/env/bin/activate
cd ~/instavibe-bootstrap/agents/
python -m planner.a2a_server
👉 अब, कोई दूसरी टर्मिनल विंडो खोलें. (टर्मिनल पैनल में मौजूद + के निशान पर क्लिक करें)
👉💻 स्थानीय तौर पर चल रहे सर्वर से एजेंट कार्ड का अनुरोध करने के लिए, curl का इस्तेमाल करें:
curl http://localhost:10003/.well-known/agent.json | jq
आपको हमारे तय किए गए AgentCard का JSON फ़ॉर्मैट दिखेगा. इससे यह पुष्टि होगी कि सर्वर चल रहा है और Planner एजेंट का विज्ञापन दिखा रहा है.
पहले टर्मिनल पर वापस जाएं (जहां सर्वर चल रहा है) और इसे रोकने के लिए Ctrl+C
दबाएं.
👉💻 A2A सर्वर लॉजिक जोड़ने के बाद, अब हम कंटेनर इमेज बना सकते हैं.
प्लानर एजेंट बनाना और उसे डिप्लॉय करना
. ~/instavibe-bootstrap/set_env.sh
cd ~/instavibe-bootstrap/agents
# Set variables specific to the PLANNER agent
export IMAGE_TAG="latest"
export AGENT_NAME="planner"
export IMAGE_NAME="planner-agent"
export IMAGE_PATH="${REGION}-docker.pkg.dev/${PROJECT_ID}/${REPO_NAME}/${IMAGE_NAME}:${IMAGE_TAG}"
export SERVICE_NAME="planner-agent"
export PUBLIC_URL="https://planner-agent-${PROJECT_NUMBER}.${REGION}.run.app"
echo "Building ${AGENT_NAME} agent..."
gcloud builds submit . \
--config=cloudbuild-build.yaml \
--project=${PROJECT_ID} \
--region=${REGION} \
--substitutions=_AGENT_NAME=${AGENT_NAME},_IMAGE_PATH=${IMAGE_PATH}
echo "Image built and pushed to: ${IMAGE_PATH}"
👉💻 इसके बाद, Planner Agent को Cloud Run पर डिप्लॉय करें.
. ~/instavibe-bootstrap/set_env.sh
cd ~/instavibe-bootstrap/agents
# Set variables specific to the PLANNER agent
export IMAGE_TAG="latest"
export AGENT_NAME="planner"
export IMAGE_NAME="planner-agent"
export IMAGE_PATH="${REGION}-docker.pkg.dev/${PROJECT_ID}/${REPO_NAME}/${IMAGE_NAME}:${IMAGE_TAG}"
export SERVICE_NAME="planner-agent"
export PUBLIC_URL="https://planner-agent-${PROJECT_NUMBER}.${REGION}.run.app"
gcloud run deploy ${SERVICE_NAME} \
--image=${IMAGE_PATH} \
--platform=managed \
--region=${REGION} \
--set-env-vars="A2A_HOST=0.0.0.0" \
--set-env-vars="A2A_PORT=8080" \
--set-env-vars="GOOGLE_GENAI_USE_VERTEXAI=TRUE" \
--set-env-vars="GOOGLE_CLOUD_LOCATION=${REGION}" \
--set-env-vars="GOOGLE_CLOUD_PROJECT=${PROJECT_ID}" \
--set-env-vars="PUBLIC_URL=${PUBLIC_URL}" \
--allow-unauthenticated \
--project=${PROJECT_ID} \
--min-instances=1
आइए, A2A इंस्पेक्टर का इस्तेमाल करके पुष्टि करें कि डिप्लॉय की गई सेवा काम कर रही है और क्लाउड से अपने एजेंट कार्ड को सही तरीके से दिखा रही है.
👉 Cloud Shell टूलबार में मौजूद, वेब की झलक दिखाने वाले आइकॉन से, पोर्ट बदलें को चुनें. पोर्ट को 8081 पर सेट करें और "बदलें और झलक देखें" पर क्लिक करें. A2A इंस्पेक्टर इंटरफ़ेस के साथ एक नया ब्राउज़र टैब खुलेगा.
👉💻 टर्मिनल में, डिप्लॉय किए गए प्लानर एजेंट का यूआरएल पाएं:
export PLANNER_AGENT_URL=$(gcloud run services list --platform=managed --region=us-central1 --format='value(URL)' | grep planner-agent)
echo ${PLANNER_AGENT_URL}
👉💻 आउटपुट यूआरएल को कॉपी करें.
👉 A2A इंस्पेक्टर के यूज़र इंटरफ़ेस (यूआई) में, एजेंट यूआरएल फ़ील्ड में यूआरएल चिपकाएं और कनेक्ट करें पर क्लिक करें.
👀 एजेंट के कार्ड की जानकारी और JSON, एजेंट कार्ड टैब पर दिखना चाहिए. इससे पता चलता है कि कनेक्शन हो गया है.
👉 A2A इंस्पेक्टर में, चैट टैब पर क्लिक करें. यहां पर, डिप्लॉय किए गए एजेंट के साथ सीधे तौर पर इंटरैक्ट किया जा सकता है. इसकी प्लानिंग की क्षमता को टेस्ट करने के लिए, इसे कोई मैसेज भेजें. उदाहरण के लिए:
Plan something for me in Boston MA this weekend, and I enjoy classical music
👀 बातचीत की पूरी जानकारी देखने के लिए, अपने मैसेज बबल पर क्लिक करें. इसके बाद, चैट विंडो में एजेंट के जवाब वाले बबल पर क्लिक करें. हर एक पर क्लिक करने से, भेजा या पाया गया पूरा JSON-RPC 2.0 मैसेज दिखेगा. यह डीबग करने के लिए बहुत ज़रूरी है.
आइए, A2A इंस्पेक्टर टैब को आसानी से इस्तेमाल करने के लिए उसे नीचे की ओर खींचें और छोड़ें. इसे बंद न करें! हम इसका इस्तेमाल कुछ ही समय में, अपने दो अन्य एजेंट की जांच करने के लिए करेंगे.
प्लैटफ़ॉर्म इंटरैक्शन एजेंट (A2A की सुविधा चालू है)
इसके बाद, हम Platform Interaction Agent (MCP का इस्तेमाल करने वाला) के लिए इस प्रोसेस को दोहराएंगे.
👉📝 ~/instavibe-bootstrap/agents/platform_mcp_client/a2a_server.py
के आखिर में, A2A सर्वर सेटअप के बारे में बताएं. इसमें इसका यूनीक AgentCard भी शामिल करें:
class PlatformAgent:
"""An agent that post event and post to instavibe."""
SUPPORTED_CONTENT_TYPES = ["text", "text/plain"]
def __init__(self):
self._agent = self._build_agent()
self.runner = Runner(
app_name=self._agent.name,
agent=self._agent,
artifact_service=InMemoryArtifactService(),
session_service=InMemorySessionService(),
memory_service=InMemoryMemoryService(),
)
capabilities = AgentCapabilities(streaming=True)
skill = AgentSkill(
id="instavibe_posting",
name="Post social post and events on instavibe",
description="""
This "Instavibe" agent helps you create posts (identifying author, text, and sentiment – inferred if unspecified) and register
for events (gathering name, date, attendee). It efficiently collects required information and utilizes dedicated tools
to perform these actions on your behalf, ensuring a smooth sharing experience.
""",
tags=["instavibe"],
examples=["Create a post for me, the post is about my cute cat and make it positive, and I'm Alice"],
)
self.agent_card = AgentCard(
name="Instavibe Posting Agent",
description="""
This "Instavibe" agent helps you create posts (identifying author, text, and sentiment – inferred if unspecified) and register
for events (gathering name, date, attendee). It efficiently collects required information and utilizes dedicated tools
to perform these actions on your behalf, ensuring a smooth sharing experience.
""",
url=f"{PUBLIC_URL}",
version="1.0.0",
defaultInputModes=PlatformAgent.SUPPORTED_CONTENT_TYPES,
defaultOutputModes=PlatformAgent.SUPPORTED_CONTENT_TYPES,
capabilities=capabilities,
skills=[skill],
)
def get_processing_message(self) -> str:
return "Processing the social post and event request..."
def _build_agent(self) -> LlmAgent:
"""Builds the LLM agent for the Processing the social post and event request."""
return agent.root_agent
if __name__ == '__main__':
try:
platformAgent = PlatformAgent()
request_handler = DefaultRequestHandler(
agent_executor=PlatformAgentExecutor(platformAgent.runner,platformAgent.agent_card),
task_store=InMemoryTaskStore(),
)
server = A2AStarletteApplication(
agent_card=platformAgent.agent_card,
http_handler=request_handler,
)
uvicorn.run(server.build(), host='0.0.0.0', port=port)
except Exception as e:
logger.error(f"An error occurred during server startup: {e}")
exit(1)
सोशल एजेंट (A2A की सुविधा चालू है)
आखिर में, हम अपने सोशल प्रोफ़ाइलिंग एजेंट के लिए A2A की सुविधा चालू करेंगे.
👉📝 ~/instavibe-bootstrap/agents/social/a2a_server.py
के आखिर में, A2A सर्वर सेटअप और AgentCard के बारे में जानकारी दें:
class SocialAgent:
"""An agent that handles social profile analysis."""
SUPPORTED_CONTENT_TYPES = ["text", "text/plain"]
def __init__(self):
self._agent = self._build_agent()
self.runner = Runner(
app_name=self._agent.name,
agent=self._agent,
artifact_service=InMemoryArtifactService(),
session_service=InMemorySessionService(),
memory_service=InMemoryMemoryService(),
)
capabilities = AgentCapabilities(streaming=True)
skill = AgentSkill(
id="social_profile_analysis",
name="Analyze Instavibe social profile",
description="""
Using a provided list of names, this agent synthesizes Instavibe social profile information by analyzing posts, friends, and events.
It delivers a comprehensive single-paragraph summary for individuals, and for groups, identifies commonalities in their social activities
and connections based on profile data.
""",
tags=["instavibe"],
examples=["Can you tell me about Bob and Alice?"],
)
self.agent_card = AgentCard(
name="Social Profile Agent",
description="""
Using a provided list of names, this agent synthesizes Instavibe social profile information by analyzing posts, friends, and events.
It delivers a comprehensive single-paragraph summary for individuals, and for groups, identifies commonalities in their social activities
and connections based on profile data.
""",
url=f"{PUBLIC_URL}",
version="1.0.0",
defaultInputModes=self.SUPPORTED_CONTENT_TYPES,
defaultOutputModes=self.SUPPORTED_CONTENT_TYPES,
capabilities=capabilities,
skills=[skill],
)
def get_processing_message(self) -> str:
return "Processing the social profile analysis request..."
def _build_agent(self) -> LoopAgent:
"""Builds the LLM agent for the social profile analysis agent."""
return agent.root_agent
if __name__ == '__main__':
try:
socialAgent = SocialAgent()
request_handler = DefaultRequestHandler(
agent_executor=SocialAgentExecutor(socialAgent.runner,socialAgent.agent_card),
task_store=InMemoryTaskStore(),
)
server = A2AStarletteApplication(
agent_card=socialAgent.agent_card,
http_handler=request_handler,
)
uvicorn.run(server.build(), host='0.0.0.0', port=port)
except Exception as e:
logger.error(f"An error occurred during server startup: {e}")
exit(1)
प्लैटफ़ॉर्म इंटरैक्शन और सोशल एजेंट बनाना और उन्हें डिप्लॉय करना
इन एजेंट को Spanner का ऐक्सेस चाहिए. इसलिए, यह पक्का करें कि डिप्लॉयमेंट के दौरान SPANNER_INSTANCE_ID
, SPANNER_DATABASE_ID
, और MCP_SERVER_URL
एनवायरमेंट वैरिएबल सही तरीके से पास किए गए हों.
👉💻 Cloud Build की मदद से, Cloud Run पर इमेज बनाएं और उसे डिप्लॉय करें:
. ~/instavibe-bootstrap/set_env.sh
cd ~/instavibe-bootstrap/agents
export MCP_SERVER_URL=$(gcloud run services list --platform=managed --region=us-central1 --format='value(URL)' | grep mcp-tool-server)/sse
gcloud builds submit . \
--config=cloudbuild.yaml \
--project="${PROJECT_ID}" \
--region="${REGION}" \
--substitutions=\
_PROJECT_ID="${PROJECT_ID}",\
_PROJECT_NUMBER="${PROJECT_NUMBER}",\
_REGION="${REGION}",\
_REPO_NAME="${REPO_NAME}",\
_SPANNER_INSTANCE_ID="${SPANNER_INSTANCE_ID}",\
_SPANNER_DATABASE_ID="${SPANNER_DATABASE_ID}",\
_MCP_SERVER_URL="${MCP_SERVER_URL}"
👉💻 टर्मिनल में, डिप्लॉय किए गए प्लैटफ़ॉर्म एजेंट का यूआरएल पाएं:
export PLATFORM_MPC_CLIENT_URL=$(gcloud run services list --platform=managed --region=us-central1 --format='value(URL)' | grep platform-mcp-client)
echo $PLATFORM_MPC_CLIENT_URL
👉💻 आउटपुट यूआरएल को कॉपी करें.
👉 A2A इंस्पेक्टर के यूज़र इंटरफ़ेस (यूआई) में, एजेंट यूआरएल फ़ील्ड में यूआरएल चिपकाएं और कनेक्ट करें पर क्लिक करें.
👀 एजेंट के कार्ड की जानकारी और JSON, एजेंट कार्ड टैब पर दिखना चाहिए. इससे पता चलता है कि कनेक्शन हो गया है.
👉 A2A इंस्पेक्टर में, चैट टैब पर क्लिक करें. यहां पर, डिप्लॉय किए गए एजेंट से सीधे तौर पर बातचीत की जा सकती है. उसे मैसेज भेजकर, पोस्ट बनाने की उसकी क्षमता को परखा जा सकता है:
Create a post for me, the post says 'Paws, purrs, and ocean views 🐾☕🌊. Spent my morning at the Morning Seaside Cat Café, where every sip comes with a side of snuggles and sea breeze.' and make it positive, and I'm Oscar.
👀 बातचीत की पूरी जानकारी देखने के लिए, अपने मैसेज बबल पर क्लिक करें. इसके बाद, चैट विंडो में एजेंट के जवाब वाले बबल पर क्लिक करें. हर एक पर क्लिक करने से, भेजा या पाया गया पूरा JSON-RPC 2.0 मैसेज दिखेगा. यह डीबग करने के लिए बहुत ज़रूरी है.
👉💻 टर्मिनल में, डिप्लॉय किए गए सोशल एजेंट का यूआरएल पाएं:
export SOCIAL_AGENT_URL=$(gcloud run services list --platform=managed --region=us-central1 --format='value(URL)' | grep social-agent)
echo $SOCIAL_AGENT_URL
👉💻 आउटपुट यूआरएल को कॉपी करें.
👉 A2A इंस्पेक्टर के यूज़र इंटरफ़ेस (यूआई) में, एजेंट यूआरएल फ़ील्ड में यूआरएल चिपकाएं और कनेक्ट करें पर क्लिक करें.
👀 एजेंट के कार्ड की जानकारी और JSON, एजेंट कार्ड टैब पर दिखना चाहिए. इससे पता चलता है कि कनेक्शन हो गया है.
👉 A2A इंस्पेक्टर में, चैट टैब पर क्लिक करें. यहां पर, डिप्लॉय किए गए एजेंट के साथ सीधे तौर पर इंटरैक्ट किया जा सकता है. उसे अपने डेटाबेस से उपयोगकर्ता प्रोफ़ाइलों का विश्लेषण करने के लिए मैसेज भेजें:
Can you tell me about both Ian and Kevin's profile, what are their common interests?
👀 बातचीत की पूरी जानकारी देखने के लिए, अपने मैसेज बबल पर क्लिक करें. इसके बाद, चैट विंडो में एजेंट के जवाब वाले बबल पर क्लिक करें. हर एक पर क्लिक करने से, भेजा या पाया गया पूरा JSON-RPC 2.0 मैसेज दिखेगा. यह डीबग करने के लिए बहुत ज़रूरी है.
👉 बहुत बढ़िया, हमने अपने सभी एजेंट की जांच कर ली है. अब A2A इंस्पेक्टर टैब को बंद किया जा सकता है.
11. ऑर्केस्ट्रेटर एजेंट (A2A क्लाइंट)
अब हमारे पास तीन खास एजेंट (प्लानर, प्लैटफ़ॉर्म, सोशल) हैं. ये Cloud Run पर, A2A की सुविधा के साथ स्वतंत्र रूप से काम करते हैं. आखिरी कॉम्पोनेंट, Orchestrator Agent है. यह एजेंट, सेंट्रल कोऑर्डिनेटर या A2A क्लाइंट के तौर पर काम करेगा. इसे उपयोगकर्ता के अनुरोध मिलेंगे. यह पता लगाएगा कि अनुरोध पूरा करने के लिए, कौनसे रिमोट एजेंट की ज़रूरत है. इसके बाद, A2A प्रोटोकॉल का इस्तेमाल करके, उन रिमोट एजेंट को टास्क सौंपेगा. इस वर्कशॉप के लिए, हम ADK Dev UI का इस्तेमाल करके, Orchestrator एजेंट को स्थानीय तौर पर चलाएंगे.
सबसे पहले, Orchestrator के लॉजिक को बेहतर बनाते हैं, ताकि यह उन रिमोट एजेंट के रजिस्ट्रेशन को मैनेज कर सके जिन्हें यह ढूंढता है. यह कुकी, एजेंट कार्ड फ़ेच करने के दौरान कनेक्शन की जानकारी सेव करती है. ऐसा तब होता है, जब एजेंट कार्ड को पहली बार शुरू किया जाता है.
👉📝 ~/instavibe-bootstrap/agents/orchestrate/agent.py
में, #REPLACE ME REG AGENT CARD
को इससे बदलें:
async with httpx.AsyncClient(timeout=30) as client:
for i, address in enumerate(REMOTE_AGENT_ADDRESSES):
log.info(f"--- STEP 3.{i}: Attempting connection to: {address} ---")
try:
card_resolver = A2ACardResolver(client, address)
card = await card_resolver.get_agent_card()
remote_connection = RemoteAgentConnections(agent_card=card, agent_url=address)
self.remote_agent_connections[card.name] = remote_connection
self.cards[card.name] = card
log.info(f"--- STEP 5.{i}: Successfully stored connection for {card.name} ---")
except Exception as e:
log.error(f"--- CRITICAL FAILURE at STEP 4.{i} for address: {address} ---")
log.error(f"--- The hidden exception type is: {type(e).__name__} ---")
log.error(f"--- Full exception details and traceback: ---", exc_info=True)
इसके बाद, ADK में Orchestrator एजेंट के लिए टूल तय करें.
send_message
(काम सौंपने के लिए A2A फ़ंक्शन).
👉📝 ~/instavibe-bootstrap/agents/orchestrate/agent.py
में मौजूद #REPLACE ME CREATE AGENT
को इससे बदलें:
def create_agent(self) -> Agent:
"""Synchronously creates the ADK Agent object."""
return Agent(
model="gemini-2.5-flash",
name="orchestrate_agent",
instruction=self.root_instruction,
before_agent_callback=self.before_agent_callback,
description=("Orchestrates tasks for child agents."),
tools=[self.send_message],
)
ऑर्केस्ट्रेटर का मुख्य लॉजिक, उसके निर्देशों में होता है. इन निर्देशों से ऑर्केस्ट्रेटर को पता चलता है कि A2A का इस्तेमाल कैसे करना है.
👉📝 ~/instavibe-bootstrap/agents/orchestrate/agent.py
में मौजूद #REPLACE ME INSTRUCTIONS
को निर्देश जनरेट करने के इस तरीके से बदलें:
def root_instruction(self, context: ReadonlyContext) -> str:
current_agent = self.check_active_agent(context)
return f"""
You are an expert AI Orchestrator. Your primary responsibility is to intelligently interpret user requests, break them down into a logical plan of discrete actions, and delegate each action to the most appropriate specialized remote agent using the send_message function. You do not perform the tasks yourself but manage their assignment, sequence, and critically, their outcomes.
**Core Directives & Decision Making:**
* **Understand User Intent & Complexity:**
* Carefully analyze the user's request to determine the core task(s) they want to achieve. Pay close attention to keywords and the overall goal.
* Identify if the request requires a single agent or a sequence of actions from multiple agents. For example, "Analyze John Doe's profile and then create a positive post about his recent event attendance" would require two agents in sequence.
* **Task Planning & Sequencing (for Multi-Step Requests):**
* Before delegating, outline the clear sequence of agent tasks.
* Identify dependencies. If Task B requires output from Task A, execute them sequentially. If tasks are independent (like creating a post and then creating an event), execute them one after the other as separate delegations.
* Agent Reusability: An agent's completion of one task does not make it unavailable. If a user's plan involves multiple, distinct actions that fall under the same agent's expertise (e.g., create a post, then create an event), you must call that same agent again for the subsequent task.
* **Task Delegation & Management (using `send_message`):**
* **Delegation:** Use `send_message` to assign actionable tasks to the selected remote agent. Your `send_message` call MUST include:
* The `remote_agent_name` you've selected.
* The `user_request` or all necessary parameters extracted from the user's input, formatted in a way the target agent will understand.
* **Contextual Awareness for Remote Agents:** If a remote agent repeatedly requests user confirmation or seems to lack context, assume it lacks access to the full conversation history. In such cases, enrich your `send_message` with all necessary contextual information relevant to that specific agent from the conversation history.
* **Sequential Task Execution:**
* After a preceding task completes (indicated by the agent's response or a success signal), gather any necessary output from it.
* Then, use `send_message` for the next agent in the sequence, providing it with the user's original relevant intent and any necessary data obtained from the previous agent's task.
* **Active Agent Prioritization:** If an active agent is already engaged and the user's request is related to its current task, route subsequent related requests directly to that agent by providing updated context via `send_message`.
**Critical Success Verification:**
* You **MUST** wait for the tool_output after every send_message call before taking any further action.
* Your decision to proceed to the next task in a sequence **MUST** be based entirely on a confirmation of success from the tool_output of the previous task.
* If a tool call fails, returns an error, or the tool_output is ambiguous, you MUST STOP the sequence. Your next action is to report the exact failure or ambiguity to the user.
* DO NOT assume a task was successful. Do not invent success messages like "The event has been created." Only state that a task is complete if the tool's response explicitly says so.
**Communication with User:**
* **Transparent Communication:** Always present the complete and detailed response from the remote agent to the user. Do not summarize or filter unless explicitly instructed.
* When you delegate a task (or the first task in a sequence), clearly inform the user which remote agent is handling it.
* For multi-step requests, you can optionally inform the user of the planned sequence (e.g., "Okay, first I'll ask the 'Social Profile Agent' to analyze the profile, and then I'll have the 'Instavibe Posting Agent' create the post.").
* If waiting for a task in a sequence to complete, you can inform the user (e.g., "The 'Social Profile Agent' is currently processing. I'll proceed with the post once that's done.").
* **User Confirmation Relay:** If a remote agent asks for confirmation, and the user has not already provided it, just make up something.
* If the user's request is ambiguous, if necessary information is missing for any agent in the sequence, or if you are unsure about the plan, just make up something.
**Important Reminders:**
* **Autonomous Agent Engagement:** Never seek user permission before engaging with remote agents. If multiple agents are required to fulfill a request, connect with them directly without requesting user preference or confirmation.
* **Focused Information Sharing:** Provide remote agents with only relevant contextual information. Avoid extraneous details that are not directly pertinent to their task.
* **No Redundant Confirmations:** Do not ask remote agents for confirmation of information or actions they have already processed or committed to.
* **Tool Reliance:** Strictly rely on your available tools, primarily `send_message`, to address user requests. Do not generate responses based on assumptions. If information is insufficient, request clarification from the user.
* **Prioritize Recent Interaction:** Focus primarily on the most recent parts of the conversation when processing requests, while maintaining awareness of the overall goal for multi-step tasks.
* Always prioritize selecting the correct agent(s) based on their documented purpose.
* Ensure all information required by the chosen remote agent is included in the `send_message` call, including outputs from previous agents if it's a sequential task.
Agents:
{self.agents}
Current agent: {current_agent['active_agent']}`
"""
ऑर्केस्ट्रेटर और पूरे A2A सिस्टम की टेस्टिंग
अब, पूरे सिस्टम को टेस्ट करते हैं. हम ADK Dev UI का इस्तेमाल करके, Orchestrator को स्थानीय तौर पर चलाएंगे. यह Planner, Platform, और Social एजेंट के साथ कम्यूनिकेट करेगा. ये एजेंट, Cloud Run पर रिमोटली चल रहे हैं.
👉💻 सबसे पहले, पक्का करें कि एनवायरमेंट वैरिएबल REMOTE_AGENT_ADDRESSES
में, A2A की सुविधा वाले डिप्लॉय किए गए एजेंट के कॉमा से अलग किए गए यूआरएल मौजूद हों. इसके बाद, Orchestrator एजेंट के लिए ज़रूरी एनवायरमेंट वैरिएबल सेट करें और ADK Dev UI लॉन्च करें:
. ~/instavibe-bootstrap/set_env.sh
source ~/instavibe-bootstrap/env/bin/activate
export PLATFORM_MPC_CLIENT_URL=$(gcloud run services list --platform=managed --region=us-central1 --format='value(URL)' | grep platform-mcp-client)
export PLANNER_AGENT_URL=$(gcloud run services list --platform=managed --region=us-central1 --format='value(URL)' | grep planner-agent)
export SOCIAL_AGENT_URL=$(gcloud run services list --platform=managed --region=us-central1 --format='value(URL)' | grep social-agent)
export REMOTE_AGENT_ADDRESSES=${PLANNER_AGENT_URL},${PLATFORM_MPC_CLIENT_URL},${SOCIAL_AGENT_URL}
cd ~/instavibe-bootstrap/agents
sed -i "s|^\(O\?REMOTE_AGENT_ADDRESSES\)=.*|REMOTE_AGENT_ADDRESSES=${REMOTE_AGENT_ADDRESSES}|" ~/instavibe-bootstrap/agents/orchestrate/.env
adk web
👉 ADK Dev UI खोलें. वेब प्रीव्यू की मदद से, पोर्ट को वापस 8000 पर सेट करें.
👉 एजेंट ड्रॉपडाउन में, ऑर्केस्ट्रेट एजेंट चुनें.
👉 अब इसे कोई ऐसा मुश्किल टास्क दें जिसके लिए, दूर से काम करने वाले कई एजेंट के साथ समन्वय करना ज़रूरी हो. यहां दिया गया पहला उदाहरण आज़माएं. इसमें सबसे पहले सोशल एजेंट और फिर प्लानर एजेंट को शामिल किया जाना चाहिए:
You are an expert event planner for a user named Diana.
Your task is to design a fun and personalized event.
Here are the details for the plan:
- Friends to invite: Ian, Nora
- Desired date: "2025-10-15"
- Location idea or general preference: "Chicago"
Your process should be:
1. Analyze the provided friend names. If you have access to a tool to get their InstaVibe profiles or summarized interests, please use it.
2. Based on their potential interests (or general good taste if profiles are unavailable), create a tailored plan for the outing, check if you have access to any event planner tools.
3. Ensure the plan includes the original `planned_date`.
The user wants a comprehensive plan that includes:
- The list of invited friends.
- A catchy and descriptive name for the event.
- The exact planned date for the event.
- A summary of what the group will do.
- Specific recommended spots (e.g., restaurants, bars, activity venues) with their names, (if possible, approximate latitude/longitude for mapping, and address), and a brief description of why it fits the plan.
- A short, exciting message that {Diana} can send to {Ian, Nora} to get them excited about the event.
ADK Dev UI की चैट विंडो में इंटरैक्शन देखें. ऑर्केस्ट्रेटर के जवाबों पर ध्यान दें.इसमें यह बताया जाना चाहिए कि वह किस रिमोट एजेंट को टास्क सौंप रहा है. जैसे, "ठीक है, मैं पहले सोशल प्रोफ़ाइल एजेंट से इयान और नोरा के बारे में पूछूंगा...").
इसके अलावा, यूज़र इंटरफ़ेस (यूआई) में मौजूद इवेंट टैब में जाकर देखें कि रिमोट एजेंट के यूआरएल को कौनसे टूल कॉल (send_message) किए जा रहे हैं.
👉 अब, एक दूसरा उदाहरण आज़माएं. इसमें प्लैटफ़ॉर्म इंटिग्रेशन एजेंट को सीधे तौर पर शामिल किया जाना चाहिए:
Hey, can you register an event on Instavibe for Laura and Charlie? Let's call it 'Vienna Concert & Castles Day'.
here are more info
"event_name": "Vienna Concert & Castles Day",
"description": "A refined and unforgettable day in Vienna with Laura and Charlie. The day begins with a guided tour of the magnificent Schönbrunn Palace, showcasing imperial architecture and history. In the evening, enjoy a classical music concert in one of Vienna's most iconic concert halls.",
"event_date": "2025-10-14T10:00:00+02:00",
"locations": [
{
"name": "Schönbrunn Palace",
"description": "A UNESCO World Heritage Site and former imperial summer residence, Schönbrunn Palace offers opulent rooms, beautiful baroque gardens, and a glimpse into the life of the Habsburg monarchy. Visitors can stroll the grounds or take a guided historical tour.",
"latitude": 48.184516,
"longitude": 16.312222,
"address": "Schönbrunner Schloßstraße 47, 1130 Wien, Austria"
},
{
"name": "Musikverein Vienna",
"description": "Home to the world-renowned Vienna Philharmonic, the Musikverein is one of the finest concert halls in the world. Its 'Golden Hall' is famous for its acoustics and ornate design. Attendees can enjoy a powerful classical concert in an unforgettable setting.",
"latitude": 48.200132,
"longitude": 16.373777,
"address": "Musikvereinsplatz 1, 1010 Wien, Austria"
}
],
"attendee_names": ["Laura", "Charlie", "Oscar"] And I am Oscar
चैट और Events टैब पर फिर से नज़र रखें. ऑर्केस्ट्रेटर को यह पता होना चाहिए कि इवेंट बनाने की ज़रूरत कब है. साथ ही, उसे "प्लैटफ़ॉर्म इंटिग्रेशन एजेंट" को यह टास्क सौंपना चाहिए. इसमें, इवेंट से जुड़ी सभी जानकारी शामिल होनी चाहिए. क्वेरी के जवाब देने में लगने वाले समय और लागू किए गए ऑपरेशनों का विश्लेषण करने के लिए, ट्रेस करें बटन पर भी क्लिक किया जा सकता है.
इसके बाद, पुष्टि करें कि इवेंट, InstaVibe के वेब ऐप्लिकेशन में दिखता है.
इससे पता चलता है कि ADK और A2A प्रोटोकॉल का इस्तेमाल करके, मल्टी-एजेंट सिस्टम को सही तरीके से लागू किया गया है. इसमें एक सेंट्रल ऑर्केस्ट्रेटर, टास्क को रिमोट एजेंट को सौंपता है.
जांच पूरी हो जाने के बाद, ADK Dev UI (टर्मिनल में Ctrl+C
) को बंद करना न भूलें.
12. InstaVibe से एजेंट इंजन और रिमोट कॉल की सुविधा
अब तक, हमने Cloud Run पर अपने खास एजेंट चलाए हैं. साथ ही, ADK Dev UI का इस्तेमाल करके, Orchestrator को स्थानीय तौर पर टेस्ट किया है. प्रोडक्शन के लिए, हमें अपने एजेंटों को होस्ट करने के लिए एक मज़बूत, बढ़ाने लायक, और मैनेज किया गया एनवायरमेंट चाहिए. इस मामले में, Google Vertex AI Agent Engine आपकी मदद कर सकता है.
Agent Engine, Vertex AI पर पूरी तरह से मैनेज की जाने वाली सेवा है. इसे खास तौर पर एआई एजेंट को डिप्लॉय करने और बड़े पैमाने पर उपलब्ध कराने के लिए डिज़ाइन किया गया है. यह इंफ़्रास्ट्रक्चर मैनेजमेंट, सुरक्षा, और ऑपरेशनल ओवरहेड को कम करता है. इससे डेवलपर (खास तौर पर वे डेवलपर जिन्हें जटिल क्लाउड एनवायरमेंट के बारे में कम जानकारी है) सर्वर मैनेज करने के बजाय, एजेंट के लॉजिक और क्षमताओं पर फ़ोकस कर पाते हैं. यह एजेंटिक वर्कलोड के लिए ऑप्टिमाइज़ किया गया एक खास रनटाइम उपलब्ध कराता है.
अब हम अपने Orchestrator एजेंट को Agent Engine पर डिप्लॉय करेंगे. (ध्यान दें: यहां दिखाए गए डिप्लॉयमेंट मैकेनिज़्म में, वर्कशॉप के मटीरियल में दी गई कस्टम स्क्रिप्ट (agent_engine_app.py) का इस्तेमाल किया गया है. ऐसा इसलिए, क्योंकि ADK से सीधे एजेंट इंजन पर डिप्लॉय करने वाले आधिकारिक टूल अब भी विकसित हो रहे हैं. यह स्क्रिप्ट, Orchestrator एजेंट को पैकेज और डिप्लॉय करती है. इसे ज़रूरी रिमोट एजेंट पतों के साथ कॉन्फ़िगर किया जाता है.)
Orchestrator एजेंट को एजेंट इंजन पर डिप्लॉय करने के लिए, यह कमांड चलाएं. पक्का करें कि पिछले सेक्शन में, REMOTE_AGENT_ADDRESSES एनवायरमेंट वैरिएबल (इसमें Cloud Run पर मौजूद आपके Planner, Platform, और Social एजेंट के यूआरएल होते हैं) अब भी सही तरीके से सेट हो.
👉💻 हम Orchestrate एजेंट को Agent Engine पर डिप्लॉय करेंगे (ध्यान दें: यह डिप्लॉयमेंट का मेरा अपना तरीका है. ADK में डिप्लॉय करने में मदद करने के लिए सीएलआई है. BYO-SA लागू होने के बाद, मैं इसे अपडेट करूंगा.)
cd ~/instavibe-bootstrap/agents/
. ~/instavibe-bootstrap/set_env.sh
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:service-$PROJECT_NUMBER@gcp-sa-aiplatform-re.iam.gserviceaccount.com" \
--role="roles/viewer"
source ~/instavibe-bootstrap/env/bin/activate
export PLATFORM_MPC_CLIENT_URL=$(gcloud run services list --platform=managed --region=us-central1 --format='value(URL)' | grep platform-mcp-client)
export PLANNER_AGENT_URL=$(gcloud run services list --platform=managed --region=us-central1 --format='value(URL)' | grep planner-agent)
export SOCIAL_AGENT_URL=$(gcloud run services list --platform=managed --region=us-central1 --format='value(URL)' | grep social-agent)
export REMOTE_AGENT_ADDRESSES=${PLANNER_AGENT_URL},${PLATFORM_MPC_CLIENT_URL},${SOCIAL_AGENT_URL}
sed -i "s|^\(O\?REMOTE_AGENT_ADDRESSES\)=.*|REMOTE_AGENT_ADDRESSES=${REMOTE_AGENT_ADDRESSES}|" ~/instavibe-bootstrap/agents/orchestrate/.env
adk deploy agent_engine \
--display_name "orchestrate-agent" \
--project $GOOGLE_CLOUD_PROJECT \
--region $GOOGLE_CLOUD_LOCATION \
--staging_bucket gs://$GOOGLE_CLOUD_PROJECT-agent-engine \
--trace_to_cloud \
--requirements_file orchestrate/requirements.txt \
orchestrate
अब Orchestrator को मैनेज किए जा रहे Agent Engine प्लैटफ़ॉर्म पर होस्ट किया गया है. इसलिए, हमारे InstaVibe वेब ऐप्लिकेशन को इससे कम्यूनिकेट करने की ज़रूरत है. ADK Dev UI के ज़रिए इंटरैक्ट करने के बजाय, वेब ऐप्लिकेशन, एजेंट इंजन के एंडपॉइंट पर रिमोट कॉल करेगा.
सबसे पहले, हमें InstaVibe ऐप्लिकेशन कोड में बदलाव करना होगा, ताकि हम अपने डिप्लॉय किए गए Orchestrator एजेंट के यूनीक आईडी का इस्तेमाल करके, Agent Engine क्लाइंट को शुरू कर सकें. इस आईडी की मदद से, प्लैटफ़ॉर्म पर सही एजेंट इंस्टेंस को टारगेट किया जा सकता है.
👉📝 ~/instavibe-bootstrap/instavibe/introvertally.py
खोलें और #REPLACE ME initiate agent_engine
की जगह यह कोड डालें. यह एनवायरमेंट वैरिएबल से एजेंट इंजन आईडी को वापस पाता है. हम इसे जल्द ही सेट करेंगे. साथ ही, यह क्लाइंट ऑब्जेक्ट को वापस पाता है:
ORCHESTRATE_AGENT_ID = os.environ.get('ORCHESTRATE_AGENT_ID')
agent_engine = agent_engines.get(ORCHESTRATE_AGENT_ID)
InstaVibe में, उपयोगकर्ता के लिए तय किए गए फ़्लो में एजेंट के साथ दो इंटरैक्शन शामिल हैं: पहला, सुझाया गया प्लान जनरेट करना और दूसरा, एजेंट के प्लैटफ़ॉर्म पर इवेंट पोस्ट करने से पहले उपयोगकर्ता से पुष्टि करने के लिए कहना.
InstaVibe वेब ऐप्लिकेशन (Cloud Run पर चल रहा है) और Orchestrator एजेंट (Agent Engine पर चल रहा है) अब अलग-अलग सेवाएं हैं. इसलिए, एजेंट से इंटरैक्ट करने के लिए, वेब ऐप्लिकेशन को Agent Engine के एंडपॉइंट पर रिमोट कॉल करने होंगे.
👉📝 आइए, उस कोड को अपडेट करें जो प्लान के सुझाव जनरेट करने के लिए शुरुआती कॉल करता है. उसी introvertally.py
फ़ाइल में, #REPLACE ME Query remote agent get plan
को इस स्निपेट से बदलें. यह स्निपेट, उपयोगकर्ता के अनुरोध को भेजने के लिए agent_engine क्लाइंट का इस्तेमाल करता है:
agent_engine.stream_query(
user_id=user_id,
message=prompt_message,
)
👉📝 इसके बाद, उस कोड को अपडेट करें जो उपयोगकर्ता की पुष्टि करता है. उदाहरण के लिए, जब उपयोगकर्ता "प्लान की पुष्टि करें" पर क्लिक करता है. इससे Agent Engine पर, उसी बातचीत में फ़ॉलो-अप मैसेज भेजा जाता है. इसमें Orchestrator को इवेंट पोस्ट करने का निर्देश दिया जाता है. Orchestrator, यह काम Platform Integration एजेंट को सौंप देगा. introvertally.py
में पुष्टि करने के लिए, #REPLACE ME Query remote agent for confirmation
को इससे बदलें:
agent_engine.stream_query(
user_id=agent_session_user_id,
message=prompt_message,
)
वेब ऐप्लिकेशन के रास्तों को इन फ़ंक्शन का ऐक्सेस चाहिए. पक्का करें कि introvertally.py से ज़रूरी फ़ंक्शन, Flask राउट फ़ाइल में इंपोर्ट किए गए हों.
👉📝 cd ~/instavibe-bootstrap/instavibe/ally_routes.py
में, हम सबसे पहले इंस्टेंस को बदलेंगे. # REPLACE ME TO ADD IMPORT
को इससे बदलें:
from introvertally import call_agent_for_plan, post_plan_event
👉📝 InstaVibe में प्रोटोटाइप सुविधा जोड़ें. ~/instavibe-bootstrap/instavibe/templates/base.html
में, <!–REPLACE_ME_LINK_TO_INTROVERT_ALLY–> को इससे बदलें:
<li class="nav-item">
<a class="nav-link" href="{{ url_for('ally.introvert_ally_page') }}">Introvert Ally</a>
</li>
InstaVibe ऐप्लिकेशन को फिर से डिप्लॉय करने से पहले, हमें Orchestrator एजेंट का वह Resource ID
चाहिए जिसे हमने Agent Engine पर डिप्लॉय किया था.
फ़िलहाल, gcloud
के ज़रिए प्रोग्राम के हिसाब से इसे वापस पाने की सुविधा सीमित हो सकती है. इसलिए, हम आईडी को फ़ेच करने और उसे एनवायरमेंट वैरिएबल में सेव करने के लिए, Python की हेल्पर स्क्रिप्ट (temp-endpoint.py
वर्कशॉप में दी गई) का इस्तेमाल करेंगे.
👉💻 स्क्रिप्ट को चलाने के लिए, यहां दिए गए कमांड का इस्तेमाल करें. स्क्रिप्ट, Agent Engine Endpoint ID को कैप्चर करेगी और एजेंट इंजन के डिफ़ॉल्ट सेवा खाते को ज़रूरी अनुमतियां देगी (ध्यान दें: स्क्रिप्ट को डिफ़ॉल्ट सेवा खाते का इस्तेमाल करने के लिए कॉन्फ़िगर किया गया है, क्योंकि फ़िलहाल इसे उपयोगकर्ता के हिसाब से नहीं बदला जा सकता).
. ~/instavibe-bootstrap/set_env.sh
cd ~/instavibe-bootstrap/instavibe/
source ~/instavibe-bootstrap/env/bin/activate
python temp-endpoint.py
export ORCHESTRATE_AGENT_ID=$(cat temp_endpoint.txt)
echo "ORCHESTRATE_AGENT_ID set to: ${ORCHESTRATE_AGENT_ID}"
आखिर में, हमें अपडेट किए गए कोड और नई ORCHESTRATE_AGENT_ID
एनवायरमेंट वैरिएबल के साथ InstaVibe वेब ऐप्लिकेशन को फिर से डिप्लॉय करना होगा, ताकि इसे पता चल सके कि Agent Engine पर चल रहे हमारे एजेंट से कैसे कनेक्ट करना है.
👉💻 यहां दिए गए निर्देशों की मदद से, InstaVibe ऐप्लिकेशन की इमेज को फिर से बनाया जा सकता है. साथ ही, नए वर्शन को Cloud Run पर डिप्लॉय किया जा सकता है:
. ~/instavibe-bootstrap/set_env.sh
cd ~/instavibe-bootstrap/instavibe/
export IMAGE_TAG="latest"
export APP_FOLDER_NAME="instavibe"
export IMAGE_NAME="instavibe-webapp"
export IMAGE_PATH="${REGION}-docker.pkg.dev/${PROJECT_ID}/${REPO_NAME}/${IMAGE_NAME}:${IMAGE_TAG}"
export SERVICE_NAME="instavibe"
echo "Building ${APP_FOLDER_NAME} webapp image..."
gcloud builds submit . \
--tag=${IMAGE_PATH} \
--project=${PROJECT_ID}
echo "Deploying ${SERVICE_NAME} to Cloud Run..."
gcloud run deploy ${SERVICE_NAME} \
--image=${IMAGE_PATH} \
--platform=managed \
--region=${REGION} \
--allow-unauthenticated \
--set-env-vars="SPANNER_INSTANCE_ID=${SPANNER_INSTANCE_ID}" \
--set-env-vars="SPANNER_DATABASE_ID=${SPANNER_DATABASE_ID}" \
--set-env-vars="APP_HOST=0.0.0.0" \
--set-env-vars="APP_PORT=8080" \
--set-env-vars="GOOGLE_CLOUD_LOCATION=${REGION}" \
--set-env-vars="GOOGLE_CLOUD_PROJECT=${PROJECT_ID}" \
--set-env-vars="GOOGLE_MAPS_API_KEY=${GOOGLE_MAPS_API_KEY}" \
--set-env-vars="ORCHESTRATE_AGENT_ID=${ORCHESTRATE_AGENT_ID}" \
--project=${PROJECT_ID} \
--min-instances=1 \
--cpu=2 \
--memory=2Gi
फ़ाइनल डिप्लॉयमेंट पूरा होने के बाद, किसी दूसरे ब्राउज़र टैब में अपने InstaVibe ऐप्लिकेशन के यूआरएल पर जाएं.
एआई की मदद से काम करने वाली InstaVibe की पूरी सुविधा को टेस्ट करना
"InstaVibe Ally" सुविधा अब लाइव है. यह सुविधा, हमारे मल्टी-एजेंट सिस्टम की मदद से काम करती है. इसे Vertex AI Agent Engine के ज़रिए मैनेज किया जाता है और यह A2A के ज़रिए कम्यूनिकेट करती है.
"InstaVibe Ally" पर क्लिक करें और उससे कोई इवेंट प्लान करने के लिए कहें.
एजेंट के काम करने के दौरान, दाईं ओर मौजूद गतिविधि लॉग देखें. इसमें 90 से 120 सेकंड लग सकते हैं. प्लान दिखने के बाद, उसकी समीक्षा करें. इसके बाद, पोस्ट करने के लिए "इस प्लान की पुष्टि करें" पर क्लिक करें.
अब ऑर्केस्ट्रेटर, प्लैटफ़ॉर्म एजेंट को InstaVibe में पोस्ट और इवेंट बनाने का निर्देश देगा.
नई पोस्ट और इवेंट के लिए, InstaVibe का होम पेज देखें.
इवेंट पेज पर, एजेंट से जनरेट की गई जानकारी दिखेगी.
Cloud Trace की मदद से परफ़ॉर्मेंस का विश्लेषण करना
इस प्रोसेस में कुछ समय लग सकता है. Vertex AI Agent Engine, Cloud Trace के साथ इंटिग्रेट होता है. इससे हमें मल्टी-एजेंट सिस्टम की लेटेन्सी का विश्लेषण करने में मदद मिलती है.
Google Cloud Console में ट्रेस पर जाएं. स्पैन में agent_run[orchestrate_agent]
को चुनें. आपको कुछ स्पैन दिखेंगे. उन पर क्लिक करें
ट्रेस की जानकारी में, यह पता लगाया जा सकता है कि कौनसे हिस्से में ज़्यादा समय लगा. उदाहरण के लिए, खोज के आधार पर जवाब जनरेट करने और मुश्किल जवाब जनरेट करने की वजह से, प्लानर एजेंट को किए गए कॉल में ज़्यादा समय लग सकता है.
इसी तरह, पोस्ट और इवेंट बनाते समय, आपको यह दिख सकता है कि Orchestrator को डेटा प्रोसेस करने और प्लैटफ़ॉर्म एजेंट के लिए टूल कॉल तैयार करने में कितना समय लगा.
इन ट्रेस को एक्सप्लोर करने से, एजेंट सिस्टम की परफ़ॉर्मेंस को समझने और उसे ऑप्टिमाइज़ करने में मदद मिलती है.
बधाई हो! आपने Google के ADK, A2A, MCP, और Google Cloud सेवाओं का इस्तेमाल करके, एक बेहतर मल्टी-एजेंट एआई सिस्टम बनाया, उसे डिप्लॉय किया, और उसकी जांच की. आपने एजेंट ऑर्केस्ट्रेशन, टूल के इस्तेमाल, स्टेट मैनेजमेंट, और क्लाउड डिप्लॉयमेंट से जुड़ी समस्याओं को हल किया है. इससे InstaVibe के लिए, एआई की मदद से काम करने वाली एक सुविधा तैयार की जा सकी है. वर्कशॉप पूरी करने के लिए बधाई!
13. क्लीन अप करें
अपने Google Cloud खाते से शुल्क लिए जाने से बचने के लिए, इस वर्कशॉप के दौरान बनाई गई संसाधनों को मिटाना ज़रूरी है. यहां दी गई कमांड की मदद से, Spanner इंस्टेंस, Cloud Run सेवाएं, Artifact Registry रिपॉज़िटरी, एपीआई पासकोड, Vertex AI Agent Engine, और उनसे जुड़ी IAM अनुमतियां हटाई जा सकती हैं.
अहम जानकारी:
- पक्का करें कि आपने इन कमांड को उसी Google Cloud प्रोजेक्ट में चलाया हो जिसका इस्तेमाल वर्कशॉप के लिए किया गया था.
- अगर आपने Cloud Shell टर्मिनल बंद कर दिया है, तो हो सकता है कि कुछ एनवायरमेंट वैरिएबल सेट न हों. जैसे, $PROJECT_ID, $SPANNER_INSTANCE_ID वगैरह. आपको उन्हें फिर से एक्सपोर्ट करना होगा. ऐसा आपको वर्कशॉप सेटअप के दौरान करना होगा. इसके अलावा, नीचे दिए गए निर्देशों में मौजूद वैरिएबल को उनकी असल वैल्यू से बदला जा सकता है.
- इन कमांड से, आपके संसाधनों को हमेशा के लिए मिटा दिया जाएगा. अगर इस प्रोजेक्ट में आपका कोई अन्य ज़रूरी डेटा है, तो इसे चलाने से पहले अच्छी तरह से जांच कर लें.
👉💻 साफ़ करने के लिए, यहां दी गई स्क्रिप्ट चलाएं.
एनवायरमेंट वैरिएबल रीसेट करें
. ~/instavibe-bootstrap/set_env.sh
एजेंट इंजन मिटाएं:
cd ~/instavibe-bootstrap/utils
source ~/instavibe-bootstrap/env/bin/activate
export ORCHESTRATE_AGENT_ID=$(cat ~/instavibe-bootstrap/instavibe/temp_endpoint.txt)
echo "ORCHESTRATE_AGENT_ID set to: ${ORCHESTRATE_AGENT_ID}"
python remote_delete.py
deactivate
echo "Vertex AI Agent Engine deletion initiated."
Cloud Run की सेवाओं को मिटाना:
# InstaVibe Web Application
gcloud run services delete instavibe --platform=managed --region=${REGION} --project=${PROJECT_ID} --quiet
# MCP Tool Server
gcloud run services delete mcp-tool-server --platform=managed --region=${REGION} --project=${PROJECT_ID} --quiet
# Planner Agent (A2A Server)
gcloud run services delete planner-agent --platform=managed --region=${REGION} --project=${PROJECT_ID} --quiet
# Platform MCP Client Agent (A2A Server)
gcloud run services delete platform-mcp-client --platform=managed --region=${REGION} --project=${PROJECT_ID} --quiet
# Social Agent (A2A Server)
gcloud run services delete social-agent --platform=managed --region=${REGION} --project=${PROJECT_ID} --quiet
echo "Cloud Run services deletion initiated."
A2A इंस्पेक्टर डॉकर कंटेनर को बंद करना और हटाना
docker rm --force a2a-inspector
Spanner इंस्टेंस मिटाने के लिए:
echo "Deleting Spanner instance: ${SPANNER_INSTANCE_ID}..."
gcloud spanner instances delete ${SPANNER_INSTANCE_ID} --project=${PROJECT_ID} --quiet
echo "Spanner instance deletion initiated."
Artifact Registry के डेटा स्टोर करने की जगह को मिटाना:
echo "Deleting Artifact Registry repository: ${REPO_NAME}..."
gcloud artifacts repositories delete ${REPO_NAME} --location=${REGION} --project=${PROJECT_ID} --quiet
echo "Artifact Registry repository deletion initiated."
सेवा खाते से भूमिकाएं हटाएं:
echo "Removing roles from service account: $SERVICE_ACCOUNT_NAME in project $PROJECT_ID"
# Remove Project-level roles for default service account
gcloud projects remove-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:$SERVICE_ACCOUNT_NAME" \
--role="roles/spanner.admin"
gcloud projects remove-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:$SERVICE_ACCOUNT_NAME" \
--role="roles/spanner.databaseUser"
gcloud projects remove-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:$SERVICE_ACCOUNT_NAME" \
--role="roles/artifactregistry.admin"
gcloud projects remove-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:$SERVICE_ACCOUNT_NAME" \
--role="roles/cloudbuild.builds.editor"
gcloud projects remove-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:$SERVICE_ACCOUNT_NAME" \
--role="roles/run.admin"
gcloud projects remove-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:$SERVICE_ACCOUNT_NAME" \
--role="roles/iam.serviceAccountUser"
gcloud projects remove-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:$SERVICE_ACCOUNT_NAME" \
--role="roles/aiplatform.user"
gcloud projects remove-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:$SERVICE_ACCOUNT_NAME" \
--role="roles/logging.logWriter"
gcloud projects remove-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:$SERVICE_ACCOUNT_NAME" \
--role="roles/logging.viewer"
echo "All specified roles have been removed."
लोकल वर्कशॉप फ़ाइलें मिटाने के लिए:
echo "Removing local workshop directory ~/instavibe-bootstrap..."
rm -rf ~/instavibe-bootstrap
rm -rf ~/a2a-inspector
rm -f ~/mapkey.txt
rm -f ~/project_id.txt
echo "Local directory removed."