১. এক নজরে
AI এজেন্ট দ্রুত জনপ্রিয় হয়ে উঠছে, টাস্ক অটোমেশন ও সিদ্ধান্ত নেওয়ার ক্ষেত্রে বিপ্লব ঘটাচ্ছে। এর কারণ হল, এগুলি অটোনোমাসভাবে কাজ করতে, শিখতে এবং লক্ষ্য পূরণের জন্য পরিবেশের সাথে ইন্টার্যাক্ট করতে পারে।
এই কোডল্যাব আপনাকে এন্ড-টু-এন্ড মাল্টি-এজেন্ট সিস্টেম তৈরি করার মাধ্যমে শুরু করতে সাহায্য করবে। আপনি একটি কারেন্সি MCP সার্ভার তৈরি করবেন, একটি কারেন্সি এজেন্ট তৈরি করবেন যা MCP সার্ভার ব্যবহার করে এবং Agent2Agent (A2A) প্রোটোকলের মাধ্যমে প্রকাশ করা হয়, একটি ইন-প্রসেস ওয়েদার সাবএজেন্ট সহ একটি ট্রাভেল এজেন্ট তৈরি করবেন যা A2A-এর মাধ্যমে কারেন্সি এজেন্ট ব্যবহার করে এবং অবশেষে Cloud Run-এ সব পরিষেবা ডিপ্লয় করবেন।

