Google এর এজেন্ট স্ট্যাক ইন অ্যাকশন: Google ক্লাউডে ADK, A2A, MCP

1. আপনি কি শিখবেন

স্বাগতম! আমরা আজ একটি সুন্দর যাত্রা শুরু করতে যাচ্ছি। আসুন একটি জনপ্রিয় সামাজিক ইভেন্ট প্ল্যাটফর্ম InstaVibe সম্পর্কে চিন্তা করে শুরু করি। যদিও এটি সফল, আমরা জানি যে কিছু ব্যবহারকারীদের জন্য, গ্রুপ কার্যকলাপের প্রকৃত পরিকল্পনা একটি কাজের মত মনে হতে পারে। কল্পনা করুন যে আপনার সমস্ত বন্ধুরা কী বিষয়ে আগ্রহী তা খুঁজে বের করার চেষ্টা করুন, তারপর ইভেন্ট বা ভেন্যুগুলির জন্য অফুরন্ত বিকল্পগুলি খুঁজে বের করুন এবং অবশেষে সবকিছু সমন্বয় করুন। এটা অনেক! এটিই সঠিকভাবে যেখানে আমরা প্রকৃত পার্থক্য করতে AI, এবং আরও নির্দিষ্টভাবে, বুদ্ধিমান এজেন্টদের পরিচয় করিয়ে দিতে পারি।

ধারণাটি এমন একটি সিস্টেম তৈরি করা যেখানে এই এজেন্টরা ভারী উত্তোলন পরিচালনা করতে পারে, যেমন ব্যবহারকারী এবং বন্ধুদের পছন্দগুলি বোঝার জন্য চতুরতার সাথে 'শোনা' এবং তারপরে সক্রিয়ভাবে চমত্কার, উপযোগী কার্যকলাপের পরামর্শ দেওয়া। আমাদের লক্ষ্য হল InstaVibe-এ সামাজিক পরিকল্পনাকে নিরবচ্ছিন্ন এবং আনন্দদায়ক কিছুতে রূপান্তর করা। এই স্মার্ট সহকারীগুলি তৈরি করা শুরু করার জন্য, আমাদের সঠিক সরঞ্জামগুলির সাথে একটি শক্তিশালী ভিত্তি স্থাপন করতে হবে।

আপনি যে ধারণাটি দেখতে পাবেন তা এখানে:

শিরোনাম পৃষ্ঠা

Google-এর ADK-এর সাথে ভিত্তি: Google-এর এজেন্ট ডেভেলপমেন্ট কিট (ADK) ব্যবহার করে আপনার প্রথম বুদ্ধিমান এজেন্ট তৈরির মৌলিক বিষয়গুলি আয়ত্ত করুন৷ প্রয়োজনীয় উপাদান, এজেন্ট জীবনচক্র এবং ফ্রেমওয়ার্কের অন্তর্নির্মিত সরঞ্জামগুলি কার্যকরভাবে কীভাবে ব্যবহার করা যায় তা বুঝুন।

মডেল কনটেক্সট প্রোটোকল (MCP) সহ এজেন্টের ক্ষমতা প্রসারিত করুন: আপনার এজেন্টদের কাস্টম সরঞ্জাম এবং প্রসঙ্গ দিয়ে সজ্জিত করতে শিখুন, তাদের বিশেষ কাজ সম্পাদন করতে এবং নির্দিষ্ট তথ্য অ্যাক্সেস করতে সক্ষম করে। মডেল কনটেক্সট প্রোটোকল (MCP) ধারণাটি প্রবর্তন করুন। এই প্রসঙ্গটি প্রদান করতে আপনি কীভাবে একটি MCP সার্ভার সেট আপ করবেন তা শিখবেন।

ডিজাইনিং এজেন্ট ইন্টারঅ্যাকশন এবং অর্কেস্ট্রেশন: এজেন্ট অর্কেস্ট্রেশন বুঝতে একক এজেন্টের বাইরে যান। সহজ অনুক্রমিক কর্মপ্রবাহ থেকে লুপ, শর্তসাপেক্ষ যুক্তি এবং সমান্তরাল প্রক্রিয়াকরণ জড়িত জটিল পরিস্থিতি পর্যন্ত ডিজাইন ইন্টারঅ্যাকশন প্যাটার্ন। মডুলার কাজগুলি পরিচালনা করার জন্য ADK কাঠামোর মধ্যে সাব-এজেন্টের ধারণাটি প্রবর্তন করুন।

সহযোগিতামূলক মাল্টি-এজেন্ট সিস্টেম তৈরি করা: জটিল লক্ষ্য অর্জনের জন্য একাধিক এজেন্ট সহযোগিতা করে এমন সিস্টেমগুলিকে কীভাবে স্থপতি করতে হয় তা আবিষ্কার করুন। এজেন্ট-টু-এজেন্ট (A2A) কমিউনিকেশন প্রোটোকল শিখুন এবং প্রয়োগ করুন, নির্ভরযোগ্যভাবে ইন্টারঅ্যাক্ট করার জন্য বিতরণ করা এজেন্টদের (সম্ভাব্যভাবে বিভিন্ন মেশিন বা পরিষেবাতে চলমান) জন্য একটি প্রমিত উপায় স্থাপন করুন।

Google ক্লাউডে উত্পাদনকারী এজেন্ট: আপনার এজেন্ট অ্যাপ্লিকেশনগুলিকে উন্নয়ন পরিবেশ থেকে ক্লাউডে স্থানান্তর করুন। Google ক্লাউড প্ল্যাটফর্মে (GCP) স্কেলযোগ্য, মজবুত মাল্টি-এজেন্ট সিস্টেম আর্কিটেক্ট এবং স্থাপনের জন্য সর্বোত্তম অনুশীলন শিখুন। ক্লাউড রানের মতো GCP পরিষেবাগুলিকে কাজে লাগানোর জন্য অন্তর্দৃষ্টি লাভ করুন এবং আপনার এজেন্টদের হোস্টিং ও পরিচালনার জন্য সর্বশেষ Google এজেন্ট ইঞ্জিনের ক্ষমতাগুলি অন্বেষণ করুন৷

2. স্থাপত্য

InstaVibe-এর সাথে AI-চালিত সামাজিক পরিকল্পনা

সামাজিক শ্রবণ কি?

সোশ্যাল লিসেনিং হল সোশ্যাল মিডিয়া, ফোরাম এবং নিউজ সাইটগুলির মতো প্ল্যাটফর্ম জুড়ে ডিজিটাল কথোপকথনগুলি পর্যবেক্ষণ করার প্রক্রিয়া যাতে লোকেরা একটি বিষয়, ব্র্যান্ড বা শিল্প সম্পর্কে কী বলছে তা বোঝার জন্য। এটি জনসাধারণের অনুভূতি, প্রবণতা এবং ব্যবহারকারীর চাহিদার মূল্যবান অন্তর্দৃষ্টি প্রদান করে। এই কর্মশালায়, আমরা একটি এজেন্ট-ভিত্তিক সিস্টেমের মধ্যে এই ধারণাটি ব্যবহার করব।

আপনি InstaVibe এ দলে আছেন

কল্পনা করুন যে আপনি "InstaVibe" এ কাজ করেন, একটি জনপ্রিয় সামাজিক ইভেন্ট প্ল্যাটফর্মের সাথে একটি সফল স্টার্টআপ যা অল্প বয়স্কদের লক্ষ্য করে। সবকিছু ঠিকঠাক চলছে, কিন্তু অনেক প্রযুক্তি কোম্পানির মতো, আপনার টিম AI ব্যবহার করে উদ্ভাবনের জন্য বিনিয়োগকারীদের চাপের সম্মুখীন হয়। অভ্যন্তরীণভাবে, আপনি এমন ব্যবহারকারীদের একটি অংশও লক্ষ্য করেছেন যারা অন্যদের মতো বেশি আকৃষ্ট হন না - হয়ত তারা গোষ্ঠী কার্যক্রম শুরু করতে বা পরিকল্পনা প্রক্রিয়াটিকে চ্যালেঞ্জিং মনে করতে কম আগ্রহী। আপনার কোম্পানির জন্য, এর মানে এই গুরুত্বপূর্ণ ব্যবহারকারী গ্রুপের মধ্যে কম প্ল্যাটফর্মের আঠালোতা।

আপনার দলের গবেষণা পরামর্শ দেয় যে AI-চালিত সহায়তা এই ব্যবহারকারীদের অভিজ্ঞতা উল্লেখযোগ্যভাবে উন্নত করতে পারে। ধারণাটি হল ব্যবহারকারী এবং তাদের বন্ধুদের স্বার্থের উপর ভিত্তি করে প্রাসঙ্গিক ক্রিয়াকলাপগুলিকে সক্রিয়ভাবে পরামর্শ দিয়ে সামাজিক ভ্রমণের পরিকল্পনা করার প্রক্রিয়াটিকে প্রবাহিত করা। আপনি এবং আপনার সহকর্মীরা যে প্রশ্নের মুখোমুখি হন তা হল: কীভাবে এআই এজেন্টরা আগ্রহের আবিষ্কার, কার্যকলাপ গবেষণা এবং সম্ভাব্য প্রাথমিক সমন্বয়ের প্রায়শই সময়সাপেক্ষ কাজগুলিকে স্বয়ংক্রিয় করতে পারে?

একটি এজেন্ট-ভিত্তিক সমাধান (প্রোটোটাইপ ধারণা)

আপনি একটি মাল্টি-এজেন্ট সিস্টেম দ্বারা চালিত একটি প্রোটোটাইপ বৈশিষ্ট্য বিকাশের প্রস্তাব করেন৷ এখানে একটি ধারণাগত ভাঙ্গন আছে:

ইউজকেস

  • সোশ্যাল প্রোফাইলিং এজেন্ট : এই এজেন্ট ব্যবহারকারীর সংযোগ, মিথস্ক্রিয়া এবং ব্যবহারকারীর পছন্দের সাথে সম্পর্কিত সম্ভাব্য বিস্তৃত জনসাধারণের প্রবণতা বিশ্লেষণ করতে সামাজিক শোনার কৌশল নিযুক্ত করে। এর উদ্দেশ্য হ'ল ভাগ করা আগ্রহ এবং উপযুক্ত কার্যকলাপের বৈশিষ্ট্যগুলি সনাক্ত করা (যেমন, শান্ত সমাবেশের জন্য পছন্দ, নির্দিষ্ট শখ)।
  • ইভেন্ট প্ল্যানিং এজেন্ট : সোশ্যাল প্রোফাইলিং এজেন্টের অন্তর্দৃষ্টি ব্যবহার করে, এই এজেন্ট নির্দিষ্ট ইভেন্ট, ভেন্যু বা আইডিয়ার জন্য অনলাইন রিসোর্স অনুসন্ধান করে যা চিহ্নিত মাপদণ্ডের সাথে সারিবদ্ধ (যেমন অবস্থান, আগ্রহ)।
  • প্ল্যাটফর্ম ইন্টারঅ্যাকশন এজেন্ট (এমসিপি ব্যবহার করে) : এই এজেন্ট অ্যাক্টিভিটি প্ল্যানিং এজেন্টের কাছ থেকে চূড়ান্ত পরিকল্পনা নেয়। এর মূল কাজ হল একটি পূর্ব-নির্ধারিত MCP (মডেল কনটেক্সট প্রোটোকল) টুল ব্যবহার করে সরাসরি ইন্সটাভিব প্ল্যাটফর্মের সাথে যোগাযোগ করা। এই টুলটি এজেন্টকে একটি ইভেন্টের পরামর্শ খসড়া করার এবং পরিকল্পনার রূপরেখা দিয়ে একটি পোস্ট তৈরি করার নির্দিষ্ট ক্ষমতা প্রদান করে।
  • অর্কেস্ট্রেটর এজেন্ট : এই এজেন্ট কেন্দ্রীয় সমন্বয়কারী হিসাবে কাজ করে। এটি InstaVibe প্ল্যাটফর্ম থেকে প্রাথমিক ব্যবহারকারীর অনুরোধ গ্রহণ করে, সামগ্রিক লক্ষ্য বুঝতে পারে (যেমন, "আমার এবং আমার বন্ধুদের জন্য একটি ইভেন্টের পরিকল্পনা করুন"), এবং তারপর একটি যৌক্তিক ক্রমানুসারে উপযুক্ত বিশেষ এজেন্টদের কাছে নির্দিষ্ট কাজগুলি অর্পণ করে৷ এটি এজেন্টদের মধ্যে তথ্যের প্রবাহ পরিচালনা করে এবং নিশ্চিত করে যে চূড়ান্ত ফলাফল ব্যবহারকারীর কাছে ফেরত দেওয়া হয়েছে।

মূল স্থাপত্য উপাদান এবং প্রযুক্তি

স্থাপত্য

Google ক্লাউড প্ল্যাটফর্ম (GCP):

  • ভার্টেক্স এআই :
    • Gemini মডেল: Gemini-এর মতো Google-এর অত্যাধুনিক Large Language Models (LLMs) অ্যাক্সেস প্রদান করে, যা আমাদের এজেন্টদের যুক্তি ও সিদ্ধান্ত নেওয়ার ক্ষমতাকে শক্তিশালী করে।
    • ভার্টেক্স এআই এজেন্ট ইঞ্জিন: একটি পরিচালিত পরিষেবা যা আমাদের অর্কেস্ট্রেটর এজেন্টকে স্থাপন, হোস্ট এবং স্কেল করতে ব্যবহৃত হয়, উত্পাদনকে সহজ করে এবং অবকাঠামোগত জটিলতাগুলিকে বিমূর্ত করে।
  • ক্লাউড রান : কনটেইনারাইজড অ্যাপ্লিকেশন স্থাপনের জন্য একটি সার্ভারহীন প্ল্যাটফর্ম। আমরা এটি ব্যবহার করি:
    • প্রধান InstaVibe ওয়েব অ্যাপ্লিকেশন হোস্ট করুন।
    • স্বতন্ত্র মাইক্রোসার্ভিস হিসাবে পৃথক A2A-সক্ষম এজেন্ট (পরিকল্পক, সামাজিক প্রোফাইলিং, প্ল্যাটফর্ম ইন্টারঅ্যাকশন) স্থাপন করুন।
    • MCP টুল সার্ভার চালান, InstaVibe-এর অভ্যন্তরীণ API এজেন্টদের জন্য উপলব্ধ করে।
  • স্প্যানার : একটি সম্পূর্ণরূপে পরিচালিত, বিশ্বব্যাপী বিতরণ করা, এবং দৃঢ়ভাবে সামঞ্জস্যপূর্ণ রিলেশনাল ডাটাবেস। এই কর্মশালায়, আমরা একটি গ্রাফ ডাটাবেস হিসাবে এর গ্রাফ ডিডিএল ব্যবহার করে এর ক্ষমতাগুলি ব্যবহার করি এবং এর জন্য ক্যোয়ারী বৈশিষ্ট্যগুলি ব্যবহার করি:
    • জটিল সামাজিক সম্পর্ক মডেল এবং স্টোর করুন (ব্যবহারকারী, বন্ধুত্ব, ইভেন্টে উপস্থিতি, পোস্ট)।
    • সামাজিক প্রোফাইলিং এজেন্টদের জন্য এই সম্পর্কের দক্ষ অনুসন্ধান সক্ষম করুন।
  • আর্টিফ্যাক্ট রেজিস্ট্রি : কন্টেইনার ছবি সংরক্ষণ, পরিচালনা এবং সুরক্ষিত করার জন্য একটি সম্পূর্ণরূপে পরিচালিত পরিষেবা।
  • ক্লাউড বিল্ড : একটি পরিষেবা যা Google ক্লাউডে আপনার বিল্ডগুলি কার্যকর করে৷ আমরা আমাদের এজেন্ট এবং অ্যাপ্লিকেশন সোর্স কোড থেকে স্বয়ংক্রিয়ভাবে ডকার কন্টেইনার ইমেজ তৈরি করতে এটি ব্যবহার করি।
  • ক্লাউড স্টোরেজ : বিল্ড আর্টিফ্যাক্ট সংরক্ষণের জন্য ক্লাউড বিল্ডের মতো পরিষেবা এবং এজেন্ট ইঞ্জিন এর অপারেশনাল প্রয়োজনের জন্য ব্যবহার করে।
  • মূল এজেন্ট ফ্রেমওয়ার্ক এবং প্রোটোকল :
    • Google এর এজেন্ট ডেভেলপমেন্ট কিট (ADK) : এর জন্য প্রাথমিক কাঠামো:
      • স্বতন্ত্র বুদ্ধিমান এজেন্টদের জন্য মূল যুক্তি, আচরণ এবং নির্দেশ সেট সংজ্ঞায়িত করা।
      • এজেন্ট জীবনচক্র, রাষ্ট্র এবং মেমরি পরিচালনা (স্বল্পমেয়াদী সেশনের অবস্থা এবং সম্ভাব্য দীর্ঘমেয়াদী জ্ঞান)।
      • একীভূত করা টুল (যেমন Google সার্চ বা কাস্টম-বিল্ট টুল) যা এজেন্টরা বিশ্বের সাথে ইন্টারঅ্যাক্ট করতে ব্যবহার করতে পারে।
      • ক্রমিক, লুপ, এবং সাব-এজেন্টগুলির সমান্তরাল সম্পাদন সহ বহু-এজেন্ট ওয়ার্কফ্লো অর্কেস্ট্রেটিং।
    • এজেন্ট-টু-এজেন্ট (A2A) কমিউনিকেশন প্রোটোকল : একটি ওপেন স্ট্যান্ডার্ড সক্রিয় করে:
      • বিভিন্ন এআই এজেন্টদের মধ্যে সরাসরি, মানসম্মত যোগাযোগ এবং সহযোগিতা, এমনকি তারা আলাদা পরিষেবা হিসাবে বা বিভিন্ন মেশিনে চললেও।
      • এজেন্ট একে অপরের ক্ষমতা আবিষ্কার করতে (এজেন্ট কার্ডের মাধ্যমে) এবং কার্য অর্পণ করতে। বিশেষ পরিকল্পনাকারী, সামাজিক এবং প্ল্যাটফর্ম এজেন্টদের সাথে যোগাযোগ করার জন্য আমাদের অর্কেস্ট্রেটর এজেন্টের জন্য এটি অত্যন্ত গুরুত্বপূর্ণ।
    • A2A পাইথন লাইব্রেরি (a2a-python) : আমাদের ADK এজেন্টদের A2A প্রোটোকল বলতে ব্যবহৃত কংক্রিট লাইব্রেরি। এটি প্রয়োজনীয় সার্ভার-সাইড উপাদান সরবরাহ করে:
      • আমাদের এজেন্টদেরকে A2A-সঙ্গী সার্ভার হিসাবে প্রকাশ করুন।
      • আবিষ্কারের জন্য "এজেন্ট কার্ড" পরিবেশন করা স্বয়ংক্রিয়ভাবে পরিচালনা করুন।
      • অন্যান্য এজেন্টদের (যেমন অর্কেস্ট্রেটর) থেকে ইনকামিং টাস্ক অনুরোধগুলি গ্রহণ এবং পরিচালনা করুন।
    • মডেল কনটেক্সট প্রোটোকল (MCP) : একটি উন্মুক্ত মান যা এজেন্টদের অনুমতি দেয়:
      • একটি প্রমিত উপায়ে বহিরাগত সরঞ্জাম, ডেটা উত্স এবং সিস্টেমগুলির সাথে সংযোগ করুন এবং ব্যবহার করুন।
      • আমাদের প্ল্যাটফর্ম ইন্টারঅ্যাকশন এজেন্ট একটি MCP সার্ভারের সাথে যোগাযোগ করার জন্য একটি MCP ক্লায়েন্ট ব্যবহার করে, যা InstaVibe প্ল্যাটফর্মের বিদ্যমান API-এর সাথে ইন্টারঅ্যাক্ট করার জন্য সরঞ্জামগুলিকে প্রকাশ করে।
  • ডিবাগিং টুলস :
    • A2A ইন্সপেক্টর : A2A ইন্সপেক্টর হল একটি ওয়েব-ভিত্তিক ডিবাগিং টুল যা এই ওয়ার্কশপ জুড়ে আমাদের A2A-সক্ষম এজেন্টদের সাথে সংযোগ, পরিদর্শন এবং ইন্টারঅ্যাক্ট করতে ব্যবহৃত হয়। চূড়ান্ত উৎপাদন আর্কিটেকচারের অংশ না হলেও, এটি আমাদের উন্নয়ন কর্মপ্রবাহের একটি অপরিহার্য অংশ। এটি প্রদান করে:
      • এজেন্ট কার্ড ভিউয়ার: একটি এজেন্টের পাবলিক ক্ষমতা আনতে এবং যাচাই করতে।
      • লাইভ চ্যাট ইন্টারফেস: তাৎক্ষণিক পরীক্ষার জন্য নিযুক্ত এজেন্টকে সরাসরি বার্তা পাঠাতে।
      • ডিবাগ কনসোল: পরিদর্শক এবং এজেন্টের মধ্যে আদান-প্রদান করা কাঁচা JSON-RPC বার্তাগুলি দেখতে৷
  • ভাষা মডেল (LLMs) : সিস্টেমের "মস্তিষ্ক":
    • Google-এর জেমিনি মডেল: বিশেষত, আমরা gemini-2.0-flash-এর মত সংস্করণ ব্যবহার করি। এই মডেলগুলির জন্য বেছে নেওয়া হয়েছে:
      • উন্নত যুক্তি ও নির্দেশনা অনুসরণ: জটিল প্রম্পট বোঝার, বিশদ নির্দেশাবলী অনুসরণ করার এবং কাজ সম্পর্কে যুক্তি তাদের ক্ষমতা এজেন্ট সিদ্ধান্ত গ্রহণের জন্য উপযুক্ত করে তোলে।
      • টুল ব্যবহার (ফাংশন কলিং): জেমিনি মডেলগুলি ADK-এর মাধ্যমে প্রদত্ত সরঞ্জামগুলি কখন এবং কীভাবে ব্যবহার করতে হবে তা নির্ধারণে দক্ষতা অর্জন করে, এজেন্টদের তথ্য সংগ্রহ করতে বা ক্রিয়া সম্পাদন করতে সক্ষম করে।
      • দক্ষতা (ফ্ল্যাশ মডেল): "ফ্ল্যাশ" ভেরিয়েন্টগুলি পারফরম্যান্স এবং খরচ-কার্যকারিতার একটি ভাল ভারসাম্য অফার করে, অনেক ইন্টারেক্টিভ এজেন্ট কাজের জন্য উপযুক্ত যার জন্য দ্রুত প্রতিক্রিয়া প্রয়োজন।

Google ক্লাউড ক্রেডিট প্রয়োজন?

3. আপনি শুরু করার আগে

👉Google ক্লাউড কনসোলের শীর্ষে ক্লাউড শেল সক্রিয় করুন- এ ক্লিক করুন (এটি ক্লাউড শেল প্যানের শীর্ষে টার্মিনাল আকৃতির আইকন), মেঘের শেল

👉"ওপেন এডিটর " বোতামে ক্লিক করুন (এটি একটি পেন্সিল সহ একটি খোলা ফোল্ডারের মতো দেখায়)। এটি উইন্ডোতে ক্লাউড শেল কোড এডিটর খুলবে। আপনি বাম দিকে একটি ফাইল এক্সপ্লোরার দেখতে পাবেন। মেঘের শেল

👉 নিচের স্ট্যাটাস বারে দেখানো ক্লাউড কোড সাইন-ইন বোতামে ক্লিক করুন। নির্দেশিত হিসাবে প্লাগইন অনুমোদন করুন. যদি আপনি ক্লাউড কোড দেখেন - স্ট্যাটাস বারে কোনো প্রকল্প নেই , তাহলে সেটি নির্বাচন করুন তারপর ড্রপ ডাউনে 'একটি Google ক্লাউড প্রকল্প নির্বাচন করুন' এবং তারপরে আপনার তৈরি করা প্রকল্পগুলির তালিকা থেকে নির্দিষ্ট Google ক্লাউড প্রকল্পটি নির্বাচন করুন৷ মেঘের শেল

👉 আপনার গুগল ক্লাউড প্রজেক্ট আইডি খুঁজুন:

  • Google ক্লাউড কনসোল খুলুন: 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/ : এটি আমাদের এআই সিস্টেমের হৃদয়। প্রতিটি সাব-ডিরেক্টরি (প্লানার/, সামাজিক/, ইত্যাদি) একটি নির্দিষ্ট বুদ্ধিমান এজেন্টের জন্য সোর্স কোড ধারণ করে।
    • agent.py : প্রতিটি এজেন্টের ফোল্ডারের ভিতরে, এটি হল প্রধান ফাইল যেখানে এজেন্টের যুক্তি।
    • a2a_server.py : এই ফাইলটি একটি এজেন্ট-টু-এজেন্ট (A2A) সার্ভারের সাথে ADK এজেন্টকে মোড়ানো হয়।
    • Dockerfile : ক্লাউড রান বা এজেন্ট ইঞ্জিনে এজেন্ট স্থাপনের জন্য কন্টেইনার ইমেজ কীভাবে তৈরি করা যায় তা সংজ্ঞায়িত করে।
  • instavibe/ : এই ডিরেক্টরিতে InstaVibe ওয়েব অ্যাপ্লিকেশনের জন্য পুরো সোর্স কোড রয়েছে।
  • tools/ : এই ডিরেক্টরিটি বাহ্যিক সরঞ্জাম তৈরির জন্য যা আমাদের এজেন্টরা ব্যবহার করতে পারে।
    • instavibe/ এ মডেল কনটেক্সট প্রোটোকল (MCP) সার্ভার রয়েছে।

এই মডুলার স্ট্রাকচার ওয়েব অ্যাপ্লিকেশনটিকে বিভিন্ন এআই উপাদান থেকে আলাদা করে, যা পুরো সিস্টেমটিকে পরিচালনা, পরীক্ষা এবং স্থাপন করা সহজ করে তোলে।

👉💻 প্রারম্ভিক স্ক্রিপ্ট চালান:

এই স্ক্রিপ্টটি আপনাকে আপনার Google ক্লাউড প্রজেক্ট আইডি লিখতে অনুরোধ করবে।

Google ক্লাউড প্রজেক্ট আইডি লিখুন যেটি আপনি শেষ ধাপে পেয়েছিলেন যখন init.sh স্ক্রিপ্ট দ্বারা অনুরোধ করা হয়:

cd ~/instavibe-bootstrap
./init.sh

👉💻 প্রয়োজনীয় প্রজেক্ট আইডি সেট করুন:

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

👉💻 প্রয়োজনীয় Google ক্লাউড 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 কনসোলে ফলাফল যাচাই করুন মেঘের শেল

👉💻 একটি আর্টিফ্যাক্ট রেজিস্ট্রি সংগ্রহস্থল তৈরি করতে টার্মিনালে নিম্নলিখিত কমান্ডগুলি চালান। ক্লাউড রান বা এজেন্ট ইঞ্জিনে স্থাপনের আগে আমাদের এজেন্ট, MCP সার্ভার এবং InstaVibe অ্যাপ্লিকেশনের জন্য সমস্ত ডকার ছবি এখানে সংরক্ষণ করা হয়।

export REPO_NAME="introveally-repo"
gcloud artifacts repositories create $REPO_NAME \
  --repository-format=docker \
  --location=us-central1 \
  --description="Docker repository for InstaVibe workshop"

API কীগুলির জন্য মানচিত্র প্ল্যাটফর্ম সেটআপ করুন

আপনার InstaVibe অ্যাপ্লিকেশনে Google মানচিত্র পরিষেবাগুলি ব্যবহার করতে, আপনাকে একটি API কী তৈরি করতে হবে এবং এটি যথাযথভাবে সীমাবদ্ধ করতে হবে।

👉 একটি নতুন ট্যাবে, APIs & Services > Credentials- এ যান। "শংসাপত্র" পৃষ্ঠায়, শীর্ষে + শংসাপত্র তৈরি করুন বোতামে ক্লিক করুন৷ ড্রপডাউন মেনু থেকে API কী নির্বাচন করুন। alt পাঠ্য

👉 একটি ডায়ালগ বক্স আসবে যেখানে আপনার নতুন তৈরি API কী দেখানো হবে। আপনার অ্যাপ্লিকেশন কনফিগারেশনের জন্য পরে এটির প্রয়োজন হবে।

👉 "API কী তৈরি করা হয়েছে" ডায়ালগে বন্ধ ক্লিক করুন।

👉 আপনি আপনার নতুন API কী তালিকাভুক্ত দেখতে পাবেন (যেমন, "API কী 1")। ডানদিকে তিনটি বিন্দুতে ক্লিক করুন "এপিআই কী সীমাবদ্ধ করুন এবং পুনঃনামকরণ করুন" পৃষ্ঠাটি খুলতে সম্পাদনা API কী নির্বাচন করুন। alt পাঠ্য

👉 উপরের নামের ক্ষেত্রে, ডিফল্ট নামটি এতে পরিবর্তন করুন: মানচিত্র প্ল্যাটফর্ম API কী (🚨🚨গুরুত্বপূর্ণ🚨🚨 অনুগ্রহ করে এই নামটি ব্যবহার করুন!)

Maps Platform API Key

👉 "অ্যাপ্লিকেশন সীমাবদ্ধতা" বিভাগের অধীনে নিশ্চিত করুন যে কোনোটিই নির্বাচন করা হয়নি।

👉 "API সীমাবদ্ধতা" বিভাগের অধীনে, সীমাবদ্ধ কী রেডিও বোতামটি নির্বাচন করুন।

👉 এপিআই নির্বাচন করুন ড্রপডাউন মেনুতে ক্লিক করুন। প্রদর্শিত অনুসন্ধান বাক্সে, Maps JavaScript API টাইপ করুন এবং তালিকা থেকে এটি নির্বাচন করুন। alt পাঠ্য

👉 ওকে ক্লিক করুন।

👉 পৃষ্ঠার নীচে সংরক্ষণ বোতামে ক্লিক করুন।

মূল ফলাফল

আপনি এখন সফলভাবে "Maps Platform API Key" নামে একটি API কী তৈরি করেছেন, এটিকে শুধুমাত্র "Maps JavaScript API" ব্যবহারের অনুমতি দেওয়ার জন্য সীমাবদ্ধ করেছেন এবং নিশ্চিত করেছেন যে API আপনার প্রকল্পের জন্য সক্ষম হয়েছে৷

4. গ্রাফ ডাটাবেস সেটআপ করুন