কোর টেকনোলজিস
Model Context Protocol (MCP)
মডেল কন্টেক্সট প্রোটোকল (MCP) হল একটি ওপেন প্রোটোকল যা LLM-এ অ্যাপ্লিকেশন কীভাবে কন্টেক্সট ও টুল প্রদান করে তা স্ট্যান্ডার্ডাইজ করে। AI অ্যাপ্লিকেশনের জন্য MCP-কে USB-C পোর্টের মতো মনে করুন: এটি AI মডেলগুলিকে এক্সটার্নাল ডেটা সোর্স, API এবং টুলের সাথে কানেক্ট করার একটি স্ট্যান্ডার্ডাইজড উপায় প্রদান করে।
এই কোডল্যাবে, currency_mcp_server, স্ট্রিমেবল HTTP (/mcp)-এর মাধ্যমে একটি get_exchange_rate টুল প্রকাশ করে, যা পাবলিক Frankfurter API দ্বারা সমর্থিত।
এজেন্ট ডেভেলপমেন্ট কিট (ADK)
Agent Development Kit (ADK) হল AI এজেন্ট ডেভেলপ ও ডিপ্লয় করার জন্য একটি ফ্লেক্সিবল অর্কেস্ট্রেশন ফ্রেমওয়ার্ক। ADK হল মডেল-অ্যাগনস্টিক, ডিপ্লয়মেন্ট-অ্যাগনস্টিক এবং অন্যান্য ফ্রেমওয়ার্কের সাথে মানানসই হওয়ার জন্য তৈরি করা হয়েছে। ADK-এর মাধ্যমে এজেন্ট ডেভেলপমেন্টকে স্ট্যান্ডার্ড সফ্টওয়্যার ইঞ্জিনিয়ারিংয়ের মতো মনে হয়, যা জটিল এজেন্টিক ওয়ার্কফ্লো তৈরি, পরীক্ষা ও অর্কেস্ট্রেট করা সহজ করে তোলে।
ADK ব্যবহারকারীর কথোপকথন ম্যানেজ করে, ইন্টার্যাক্টিভ ওয়েব UI প্রদান করে, McpToolset-এর মাধ্যমে MCP টুলের সাথে কানেক্ট করে এবং A2A কমিউনিকেশন ম্যানেজ করে।
Agent2Agent (A2A) প্রোটোকল
Agent2Agent (A2A) প্রোটোকল হল একটি ওপেন স্ট্যান্ডার্ড যা AI এজেন্টদের মধ্যে যোগাযোগ ও কোলাবরেশন করার জন্য ডিজাইন করা হয়েছে। MCP যেভাবে এজেন্ট-টু-টুল কানেকশনকে স্ট্যান্ডার্ডাইজ করে, ঠিক সেভাবেই A2A এজেন্ট-টু-এজেন্ট কোলাবরেশনকে স্ট্যান্ডার্ডাইজ করে! এমন এক দুনিয়া যেখানে বিভিন্ন ফ্রেমওয়ার্ক, হোস্টিং এনভায়রনমেন্ট ও সংস্থা জুড়ে এজেন্ট তৈরি করা হয়, সেখানে A2A ডিসকভারি ও টাস্ক ডেলিগেশনের জন্য একটি সাধারণ ভাষা প্রদান করে।
ADK, currency_agent-কে A2A পরিষেবা (to_a2a) হিসেবে প্রকাশ করে এবং travel_agent-কে AgentTool (RemoteA2aAgent) হিসেবে রিমোটলি এটি ব্যবহার করার অনুমতি দেয়।
স্থানীয় সাব-এজেন্ট বনাম রিমোট A2A এজেন্ট
এই আর্কিটেকচার মাল্টি-এজেন্ট ডিজাইনে একটি গুরুত্বপূর্ণ প্যাটার্ন হাইলাইট করে:
- লোকাল এজেন্ট টুল (
weather_agent): অর্কেস্ট্রেটরের মধ্যেAgentToolহিসেবে ইন-প্রসেস রান করে, যার ফলে নেটওয়ার্ক লেটেন্সি বা প্রোটোকল সিরিয়ালাইজেশন ওভারহেড হয় না। - রিমোট এজেন্ট টুল (
currency_agent): একটি স্বাধীন মাইক্রোসার্ভিস হিসেবে চলে, যা A2A প্রোটোকলের মাধ্যমে নেটওয়ার্ক জুড়ে কল করা হয়।
আপনি কী শিখবেন
- স্ট্রিমেবল HTTP-তে FastMCP ব্যবহার করে কীভাবে লোকাল MCP সার্ভার তৈরি ও পরীক্ষা করতে হয়
- MCP টুল (
McpToolset) ব্যবহার করে ADK-এর মাধ্যমে কীভাবে এজেন্ট তৈরি করতে হয় - A2A সার্ভার (
to_a2a) হিসেবে ADK এজেন্ট কীভাবে এক্সপোজ করবেন - A2A Python ক্লায়েন্ট (
a2a.client) ব্যবহার করে কীভাবে A2A সার্ভার পরীক্ষা করবেন - কীভাবে এমন একটি অর্কেস্ট্রেটর এজেন্ট তৈরি করা যায় যা রিমোট A2A এজেন্টের সাথে লোকাল সাবএজেন্ট টুলকে একত্রিত করে
- ADK ওয়েব UI-এর মাধ্যমে কীভাবে সম্পূর্ণ মাল্টি-এজেন্ট সিস্টেম লোকালি রান ও টেস্ট করবেন
- Google Cloud Run-এ কীভাবে তিনটি কম্পোনেন্ট কন্টেনারাইজ ও ডিপ্লয় করবেন
আপনার কী প্রয়োজন হবে
- Chrome-এর মতো ব্রাউজার।
- বিলিং চালু করা আছে এমন একটি Google Cloud প্রোজেক্ট।
২. শুরু করার আগে
প্রোজেক্ট তৈরি করুন
আপনার কোনও Google Cloud প্রোজেক্ট না থাকলে, একটি তৈরি করুন।
Google Cloud Console-এ, প্রোজেক্ট সিলেক্টর পৃষ্ঠায়, Google Cloud প্রোজেক্ট বেছে নিন বা তৈরি করুন।
এছাড়াও, আপনার ক্লাউড প্রোজেক্টের জন্য বিলিং চালু করা আছে কিনা তা ভাল করে দেখে নিন। প্রোজেক্টে বিলিং চালু করা আছে কিনা তা চেক করবেন কীভাবে তা জানুন।
Cloud Shell চালু করুন
Google Cloud Shell হল একটি ইন্টার্যাক্টিভ, ব্রাউজার-ভিত্তিক ডেভেলপমেন্ট এনভায়রনমেন্ট যা সরাসরি Google Cloud Console-এর মধ্যে প্রদান করা হয়। স্থানীয়ভাবে টুল ইনস্টল না করেই Google Cloud ব্যবহার শুরু করার এটি সবচেয়ে সহজ উপায়।
এই লিঙ্কে ক্লিক করে Cloud Shell চালু করুন। Cloud Shell-এ সংশ্লিষ্ট বোতামে ক্লিক করে আপনি Cloud Shell Terminal (ক্লাউড কমান্ড চালানোর জন্য) এবং Editor (ফাইল দেখার জন্য)-এর মধ্যে টগল করতে পারবেন।
Cloud Shell-এ কানেক্ট করার পরে, আপনি যাচাইকৃত কিনা তা চেক করুন:
gcloud auth list
gcloud কমান্ড আপনার প্রোজেক্ট সম্পর্কে জানে কিনা তা কনফার্ম করুন:
gcloud config list project
আপনার প্রোজেক্ট আইডি সেট করুন:
export PROJECT_ID=<YOUR_GOOGLE_CLOUD_PROJECT_ID>
gcloud config set project $PROJECT_ID
Cloud API চালু করুন
Cloud Run, Cloud Build, Artifact Registry এবং Vertex AI-এর জন্য প্রয়োজনীয় API চালু করুন:
gcloud services enable run.googleapis.com \
cloudbuild.googleapis.com \
artifactregistry.googleapis.com \
aiplatform.googleapis.com
কোড পান
রিপোজিটরি ক্লোন করুন এবং python ডিরেক্টরিতে নেভিগেট করুন:
git clone https://github.com/meteatamel/getting-started-mcp-a2a-adk.git
cd getting-started-mcp-a2a-adk/python
uv-এর সাথে ডিপেন্ডেন্সি ইনস্টল করুন
uv হল একটি দ্রুত Python প্যাকেজ ও প্রোজেক্ট ম্যানেজার। এটি Cloud Shell-এ আগে থেকেই ইনস্টল করা থাকে। লোকালি রান করলে, আপনি এটি এইভাবে ইনস্টল করতে পারবেন:
# macOS and Linux
curl -LsSf https://astral.sh/uv/install.sh | sh
# Windows (PowerShell)
# powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
Python ডিরেক্টরি ইউনিফায়েড uv হিসেবে স্ট্রাকচার করা হয়েছে
Workspace। এটি রান করে একটি ভার্চুয়াল এনভায়রনমেন্টে সব Workspace মেম্বার (currency_mcp_server, currency_agent এবং travel_agent) জুড়ে সব ডিপেন্ডেন্সি ইনস্টল করুন:
uv sync
এনভায়রনমেন্ট ভেরিয়েবল কনফিগার করুন
python ডিরেক্টরিতে .env ফাইলে এনভায়রনমেন্ট ভেরিয়েবেল কনফিগার করুন:
বিকল্প ক: Gemini Enterprise (Google Cloud / Cloud Shell)
echo "GOOGLE_GENAI_USE_ENTERPRISE=TRUE" >> .env \
&& echo "GOOGLE_CLOUD_PROJECT=$PROJECT_ID" >> .env \
&& echo "GOOGLE_CLOUD_LOCATION=global" >> .env
বিকল্প খ: Google AI Studio (লোকাল API কী)
আপনি যদি এর পরিবর্তে Google AI Studio থেকে API কী ব্যবহার করতে চান:
echo "GOOGLE_API_KEY=<your_api_key_here>"<>>/span> .env \
&& echo "GOOGLE_GENAI_USE_ENTERPRISE=FALSE" >> .env
৩. কারেন্সি MCP সার্ভার তৈরি করা
আপনার এজেন্ট তৈরি করার আগে, আপনি প্রথমে MCP সার্ভার এক্সপ্লোর করবেন যা মুদ্রা রূপান্তর টুল দেখায়।
MCP সার্ভার আপনাকে টুল হিসেবে ক্ষমতা প্রকাশ করার জন্য লাইটওয়েট প্রোগ্রাম লিখতে দেয়। এরপর, কোনও এজেন্ট (বা একাধিক এজেন্ট) স্ট্যান্ডার্ডাইজড Model Context Protocol ব্যবহার করে এইসব টুল অ্যাক্সেস করতে পারে।
FastMCP Python প্যাকেজ ব্যবহার করে এমন একটি MCP সার্ভার তৈরি করা যেতে পারে যা get_exchange_rate নামের একটি টুলকে এক্সপোজ করে। get_exchange_rate টুলটি দুটি মুদ্রার মধ্যে বর্তমান এক্সচেঞ্জ রেট পেতে Frankfurter API কল করে।
MCP সার্ভারের কোড currency_mcp_server/server.py-এ রয়েছে:
import asyncio
import logging
import os
import httpx
from fastmcp import FastMCP
logger = logging.getLogger(__name__)
logging.basicConfig(format="[%(levelname)s]: %(message)s", level=logging.INFO)
mcp = FastMCP("Currency MCP Server 💵")
@mcp.tool()
def get_exchange_rate(
currency_from: str = "USD",
currency_to: str = "EUR",
currency_date: str = "latest",
):
"""Use this to get current exchange rate.
Args:
currency_from: The currency to convert from (e.g., "USD").
currency_to: The currency to convert to (e.g., "EUR").
currency_date: The date for the exchange rate or "latest". Defaults to "latest".
Returns:
A dictionary containing the exchange rate data, or an error message if the request fails.
"""
logger.info(
f"--- 🛠️ Tool: get_exchange_rate called for converting {currency_from} to {currency_to} ---"
)
try:
response = httpx.get(
f"https://api.frankfurter.dev/v1/{currency_date}",
params={"from": currency_from, "to": currency_to},
)
response.raise_for_status()
data = response.json()
if "rates" not in data:
logger.error(f"❌ rates not found in response: {data}")
return {"error": "Invalid API response format."}
logger.info(f"✅ API response: {data}")
return data
except httpx.HTTPError as e:
logger.error(f"❌ API request failed: {e}")
return {"error": f"API request failed: {e}"}
except ValueError:
logger.error("❌ Invalid JSON response from API")
return {"error": "Invalid JSON response from API."}
if __name__ == "__main__":
port = int(os.getenv("PORT", 8080))
logger.info(f"🚀 MCP server started on port {port}")
# Could also use 'sse' transport, host="0.0.0.0" required for Cloud Run.
asyncio.run(
mcp.run_async(
transport="http",
host="0.0.0.0",
port=port,
)
)
স্থানীয়ভাবে MCP সার্ভার চালু করুন
আপনার টার্মিনালে MCP সার্ভার চালু করুন:
uv run python currency_mcp_server/server.py
সার্ভারটি 8080 পোর্টে শুরু হয় এবং স্ট্রিমেবল HTTP এন্ডপয়েন্ট /mcp (http://localhost:8080/mcp)-এ উপলভ্য থাকে।
MCP সার্ভার টেস্ট করুন
দ্বিতীয় টার্মিনাল উইন্ডো খুলুন (প্রথমটিতে MCP সার্ভার চলতে দিন), python ফোল্ডারে (cd getting-started-mcp-a2a-adk/python) নেভিগেট করুন এবং টেস্ট স্ক্রিপ্ট রান করুন:
uv run python currency_mcp_server/test_server.py
টেস্ট স্ক্রিপ্ট FastMCP-এর Client ব্যবহার করে MCP এন্ডপয়েন্টের সাথে কানেক্ট করে, টুলগুলি তালিকাভুক্ত করে এবং get_exchange_rate-কে কল করে:
Connecting to MCP server at: http://localhost:8080/mcp
--- 🛠️ Tool found: get_exchange_rate ---
--- 🪛 Calling get_exchange_rate tool for USD to EUR ---
--- ✅ Success: {"amount":1.0,"base":"USD","date":"2026-09-29","rates":{"EUR":0.84919}} ---
দুর্দান্ত! আপনার কাছে একটি কাজ করছে এমন MCP সার্ভার আছে যা একটি লাইভ কারেন্সি টুল প্রকাশ করছে। পরবর্তী ধাপের জন্য এই টার্মিনাল খোলা রাখুন।
৪. ADK-এর মাধ্যমে কারেন্সি এজেন্ট তৈরি করা
এখন Agent Development Kit (ADK) ব্যবহার করে কারেন্সি এজেন্ট তৈরি করার সময় এসেছে।
ADK, McpToolset ক্লাসের মাধ্যমে MCP টুলের জন্য বিল্ট-ইন সহায়তা প্রদান করে। কারেন্সি এজেন্ট StreamableHTTPConnectionParams ব্যবহার করে আমাদের MCP সার্ভারের সাথে কানেক্ট করে।
currency_agent/agent.py-এ কারেন্সি এজেন্ট সংক্রান্ত সংজ্ঞা দেখুন:
import logging
import os
from urllib.parse import urlparse
from dotenv import load_dotenv
from google.adk.agents import LlmAgent
from google.adk.a2a.utils.agent_to_a2a import to_a2a
from google.adk.tools.mcp_tool import McpToolset, StreamableHTTPConnectionParams
logger = logging.getLogger(__name__)
logging.basicConfig(format="[%(levelname)s]: %(message)s", level=logging.INFO)
load_dotenv()
SYSTEM_INSTRUCTION = (
"You are a specialized assistant for currency conversions. "
"Your sole purpose is to use the 'get_exchange_rate' tool to answer questions about currency exchange rates. "
"If the user asks about anything other than currency conversion or exchange rates, "
"politely state that you cannot help with that topic and can only assist with currency-related queries. "
"Do not attempt to answer unrelated questions or use tools for other purposes."
)
mcp_server_url = os.getenv("MCP_SERVER_URL", "http://localhost:8080/mcp")
if not mcp_server_url.endswith("/mcp"):
mcp_server_url = f"{mcp_server_url.rstrip('/')}/mcp"
logger.info(f"--- 🔧 Loading MCP tools from MCP Server at {mcp_server_url}... ---")
logger.info("--- 🤖 Creating ADK Currency Agent... ---")
root_agent = LlmAgent(
model="gemini-3.8-flash",
name="currency_agent",
description="An agent that can help with currency conversions",
instruction=SYSTEM_INSTRUCTION,
tools=[
McpToolset(
connection_params=StreamableHTTPConnectionParams(
url=mcp_server_url
)
)
],
)
লক্ষ্য করুন কীভাবে McpToolset HTTP-এর মাধ্যমে চালু থাকা MCP সার্ভার থেকে সরাসরি get_exchange_rate টুল অটোমেটিক খুঁজে নেয় ও লোড করে।
ADK Web UI-এর মাধ্যমে কারেন্সি এজেন্ট পরীক্ষা করা
আপনি ADK-এর ডেভেলপমেন্ট ওয়েব ইন্টারফেস ব্যবহার করে এজেন্টকে আলাদাভাবে পরীক্ষা করতে পারেন। আপনার দ্বিতীয় টার্মিনালে, রান করুন:
uv run adk web --allow_origins "*" currency_agent
http://localhost:8000-এ আপনার ব্রাউজার খুলুন (অথবা Cloud Shell-এ ওয়েব প্রিভিউ বিকল্পে ক্লিক করুন)।

এজেন্টকে জিজ্ঞাসা করুন:
"২৫০ মার্কিন ডলারের মূল্য ইউরোতে কত?"
আপনি দেখতে পাবেন যে এজেন্ট get_exchange_rate MCP টুলটি চালু করে এবং কনভার্ট করা পরিমাণ ফেরত দেয়। এগিয়ে যাওয়ার আগে Ctrl+C ব্যবহার করে adk web প্রসেস বন্ধ করুন।
৫. Agent2Agent (A2A) প্রোটোকল
Agent2Agent (A2A) প্রোটোকল হল একটি ওপেন স্ট্যান্ডার্ড যা AI এজেন্টদের মধ্যে যোগাযোগ ও কোলাবরেশন করার জন্য ডিজাইন করা হয়েছে।
আধুনিক মাল্টি-এজেন্ট সিস্টেমে, এজেন্টরা প্রায়শই বিভিন্ন ফ্রেমওয়ার্ক (ADK, LangChain, CrewAI, AutoGen) ব্যবহার করে তৈরি করা হয় এবং বিভিন্ন পরিকাঠামোতে ডিপ্লয় করা হয়। A2A একটি স্ট্যান্ডার্ডাইজড কমিউনিকেশন কন্ট্র্যাক্ট সংজ্ঞায়িত করে এই সাইলো ভেঙে দেয়।

A2A-এর মূল ধারণা
- এজেন্ট ডিসকভারি (এজেন্ট কার্ড): প্রতিটি A2A-কমপ্লায়েন্ট এজেন্ট তার ক্ষমতা, সমর্থিত I/O মোড, যাচাইকরণের প্রয়োজনীয়তা এবং দক্ষতা
/.well-known/agent-card.json-এ হোস্ট করা একটি স্ট্যান্ডার্ড JSON ফাইলের মাধ্যমে বিজ্ঞাপন দেয়। - এজেন্ট স্কিল (
AgentSkill): নির্দিষ্ট ক্ষমতা বা টুল যা এজেন্ট এক্সিকিউট করতে পারে। অন্যান্য এজেন্ট কখন টাস্ক ডেলিগেট করতে হবে তা সিদ্ধান্ত নিতে এই দক্ষতাগুলি পড়ে। - JSON-RPC কমিউনিকেশন: এজেন্টরা HTTP JSON-RPC 2.0-এর মতো স্ট্যান্ডার্ড ট্রান্সপোর্টের মাধ্যমে স্ট্রাকচার্ড মেসেজ, টাস্ক ও আর্টিফ্যাক্ট আদানপ্রদান করে।

পরবর্তী ধাপে, আপনি আমাদের ADK কারেন্সি এজেন্টকে A2A সার্ভার হিসেবে প্রকাশ করবেন যাতে অন্যান্য এজেন্টরা এটি খুঁজে পেতে পারে এবং এতে মুদ্রা রূপান্তর টাস্ক ডেলিগেট করতে পারে!
৬. কারেন্সি এজেন্টকে A2A সার্ভার হিসেবে এক্সপোজ করুন
ADK, to_a2a() ইউটিলিটি ফাংশনের মাধ্যমে যেকোনও LlmAgent-কে A2A-মানানসই সার্ভারে অনায়াসে পরিবর্তন করে।
currency_agent/agent.py-এর নিচের অংশ পর্যালোচনা করুন:
# Make the agent A2A-compatible
PORT = int(os.getenv("PORT", 8081))
AGENT_URL = os.getenv("AGENT_URL")
if AGENT_URL:
parsed = urlparse(AGENT_URL)
protocol = parsed.scheme or "https"
host = parsed.hostname
port = parsed.port or 443
else:
protocol = "http"
host = "localhost"
port = PORT
a2a_app = to_a2a(root_agent, host=host, port=port, protocol=protocol)
if __name__ == "__main__":
import uvicorn
logger.info(f"🚀 Starting currency_agent on port {PORT}")
uvicorn.run(a2a_app, host="0.0.0.0", port=PORT)
to_a2a() হেল্পার অটোমেটিক:
LlmAgent-এর টুল ও নির্দেশাবলী পরীক্ষা করে।- এর দক্ষতা বর্ণনা করে একটি A2A
AgentCardতৈরি করে (যেমনcurrency_agent-get_exchange_rate)। - JSON-RPC এন্ডপয়েন্ট সাপোর্ট করে এমন FastAPI অ্যাপ্লিকেশনে (
a2a_app) এজেন্টকে র্যাপ করে। AGENT_URL(বা লোকালহোস্ট)-এর উপর ভিত্তি করে এজেন্ট কার্ডে বিজ্ঞাপন দেওয়াurlডায়নামিকভাবে কনফিগার করে।
Currency Agent A2A সার্ভার চালু করা
আপনার দ্বিতীয় টার্মিনালে, কারেন্সি এজেন্ট চালু করুন:
uv run python currency_agent/agent.py
সার্ভার 8081 পোর্টে শুরু হয়:
[INFO]: --- 🔧 Loading MCP tools from MCP Server at http://localhost:8080/mcp... ---
[INFO]: --- 🤖 Creating ADK Currency Agent... ---
[INFO]: 🚀 Starting currency_agent on port 8081
INFO: Started server process
INFO: Waiting for application startup.
INFO: Application startup complete.
INFO: Uvicorn running on http://0.0.0.0:8081 (Press CTRL+C to quit)
এজেন্ট কার্ড পরীক্ষা করুন
আপনার ব্রাউজারে, এজেন্ট কার্ড এন্ডপয়েন্টে যান: http://localhost:8081/.well-known/agent-card.json
আপনি অটোমেটিক জেনারেট করা JSON মেটাডেটা দেখতে পাবেন:
{
"name": "currency_agent",
"description": "An agent that can help with currency conversions",
"supportedInterfaces": [
{
"url": "http://localhost:8081",
"protocolBinding": "JSONRPC",
"protocolVersion": "1.0"
}
],
"version": "0.0.1",
"capabilities": {
"streaming": true
},
"defaultInputModes": [
"text/plain"
],
"defaultOutputModes": [
"text/plain"
],
"skills": [
{
"id": "currency_agent",
"name": "model",
"description": "An agent that can help with currency conversions",
"tags": [
"llm"
]
},
{
"id": "currency_agent-get_exchange_rate",
"name": "get_exchange_rate",
"description": "Use this to get current exchange rate.",
"tags": [
"llm",
"tools"
]
}
]
}
A2A ক্লায়েন্টের সাথে পরীক্ষা করুন
তৃতীয় টার্মিনাল খুলুন, python ফোল্ডারে (cd getting-started-mcp-a2a-adk/python) নেভিগেট করুন এবং নির্দিষ্ট A2A টেস্ট ক্লায়েন্ট স্ক্রিপ্ট ব্যবহার করে A2A এন্ডপয়েন্ট টেস্ট করুন:
uv run python currency_agent/test_a2aclient.py
ক্লায়েন্ট A2ACardResolver ব্যবহার করে এজেন্ট কার্ড রিজলভ করে এবং JSON-RPC মেসেজ পাঠায়:
🔄 Fetching the agent card at http://localhost:8081
✅ Successfully fetched the agent card
====================================================
AgentCard
====================================================
Name : currency_agent
Description : An agent that can help with currency conversions
Interfaces : [0] http://localhost:8081 (JSONRPC 1.0)
Skills : currency_agent, currency_agent-get_exchange_rate
====================================================
🔄 Initializing a non-streaming client
Sending request: "how much is 100 USD in GBP?"
Response:
100 USD is currently equal to approximately 73.37 GBP...
কারেন্সি এজেন্ট এখন সম্পূর্ণ ফাংশনাল A2A সার্ভার হিসেবে কাজ করছে!
৭. ট্রাভেল এজেন্ট তৈরি করুন
এখন আপনি অর্কেস্ট্রেটিং ট্রাভেল এজেন্ট তৈরি করবেন। এই এজেন্ট দেখায় যে কীভাবে একটি ADK এজেন্ট অনায়াসে দুটি ভিন্ন টুল প্যারাডাইম একত্রিত করতে পারে:
- লোকাল এজেন্ট টুল (
weather_agent): একই Python রানটাইমে চলা একটি ইন-প্রসেস ADK সাবএজেন্ট, যা কোনও নেটওয়ার্ক বা সিরিয়ালাইজেশন লেটেন্সি এড়িয়ে চলে। - রিমোট এজেন্ট টুল (
currency_agent):RemoteA2aAgentব্যবহার করে A2A প্রোটোকলের মাধ্যমে নেটওয়ার্কে কানেক্ট করা এক্সটার্নাল এজেন্ট।
+-----------------------------+
| travel_agent |
| (Orchestrator with Web UI) |
+--------------+--------------+
|
+---------------------+---------------------+
| (In-process call) | (A2A Network Hop)
v v
+-------------------------+ +-------------------------+
| weather_agent | | currency_agent |
| (Local AgentTool) | | (Remote A2A Agent) |
| Calls wttr.in API | | Calls Currency MCP Svc |
+-------------------------+ +-------------------------+
১. স্থানীয় আবহাওয়া সাব-এজেন্ট
travel_agent/subagents/weather_agent.py-এর দিকে নজর দিন:
import logging
import httpx
from google.adk.agents import LlmAgent
logger = logging.getLogger(__name__)
SYSTEM_INSTRUCTION = (
"You are a specialized assistant for providing weather forecasts and conditions for travel destinations. "
"Your sole purpose is to use the 'get_weather' tool to fetch weather information. "
"Provide clear, concise summaries of current weather conditions, temperatures, and forecasts to help travelers pack and plan."
)
def get_weather(location: str = "London") -> dict:
"""Gets the current weather and forecast for a given location or city."""
logger.info(f"--- 🌤️ Tool: get_weather called for {location} ---")
try:
response = httpx.get(
f"https://wttr.in/{location}?format=j1",
headers={"User-Agent": "curl/7.68.0"},
timeout=8.0,
)
response.raise_for_status()
data = response.json()
current = data["current_condition"][0]
return {
"location": location,
"condition": current.get("weatherDesc", [{}])[0].get("value", "Unknown"),
"temperature_celsius": f"{current.get('temp_C', 'N/A')}°C",
"temperature_fahrenheit": f"{current.get('temp_F', 'N/A')}°F",
"humidity": f"{current.get('humidity', 'N/A')}%",
"wind_speed_kmph": f"{current.get('windspeedKmph', 'N/A')} km/h",
}
except Exception as e:
logger.warning(f"⚠️ Weather lookup failed: {e}. Returning simulated estimate.")
return {
"location": location,
"condition": "Partly Cloudy",
"temperature_celsius": "20°C",
"temperature_fahrenheit": "68°F",
"humidity": "55%",
"wind_speed_kmph": "10 km/h",
"note": f"Live data unavailable ({e}); showing estimated conditions.",
}
weather_agent = LlmAgent(
model="gemini-3.8-flash",
name="weather_agent",
description="A local specialist agent that provides current weather reports and forecasts for travel destinations.",
instruction=SYSTEM_INSTRUCTION,
tools=[get_weather],
)
আবহাওয়া এজেন্ট হল একটি LlmAgent যার একটি ফাংশন টুল আছে যা wttr.in থেকে রিয়েল-টাইম আবহাওয়া সংক্রান্ত তথ্য নিয়ে আসে এবং এর একটি রেজিলিয়েন্ট ফলব্যাক আছে।
২. ট্রাভেল এজেন্ট অর্কেস্ট্রেটর
এখন travel_agent/agent.py-কে ঘিরে সেরা কিছু স্মৃতি দেখুন:
import logging
import os
from dotenv import load_dotenv
from google.adk.agents import LlmAgent
from google.adk.tools.agent_tool import AgentTool
from google.adk.agents.remote_a2a_agent import RemoteA2aAgent, AGENT_CARD_WELL_KNOWN_PATH
try:
from travel_agent.subagents.weather_agent import weather_agent
except ImportError:
from subagents.weather_agent import weather_agent
logger = logging.getLogger(__name__)
logging.basicConfig(format="[%(levelname)s]: %(message)s", level=logging.INFO)
load_dotenv()
SYSTEM_INSTRUCTION = (
"You are a helpful travel assistant. You help users plan trips, recommend places, "
"and answer travel-related questions.\n\n"
"- Whenever a user asks about currency exchange rates or money conversions, "
"delegate the request to the 'currency_agent' tool.\n"
"- Whenever a user asks about the weather, climate, or forecasts for a destination, "
"delegate the request to the 'weather_agent' tool."
)
CURRENCY_AGENT_URL = os.getenv("CURRENCY_AGENT_URL", "http://localhost:8081").rstrip("/")
logger.info(
"--- 🔗 Connecting to Remote A2A Currency Agent at %s... ---",
CURRENCY_AGENT_URL,
)
currency_remote_agent = RemoteA2aAgent(
name="currency_agent",
agent_card=f"{CURRENCY_AGENT_URL}{AGENT_CARD_WELL_KNOWN_PATH}",
description="An agent that can help with currency conversions and exchange rates.",
)
logger.info("--- 🤖 Creating ADK Travel Agent... ---")
root_agent = LlmAgent(
model="gemini-3.8-flash",
name="travel_agent",
description="A travel assistant that can help plan trips, check weather forecasts via the local weather agent, and convert currencies via the remote currency agent.",
instruction=SYSTEM_INSTRUCTION,
tools=[
AgentTool(agent=currency_remote_agent),
AgentTool(agent=weather_agent),
],
)
if __name__ == "__main__":
import uvicorn
from google.adk.cli.fast_api import get_fast_api_app
PORT = int(os.getenv("PORT", 8082))
logger.info(f"🚀 Starting travel_agent Web UI on port {PORT}")
app = get_fast_api_app(web=True, allow_origins=["*"], agents_dir=os.path.dirname(__file__) or ".")
uvicorn.run(app, host="0.0.0.0", port=PORT)
কী হাইলাইট:
RemoteA2aAgenthttp://localhost:8081/.well-known/agent-card.jsonথেকে কারেন্সি এজেন্টের কার্ড নিয়ে আসে।currency_remote_agentএবংweather_agent, দুটিই ADK-এরAgentToolব্যবহার করে র্যাপ করা হয়েছে।travel_agent/agent.pyরান করলে,get_fast_api_app(web=True)ব্যবহার করে8082পোর্টে সরাসরি ADK ওয়েব UI বুট হয়।
৮. লোকাল ডিভাইসে মাল্টি-এজেন্ট সিস্টেম রান ও টেস্ট করা
আপনার কাছে এখন তিনটি কম্পোনেন্টই রেডি আছে! আসুন, সম্পূর্ণ সিস্টেমটি লোকাল ডিভাইসে রান ও টেস্ট করি।
তিনটি পরিষেবাই চলছে
পরিষেবাগুলি তিনটি পৃথক টার্মিনাল উইন্ডো জুড়ে (getting-started-mcp-a2a-adk/python ডিরেক্টরি থেকে) নিম্নলিখিত ক্রমে চলছে কিনা তা নিশ্চিত করুন:
Terminal 1 (Currency MCP Server):
uv run python currency_mcp_server/server.py
(পোর্ট ৮০৮০-তে চলছে)
টার্মিনাল ২ (কারেন্সি A2A এজেন্ট):
uv run python currency_agent/agent.py
(পোর্ট ৮০৮১-এ চলছে)
টার্মিনাল ৩ (ওয়েব UI সহ ট্রাভেল এজেন্ট):
uv run python travel_agent/agent.py
(পোর্ট ৮০৮২-এ চলছে)
ADK ওয়েব UI-এর মাধ্যমে পরীক্ষা করা
http://localhost:8082-এ আপনার ব্রাউজার খুলুন (অথবা Cloud Shell-এ পোর্ট 8082-এ ওয়েব প্রিভিউ ব্যবহার করুন)।
ট্রাভেল এজেন্টকে এমন একটি জটিল প্রশ্ন জিজ্ঞাসা করুন যার জন্য দুটি টুলই প্রয়োজন:
"আমি লন্ডন বেড়াতে যাওয়ার প্ল্যান করছি। আবহাওয়া কেমন এবং ২০০ ইউরো মানে কত পাউন্ড?"
এক্সিকিউশন ফ্লো দেখুন:
- ট্রাভেল এজেন্ট ওয়েব UI-তে অনুরোধটি পান।
- এটি আবহাওয়া সংক্রান্ত প্রশ্নকে প্রসেস করার জন্য স্থানীয়
weather_agent-এ ডেলিগেট করে, যাwttr.inথেকে বর্তমান পরিস্থিতি সংক্রান্ত তথ্য নিয়ে আসে। - এটি A2A প্রোটোকল-এর মাধ্যমে
currency_agent-এ ৮০৮১ পোর্টে মুদ্রা রূপান্তর ডেলিগেট করে। currency_agentএক্সচেঞ্জ রেট ফেচ করার জন্য MCP-এর মাধ্যমে 8080 পোর্টেcurrency_mcp_server-কে কল করে।- সব ফলাফল সিন্থেসাইজ করে আপনাকে একটি ইউনিফায়েড, সহায়ক উত্তর দেওয়া হয়!

কমান্ড লাইনের মাধ্যমে পরীক্ষা করুন
এছাড়াও, আপনি ব্রাউজার না খুলেই সরাসরি CLI থেকে কোয়েরি পরীক্ষা করতে পারেন:
uv run adk run travel_agent "What is the weather in London and how much is 100 USD in EUR?"
আপনার লোকাল মেশিনে এখন সবকিছু নির্বিঘ্নে কাজ করছে, তাই এবার Google Cloud Run-এ সম্পূর্ণ সিস্টেম ডিপ্লয় করা যাক!
৯. Cloud Run-এ মাল্টি-এজেন্ট সিস্টেম ডিপ্লয় করা
প্রতিটি কম্পোনেন্টের নিজস্ব Dockerfile এবং স্বয়ংসম্পূর্ণ pyproject.toml আছে, যাতে এটি Cloud Run-এ স্বাধীনভাবে তৈরি ও ডিপ্লয় করা যায়।
gcloud ব্যবহার করে, আপনি প্রতিটি পরিষেবা ডিপ্লয় করবেন এবং অটোমেটিক তাদের URL একসাথে ওয়্যার করবেন।
এনভায়রনমেন্ট ভেরিয়েবল সেট করুন
আপনার ক্লাউড প্রোজেক্ট আইডি এবং টার্গেট অঞ্চল সেট করুন:
export PROJECT_ID=<YOUR_GOOGLE_CLOUD_PROJECT_ID>
export REGION=us-central1
ধাপ ১: কারেন্সি MCP সার্ভার ডিপ্লয় করা
সোর্স থেকে সরাসরি MCP সার্ভার ডিপ্লয় করুন:
# 1. Deploy MCP server
gcloud run deploy currency-mcp-server \
--source currency_mcp_server \
--region $REGION \
--allow-unauthenticated
# 2. Capture the deployed MCP server URL
MCP_SERVER_URL=$(gcloud run services describe currency-mcp-server --region $REGION --format='value(status.url)')/mcp
echo "MCP Server URL: $MCP_SERVER_URL"
ধাপ ২: কারেন্সি এজেন্ট ডিপ্লয় করুন
যেহেতু currency-agent-এর পাবলিক URL প্রথমবার ডিপ্লয় করার সময় অ্যাসাইন করা হয়, তাই প্রথমে পরিষেবা ডিপ্লয় করুন, এর URL ক্যাপচার করুন এবং এর AGENT_URL এনভায়রনমেন্ট ভেরিয়েবল আপডেট করুন যাতে এর A2A এজেন্ট কার্ড সঠিক পাবলিক HTTPS অ্যাড্রেস বিজ্ঞাপন দেয়:
# 1. Deploy Currency Agent connected to the deployed MCP Server
gcloud run deploy currency-agent \
--source currency_agent \
--region $REGION \
--allow-unauthenticated \
--update-env-vars MCP_SERVER_URL="$MCP_SERVER_URL",GOOGLE_GENAI_USE_ENTERPRISE="true",GOOGLE_CLOUD_PROJECT="$PROJECT_ID",GOOGLE_CLOUD_LOCATION="global"
# 2. Capture its assigned Cloud Run URL
CURRENCY_AGENT_URL=$(gcloud run services describe currency-agent --region $REGION --format='value(status.url)')
echo "Currency Agent URL: $CURRENCY_AGENT_URL"
# 3. Update AGENT_URL so the agent advertises its public HTTPS endpoint in its Agent Card
gcloud run services update currency-agent \
--region $REGION \
--update-env-vars AGENT_URL="$CURRENCY_AGENT_URL"
ধাপ ৩: ট্রাভেল এজেন্ট ডিপ্লয় করা
এখন CURRENCY_AGENT_URL-এর সাথে কনফিগার করে ট্রাভেল এজেন্ট ডিপ্লয় করুন:
# 1. Deploy Travel Agent (with ADK Web UI) connected to Currency Agent
gcloud run deploy travel-agent \
--source travel_agent \
--region $REGION \
--allow-unauthenticated \
--update-env-vars CURRENCY_AGENT_URL="$CURRENCY_AGENT_URL",GOOGLE_GENAI_USE_ENTERPRISE="true",GOOGLE_CLOUD_PROJECT="$PROJECT_ID",GOOGLE_CLOUD_LOCATION="global"
# 2. Capture its assigned Cloud Run URL
TRAVEL_AGENT_URL=$(gcloud run services describe travel-agent --region $REGION --format='value(status.url)')
echo "Travel Agent URL: $TRAVEL_AGENT_URL"
১০. Cloud Run-এ মাল্টি-এজেন্ট সিস্টেম পরীক্ষা করা
তিনটি মাইক্রোসার্ভিসই ডিপ্লয় করা হয়ে গেলে, Cloud Run-এ প্রতিটি লেয়ার যাচাই করা যাক।
১. রিমোট MCP সার্ভার টেস্ট করুন
আপনার কমান্ড লাইন থেকে ডিপ্লয় করা Cloud Run MCP সার্ভার টেস্ট করুন:
MCP_SERVER_URL="$MCP_SERVER_URL" uv run python currency_mcp_server/test_server.py
আপনি Cloud Run-এ টুলটি তালিকাভুক্ত এবং সফলভাবে চালু করা দেখতে পাবেন।
২. A2A-এর মাধ্যমে কারেন্সি এজেন্ট পরীক্ষা করুন
A2A টেস্ট ক্লায়েন্ট ব্যবহার করে ডিপ্লয় করা কারেন্সি এজেন্ট টেস্ট করুন:
AGENT_URL="$CURRENCY_AGENT_URL" uv run python currency_agent/test_a2aclient.py
ক্লায়েন্ট Cloud Run থেকে রিমোট এজেন্ট কার্ড ফেচ করবে এবং HTTPS JSON-RPC-এর মাধ্যমে মেসেজ আদানপ্রদান করবে।
৩. Cloud Run-এ ট্রাভেল এজেন্ট ওয়েব UI পরীক্ষা করা
আপনার ব্রাউজারে $TRAVEL_AGENT_URL খুলুন!
সম্পূর্ণ ADK ওয়েব UI সরাসরি Cloud Run থেকে পরিবেশন করা হয়। কোয়েরি করে দেখুন:
"আমি টোকিওতে ট্রিপের প্ল্যান করছি। আবহাওয়া কেমন এবং ৫০০ মার্কিন ডলারের মূল্য জাপানি ইয়েনে কত?"
[Browser]
│
▼ (HTTPS)
[Cloud Run: travel-agent]
├──> Local in-process tool: weather_agent (wttr.in)
└──> A2A JSON-RPC (HTTPS)
│
▼
[Cloud Run: currency-agent]
└──> MCP Streamable HTTP (HTTPS)
│
▼
[Cloud Run: currency-mcp-server] (Frankfurter API)
তিনটি পরিষেবাই সার্ভারলেস ইনফ্রাস্ট্রাকচারে স্বাধীনভাবে স্কেল করে, ওপেন প্রোটোকলের মাধ্যমে নির্বিঘ্নে যোগাযোগ করে!
১১. অভিনন্দন ও ক্লিন-আপ
আপনি যা অর্জন করেছেন
অভিনন্দন! আপনি প্রোডাকশন-গ্রেড মাল্টি-এজেন্ট সিস্টেম তৈরি ও ডিপ্লয় করেছেন:
- Model Context Protocol (MCP): স্ট্রিমেবল HTTP-তে লাইভ API টুল প্রকাশ করে এমন একটি FastMCP সার্ভার তৈরি করা হয়েছে।
- Agent Development Kit (ADK):
LlmAgentব্যবহার করে মডিউলার এজেন্ট তৈরি করা,McpToolset-এর সাথে MCP টুল কানেক্ট করা এবং ADK ওয়েব UI হোস্ট করা। - Agent2Agent (A2A) প্রোটোকল: A2A পরিষেবা (
to_a2a) হিসেবে এজেন্টকে এক্সপোজ করা, এজেন্ট কার্ড (agent-card.json) প্রকাশ করা এবংRemoteA2aAgentব্যবহার করে রিমোট এজেন্ট ব্যবহার করা। - মাল্টি-এজেন্ট আর্কিটেকচার: ডিস্ট্রিবিউটেড রিমোট এজেন্টের (
currency_agent) সাথে লোকাল ইন-প্রসেস সাবএজেন্ট (weather_agent) একত্রিত করা হয়েছে। - Cloud Run সার্ভারলেস ডিপ্লয়মেন্ট: অটোমেটিক কনফিগারেশন ওয়্যারিংয়ের মাধ্যমে তিনটি পরিষেবাই কন্টেনারাইজ ও ডিপ্লয় করা হয়েছে।
সম্পূর্ণ কোড (Python এবং Java ইমপ্লিমেন্টেশন সহ) এবং ভবিষ্যতের আপডেটের জন্য, getting-started-mcp-a2a-adk রিপোজিটরি দেখুন।
অপ্রয়োজনীয়গুলি মুছুন
এই কোডল্যাবে তৈরি করা Cloud Run পরিষেবার জন্য আপনার Google Cloud অ্যাকাউন্টে চার্জ এড়াতে:
ডিপ্লয় করা Cloud Run পরিষেবা মুছে দিন:
gcloud run services delete currency-mcp-server --region $REGION --quiet
gcloud run services delete currency-agent --region $REGION --quiet
gcloud run services delete travel-agent --region $REGION --quiet
অন্যথায়, আপনি যদি এই কোডল্যাবের জন্য কোনও নির্দিষ্ট প্রোজেক্ট তৈরি করে থাকেন, তাহলে আপনি পুরো প্রোজেক্টটি বন্ধ করে দিতে পারেন:
gcloud projects delete $PROJECT_ID