আমরা আমাদের বুদ্ধিমান এজেন্ট তৈরি করতে পারার আগে, আমাদের InstaVibe সামাজিক নেটওয়ার্কের মধ্যে সমৃদ্ধ সংযোগগুলি সংরক্ষণ এবং বোঝার একটি উপায় প্রয়োজন৷ এখানেই একটি গ্রাফ ডাটাবেস আসে। ঐতিহ্যগত রিলেশনাল ডাটাবেসের বিপরীতে যা সারি এবং কলামের টেবিলে ডেটা সঞ্চয় করে, একটি গ্রাফ ডাটাবেস বিশেষভাবে নোডের (যেমন মানুষ, ইভেন্ট বা পোস্ট) এবং সম্পর্ক (প্রান্ত) যা তাদের সংযুক্ত করে (যেমন বন্ধুত্ব, ইভেন্টে উপস্থিতি, বা উল্লেখ) এর পরিপ্রেক্ষিতে ডেটা উপস্থাপন এবং অনুসন্ধান করার জন্য ডিজাইন করা হয়েছে। এই কাঠামোটি সোশ্যাল মিডিয়া অ্যাপ্লিকেশনগুলির জন্য অবিশ্বাস্যভাবে শক্তিশালী কারণ এটি বাস্তব-বিশ্বের সামাজিক নেটওয়ার্কগুলিকে যেভাবে গঠন করা হয় তা প্রতিফলিত করে, এটি বিভিন্ন সত্তা কীভাবে আন্তঃসংযুক্ত রয়েছে তা অন্বেষণ করতে স্বজ্ঞাত করে তোলে৷

আমরা Google ক্লাউড স্প্যানার ব্যবহার করে এই গ্রাফ ডাটাবেস বাস্তবায়ন করছি। যদিও স্প্যানার প্রাথমিকভাবে বিশ্বব্যাপী বিতরণ করা, দৃঢ়ভাবে সামঞ্জস্যপূর্ণ রিলেশনাল ডাটাবেস হিসাবে পরিচিত, এটি আমাদের রিলেশনাল টেবিলের উপরে সরাসরি গ্রাফ স্ট্রাকচারগুলিকে সংজ্ঞায়িত করতে এবং অনুসন্ধান করতে দেয়।

এটি আমাদের এআই-চালিত বৈশিষ্ট্যগুলির জন্য গুরুত্বপূর্ণ জটিল সামাজিক গতিবিদ্যা বিশ্লেষণের জন্য গ্রাফ প্রশ্নগুলির অভিব্যক্তিপূর্ণ শক্তি সহ স্প্যানারের মাপযোগ্যতা, লেনদেনের সামঞ্জস্য এবং পরিচিত SQL ইন্টারফেসের সম্মিলিত সুবিধা দেয়।

👉💻 ক্লাউড শেল আইডিই টার্মিনালে। Google ক্লাউডে প্রয়োজনীয় পরিকাঠামোর ব্যবস্থা করুন। আমরা একটি স্প্যানার ইনস্ট্যান্স তৈরি করে শুরু করব, যা আমাদের ডাটাবেসের জন্য একটি ডেডিকেটেড ধারক হিসেবে কাজ করে। একবার দৃষ্টান্তটি প্রস্তুত হয়ে গেলে, আমরা তারপরে এটির মধ্যে প্রকৃত স্প্যানার ডেটাবেস তৈরি করব, যেটিতে আমাদের সমস্ত টেবিল এবং 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

👉💻 স্প্যানারকে ডিফল্ট পরিষেবা অ্যাকাউন্টে পড়ার/লেখার অ্যাক্সেস মঞ্জুর করুন

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}

👉💻 এখন। আমরা একটি পাইথন ভার্চুয়াল এনভায়রনমেন্ট সেট আপ করব, প্রয়োজনীয় পাইথন প্যাকেজগুলি ইনস্টল করব এবং তারপর স্প্যানারের মধ্যে গ্রাফ ডেটাবেস স্কিমা সেট আপ করব এবং এটিকে প্রাথমিক ডেটা সহ লোড করব এবং 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 ক্লাউড কনসোলে যান, স্প্যানারে নেভিগেট করুন, আপনার স্প্যানার উদাহরণগুলির একটি তালিকা দেখতে হবে৷ instavibe-graph-instance এ ক্লিক করুন। স্প্যানার উদাহরণ 👉 ইনস্ট্যান্স ওভারভিউ পৃষ্ঠায়, আপনি সেই উদাহরণের মধ্যে ডাটাবেসের একটি তালিকা দেখতে পাবেন। graphdb -তে ক্লিক করুন স্প্যানার ডিবি

👉 আপনার ডাটাবেসের জন্য বাম দিকের নেভিগেশন প্যানে, স্প্যানার স্টুডিওতে ক্লিক করুন স্প্যানার স্টুডিও

👉 ক্যোয়ারী এডিটরে (শিরোনামহীন ক্যোয়ারী ট্যাব), নিম্নলিখিত গ্রাফ SQL ক্যোয়ারী পেস্ট করুন। এই প্রশ্নটি সমস্ত ব্যক্তি নোড এবং অন্যান্য ব্যক্তি নোডের সাথে তাদের সরাসরি বন্ধুত্বের সম্পর্ক খুঁজে পাবে। এবং ফলাফল দেখতে RUN এ ক্লিক করুন।

Graph SocialGraph
MATCH result_paths = ((p:Person)-[f:Friendship]-(friend:Person))
RETURN SAFE_TO_JSON(result_paths) AS result_paths

স্প্যানার গ্রাফ

👉 একই ক্যোয়ারী এডিটরে, একই ইভেন্টে যোগদানকারী লোকেদের খুঁজে পেতে আগের DDL প্রতিস্থাপন করুন, যা একটি ভাগ করা কার্যকলাপের মাধ্যমে একটি পরোক্ষ সংযোগ বোঝায়।

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 অ্যাপ্লিকেশনের জন্য গ্রাফ ডাটাবেস হিসাবে স্প্যানার ব্যবহার করার ক্ষমতার একটি আভাস দেয়। আমাদের সামাজিক ডেটাকে একটি আন্তঃসংযুক্ত গ্রাফ হিসাবে মডেল করার মাধ্যমে, আমরা সম্পর্ক এবং ক্রিয়াকলাপগুলির পরিশীলিত বিশ্লেষণ সক্ষম করি, যা আমাদের AI এজেন্টদের জন্য ব্যবহারকারীর প্রসঙ্গ বুঝতে, আগ্রহগুলি আবিষ্কার করতে এবং শেষ পর্যন্ত বুদ্ধিমান সামাজিক পরিকল্পনা সহায়তা প্রদানের জন্য মৌলিক হবে।

আমাদের মৌলিক ডেটা স্ট্রাকচার এখন যথাস্থানে আছে এবং পরীক্ষিত আছে, আসুন আমাদের এজেন্টদের সাথে যোগাযোগ করবে এমন বিদ্যমান InstaVibe অ্যাপ্লিকেশনের দিকে নজর দেওয়া যাক।

5. InstaVibe-এর বর্তমান অবস্থা

আমাদের AI এজেন্টরা কোথায় ফিট করবে তা বোঝার জন্য, আমাদের প্রথমে বিদ্যমান InstaVibe ওয়েব অ্যাপ্লিকেশনটি স্থাপন এবং চালাতে হবে। এই অ্যাপ্লিকেশনটি ব্যবহারকারী ইন্টারফেস এবং মৌলিক কার্যকারিতা প্রদান করে যা আমরা ইতিমধ্যে সেট আপ করেছি স্প্যানার গ্রাফ ডাটাবেসের সাথে সংযোগ স্থাপন করে।

হোম পেজ

InstaVibe অ্যাপ্লিকেশনটি তার ইভেন্ট বিবরণ পৃষ্ঠাগুলিতে দৃশ্যত ইভেন্ট অবস্থানগুলি প্রদর্শন করতে Google মানচিত্র ব্যবহার করে। এই কার্যকারিতা সক্ষম করার জন্য, অ্যাপ্লিকেশনটির প্রয়োজন আমাদের আগে তৈরি করা API কী। নিচের স্ক্রিপ্টটি আমাদের বরাদ্দ করা ডিসপ্লে নাম ব্যবহার করে প্রকৃত কী স্ট্রিং পুনরুদ্ধার করবে ("মানচিত্র প্ল্যাটফর্ম API কী")।

ইভেন্ট পৃষ্ঠা

👉💻 ক্লাউড শেল IDE- এ ফিরে যান। নীচের স্ক্রিপ্ট চালান. তারপরে, আউটপুটটি সাবধানে চেক করে নিশ্চিত করুন যে দেখানো GOOGLE_MAPS_API_KEY আপনার তৈরি এবং আগে Google ক্লাউড কনসোল থেকে অনুলিপি করা কীটির সাথে মেলে৷

. ~/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 ওয়েব অ্যাপ্লিকেশনের জন্য কন্টেইনার ইমেজ তৈরি করি এবং এটিকে আমাদের আর্টিফ্যাক্ট রেজিস্ট্রি সংগ্রহস্থলে পুশ করি।

. ~/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 ওয়েবঅ্যাপ ইমেজ স্থাপন করুন

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

স্থাপনা সফলভাবে সম্পন্ন হলে, ক্লাউড রান লগগুলি আপনার চলমান InstaVibe অ্যাপ্লিকেশনের জন্য সর্বজনীন URL প্রদর্শন করবে।

URL

আপনি Google ক্লাউড কনসোলের ক্লাউড রান বিভাগে নেভিগেট করে এবং instavibe পরিষেবা নির্বাচন করে এই URLটি খুঁজে পেতে পারেন। তালিকাURL

বেসিক InstaVibe প্ল্যাটফর্ম অন্বেষণ করতে এখনই আপনার ওয়েব ব্রাউজারে সেই URLটি খুলুন। আমাদের সেট আপ করা গ্রাফ ডাটাবেস দ্বারা চালিত পোস্ট, ইভেন্ট এবং ব্যবহারকারীর সংযোগগুলি দেখুন৷

এখন যেহেতু আমাদের টার্গেট অ্যাপ্লিকেশন চলছে, আসুন এর ক্ষমতা বাড়ানোর জন্য প্রথম বুদ্ধিমান এজেন্ট তৈরি করা শুরু করি।

6. বেসিক এজেন্ট, এডিকে সহ ইভেন্ট প্ল্যানার

ADK ফ্রেমওয়ার্ক

Google এর ADK ফ্রেমওয়ার্কের ভূমিকা এখন যেহেতু আমাদের ভিত্তি (InstaVibe অ্যাপ এবং ডাটাবেস) সেট করা হয়েছে, আমরা Google এর এজেন্ট ডেভেলপমেন্ট কিট (ADK) ব্যবহার করে আমাদের প্রথম বুদ্ধিমান এজেন্ট তৈরি করা শুরু করতে পারি।

এজেন্ট ডেভেলপমেন্ট কিট (ADK) হল একটি নমনীয় এবং মডুলার ফ্রেমওয়ার্ক যা বিশেষভাবে এআই এজেন্টদের ডেভেলপমেন্ট এবং মোতায়েন করার জন্য ডিজাইন করা হয়েছে। এর ডিজাইন নীতি হল এজেন্ট ডেভেলপমেন্টকে প্রথাগত সফ্টওয়্যার ডেভেলপমেন্টের মতো অনুভব করা, যার লক্ষ্য হল ডেভেলপারদের জন্য এজেন্টিক আর্কিটেকচার তৈরি করা, স্থাপন করা এবং অর্কেস্ট্রেট করা যা সহজ, একক-উদ্দেশ্যমূলক কাজ থেকে জটিল, মাল্টি-এজেন্ট ওয়ার্কফ্লো পর্যন্ত সবকিছু পরিচালনা করতে পারে তা উল্লেখযোগ্যভাবে সহজ করে তোলা।

এর মূল অংশে, ADK একটি Agent ধারণার চারপাশে ঘোরাফেরা করে, যা নির্দেশাবলী, কনফিগারেশন (যেমন নির্বাচিত ভাষা মডেল, যেমন, জেমিনি), এবং Tools একটি সেট যা এটি ক্রিয়া সম্পাদন করতে বা তথ্য সংগ্রহ করতে ব্যবহার করতে পারে।

06-agent.png

আমাদের প্রাথমিক এজেন্ট হবেন একজন "ইভেন্ট প্ল্যানার।" এর মূল উদ্দেশ্য হল সামাজিক ভ্রমণের জন্য ব্যবহারকারীর অনুরোধ গ্রহণ করা (অবস্থান, তারিখ এবং আগ্রহ নির্দিষ্ট করে) এবং সৃজনশীল, উপযোগী পরামর্শ তৈরি করা। পরামর্শগুলি প্রাসঙ্গিক এবং বর্তমান তথ্যের উপর ভিত্তি করে (যেমন নির্দিষ্ট ইভেন্টগুলি সেই সপ্তাহান্তে ঘটছে) তা নিশ্চিত করতে, আমরা ADK-এর অন্তর্নির্মিত সরঞ্জামগুলির একটি ব্যবহার করব: Google অনুসন্ধান ৷ এটি এজেন্টকে রিয়েল-টাইম ওয়েব ফলাফলে তার প্রতিক্রিয়াগুলিকে গ্রাউন্ড করার অনুমতি দেয়, স্থান, ইভেন্ট এবং ব্যবহারকারীর মানদণ্ডের সাথে মিলে যাওয়া ক্রিয়াকলাপ সম্পর্কে সর্বশেষ বিবরণ আনয়ন করে।

👉📝 ক্লাউড শেল 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 অ্যাক্সেস করতে:

ক্লাউড শেল টুলবারে (সাধারণত উপরের ডানদিকে) ওয়েব প্রিভিউ আইকন থেকে (প্রায়শই একটি চোখ বা তীরযুক্ত একটি বর্গক্ষেত্রের মতো দেখায়), পোর্ট পরিবর্তন করুন নির্বাচন করুন। পপ-আপ উইন্ডোতে, পোর্টটি 8000 এ সেট করুন এবং "পরিবর্তন এবং পূর্বরূপ" ক্লিক করুন। ক্লাউড শেল তারপর একটি নতুন ব্রাউজার ট্যাব বা উইন্ডো খুলবে যা ADK Dev UI প্রদর্শন করবে।

ওয়েব প্রিভিউ

একবার আপনার ব্রাউজারে ADK Dev UI খুললে: UI-এর উপরের-ডান ড্রপডাউন মেনুতে, আপনি যে এজেন্টের সাথে ইন্টারঅ্যাক্ট করতে চান সেই এজেন্ট হিসাবে প্ল্যানার নির্বাচন করুন। এখন, ডানদিকে চ্যাট ডায়ালগে, আপনার এজেন্টকে একটি কাজ দেওয়ার চেষ্টা করুন। উদাহরণস্বরূপ, এজেন্টের সাথে কথোপকথন করুন:

Search and plan something in Seattle for me this weekend
This weekend and I enjoy food and anime

একটি তারিখ প্রস্তাব করুন (আপনার পছন্দ)

July 12 2025

আপনি এজেন্টকে আপনার অনুরোধের প্রক্রিয়া দেখতে পাবেন এবং তার Google অনুসন্ধান ফলাফলের উপর ভিত্তি করে একটি পরিকল্পনা প্রদান করুন।

adk dev ui

এখন, একটি এজেন্টের সাথে যোগাযোগ করা একটি জিনিস, কিন্তু আমরা কীভাবে জানব যে এটি ধারাবাহিকভাবে প্রত্যাশিত আচরণ করছে কিনা, বিশেষ করে যখন আমরা পরিবর্তন করি?

প্রথাগত সফ্টওয়্যার পরীক্ষার পদ্ধতিগুলি প্রায়শই এআই এজেন্টদের জন্য কম হয় কারণ তাদের জেনারেটিভ এবং অ-নির্ধারক প্রকৃতির কারণে। একটি দুর্দান্ত ডেমো থেকে একটি নির্ভরযোগ্য উত্পাদন এজেন্টের ব্যবধান পূরণ করতে, একটি কঠিন মূল্যায়ন কৌশল অত্যন্ত গুরুত্বপূর্ণ। শুধুমাত্র একটি জেনারেটিভ মডেলের চূড়ান্ত আউটপুট পরীক্ষা করার বিপরীতে, একটি এজেন্টের মূল্যায়ন প্রায়ই তার সিদ্ধান্ত গ্রহণের প্রক্রিয়া এবং বিভিন্ন পরিস্থিতিতে সঠিকভাবে সরঞ্জাম ব্যবহার বা নির্দেশাবলী অনুসরণ করার ক্ষমতা মূল্যায়ন জড়িত। ADK এতে সাহায্য করার জন্য বৈশিষ্ট্যগুলি প্রদান করে৷

ইভাল

👉 ADK Dev UI-তে, বাঁ-হাতের নেভিগেশনে "Eval" ট্যাবে ক্লিক করুন। আপনি plan_eval নামে একটি প্রাক-লোড করা পরীক্ষা ফাইল দেখতে পাবেন। এই ফাইলটিতে আমাদের পরিকল্পনাকারী এজেন্ট পরীক্ষা করার জন্য পূর্বনির্ধারিত ইনপুট এবং মানদণ্ড রয়েছে।

👉 একটি দৃশ্যকল্প নির্বাচন করুন, যেমন "বোস্টন" এবং রান মূল্যায়ন বোতামে ক্লিক করুন। প্রদর্শিত পপ-আপ উইন্ডোতে, ম্যাচের স্কোর 0.3 এ নামিয়ে স্টার্ট ক্লিক করুন।

ম্যাচ স্কোর

এটি পরীক্ষার ইনপুট সহ এজেন্টকে নির্বাহ করবে এবং এর আউটপুট সংজ্ঞায়িত প্রত্যাশা পূরণ করে কিনা তা পরীক্ষা করবে। এটি আপনাকে পদ্ধতিগতভাবে আপনার এজেন্টের কর্মক্ষমতা পরীক্ষা করার একটি উপায় দেয়।

adk dev ui মূল্যায়ন

👉 এখন দেখা যাক কঠোর থ্রেশহোল্ড দিয়ে কি হয়। "nyc" দৃশ্যকল্প নির্বাচন করুন এবং আবার মূল্যায়ন চালান ক্লিক করুন। এইবার, ম্যাচের স্কোরটিকে তার ডিফল্ট মান (প্রতিক্রিয়া ম্যাচ স্কোর: 0.7) এ ছেড়ে দিন এবং শুরুতে ক্লিক করুন। আপনি ফলাফলটি ব্যর্থ লক্ষ্য করবেন। এটি প্রত্যাশিত, কারণ এজেন্টের সৃজনশীল আউটপুট পূর্ব-সংজ্ঞায়িত "সোনালি" উত্তরের সাথে পুরোপুরি মেলে না।

adk dev ui মূল্যায়ন ব্যর্থ

👉 কেন এটি ব্যর্থ হয়েছে তা বুঝতে, "nyc" সারিতে ব্যর্থ আইকনে ক্লিক করুন। UI এখন এজেন্টের প্রকৃত প্রতিক্রিয়া এবং পরীক্ষার ক্ষেত্রে প্রত্যাশিত প্রতিক্রিয়ার পাশাপাশি একটি তুলনা প্রদর্শন করে। এই দৃশ্যটি ডিবাগিংয়ের জন্য অপরিহার্য, আপনাকে এজেন্টের আউটপুট ঠিক কোথায় বিচ্ছিন্ন হয়েছে তা দেখতে এবং সেই অনুযায়ী এর নির্দেশাবলী পরিমার্জন করার অনুমতি দেয়।

একবার আপনি UI এবং মূল্যায়ন করা হয়ে গেলে, আপনার ক্লাউড শেল এডিটর টার্মিনালে ফিরে যান এবং 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 পুনরায় চালু করুন :

. ~/instavibe-bootstrap/set_env.sh
source ~/instavibe-bootstrap/env/bin/activate
cd  ~/instavibe-bootstrap/agents
adk web

ট্যাবটি রিফ্রেশ করুন যদি আপনি এটি ইতিমধ্যেই খোলা থাকে। অথবা আপনার ব্রাউজারে ADK Dev UI খুলতে আগের মতো একই ধাপ অনুসরণ করুন (পোর্ট 8000-এ ক্লাউড শেলের ওয়েব প্রিভিউয়ের মাধ্যমে)। একবার UI লোড হয়ে গেলে, পরিকল্পনাকারী এজেন্ট নির্বাচন করা হয়েছে তা নিশ্চিত করুন।

👉 এবার একটু অন্যরকম অনুরোধ করা যাক। চ্যাট ডায়ালগে, লিখুন:

Plan an event Boston this weekend with art and coffee

এজেন্টের প্রতিক্রিয়া সাবধানে পরীক্ষা করুন। একটি সম্পূর্ণ কথোপকথনমূলক পাঠ্য উত্তরের পরিবর্তে, আপনি এখন একটি JSON অবজেক্ট হিসাবে কঠোরভাবে ফর্ম্যাট করা একটি প্রতিক্রিয়া দেখতে পাবেন, নির্দেশাবলীতে আমরা যে কাঠামোটি সংজ্ঞায়িত করেছি তার সাথে মেলে (ফ্যান_প্ল্যান, প্ল্যান_বিবরণ, অবস্থান_এন্ড_ক্রিয়াকলাপ ইত্যাদি)। এটি নিশ্চিত করে যে এজেন্ট এখন আমাদের InstaVibe অ্যাপ্লিকেশন দ্বারা প্রোগ্রাম্যাটিক ব্যবহারের জন্য উপযুক্ত কাঠামোগত আউটপুট তৈরি করতে পারে।

adk dev ui json

JSON আউটপুট নিশ্চিত করার পরে, আপনার ক্লাউড শেল টার্মিনালে ফিরে যান এবং ADK Dev UI বন্ধ করতে Ctrl+C টিপুন।

ADK উপাদান

যদিও ADK Dev UI ইন্টারেক্টিভ পরীক্ষার জন্য দুর্দান্ত, আমাদের প্রায়শই আমাদের এজেন্টগুলিকে প্রোগ্রাম্যাটিকভাবে চালাতে হয়, সম্ভবত একটি বড় অ্যাপ্লিকেশন বা ব্যাকএন্ড পরিষেবার অংশ হিসাবে। এটি কীভাবে কাজ করে তা বোঝার জন্য, আসুন রানটাইম এবং প্রসঙ্গ ব্যবস্থাপনা সম্পর্কিত কিছু মূল ADK ধারণা দেখি।

অর্থপূর্ণ, বহু-মুখী কথোপকথনের জন্য এজেন্টদের প্রসঙ্গ বোঝার প্রয়োজন - ধারাবাহিকতা বজায় রাখার জন্য যা বলা হয়েছে এবং যা করা হয়েছে তা স্মরণ করা। ADK সেশন , স্টেট এবং মেমরির মাধ্যমে এই প্রসঙ্গ পরিচালনা করার জন্য কাঠামোগত উপায় প্রদান করে:

  • সেশন: যখন একজন ব্যবহারকারী একজন এজেন্টের সাথে ইন্টারঅ্যাক্ট শুরু করেন, তখন একটি সেশন তৈরি হয়। এটিকে একটি একক, নির্দিষ্ট চ্যাট থ্রেডের ধারক হিসাবে ভাবুন। এটি একটি অনন্য আইডি, ইন্টারঅ্যাকশনের ইতিহাস (ইভেন্টস), বর্তমান কাজের ডেটা (স্টেট) এবং শেষ আপডেটের সময়ের মতো মেটাডেটা ধারণ করে।
  • রাজ্য: এটি হল এজেন্টের স্বল্প-মেয়াদী, একটি একক সেশনের মধ্যে কাজ করার স্মৃতি৷ এটি একটি পরিবর্তনযোগ্য অভিধান যেখানে এজেন্ট বর্তমান কাজটি সম্পূর্ণ করার জন্য প্রয়োজনীয় অস্থায়ী তথ্য সংরক্ষণ করতে পারে (যেমন, এখন পর্যন্ত সংগৃহীত ব্যবহারকারীর পছন্দ, টুল কল থেকে মধ্যবর্তী ফলাফল)।
  • স্মৃতি: এটি বিভিন্ন সেশন জুড়ে দীর্ঘমেয়াদী প্রত্যাহার বা বাহ্যিক জ্ঞানের ভিত্তিগুলিতে অ্যাক্সেসের জন্য এজেন্টের সম্ভাবনাকে প্রতিনিধিত্ব করে। যখন সেশন এবং স্টেট তাৎক্ষণিক কথোপকথন পরিচালনা করে, মেমরি (প্রায়শই একটি MemoryService দ্বারা পরিচালিত) একটি এজেন্টকে অতীতের মিথস্ক্রিয়া বা কাঠামোগত ডেটা উত্স থেকে তথ্য পুনরুদ্ধার করার অনুমতি দেয়, এটি একটি বিস্তৃত জ্ঞানের প্রসঙ্গ দেয়। (দ্রষ্টব্য: আমাদের সাধারণ ক্লায়েন্ট সরলতার জন্য মেমরি পরিষেবাগুলিতে ব্যবহার করে, যার অর্থ মেমরি/স্টেট শুধুমাত্র স্ক্রিপ্ট চালানোর সময় বজায় থাকে)।
  • ইভেন্ট: একটি সেশনের মধ্যে প্রতিটি মিথস্ক্রিয়া (ব্যবহারকারীর বার্তা, এজেন্ট প্রতিক্রিয়া, টুল ব্যবহারের অনুরোধ, টুল ফলাফল, রাষ্ট্র পরিবর্তন, ত্রুটি) একটি অপরিবর্তনীয় ইভেন্ট হিসাবে রেকর্ড করা হয়। এটি একটি কালানুক্রমিক লগ তৈরি করে, মূলত কথোপকথনের প্রতিলিপি এবং কর্মের ইতিহাস।

সুতরাং, যখন একজন এজেন্ট চলে তখন এগুলো কিভাবে পরিচালিত হয়? এটাই রানার কাজ।

  • রানার : রানার হল ADK দ্বারা প্রদত্ত মূল এক্সিকিউশন ইঞ্জিন। আপনি আপনার এজেন্ট এবং এটি যে সরঞ্জামগুলি ব্যবহার করে তা সংজ্ঞায়িত করুন এবং রানার ব্যবহারকারীর অনুরোধ পূরণ করার প্রক্রিয়াটি সাজান৷ এটি অধিবেশন পরিচালনা করে, ইভেন্টের প্রবাহ পরিচালনা করে, রাজ্য আপডেট করে, অন্তর্নিহিত ভাষার মডেল আহ্বান করে, টুল কলগুলিকে সমন্বয় করে এবং সম্ভাব্য মেমোরিসার্ভিসের সাথে যোগাযোগ করে। এটিকে কন্ডাক্টর হিসাবে ভাবুন যাতে সমস্ত বিভিন্ন অংশ সঠিকভাবে একসাথে কাজ করে।

আমরা আমাদের এজেন্টকে একটি স্বতন্ত্র পাইথন অ্যাপ্লিকেশন হিসাবে চালানোর জন্য রানার ব্যবহার করতে পারি, যা Dev UI থেকে সম্পূর্ণ স্বাধীন।

আমাদের প্ল্যানার এজেন্টকে প্রোগ্রাম্যাটিকভাবে আহ্বান করতে একটি সাধারণ ক্লায়েন্ট স্ক্রিপ্ট তৈরি করা যাক।

👉📝 ~/instavibe-bootstrap/agents/planner/planner_client.py ফাইলে, বিদ্যমান আমদানির অধীনে নিম্নলিখিত পাইথন কোড যোগ করুন। 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 অনুসন্ধান), এবং অবশেষে, JSON প্ল্যান সহ মডেলের প্রতিক্রিয়া ইভেন্ট। এই বিশদ ইভেন্ট স্ট্রিমটি এডিকে রানটাইমের মধ্যে ঘটে যাওয়া ধাপে ধাপে প্রক্রিয়াজাতকরণ ডিবাগিং এবং বোঝার জন্য খুব দরকারী।

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। প্ল্যাটফর্ম ইন্টারঅ্যাকশন এজেন্ট - এমসিপি সার্ভারের সাথে ইন্টারঅ্যাক্ট করুন

যদিও এডিকে আমাদের এজেন্টদের কাঠামোকে সহায়তা করে, তাদের প্রায়শই বাস্তব-বিশ্বের ক্রিয়া সম্পাদনের জন্য বাহ্যিক সিস্টেম বা এপিআইয়ের সাথে ইন্টারঅ্যাক্ট করা প্রয়োজন।

মডেল কনটেক্সট প্রোটোকল (MCP)

মডেল কনটেক্সট প্রোটোকল (এমসিপি) একটি ওপেন স্ট্যান্ডার্ড যা এআই অ্যাপ্লিকেশনগুলি এজেন্টদের মতো কীভাবে বাহ্যিক ডেটা উত্স, সরঞ্জাম এবং সিস্টেমগুলির সাথে সংযুক্ত হয় তা মানিক করার জন্য ডিজাইন করা হয়েছে। এটি একটি সর্বজনীন ইন্টারফেস সরবরাহ করে প্রতিটি এআই অ্যাপ্লিকেশন এবং ডেটা উত্স সংমিশ্রণের জন্য কাস্টম সংহতকরণের প্রয়োজনের সমস্যাটি সমাধান করার লক্ষ্য। এমসিপি একটি ক্লায়েন্ট-সার্ভার আর্কিটেকচার ব্যবহার করে যেখানে এমসিপি ক্লায়েন্টরা, এআই অ্যাপ্লিকেশনগুলির (হোস্ট) এর মধ্যে থাকে, এমসিপি সার্ভারগুলির সাথে সংযোগ পরিচালনা করে। এই সার্ভারগুলি হ'ল বাহ্যিক প্রোগ্রাম যা স্থানীয় ডেটা অ্যাক্সেস করা, এপিআইয়ের মাধ্যমে দূরবর্তী পরিষেবাদির সাথে ইন্টারঅ্যাক্ট করা বা পূর্বনির্ধারিত প্রম্পটগুলি সরবরাহ করার মতো নির্দিষ্ট কার্যকারিতা প্রকাশ করে, এআই মডেলগুলিকে বর্তমান তথ্য অ্যাক্সেস করতে এবং তাদের প্রাথমিক প্রশিক্ষণের বাইরেও কাজ সম্পাদন করতে দেয়। এই কাঠামোটি এআই মডেলগুলিকে একটি মানক উপায়ে বাহ্যিক ক্ষমতাগুলির সাথে আবিষ্কার এবং ইন্টারঅ্যাক্ট করতে সক্ষম করে, সংহতকরণকে আরও সহজ এবং আরও স্কেলযোগ্য করে তোলে।

ইন্সটভিব এমসিপি সার্ভারটি তৈরি করুন এবং স্থাপন করুন

07-এমসিপি-সার্ভার.পিএনজি

আমাদের এজেন্টদের শেষ পর্যন্ত ইন্সটভিবি প্ল্যাটফর্মের সাথে নিজেই ইন্টারঅ্যাক্ট করতে হবে P প্ল্যাটফর্মের বিদ্যমান এপিআই ব্যবহার করে পোস্ট তৈরি এবং ইভেন্টগুলি নিবন্ধন করতে। ইন্সটভিব অ্যাপ্লিকেশনটি ইতিমধ্যে স্ট্যান্ডার্ড এইচটিটিপি এন্ডপয়েন্টগুলির মাধ্যমে এই কার্যকারিতাগুলি প্রকাশ করে:

এনপয়েন্ট

URL

এইচটিটিপি পদ্ধতি

বর্ণনা

পোস্ট তৈরি করুন

এপিআই/পোস্ট

পোস্ট

একটি নতুন পোস্ট যুক্ত করতে API শেষ পয়েন্ট। জসন বডি প্রত্যাশা করে:
{"author_name": "...", "text": "...", "sentiment": "..." (optional)}

ইভেন্ট তৈরি করুন

এপিআই/ইভেন্টস

পোস্ট

একটি নতুন ইভেন্ট এবং এর উপস্থিতি (সরলীকৃত স্কিমা) যুক্ত করার জন্য এপিআই শেষ পয়েন্ট।
জসন বডি প্রত্যাশা করে: { "event_name": "...", "description": "...", "event_date": "YYYY-MM-DDTHH:MM:SSZ", "locations": [ {"name": "...", "description": "...", "latitude": 0.0, "longitude": 0.0, "address": "..."} ], "attendee_names": ["...", "..."] } "attice_names": ["...", "..."]}

এমসিপির মাধ্যমে আমাদের এজেন্টদের কাছে এই ক্ষমতাগুলি উপলব্ধ করার জন্য, আমাদের প্রথমে সাধারণ পাইথন ফাংশনগুলি তৈরি করতে হবে যা এই এপিআই কলগুলির চারপাশে মোড়ক হিসাবে কাজ করে। এই ফাংশনগুলি HTTP অনুরোধ যুক্তি পরিচালনা করবে।

👉 প্রথমে, একটি পোস্ট তৈরির জন্য মোড়ক ফাংশনটি প্রয়োগ করা যাক। ফাইলটি খুলুন ~/instavibe-bootstrap/tools/instavibe/instavibe.py এবং প্রতিস্থাপন করুন #REPLACE ME CREATE POST :

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

আপনি দেখতে পাচ্ছেন, এই ফাংশনগুলি বিদ্যমান ইন্সটভিবে এপিআইগুলির চারপাশে সোজা মোড়ক। এই প্যাটার্নটি কার্যকর, যদি আপনার ইতিমধ্যে আপনার পরিষেবার জন্য এপিআই থাকে তবে আপনি এ জাতীয় মোড়ক তৈরি করে এজেন্টদের সরঞ্জাম হিসাবে তাদের কার্যকারিতা সহজেই প্রকাশ করতে পারেন।

এমসিপি সার্ভার বাস্তবায়ন

এখন যেহেতু আমাদের কাছে পাইথন ফাংশন রয়েছে যা ক্রিয়াগুলি সম্পাদন করে (ইন্সটভিবে এপিআইগুলিকে কল করে), আমাদের এমসিপি সার্ভার উপাদানটি তৈরি করতে হবে। এই সার্ভারটি এমসিপি স্ট্যান্ডার্ড অনুসারে এই ফাংশনগুলিকে "সরঞ্জাম" হিসাবে প্রকাশ করবে, এমসিপি ক্লায়েন্টদের (আমাদের এজেন্টদের মতো) তাদের আবিষ্কার এবং আহ্বান করতে দেয়।

একটি এমসিপি সার্ভার সাধারণত দুটি মূল কার্যকারিতা প্রয়োগ করে:

  • তালিকা_টুলস : ক্লায়েন্টকে সার্ভারে উপলভ্য সরঞ্জামগুলি আবিষ্কার করার অনুমতি দেওয়ার জন্য দায়বদ্ধ, তাদের নাম, বিবরণ এবং প্রয়োজনীয় পরামিতিগুলির মতো মেটাডেটা সরবরাহ করে, প্রায়শই জেএসএন স্কিমা ব্যবহার করে সংজ্ঞায়িত করা হয়
  • কল_টুল : ক্লায়েন্টের দ্বারা অনুরোধ করা একটি নির্দিষ্ট সরঞ্জামের কার্যকরকরণ পরিচালনা করে, সরঞ্জামটির নাম এবং যুক্তিগুলি গ্রহণ করে এবং সংশ্লিষ্ট ক্রিয়া সম্পাদন করে, যেমন আমাদের ক্ষেত্রে একটি এপিআইয়ের সাথে ইন্টারঅ্যাক্ট করা

এমসিপি সার্ভারগুলি এআই মডেলগুলিকে রিয়েল-ওয়ার্ল্ড ডেটা এবং ক্রিয়াকলাপগুলিতে অ্যাক্সেস সহ, ইমেল প্রেরণ, প্রকল্প পরিচালন ব্যবস্থায় কাজ তৈরি করা, ডাটাবেসগুলি অনুসন্ধান করা বা বিভিন্ন সফ্টওয়্যার এবং ওয়েব পরিষেবাদির সাথে ইন্টারঅ্যাক্ট করার মতো কাজগুলি সক্ষম করার জন্য ব্যবহৃত হয়। প্রাথমিক বাস্তবায়নগুলি প্রায়শই সরলতার জন্য স্ট্যান্ডার্ড ইনপুট/আউটপুট (এসটিডিআইও) এর মাধ্যমে যোগাযোগ করা স্থানীয় সার্ভারগুলিতে মনোনিবেশ করে, বিশেষত বিকাশ বা "স্টুডিও" পরিবেশে, সার্ভার-সিনেন্ট ইভেন্টস (এসএসই) এর সাথে এইচটিটিপি-র মতো প্রোটোকলগুলি ব্যবহার করে দূরবর্তী সার্ভারগুলির দিকে অগ্রসর হওয়া বিস্তৃত গ্রহণ এবং এন্টারপ্রাইজ ব্যবহারের ক্ষেত্রে আরও বেশি অর্থবোধ করে।

রিমোট আর্কিটেকচার, যুক্ত নেটওয়ার্ক যোগাযোগ স্তর সত্ত্বেও, উল্লেখযোগ্য সুবিধাগুলি সরবরাহ করে: এটি একাধিক এআই ক্লায়েন্টকে একটি একক সার্ভারে অ্যাক্সেস ভাগ করে নেওয়ার অনুমতি দেয়, পরিচালনা এবং সরঞ্জামগুলির আপডেটগুলি কেন্দ্রীভূত করে, সম্ভাব্য অনেকগুলি ক্লায়েন্ট মেশিন জুড়ে বিতরণ না করে সার্ভারে সংবেদনশীল ডেটা এবং এপিআই কীগুলি রেখে সুরক্ষা বাড়ায় এবং বাহ্যিক সিস্টেমের সংহতকরণ থেকে এআই মডেলকে ডেসপল করে, এআই মডেলকে ডেসপল করে, নিজস্ব প্রত্যক্ষ সংহতকরণগুলি পরিচালনা করার জন্য প্রতিটি এআই উদাহরণ প্রয়োজনের চেয়ে আরও স্কেলযোগ্য, সুরক্ষিত এবং রক্ষণাবেক্ষণযোগ্য।

07-এমসিপি-সার্ভার.পিএনজি

আমরা যোগাযোগের জন্য HTTP এবং সার্ভার-সিনেন্ট ইভেন্টগুলি (এসএসই) ব্যবহার করে আমাদের এমসিপি সার্ভারটি প্রয়োগ করব, যা সম্ভাব্য দীর্ঘ-চলমান সরঞ্জাম মৃত্যুদন্ড কার্যকর এবং এন্টারপ্রাইজ দৃশ্যের জন্য উপযুক্ত।

👉📝 প্রথম, আসুন তালিকা_টুলস এন্ডপয়েন্টটি বাস্তবায়ন করি। ফাইলটি #REPLACE ME - LIST TOOLS ~/instavibe-bootstrap/tools/instavibe/mcp_server.py :

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

এই ফাংশনটি সরঞ্জামের নাম এবং যুক্তিগুলি গ্রহণ করে, আমরা পূর্বে সংজ্ঞায়িত পাইথন র‌্যাপার ফাংশনটি সন্ধান করে, এটি সম্পাদন করে এবং ফলাফলটি প্রদান করে

MC এমসিপি সার্ভার লজিক সংজ্ঞায়িত করার সাথে সাথে আমাদের এখন এটি একটি ধারক হিসাবে প্যাকেজ করতে হবে, টার্মিনালটিতে ক্লাউড বিল্ড ব্যবহার করে ডকার চিত্রটি তৈরি করতে নিম্নলিখিত স্ক্রিপ্টটি চালান:

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

👉💻 এবং গুগল ক্লাউড রান এ পরিষেবা হিসাবে চিত্রটি স্থাপন করুন।

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

Meply আমাদের এই ইউআরএলটি ক্যাপচার করতে হবে যাতে আমাদের এজেন্ট (এমসিপি ক্লায়েন্ট হিসাবে অভিনয় করা) কোথায় সংযোগ করতে হবে তা জানে।

export MCP_SERVER_URL=$(gcloud run services list --platform=managed --region=us-central1 --format='value(URL)' | grep mcp-tool-server)/sse

আপনার গুগল ক্লাউড কনসোলের ক্লাউড রান বিভাগে "রানিং" হিসাবে তালিকাভুক্ত এমসিপি-টুল-সার্ভার পরিষেবাটি এখন দেখতে সক্ষম হওয়া উচিত।

মেঘ রান

এমসিপি সার্ভার মোতায়েন করা এবং এর ইউআরএল ক্যাপচারের সাথে আমরা এখন এজেন্টটি বাস্তবায়ন করতে পারি যা এমসিপি ক্লায়েন্ট হিসাবে কাজ করবে এবং এই সার্ভার দ্বারা উন্মুক্ত সরঞ্জামগুলি ব্যবহার করবে।

8। প্ল্যাটফর্ম ইন্টারঅ্যাকশন এজেন্ট (এমসিপি ব্যবহার করে)

এমসিপি ক্লায়েন্ট এমসিপি ক্লায়েন্ট এমন একটি উপাদান যা এআই অ্যাপ্লিকেশন বা এজেন্টের মধ্যে থাকে, এআই মডেল এবং এক বা একাধিক এমসিপি সার্ভারের মধ্যে ইন্টারফেস হিসাবে কাজ করে; আমাদের বাস্তবায়নে, এই ক্লায়েন্টটি সরাসরি আমাদের এজেন্টের মধ্যে সংহত করা হবে। এই ক্লায়েন্টের প্রাথমিক ফাংশনটি এমসিপি সার্ভারগুলির সাথে list_tools ফাংশনের মাধ্যমে উপলভ্য সরঞ্জামগুলি আবিষ্কার করতে এবং পরবর্তীকালে এআই মডেল দ্বারা সরবরাহিত প্রয়োজনীয় যুক্তিগুলি বা কলটি অর্কেস্টেটিংয়ের জন্য প্রয়োজনীয় যুক্তিগুলি পাস করে নির্দিষ্ট সরঞ্জামগুলি কার্যকর করার জন্য অনুরোধ করা হয় call_tool

এমসিপি ক্লায়েন্ট

এখন আমরা এজেন্টটি তৈরি করব যা এমসিপি ক্লায়েন্ট হিসাবে কাজ করে। এডিকে কাঠামোর মধ্যে চলমান এই এজেন্টটি 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 পদ্ধতি ব্যবহার করে।

এরপরে, আমাদের এডিকে এজেন্ট সংজ্ঞাটিকে আসলে এই গতিশীলভাবে আনা সরঞ্জামগুলি ব্যবহার করার জন্য বলতে হবে।

agents/platform_mcp_client/agent.py -তে, #REPLACE ME - SET TOOLs :

  tools=[tools],

👉💻 এখন, আসুন এই এজেন্টটিকে স্থানীয়ভাবে এডিকে দেব ইউআই ব্যবহার করে এটি এমসিপি সার্ভারের সাথে সঠিকভাবে সংযোগ স্থাপন করতে পারে কিনা তা দেখতে এবং আমাদের চলমান ইন্সটভিব অ্যাপ্লিকেশনটির সাথে ইন্টারঅ্যাক্ট করার জন্য সরঞ্জামগুলি ব্যবহার করতে পারে কিনা তা দেখতে আসুন।

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

আপনার ব্রাউজারে আবার এডিকে ডেভ ইউআই খুলুন (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

অ্যাড কে দেব ইউআই পোস্ট

এজেন্টের এটি প্রক্রিয়া করা উচিত, ক্রিয়েট_পোস্ট সরঞ্জামটি ব্যবহার করার প্রয়োজনীয়তা চিহ্নিত করা উচিত, এমসিপি সার্ভারের সাথে যোগাযোগ করুন, যা পরিবর্তে ইনস্টাভিব এপিআইকে কল করে।

👉 যাচাইয়ের পদক্ষেপ: এজেন্ট ক্রিয়াটি নিশ্চিত করার পরে, আপনার ইন্সটভিব অ্যাপ্লিকেশনটি যেখানে চলছে সেখানে ট্যাবটি খুলুন (বা এটি রিফ্রেশ করুন)। আপনার "জুলিয়া" থেকে নতুন পোস্টটি মূল ফিডে উপস্থিত হওয়া উচিত!

ইন্সটভিবি পোস্ট

This প্রয়োজনে ইন্সটভিবি লিঙ্ক পেতে এই স্ক্রিপ্টটি একটি পৃথক টার্মিনালে চালান:

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

আবার, এজেন্টের এমসিপি সার্ভারের মাধ্যমে উপযুক্ত সরঞ্জামটি ব্যবহার করা উচিত। ইভেন্টস ট্যাবে, স্বতন্ত্র ইভেন্টে ক্লিক করতে নির্দ্বিধায়, আপনি মৃত্যুদন্ড কার্যকর করার একটি বিশদ, ধাপে ধাপে ট্রেস দেখতে পাবেন।

এডিকে দেব ইউআই ইভেন্ট

👉 যাচাইয়ের পদক্ষেপ: আপনার চলমান ইন্সটভিব অ্যাপ্লিকেশনটিতে ফিরে যান এবং "ইভেন্টস" বিভাগে (বা সমতুল্য) নেভিগেট করুন। আপনার এখন নতুন নির্মিত "মেক্সিকো সিটি রন্ধনসম্পর্কীয় ও আর্ট ডে" ইভেন্টটি তালিকাভুক্ত হওয়া উচিত।

ইন্সটভিবি ইভেন্ট

এটি সফলভাবে প্রমাণ করে যে এমসিপি কীভাবে আমাদের এজেন্টকে বাহ্যিক সরঞ্জামগুলি (এই ক্ষেত্রে, ইনস্টাভিবের এপিআই) একটি মানসম্মত উপায়ে উপার্জন করতে দেয়।

একবার আপনি উভয় ক্রিয়া যাচাই করে নিলে, আপনার ক্লাউড শেল টার্মিনালে ফিরে যান এবং এডিকে দেব ইউআই বন্ধ করতে Ctrl+C টিপুন।

9। ওয়ার্কফ্লো এজেন্ট এবং এডিকে মাল্টি-এজেন্টস

আমাদের এজেন্টরা এখনও অবধি পরিকল্পনা করতে পারে এবং প্ল্যাটফর্মের সাথে ইন্টারঅ্যাক্ট করতে পারে। তবে, সত্যই ব্যক্তিগতকৃত পরিকল্পনার জন্য ব্যবহারকারীর সামাজিক বৃত্তটি বোঝার প্রয়োজন। ব্যস্ত ব্যবহারকারীদের জন্য যারা তাদের বন্ধুদের ক্রিয়াকলাপগুলি ঘনিষ্ঠভাবে অনুসরণ করতে পারে না, এই প্রসঙ্গটি ম্যানুয়ালি সংগ্রহ করা কঠিন। এটি সম্বোধন করার জন্য, আমরা একটি সামাজিক প্রোফাইলিং এজেন্ট তৈরি করব যা আরও উপযুক্ত পরামর্শগুলি সক্ষম করে বন্ধু ক্রিয়াকলাপ এবং আগ্রহগুলি বিশ্লেষণ করতে আমাদের স্প্যানার গ্রাফ ডাটাবেসকে উপার্জন করে।

সামাজিক প্রোফাইলিং এজেন্ট

প্রথমত, গ্রাফের ডেটা অ্যাক্সেস করার জন্য আমাদের এই এজেন্টের জন্য সরঞ্জামগুলির প্রয়োজন।

The ফাইলের শেষে নিম্নলিখিত পাইথন ফাংশনগুলি যুক্ত করুন ~/instavibe-bootstrap/agents/social/instavibe.py

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

এখন, আসুন কীভাবে আমাদের এজেন্টকে গঠন করা যায় তা নিয়ে আলোচনা করা যাক। একাধিক বন্ধুদের প্রোফাইল বিশ্লেষণ করা এবং তারপরে অনুসন্ধানগুলির সংক্ষিপ্তসারগুলিতে বেশ কয়েকটি পদক্ষেপ জড়িত। এটি এডিকে-র মাল্টি-এজেন্ট ক্ষমতাগুলি, বিশেষত ওয়ার্কফ্লো এজেন্টদের ব্যবহারের জন্য একটি নিখুঁত দৃশ্য।

গুগলের এডিকে, একটি ওয়ার্কফ্লো এজেন্ট নিজেই কাজ সম্পাদন করে না তবে সাব-এজেন্টস নামে পরিচিত অন্যান্য এজেন্টদের অর্কেস্টেট করে। এটি মডুলার ডিজাইনের জন্য অনুমতি দেয়, বিশেষ উপাদানগুলিতে জটিল সমস্যাগুলি ভেঙে দেয়। এডিকে বিল্ট-ইন ওয়ার্কফ্লো প্রকারের মতো সরবরাহ করে

  • ক্রমিক (ধাপে ধাপে)
  • সমান্তরাল (একযোগে সম্পাদন)
  • এবং লুপ (পুনরাবৃত্তি সম্পাদন)

সামাজিক প্রোফাইলিং এজেন্ট

আমাদের সামাজিক প্রোফাইলিং টাস্কের জন্য, আমাদের নকশা একটি পুনরাবৃত্ত কর্মপ্রবাহ তৈরি করতে একটি লুপ এজেন্ট ব্যবহার করে। উদ্দেশ্যটি হ'ল একবারে একজনকে প্রক্রিয়া করা: 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"
)

আমরা একটি সাধারণ প্রোগ্রাম্যাটিক চেক (চেককন্ডিশন) যুক্ত করি যা স্পষ্টভাবে রাজ্যে সঞ্চিত summary_status দেখায়, যা check_agent দ্বারা ফিরে আসে এবং লুপ এজেন্টকে জানায় যে চালিয়ে যেতে হবে (এস্কেলেট = মিথ্যা) বা স্টপ (এসকেলেট = সত্য)।

👉📝 একই ~/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))

লুপ ফলাফলের জন্য রাজ্য এবং কলব্যাকস

গুগলের এডিকে, রাষ্ট্র কার্যকর করার সময় কোনও এজেন্টের স্মৃতি বা কার্যকারী ডেটা উপস্থাপন করে এমন একটি গুরুত্বপূর্ণ ধারণা। এটি মূলত একটি অবিরাম প্রসঙ্গ যা কোনও এজেন্টকে বিভিন্ন পদক্ষেপ, সরঞ্জাম কল বা মিথস্ক্রিয়াগুলি বজায় রাখতে প্রয়োজনীয় তথ্য ধারণ করে। এই রাজ্যটি মধ্যবর্তী ফলাফল, ব্যবহারকারীর তথ্য, পরবর্তী ক্রিয়াকলাপগুলির জন্য পরামিতিগুলি বা এজেন্টের অন্য কোনও ডেটা সংরক্ষণ করতে পারে যা কোনও কাজের মাধ্যমে অগ্রসর হওয়ার সাথে সাথে এজেন্টকে মনে রাখতে হবে।

আমাদের দৃশ্যে, লুপ এজেন্ট যেমন পুনরাবৃত্তি করে, summary_agent এবং check_agent এজেন্টের রাজ্যে তাদের আউটপুটগুলি (সংক্ষিপ্ত এবং সংক্ষিপ্ত_স্ট্যাটাস) সঞ্চয় করে। এটি তথ্যগুলি পুনরাবৃত্তিগুলি চালিয়ে যাওয়ার অনুমতি দেয়। যাইহোক, লুপ এজেন্ট নিজেই স্বয়ংক্রিয়ভাবে শেষ হয়ে গেলে রাজ্য থেকে চূড়ান্ত সংক্ষিপ্তসারটি ফিরিয়ে দেয় না।

সামাজিক প্রোফাইলিং এজেন্ট

এডিকে -তে কলব্যাকগুলি আমাদের কাস্টম লজিককে কোনও এজেন্টের জীবনচক্রের সময় নির্দিষ্ট পয়েন্টগুলিতে বা নির্দিষ্ট ইভেন্টগুলির প্রতিক্রিয়া হিসাবে ইনজেকশন দেওয়ার অনুমতি দেয়, যেমন কোনও সরঞ্জাম কলের সমাপ্তি বা এজেন্ট তার সম্পাদন শেষ করার আগে। তারা এজেন্টের আচরণ এবং প্রক্রিয়া ফলাফলগুলিকে গতিশীলভাবে কাস্টমাইজ করার একটি উপায় সরবরাহ করে।

আমরা লুপটি শেষ হয়ে গেলে (কারণ চেককন্ডিশন আরও বেড়েছে) এমন একটি after_agent_callback ব্যবহার করব। এই কলব্যাকটি modify_output_after_agent রাজ্য থেকে চূড়ান্ত সংক্ষিপ্তসারটি পুনরুদ্ধার করে এবং এটিকে এজেন্টের চূড়ান্ত আউটপুট বার্তা হিসাবে ফর্ম্যাট করে।

কল ব্যাক

👉📝 একই ~/instavibe-bootstrap/agents/social/agent.py তে, #REPLACE FOR modify_output_after_agent প্রতিস্থাপন করুন:

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

রুট লুপ এজেন্ট সংজ্ঞায়িত

অবশেষে, আমরা মূল লুপেজেন্ট সংজ্ঞায়িত করি। এটি প্রতিটি লুপ পুনরাবৃত্তির মধ্যে ক্রমগুলিতে সাব -এজেন্টগুলিকে অর্কেস্টেট করে (প্রোফাইল_এজেন্ট -> সংক্ষিপ্ত_এজেন্ট -> চেক_এজেন্ট -> চেককন্ডিশন)। এটি সর্বাধিক_ট্রেশনগুলির সময় বা চেককন্ডিশন সংকেত সমাপ্তি না হওয়া পর্যন্ত এই ক্রমটি পুনরাবৃত্তি করবে। পরবর্তী_জেন্ট_ক্যালব্যাক চূড়ান্ত সংক্ষিপ্তসারটি ফিরে আসার বিষয়টি নিশ্চিত করে।

👉📝 একই ~/instavibe-bootstrap/agents/social/agent.py তে, #REPLACE FOR root_agent প্রতিস্থাপন করুন:

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
)

আসুন এডিকে দেব ইউআই ব্যবহার করে এই মাল্টি-এজেন্ট ওয়ার্কফ্লো পরীক্ষা করি।

👉💻 এডিকে ওয়েব সার্ভার চালু করুন:

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

এডিকে দেব ইউআই (ওয়েব পূর্বরূপের মাধ্যমে 8000 পোর্ট 8000) খুলুন। এজেন্ট ড্রপডাউন মেনুতে (শীর্ষ-ডান), সামাজিক এজেন্ট নির্বাচন করুন।

👉 এখন, একাধিক ব্যক্তির প্রোফাইল দেওয়ার জন্য এটি টাস্ক দিন। চ্যাট ডায়ালগে, প্রবেশ করুন:

Tell me about Mike and Bob

এজেন্ট সাড়া দেওয়ার পরে (যা লুপিং এবং একাধিক এলএলএম কলগুলির কারণে কিছুটা বেশি সময় নিতে পারে), কেবল চূড়ান্ত চ্যাট আউটপুটটি দেখুন না। অ্যাড কে দেব ইউআইয়ের বাম-হাতের ফলকের ইভেন্টস ট্যাবে নেভিগেট করুন।

👉 যাচাইয়ের পদক্ষেপ: ইভেন্টস ট্যাবে আপনি কার্যকরকরণের একটি বিশদ, ধাপে ধাপে ট্রেস দেখতে পাবেন। 09-01-অ্যাড-ডিইভি-ইউআই.পিএনজি

এজেন্ট কীভাবে প্রতিটি উপ -এজেন্টকে অনুরোধ করে তা পর্যবেক্ষণ করার পরে, যেখানে আপনি প্রোফাইল_এজেন্ট -> সংক্ষিপ্ত_জেন্ট -> চেক_জেন্ট, প্রতিটি পুনরাবৃত্তির মধ্যে চেকার থেকে প্রবাহটি যাওয়ার প্রত্যাশা করছেন। তবে বাস্তবে, আমরা এজেন্টের শক্তিশালী 'স্ব-অপ্টিমাইজেশন' কার্যকরভাবে দেখি।

অন্তর্নিহিত মডেলটি পুরো অনুরোধটি দেখে (যেমন, 'প্রোফাইল মাইক এবং বব'), এটি প্রায়শই সর্বাধিক দক্ষ পথ বেছে নেয়, একাধিকবার পুনরাবৃত্তির পরিবর্তে একক, একীভূত টার্নে সমস্ত প্রয়োজনীয় ডেটা সংগ্রহ করে। আপনি প্রোফাইল_এজেন্ট দ্বারা তৈরি সরঞ্জাম কল সহ প্রতিটি পদক্ষেপের জন্য ইনপুট এবং আউটপুট এবং রাজ্যগুলি দেখতে পারেন

09-02-ui-Graph.png

এবং চেক_এজেন্ট এবং চেককন্ডিশন থেকে স্থিতি আপডেট। 09-03-ui-tate.png

এই ভিজ্যুয়াল ট্রেসটি বোঝার জন্য এবং ডিবাগিংয়ের জন্য অমূল্য এবং কীভাবে বহু-এজেন্ট ওয়ার্কফ্লো চূড়ান্ত সংক্ষিপ্তসার তৈরি না করা এবং কলব্যাক দ্বারা ফিরে না আসা পর্যন্ত কাজ করে।

একবার আপনি চ্যাট প্রতিক্রিয়া এবং ইভেন্টের ট্রেস অন্বেষণ করার পরে, ক্লাউড শেল টার্মিনালে ফিরে যান এবং এডিকে দেব ইউআই বন্ধ করতে Ctrl+C টিপুন।

10। এজেন্ট-টু-এজেন্ট (এ 2 এ) যোগাযোগ

এখনও অবধি, আমরা বিশেষায়িত এজেন্ট তৈরি করেছি, তবে তারা বিচ্ছিন্নভাবে বা একই মেশিনের পূর্বনির্ধারিত কর্মপ্রবাহের মধ্যে কাজ করে। সত্যিকারের বিতরণ এবং সহযোগী মাল্টি-এজেন্ট সিস্টেমগুলি তৈরি করতে, আমাদের একে অপরকে আবিষ্কার করতে এবং কার্যকরভাবে যোগাযোগের জন্য সম্ভাব্যভাবে পৃথক পরিষেবা হিসাবে চলমান এজেন্টদের জন্য একটি উপায় প্রয়োজন। এখানেই এজেন্ট-টু-এজেন্ট (এ 2 এ) প্রোটোকল আসে।

এ 2 এ প্রোটোকল একটি ওপেন স্ট্যান্ডার্ড যা বিশেষত এআই এজেন্টদের মধ্যে আন্তঃযোগযোগ্য যোগাযোগের জন্য ডিজাইন করা হয়েছে। এমসিপি এজেন্ট-টু-টুল ইন্টারঅ্যাকশনকে কেন্দ্র করে, এ 2 এ এজেন্ট-থেকে-এজেন্ট ইন্টারঅ্যাকশনকে কেন্দ্র করে। এটি এজেন্টদের অনুমতি দেয়:

  • আবিষ্কার করুন : অন্যান্য এজেন্টদের সন্ধান করুন এবং মানকৃত এজেন্ট কার্ডের মাধ্যমে তাদের ক্ষমতা শিখুন।
  • যোগাযোগ করুন : নিরাপদে বার্তা এবং ডেটা বিনিময় করুন।
  • সহযোগিতা করুন : জটিল লক্ষ্য অর্জনের জন্য কাজগুলি এবং সমন্বয়মূলক ক্রিয়াগুলি।

এ 2 এ প্রোটোকল "এজেন্ট কার্ড" এর মতো পদ্ধতির মাধ্যমে এই যোগাযোগের সুবিধার্থে, যা এজেন্টরা তাদের ক্ষমতা এবং সংযোগের তথ্যের বিজ্ঞাপন দিতে ব্যবহার করতে পারে।

10-05-এজেন্ট-কার্ড

এ 2 এ পরিচিত ওয়েব স্ট্যান্ডার্ডগুলি (এইচটিটিপি, এসএসই, জেএসএন-আরপিসি) ব্যবহার করে এবং প্রায়শই একটি ক্লায়েন্ট-সার্ভার মডেল নিয়োগ করে যেখানে একজন এজেন্ট (ক্লায়েন্ট) অন্যকে (রিমোট এজেন্ট/সার্ভার) টাস্ক প্রেরণ করে। এই মানককরণটি মডুলার, স্কেলযোগ্য সিস্টেমগুলি তৈরির মূল চাবিকাঠি যেখানে এজেন্টরা স্বাধীনভাবে বিকশিতভাবে বিকশিত হতে পারে একসাথে কাজ করতে পারে।

ইন্সটভিবে এজেন্টদের জন্য এ 2 এ সক্ষম করা

আমাদের বিদ্যমান পরিকল্পনাকারী, প্ল্যাটফর্ম ইন্টারঅ্যাকশন এবং সামাজিক এজেন্টদের এ 2 এ এর মাধ্যমে অন্যান্য এজেন্টদের কাছে অ্যাক্সেসযোগ্য করে তুলতে, আমাদের প্রত্যেককে একটি এ 2 এ সার্ভার উপাদান দিয়ে গুটিয়ে রাখতে হবে। এই সার্ভার হবে:

  • একটি এজেন্ট কার্ড প্রকাশ করুন : এইচটিটিপি এন্ডপয়েন্টের মাধ্যমে এজেন্টের দক্ষতার একটি মানক বিবরণ পরিবেশন করুন।
  • কাজগুলি শুনুন (অনুরোধ বার্তা) : এ 2 এ প্রোটোকল অনুসারে অন্যান্য এজেন্টদের (এ 2 এ ক্লায়েন্ট) আগত টাস্ক অনুরোধগুলি গ্রহণ করুন।
  • টাস্ক পরিচালনা করুন (অনুরোধ বার্তা) সম্পাদন : প্রক্রিয়াজাতকরণের জন্য অন্তর্নিহিত এডিকে এজেন্ট যুক্তিতে প্রাপ্ত কাজগুলি হ্যান্ড অফ করুন।

পরিকল্পনাকারী এজেন্ট (এ 2 এ সক্ষম)

অল-এজেন্ট-পরিকল্পনাকারী

আসুন আমাদের পরিকল্পনাকারী এজেন্টে A2A সার্ভার স্তর যুক্ত করে শুরু করা যাক।

A2A সার্ভার স্টার্টআপ লজিকটি সংজ্ঞায়িত করুন। এই কোডটি এজেন্টকার্ডকে সংজ্ঞায়িত করে (এজেন্টের সর্বজনীন বিবরণ), A2ASERVER কনফিগার করে এবং এটি শুরু করে, এটি প্ল্যাটফর্মএজেন্টেক্সেকটরের সাথে সংযুক্ত করে।

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

A এ 2 এ সার্ভারটি স্থানীয়ভাবে সঠিকভাবে শুরু করে এবং তার এজেন্ট কার্ড পরিবেশন করে যদি দ্রুত পরীক্ষা করা যাক। আপনার প্রথম টার্মিনালে নিম্নলিখিত কমান্ডটি চালান:

. ~/instavibe-bootstrap/set_env.sh
source ~/instavibe-bootstrap/env/bin/activate
cd ~/instavibe-bootstrap/agents/
python -m planner.a2a_server

👉 এখন, অন্য একটি টার্মিনাল উইন্ডোটি খুলুন। (টার্মিনাল প্যানেলে + সাইন এ ক্লিক করুন) দুটি টার্মিনাল

Local স্থানীয়ভাবে চলমান সার্ভার থেকে এজেন্ট কার্ডের জন্য অনুরোধ করতে কার্ল ব্যবহার করুন:

curl http://localhost:10003/.well-known/agent.json | jq

আপনি যে এজেন্টকার্ডটি সংজ্ঞায়িত করেছি তার জেএসওএন উপস্থাপনা দেখতে হবে, সার্ভারটি চলছে এবং পরিকল্পনাকারী এজেন্টের বিজ্ঞাপন দিচ্ছে তা নিশ্চিত করে।

10-02-প্ল্যানার-এ 2 এ.পিএনজি

প্রথম টার্মিনালে ফিরে যান (যেখানে সার্ভারটি চলছে) এবং এটি বন্ধ করতে Ctrl+C টিপুন।

A এ 2 এ সার্ভার লজিক যুক্ত হওয়ার সাথে সাথে আমরা এখন ধারক চিত্রটি তৈরি করতে পারি।

পরিকল্পনাকারী এজেন্ট তৈরি এবং স্থাপন করুন

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

👉💻 এবং ক্লাউড রানে আমাদের পরিকল্পনাকারী এজেন্ট স্থাপন করুন।

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

আসুন যাচাই করা যাক যে মোতায়েন করা পরিষেবাটি এ 2 এ ইন্সপেক্টর ব্যবহার করে ক্লাউড থেকে সঠিকভাবে তার এজেন্ট কার্ডটি চালাচ্ছে এবং পরিবেশন করছে।

Web ক্লাউড শেল সরঞ্জামদণ্ডে ওয়েব পূর্বরূপ আইকন থেকে, পরিবর্তন পোর্ট নির্বাচন করুন। বন্দরটি 8081 এ সেট করুন এবং "পরিবর্তন এবং পূর্বরূপ" ক্লিক করুন। এ 2 এ ইন্সপেক্টর ইন্টারফেসের সাথে একটি নতুন ব্রাউজার ট্যাব খুলবে।

10-08-WEB-PREVIEW.PNG

Ter টার্মিনালে, আপনার মোতায়েন করা পরিকল্পনাকারী এজেন্টের ইউআরএল পান:

export PLANNER_AGENT_URL=$(gcloud run services list --platform=managed --region=us-central1 --format='value(URL)' | grep planner-agent)
echo ${PLANNER_AGENT_URL}

Out আউটপুট ইউআরএল অনুলিপি করুন।

A এ 2 এ ইন্সপেক্টর ইউআই -তে, ইউআরএলটি এজেন্ট ইউআরএল ক্ষেত্রে পেস্ট করুন এবং সংযোগ ক্লিক করুন।

Agent এজেন্টের কার্ডের বিশদ এবং জেএসওএন একটি সফল সংযোগ নিশ্চিত করে এজেন্ট কার্ড ট্যাবে উপস্থিত হওয়া উচিত।

10-03-প্ল্যানার-এ 2 এ.পিএনজি

A এ 2 এ পরিদর্শকের চ্যাট ট্যাবে ক্লিক করুন। এখানেই আপনি আপনার মোতায়েন করা এজেনের সাথে সরাসরি যোগাযোগ করতে পারেন, এটির পরিকল্পনার সক্ষমতা পরীক্ষা করার জন্য এটি একটি বার্তা প্রেরণ করুন। যেমন:

Plan something for me in Boston MA this weekend, and I enjoy classical music

RA কাঁচা যোগাযোগ পরিদর্শন করতে, আপনার বার্তা বুদ্বুদ এবং তারপরে চ্যাট উইন্ডোতে এজেন্টের প্রতিক্রিয়া বুদবুদ ক্লিক করুন। আপনি প্রত্যেককে ক্লিক করার সাথে সাথে এটি সম্পূর্ণ জেএসএন-আরপিসি 2.0 বার্তা প্রদর্শন করবে যা প্রেরণ বা প্রাপ্ত হয়েছিল, যা ডিবাগিংয়ের জন্য অমূল্য।

আসুন এ 2 এ ইন্সপেক্টর ট্যাবটি সহজ রাখি। এটা বন্ধ করবেন না! আমরা আমাদের অন্যান্য দুটি এজেন্টকে পরীক্ষা করার জন্য এক মুহুর্তে এটি আবার ব্যবহার করব।

10-06-এ 2-ইনসেকটর.পিএনজি

প্ল্যাটফর্ম ইন্টারঅ্যাকশন এজেন্ট (এ 2 এ সক্ষম)

অল-এজেন্ট-প্ল্যাটফর্ম

এরপরে, আমরা প্ল্যাটফর্ম ইন্টারঅ্যাকশন এজেন্টের (এমসিপি ব্যবহারকারী) এর জন্য প্রক্রিয়াটি পুনরাবৃত্তি করব।

~/instavibe-bootstrap/agents/platform_mcp_client/a2a_server.py এর শেষে এর অনন্য এজেন্টকার্ড সহ এ 2 এ সার্ভার সেটআপটি সংজ্ঞায়িত করুন:

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)

সামাজিক এজেন্ট (এ 2 এ সক্ষম)

সর্ব-এজেন্ট-সামাজিক

অবশেষে, আসুন আমাদের সামাজিক প্রোফাইলিং এজেন্টের জন্য A2A সক্ষম করি।

~/instavibe-bootstrap/agents/social/a2a_server.py এর শেষে এ 2 এ সার্ভার সেটআপ এবং এজেন্টকার্ড সংজ্ঞায়িত করুন:

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_INSTANCE_ID , SPANNER_DATABASE_ID এবং MCP_SERVER_URL পরিবেশের ভেরিয়েবলগুলি স্থাপনার সময় সঠিকভাবে পাস করা হয়েছে তা নিশ্চিত করুন।

Well ক্লাউড বিল্ডের সাথে ক্লাউডে রান করুন এবং মোতায়েন করুন:

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

Ter টার্মিনালে, আপনার মোতায়েন করা প্ল্যাটফর্ম এজেন্টের ইউআরএল পান:

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

Out আউটপুট ইউআরএল অনুলিপি করুন।

A এ 2 এ ইন্সপেক্টর ইউআই -তে, ইউআরএলটি এজেন্ট ইউআরএল ক্ষেত্রে পেস্ট করুন এবং সংযোগ ক্লিক করুন।

Agent এজেন্টের কার্ডের বিশদ এবং জেএসওএন একটি সফল সংযোগ নিশ্চিত করে এজেন্ট কার্ড ট্যাবে উপস্থিত হওয়া উচিত।

10-05-প্ল্যাটফর্ম-এ 2 এ.পিএনজি

A এ 2 এ পরিদর্শকের চ্যাট ট্যাবে ক্লিক করুন। এখানেই আপনি আপনার মোতায়েন করা এজেনের সাথে সরাসরি ইন্টারঅ্যাক্ট করতে পারেন, এটি একটি বার্তা পাঠান এজেন্টের পোস্ট তৈরি করার ক্ষমতা পরীক্ষা করুন:

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.

RA কাঁচা যোগাযোগ পরিদর্শন করতে, আপনার বার্তা বুদ্বুদ এবং তারপরে চ্যাট উইন্ডোতে এজেন্টের প্রতিক্রিয়া বুদবুদ ক্লিক করুন। আপনি প্রত্যেককে ক্লিক করার সাথে সাথে এটি সম্পূর্ণ জেএসএন-আরপিসি 2.0 বার্তা প্রদর্শন করবে যা প্রেরণ বা প্রাপ্ত হয়েছিল, যা ডিবাগিংয়ের জন্য অমূল্য।

Ter টার্মিনালে, আপনার মোতায়েন করা সামাজিক এজেন্টের ইউআরএল পান:

export SOCIAL_AGENT_URL=$(gcloud run services list --platform=managed --region=us-central1 --format='value(URL)' | grep social-agent)
echo $SOCIAL_AGENT_URL

Out আউটপুট ইউআরএল অনুলিপি করুন।

A এ 2 এ ইন্সপেক্টর ইউআই -তে, ইউআরএলটি এজেন্ট ইউআরএল ক্ষেত্রে পেস্ট করুন এবং সংযোগ ক্লিক করুন।

Agent এজেন্টের কার্ডের বিশদ এবং জেএসওএন একটি সফল সংযোগ নিশ্চিত করে এজেন্ট কার্ড ট্যাবে উপস্থিত হওয়া উচিত।

10-04-সামাজিক-এ 2 এ.পিএনজি

A এ 2 এ পরিদর্শকের চ্যাট ট্যাবে ক্লিক করুন। এখানেই আপনি আপনার মোতায়েন করা এজেনের সাথে সরাসরি যোগাযোগ করতে পারেন, আপনার ডাটাবেস থেকে ব্যবহারকারী প্রোফাইলগুলি বিশ্লেষণ করতে এটি একটি বার্তা প্রেরণ করুন:

Can you tell me about both Ian and Kevin's profile, what are their common interests?

RA কাঁচা যোগাযোগ পরিদর্শন করতে, আপনার বার্তা বুদ্বুদ এবং তারপরে চ্যাট উইন্ডোতে এজেন্টের প্রতিক্রিয়া বুদবুদ ক্লিক করুন। আপনি প্রত্যেককে ক্লিক করার সাথে সাথে এটি সম্পূর্ণ জেএসএন-আরপিসি 2.0 বার্তা প্রদর্শন করবে যা প্রেরণ বা প্রাপ্ত হয়েছিল, যা ডিবাগিংয়ের জন্য অমূল্য।

👉 দুর্দান্ত, আমরা আমাদের সমস্ত এজেন্ট পরিদর্শন শেষ করেছি। আপনি এখন এ 2 এ ইন্সপেক্টর ট্যাবটি বন্ধ করতে পারেন।

11। অর্কেস্টেটর এজেন্ট (এ 2 এ ক্লায়েন্ট)

আমাদের কাছে এখন তিনটি বিশেষায়িত এজেন্ট (পরিকল্পনাকারী, প্ল্যাটফর্ম, সামাজিক) রয়েছে ক্লাউড রানে স্বতন্ত্র, এ 2 এ-সক্ষম পরিষেবা হিসাবে চলছে। চূড়ান্ত টুকরোটি অর্কেস্টেটর এজেন্ট। এই এজেন্টটি কেন্দ্রীয় সমন্বয়কারী বা এ 2 এ ক্লায়েন্ট হিসাবে কাজ করবে। এটি ব্যবহারকারীর অনুরোধগুলি গ্রহণ করবে, কোন রিমোট এজেন্ট (গুলি) অনুরোধটি (সম্ভাব্যভাবে ক্রমানুসারে) পূরণের জন্য প্রয়োজন তা নির্ধারণ করুন এবং তারপরে সেই প্রত্যন্ত এজেন্টদের কার্যগুলি অর্পণ করতে A2A প্রোটোকলটি ব্যবহার করুন। এই কর্মশালার জন্য, আমরা স্থানীয়ভাবে এডিকে দেব ইউআই ব্যবহার করে অর্কেস্টেটর এজেন্ট চালাব।

অল-এজেন্ট-অর্চেস্ট্রেটর

প্রথমে, এটি আবিষ্কার করে এমন প্রত্যন্ত এজেন্টগুলির নিবন্ধকরণ পরিচালনা করতে অর্কেস্ট্রেটারের যুক্তি বাড়িয়ে তুলি। সূচনা করার সময় আন্ডার এজেন্ট কার্ডগুলি থেকে সংযোগের বিশদটি সঞ্চয় করে।

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

এরপরে, এডিকে -র মধ্যে অর্কেস্টেটর এজেন্টের জন্য সরঞ্জামটি সংজ্ঞায়িত করুন।

  • send_message (কাজের প্রতিনিধি হিসাবে A2A ফাংশন)।

Replace #REPLACE ME CREATE AGENT ~/instavibe-bootstrap/agents/orchestrate/agent.py সহ এজেন্ট তৈরি করুন:

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

অর্কেস্ট্রেটারের মূল যুক্তি তার নির্দেশাবলীর মধ্যে রয়েছে, যা এটি এ 2 এ কীভাবে ব্যবহার করতে হয় তা বলে।

This এই নির্দেশনা-উত্পাদনের পদ্ধতির সাথে ~/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']}`
                """

অর্কেস্টেটর এবং সম্পূর্ণ এ 2 এ সিস্টেম পরীক্ষা করা

এখন, পুরো সিস্টেমটি পরীক্ষা করা যাক। আমরা স্থানীয়ভাবে এডিকে দেব ইউআই ব্যবহার করে অর্কেস্ট্রেটর চালাব এবং এটি ক্লাউড রানে দূরবর্তীভাবে চলমান পরিকল্পনাকারী, প্ল্যাটফর্ম এবং সামাজিক এজেন্টদের সাথে যোগাযোগ করবে।

👉💻 প্রথমে, পরিবেশের পরিবর্তনশীল REMOTE_AGENT_ADDRESSES আপনার মোতায়েন করা এ 2 এ-সক্ষম এজেন্টগুলির কমা-বিচ্ছিন্ন ইউআরএল রয়েছে তা নিশ্চিত করুন। তারপরে, অর্কেস্টেটর এজেন্টের জন্য প্রয়োজনীয় পরিবেশের ভেরিয়েবলগুলি সেট করুন এবং এডিকে দেব ইউআই চালু করুন:

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

👉 এডিকে দেব ইউআই খুলুন (ওয়েব পূর্বরূপের মাধ্যমে বন্দরটি 8000 এ ফিরে যান)।

10-08-WEB-PREVIEW.PNG

Agent এজেন্ট ড্রপডাউনে, অর্কেস্ট্রেট এজেন্ট নির্বাচন করুন।

👉 এখন, এটিকে একটি জটিল কাজ দিন যাতে একাধিক দূরবর্তী এজেন্টদের সমন্বয় করা প্রয়োজন। এই প্রথম উদাহরণটি ব্যবহার করে দেখুন, যা সামাজিক এজেন্ট এবং তারপরে পরিকল্পনাকারী এজেন্টকে জড়িত করা উচিত:

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.

অর্কেস্ট্রেট

এডিকে দেব ইউআই চ্যাট উইন্ডোতে মিথস্ক্রিয়াটি পর্যবেক্ষণ করুন। অর্কেস্ট্রেটারের প্রতিক্রিয়াগুলিতে গভীর মনোযোগ দিন - এটি বলা উচিত যে কোন রিমোট এজেন্ট এটি কার্যগুলি অর্পণ করছে (যেমন, "ঠিক আছে, আমি সামাজিক প্রোফাইল এজেন্টকে আয়ান এবং নোরা সম্পর্কে প্রথমে জিজ্ঞাসা করব ...")।

এছাড়াও, প্রত্যন্ত এজেন্টদের ইউআরএলগুলিতে অন্তর্নিহিত সরঞ্জাম কলগুলি (সেন্ড_মেসেজ) তৈরি করা দেখতে ইউআইয়ের ইভেন্টগুলি ট্যাবটি পরীক্ষা করুন।

টাস্ক পাঠান

👉 এখন, একটি দ্বিতীয় উদাহরণ চেষ্টা করুন যা সরাসরি প্ল্যাটফর্ম ইন্টিগ্রেশন এজেন্টকে জড়িত করা উচিত:

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

আবার চ্যাট এবং ইভেন্টস ট্যাবটি পর্যবেক্ষণ করুন। অর্কেস্ট্রেটরকে একটি ইভেন্ট তৈরি করার প্রয়োজনীয়তা সনাক্ত করা উচিত এবং "প্ল্যাটফর্ম ইন্টিগ্রেশন এজেন্ট" এ টাস্কটি (সমস্ত সরবরাহিত বিশদ সহ) অর্পণ করা উচিত। আপনি ক্যোয়ারী প্রতিক্রিয়া সময় এবং সম্পাদিত অপারেশনগুলি বিশ্লেষণ করতে ট্রেস দেখতে ট্রেস বোতামে ক্লিক করতে পারেন। ইভেন্ট প্রেরণ করুন

তারপরে আপনি ইভেন্টটি ইনস্টিভিবে ওয়েব অ্যাপ্লিকেশনটিতে উপস্থিত হতে পারেন তা যাচাই করতে পারেন। ইন্সটভিবি ইভেন্ট

এটি এডিকে এবং এ 2 এ প্রোটোকল ব্যবহার করে একটি বহু-এজেন্ট সিস্টেমের সফল বাস্তবায়ন প্রদর্শন করে, যেখানে একটি কেন্দ্রীয় অর্কেস্টেটর বিশেষায়িত, প্রত্যন্ত এজেন্টদের কার্যগুলি অর্পণ করে।

আপনি যখন পরীক্ষা শেষ করেন তখন এডিকে দেব ইউআই (টার্মিনালে Ctrl+C ) বন্ধ করতে ভুলবেন না।

12। এজেন্ট ইঞ্জিন এবং ইন্সটভিবি থেকে রিমোট কল

এখনও অবধি, আমরা আমাদের বিশেষায়িত এজেন্টদের ক্লাউড রান চালিয়েছি এবং স্থানীয়ভাবে এডিকে দেব ইউআই ব্যবহার করে অর্কেস্টেটর পরীক্ষা করেছি। একটি উত্পাদন দৃশ্যের জন্য, আমাদের এজেন্টদের হোস্ট করার জন্য আমাদের একটি শক্তিশালী, স্কেলযোগ্য এবং পরিচালিত পরিবেশ প্রয়োজন। এখানেই গুগল ভার্টেক্স এআই এজেন্ট ইঞ্জিন আসে।

এজেন্ট ইঞ্জিন হ'ল এআই এজেন্ট স্থাপন এবং স্কেলিংয়ের জন্য বিশেষভাবে ডিজাইন করা ভার্টেক্স এআই -তে একটি সম্পূর্ণ পরিচালিত পরিষেবা। এটি অবকাঠামো পরিচালনা, সুরক্ষা এবং অপারেশনাল ওভারহেড দূরে সরিয়ে দেয়, বিকাশকারীদের (বিশেষত জটিল মেঘের পরিবেশের সাথে কম পরিচিত) সার্ভারগুলি পরিচালনার পরিবর্তে এজেন্টের যুক্তি এবং ক্ষমতাগুলিতে মনোনিবেশ করার অনুমতি দেয়। এটি এজেন্ট ওয়ার্কলোডগুলির জন্য অনুকূলিত একটি ডেডিকেটেড রানটাইম সরবরাহ করে।

আমরা এখন আমাদের অর্কেস্টেটর এজেন্ট এজেন্ট ইঞ্জিনে মোতায়েন করব। (দ্রষ্টব্য: নীচে প্রদর্শিত মোতায়েন প্রক্রিয়াটি কর্মশালার উপকরণগুলিতে সরবরাহিত একটি কাস্টম স্ক্রিপ্ট (এজেন্ট_জাইন_এপ.পি.পি) ব্যবহার করে, কারণ অফিসিয়াল ডাইরেক্ট এডিকে-থেকে-এজেন্ট-ইঞ্জিন ডিপ্লোয়মেন্ট সরঞ্জামগুলি এখনও বিকশিত হতে পারে। এই স্ক্রিপ্টটি প্যাকেজিং হ্যান্ডল করে এবং অর্কেস্টেটর এজেন্টকে স্থাপন করে, প্রয়োজনীয় রিমোট এজেন্ট ঠিকানাগুলি সহ কনফিগার করা)))

এজেন্ট ইঞ্জিনে অর্কেস্টেটর এজেন্ট স্থাপনের জন্য নিম্নলিখিত কমান্ডটি কার্যকর করুন। নিশ্চিত করুন যে রিমোট_এজেন্ট_এড্রেসস এনভায়রনমেন্ট ভেরিয়েবল (আপনার পরিকল্পনাকারী, প্ল্যাটফর্ম এবং ক্লাউড রানের সামাজিক এজেন্টগুলির ইউআরএল রয়েছে) এখনও পূর্ববর্তী বিভাগ থেকে সঠিকভাবে সেট করা আছে।

👉💻 আমরা অর্কেস্ট্রেট এজেন্টকে এজেন্ট ইঞ্জিনে মোতায়েন করব (দ্রষ্টব্য: এটি আমার নিজের স্থাপনার নিজস্ব বাস্তবায়ন, এডিকে মোতায়েন করতে সহায়তা করার জন্য একটি সিএলআই রয়েছে, আমি 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

এখন যেহেতু অর্কেস্ট্রেটরটি পরিচালিত এজেন্ট ইঞ্জিন প্ল্যাটফর্মে হোস্ট করা হয়েছে, আমাদের ইন্সটভিবে ওয়েব অ্যাপ্লিকেশনটির সাথে যোগাযোগ করা দরকার। এডিকে দেব ইউআইয়ের মাধ্যমে ইন্টারঅ্যাক্ট করার পরিবর্তে ওয়েব অ্যাপ্লিকেশনটি এজেন্ট ইঞ্জিনের শেষ পয়েন্টে দূরবর্তী কল করবে।

10-এজেন্ট-রিমোট.পিএনজি

প্রথমত, আমাদের মোতায়েন করা অর্কেস্টেটর এজেন্টের অনন্য আইডি ব্যবহার করে এজেন্ট ইঞ্জিন ক্লায়েন্টকে আরম্ভ করতে আমাদের ইনস্টাভিবি অ্যাপ্লিকেশন কোডটি সংশোধন করতে হবে। এই আইডিটি প্ল্যাটফর্মে সঠিক এজেন্ট উদাহরণটি লক্ষ্য করতে হবে।

👉📝 ওপেন ~/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)

ইন্সটভিবিতে আমাদের পরিকল্পিত ব্যবহারকারীর প্রবাহের মধ্যে এজেন্টের সাথে দুটি মিথস্ক্রিয়া জড়িত: প্রথমে, প্রস্তাবিত পরিকল্পনা তৈরি করা এবং দ্বিতীয়ত, ব্যবহারকারীকে এজেন্টটি আসলে প্ল্যাটফর্মে ইভেন্টটি পোস্ট করার আগে নিশ্চিত করতে বলে।

যেহেতু ইন্সটভিবে ওয়েব অ্যাপ্লিকেশন (ক্লাউড রান চালানো) এবং অর্কেস্টেটর এজেন্ট (এজেন্ট ইঞ্জিনে চলমান) এখন পৃথক পরিষেবা, তাই ওয়েব অ্যাপ্লিকেশনটিকে এজেন্টের সাথে যোগাযোগের জন্য এজেন্ট ইঞ্জিনের শেষ পয়েন্টে দূরবর্তী কল করা দরকার।

👉📝 আসুন কোডটি আপডেট করুন যা পরিকল্পনার সুপারিশ তৈরি করতে প্রাথমিক কলটি তৈরি করে। একই introvertally.py ফাইলে, #REPLACE ME Query remote agent get plan , যা ব্যবহারকারীর অনুরোধটি প্রেরণের জন্য এজেন্ট_জাইন ক্লায়েন্ট ব্যবহার করে:

agent_engine.stream_query(
                user_id=user_id,
                message=prompt_message,
            )

👉📝 পরবর্তী, কোডটি আপডেট করুন যা ব্যবহারকারীর নিশ্চিতকরণ পরিচালনা করে (যেমন, যখন ব্যবহারকারী "পরিকল্পনাটি নিশ্চিত করুন" ক্লিক করেন)। এটি এজেন্ট ইঞ্জিনে একই কথোপকথনে একটি ফলো-আপ বার্তা প্রেরণ করে, অর্কেস্টেটরকে ইভেন্টটি পোস্ট করার জন্য এগিয়ে যাওয়ার নির্দেশ দেয় (যা এটি প্ল্যাটফর্ম ইন্টিগ্রেশন এজেন্টের প্রতিনিধিত্ব করবে)। introvertally.py নিশ্চিতকরণের জন্য #REPLACE ME Query remote agent for confirmation প্রতিস্থাপন করুন।

agent_engine.stream_query(
            user_id=agent_session_user_id,
            message=prompt_message,
        )

ওয়েব অ্যাপ্লিকেশনটির রুটগুলির এই ফাংশনগুলিতে অ্যাক্সেস প্রয়োজন। অন্তর্মুখী থেকে প্রয়োজনীয় ফাংশনগুলি নিশ্চিত করুন।

cd ~/instavibe-bootstrap/instavibe/ally_routes.py , আমরা প্রথমে উদাহরণটি দেখব # প্রতিস্থাপন # REPLACE ME TO ADD IMPORT :

from introvertally import call_agent_for_plan, post_plan_event

~/instavibe-bootstrap/instavibe/templates/base.html ইনস্টিভিবিতে প্রোটোটাইপ বৈশিষ্ট্যটি যুক্ত করুন, <!-প্রতিস্থাপন করুন_মেই_লিংক_টো_ইনট্রোভার্ট_ওয়ালি –> নিম্নলিখিতগুলির সাথে:

            <li class="nav-item">
              <a class="nav-link" href="{{ url_for('ally.introvert_ally_page') }}">Introvert Ally</a>
            </li>

আমরা ইন্সটভিবি অ্যাপটি পুনরায় নিয়োগের আগে, আমাদের এজেন্ট ইঞ্জিনে মোতায়েন করা অর্কেস্টেটর এজেন্টের নির্দিষ্ট Resource ID প্রয়োজন।

বর্তমানে, gcloud মাধ্যমে এই প্রোগ্রাম্যাটিকভাবে পুনরুদ্ধার করা সীমাবদ্ধ হতে পারে, সুতরাং আমরা আইডি আনতে এবং পরিবেশের ভেরিয়েবলে সংরক্ষণ করতে একটি সহায়ক পাইথন স্ক্রিপ্ট ( temp-endpoint.py ) ব্যবহার করব।

The স্ক্রিপ্টটি কার্যকর করতে নিম্নলিখিত কমান্ডগুলি চালান। স্ক্রিপ্টটি এজেন্ট ইঞ্জিন এন্ডপয়েন্ট আইডি ক্যাপচার করবে এবং এজেন্ট ইঞ্জিনের ডিফল্ট পরিষেবা অ্যাকাউন্টে প্রয়োজনীয় অনুমতি প্রদান করবে (দ্রষ্টব্য: স্ক্রিপ্টটি বর্তমানে ব্যবহারকারী-পরিবর্তনযোগ্য নয় বলে ডিফল্ট পরিষেবা অ্যাকাউন্টটি ব্যবহার করার জন্য কনফিগার করা হয়েছে)।

. ~/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 পরিবেশের পরিবর্তনশীল সহ ইন্সটভিবে ওয়েব অ্যাপ্লিকেশনটি পুনরায় নিয়োগ করতে হবে যাতে এটি এজেন্ট ইঞ্জিনে চলমান আমাদের এজেন্টের সাথে কীভাবে সংযোগ স্থাপন করতে পারে তা জানে।

Poluter নিম্নলিখিত কমান্ডগুলি ইন্সটভিব অ্যাপ্লিকেশন চিত্রটি পুনর্নির্মাণ এবং ক্লাউড রানের জন্য নতুন সংস্করণ স্থাপন করুন:

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

With the final deployment complete, navigate to your InstaVibe application URL in a different browser tab.

Testing the Full AI-Powered InstaVibe Experience

The "InstaVibe Ally" feature is now live, powered by our multi-agent system orchestrated via Vertex AI Agent Engine and communicating through A2A.

12-02-new.png

Click into "InstaVibe Ally" and ask it to plan an event.

12-03-introvertally.png

Observe the activity log on the right while the agents work (it may take 90-120 seconds). Once the plan appears, review it and click "Confirm This Plan" to proceed with posting.

12-04-confirm.png

The orchestrator will now instruct the Platform agent to create the post and event within InstaVibe. 12-05-posting.png

Check the InstaVibe home page for the new post and event. 12-06-instavibe.png

The event page will reflect the details generated by the agent.

12-07-event.png

Analyzing Performance with Cloud Trace

You might notice the process takes some time. Vertex AI Agent Engine integrates with Cloud Trace, allowing us to analyze the latency of our multi-agent system.

Go to the Traces in the google cloud console, select agent_run[orchestrate_agent] in the Span, you should see a couple of Spans, click into it

12-08-trace.png

Within the trace details, you can identify which parts took longer. For example, calls to the Planner agent might show higher latency due to search grounding and complex generation. 12-09-plan.png

Similarly, when creating the post and event, you might see time spent by the Orchestrator processing data and preparing tool calls for the Platform agent. 12-10-post.png

Exploring these traces helps understand and optimize the performance of your agent system.

celebrate.png

অভিনন্দন! You've successfully built, deployed, and tested a sophisticated multi-agent AI system using Google's ADK, A2A, MCP, and Google Cloud services. You've tackled agent orchestration, tool usage, state management, and cloud deployment, creating a functional AI-powered feature for InstaVibe. Well done on completing the workshop!

13. Clean Up

To avoid ongoing charges to your Google Cloud account, it's important to delete the resources we created during this workshop. The following commands will help you remove the Spanner instance, Cloud Run services, Artifact Registry repository, API Key, Vertex AI Agent Engine, and associated IAM permissions.

গুরুত্বপূর্ণ:

  • Ensure you are running these commands in the same Google Cloud project used for the workshop.
  • If you've closed your Cloud Shell terminal, some environment variables like $PROJECT_ID, $SPANNER_INSTANCE_ID, etc., might not be set. You'll need to either re-export them as you did during the workshop setup or replace the variables in the commands below with their actual values.
  • These commands will permanently delete your resources. Double-check before running if you have other important data in this project.

👉💻 Run the following scripts to clean up.

Reset environment variables

. ~/instavibe-bootstrap/set_env.sh

Delete Agent Engine:

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

Delete Cloud Run Services:

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

Stop and Remove the A2A Inspector Docker Container

docker rm --force a2a-inspector

Delete Spanner Instance:

echo "Deleting Spanner instance: ${SPANNER_INSTANCE_ID}..."
gcloud spanner instances delete ${SPANNER_INSTANCE_ID} --project=${PROJECT_ID} --quiet
echo "Spanner instance deletion initiated."

Delete Artifact Registry Repository:

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

Remove Roles from Service Account:

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

Delete Local Workshop Files:

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

ক্লিন আপ