Bu codelab hakkında
1. Genel Bakış
Yapay zeka temsilcileri, bağımsız olarak çalışabilme, öğrenme ve hedeflere ulaşmak için çevreleriyle etkileşim kurma becerileri sayesinde görev otomasyonunda ve karar alma süreçlerinde devrim yaratarak popülerliklerini hızla artırıyor.
Peki bir aracı tam olarak nasıl oluştururuz? Bu codelab, farklı ülkelerin para birimleri arasında dönüşüm yapabilen bir para birimi aracısı oluşturmayı göstererek başlamanıza yardımcı olacaktır. İnternette gördüğünüz kısaltmaları (MCP, ADK, A2A) anlamanıza yardımcı olmak için en son teknolojileri açıklıyoruz.
Model Context Protocol (MCP)
Model Context Protocol (MCP), uygulamaların LLM'lere bağlam sağlama şeklini standartlaştıran açık bir protokoldür. MCP, yapay zeka modellerini kaynaklara, istemlere ve araçlara bağlamak için standart bir yöntem sunar.
Agent Development Kit (ADK)
Agent Development Kit (ADK), yapay zeka aracı geliştirme ve dağıtma için esnek bir düzenleme çerçevesidir. ADK, modele ve dağıtıma bağlı değildir ve diğer çerçevelerle uyumlu olacak şekilde tasarlanmıştır. ADK, geliştiricilerin basit görevlerden karmaşık iş akışlarına kadar değişen aralıklarda, yazılım geliştirmeye benzer bir şekilde, kolayca aracı mimarileri oluşturup dağıtmasına ve düzenlemesine olanak tanımak için tasarlanmıştır.
Agent2Agent (A2A) Protocol
Agent2Agent (A2A) Protokolü, yapay zeka temsilcileri arasında sorunsuz iletişim ve işbirliği sağlamak için tasarlanmış açık bir standarttır. MCP, LLM'lerin verilere ve araçlara erişmesi için standart bir yöntem sağlarken A2A, aracıların diğer aracılarla konuşması için standart bir yöntem sağlar. A2A, farklı satıcılar tarafından çeşitli çerçeveler kullanılarak oluşturulan aracıların bulunduğu bir dünyada ortak bir dil sunarak bilgi silolarını ortadan kaldırır ve birlikte çalışabilirliği teşvik eder.
Neler öğreneceksiniz?
- Yerel MCP sunucusu oluşturma
- MCP sunucusunu Cloud Run'a dağıtma
- MCP araçlarını kullanan bir aracı, Agent Development Kit ile oluşturma
- ADK aracısını A2A sunucusu olarak kullanıma sunma
- A2A istemcisini kullanarak A2A sunucusunu test etme
İhtiyacınız olanlar
2. Başlamadan önce
Proje oluşturma
- Google Cloud Console'daki proje seçici sayfasında bir Google Cloud projesi seçin veya oluşturun.
- Cloud projeniz için faturalandırmanın etkinleştirildiğinden emin olun. Faturalandırmanın bir projede etkin olup olmadığını kontrol etmeyi öğrenin.
- Bu bağlantıyı tıklayarak Cloud Shell'i etkinleştirin. Cloud Shell'deki ilgili düğmeyi tıklayarak Cloud Shell Terminali (bulut komutlarını çalıştırmak için) ve Düzenleyici (projeleri oluşturmak için) arasında geçiş yapabilirsiniz.
- Cloud Shell'e bağlandıktan sonra aşağıdaki komutu kullanarak kimliğinizin doğrulanıp doğrulanmadığını ve projenin proje kimliğinize ayarlanıp ayarlanmadığını kontrol edin:
gcloud auth list
- gcloud komutunun projeniz hakkında bilgi sahibi olduğunu doğrulamak için Cloud Shell'de aşağıdaki komutu çalıştırın.
gcloud config list project
- Projenizi ayarlamak için aşağıdaki komutu kullanın:
export PROJECT_ID=<YOUR_PROJECT_ID>
gcloud config set project $PROJECT_ID
- Aşağıdaki komutu kullanarak gerekli API'leri etkinleştirin. Bu işlem birkaç dakika sürebilir.
gcloud services enable cloudresourcemanager.googleapis.com \
servicenetworking.googleapis.com \
run.googleapis.com \
cloudbuild.googleapis.com \
artifactregistry.googleapis.com \
aiplatform.googleapis.com \
compute.googleapis.com
- Python 3.10 veya sonraki bir sürümün yüklü olduğundan emin olun.
gcloud komutları ve kullanımı için belgelere bakın.
3. Kurulum
- Kod deposunu klonlayın:
git clone https://github.com/jackwotherspoon/currency-agent.git
cd currency-agent
- uv'yi (bağımlılıkları yönetmek için kullanılır) yükleyin:
# macOS and Linux
curl -LsSf https://astral.sh/uv/install.sh | sh
# Windows (uncomment below line)
# powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
- Ortam değişkenlerini yapılandırma (
.env
dosyası aracılığıyla):
Aşağıdaki komutu çalıştırarak bir .env
dosyası oluşturun:
echo "GOOGLE_GENAI_USE_VERTEXAI=TRUE" >> .env \
&& echo "GOOGLE_CLOUD_PROJECT=$PROJECT_ID" >> .env \
&& echo "GOOGLE_CLOUD_LOCATION=us-central1" >> .env
4. Yerel bir MCP sunucusu oluşturma
Para birimi temsilcinizi düzenlemeye başlamadan önce, temsilcinizin ihtiyaç duyacağı araçlarınızı kullanıma sunmak için bir MCP sunucusu oluşturursunuz.
MCP sunucusu, belirli özellikleri (ör. döviz kuru getirme) araç olarak kullanıma sunmak için basit programlar yazmanıza olanak tanır. Bir veya daha fazla temsilci, standartlaştırılmış Model Context Protocol'ü (MCP) kullanarak bu araçlara erişebilir.
FastMCP Python paketi, get_exchange_rate
adlı tek bir aracı kullanıma sunan bir MCP sunucusu oluşturmak için kullanılabilir. get_exchange_rate
aracı, iki para birimi arasındaki mevcut döviz kurunu almak için internet üzerinden Frankfurter API'ye çağrı yapar.
MCP sunucusunun kodu mcp-server/server.py
dosyasında bulunabilir:
import logging
import os
import httpx
from fastmcp import FastMCP
# Set up logging
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.app/{currency_date}',
params={'from': currency_from, 'to': currency_to},
)
response.raise_for_status()
data = response.json()
if 'rates' not in data:
return {'error': 'Invalid API response format.'}
logger.info(f'✅ API response: {data}')
return data
except httpx.HTTPError as e:
return {'error': f'API request failed: {e}'}
except ValueError:
return {'error': 'Invalid JSON response from API.'}
if __name__ == "__main__":
logger.info(f"🚀 MCP server started on port {os.getenv('PORT', 8080)}")
# Could also use 'sse' transport, host="0.0.0.0" required for Cloud Run.
asyncio.run(
mcp.run_async(
transport="streamable-http",
host="0.0.0.0",
port=os.getenv("PORT", 8080),
)
)
MCP sunucusunu yerel olarak başlatmak için bir terminal açın ve aşağıdaki komutu çalıştırın (sunucu http://localhost:8080
üzerinde başlatılır):
uv run mcp-server/server.py
MCP sunucusunun düzgün çalıştığını ve get_exchange_rate
aracına Model Context Protocol kullanılarak erişilebildiğini test edin.
Yeni bir terminal penceresinde (böylece yerel MCP sunucusunu durdurmazsınız) aşağıdakileri çalıştırın:
uv run mcp-server/test_server.py
1 ABD dolarının avro cinsinden güncel döviz kurunu gösteren bir çıktı görmeniz gerekir:
--- 🛠️ Tool found: get_exchange_rate ---
--- 🪛 Calling get_exchange_rate tool for USD to EUR ---
--- ✅ Success: {
"amount": 1.0,
"base": "USD",
"date": "2025-05-26",
"rates": {
"EUR": 0.87866
}
} ---
Mükemmel! Aracınızın erişebileceği bir araçla çalışan bir MCP sunucunuz var.
Bir sonraki istasyona geçmeden önce, başlattığınız terminalde Ctrl+C
(veya Mac'te Command+C
) komutunu çalıştırarak yerel olarak çalışan MCP sunucusunu durdurun.
5. MCP sunucunuzu Cloud Run'a dağıtma
Artık MCP sunucusunu Cloud Run'a uzaktan MCP sunucusu olarak dağıtmaya hazırsınız 🚀☁️
MCP sunucusunu uzaktan çalıştırmanın avantajları
Cloud Run'da uzaktan bir MCP sunucusu çalıştırmanın çeşitli avantajları vardır:
- 📈Ölçeklenebilirlik: Cloud Run, gelen tüm istekleri karşılamak için hızlı bir şekilde ölçeklenecek şekilde tasarlanmıştır. Cloud Run, MCP sunucunuzu talebe göre otomatik olarak ölçeklendirir.
- 👥Merkezi sunucu: Merkezi bir MCP sunucusuna erişimi IAM ayrıcalıkları aracılığıyla ekip üyeleriyle paylaşabilirsiniz. Böylece ekip üyeleri, kendi sunucularını yerel olarak çalıştırmak yerine yerel makinelerinden sunucuya bağlanabilir. MCP sunucusunda yapılan değişikliklerden tüm ekip üyeleri yararlanır.
- 🔐Güvenlik: Cloud Run, kimliği doğrulanmış istekleri zorunlu kılmanın kolay bir yolunu sunar. Bu, MCP sunucunuza yalnızca güvenli bağlantıların yapılmasına izin vererek yetkisiz erişimi önler.
mcp-server
dizinine geçin:
cd mcp-server
MCP sunucusunu Cloud Run'a dağıtın:
gcloud run deploy mcp-server --no-allow-unauthenticated --region=us-central1 --source .
Hizmetiniz başarıyla dağıtıldıysa aşağıdakine benzer bir mesaj görürsünüz:
Service [mcp-server] revision [mcp-server-12345-abc] has been deployed and is serving 100 percent of traffic.
MCP İstemcilerinin Kimliğini Doğrulama
Kimlik doğrulama gerektirmek için --no-allow-unauthenticated
seçeneğini belirlediğinizden, uzak MCP sunucusuna bağlanan tüm MCP istemcilerinin kimlik doğrulaması yapması gerekir.
Host MCP servers on Cloud Run (MCP sunucularını Cloud Run'da barındırma) başlıklı resmi belgelerde, MCP istemcinizi nerede çalıştırdığınıza bağlı olarak bu konuyla ilgili daha fazla bilgi verilmektedir.
Yerel makinenizde uzak MCP sunucusuna kimliği doğrulanmış bir tünel oluşturmak için Cloud Run proxy'sini çalıştırmanız gerekir.
Varsayılan olarak, Cloud Run hizmetlerinin URL'si için tüm isteklerin Cloud Run Çağırıcı (roles/run.invoker
) IAM rolüyle yetkilendirilmesi gerekir. Bu IAM politika bağlaması, yerel MCP istemcinizin kimliğini doğrulamak için güçlü bir güvenlik mekanizması kullanılmasını sağlar.
Sizin veya uzak MCP sunucusuna erişmeye çalışan ekip üyelerinin, IAM asıl üyelerine (Google Cloud Hesabı) bağlı roles/run.invoker
IAM rolüne sahip olduğundan emin olmanız gerekir.
gcloud run services proxy mcp-server --region=us-central1
Aşağıdaki çıkışı göreceksiniz:
Proxying to Cloud Run service [mcp-server] in project [<YOUR_PROJECT_ID>] region [us-central1]
http://127.0.0.1:8080 proxies to https://mcp-server-abcdefgh-uc.a.run.app
http://127.0.0.1:8080
adresine giden tüm trafik artık doğrulanacak ve uzak MCP sunucusuna yönlendirilecek.
Uzak MCP sunucusunu test etme
Yeni bir terminalde kök klasöre geri dönün ve uzak MCP sunucusunun çalıştığından emin olmak için mcp-server/test_server.py
dosyasını yeniden çalıştırın.
cd ..
uv run mcp-server/test_server.py
Sunucuyu yerel olarak çalıştırırken gördüğünüz çıkışa benzer bir çıkış görmeniz gerekir:
--- 🛠️ Tool found: get_exchange_rate ---
--- 🪛 Calling get_exchange_rate tool for USD to EUR ---
--- ✅ Success: {
"amount": 1.0,
"base": "USD",
"date": "2025-05-26",
"rates": {
"EUR": 0.87866
}
} ---
Uzak sunucunun gerçekten çağrıldığını doğrulamak istiyorsanız dağıtılan Cloud Run MCP sunucusunun günlüklerini sorgulayabilirsiniz:
gcloud run services logs read mcp-server --region us-central1 --limit 5
Günlüklerde aşağıdaki çıkışı görmeniz gerekir:
2025-06-04 14:28:29,871 [INFO]: --- 🛠️ Tool: get_exchange_rate called for converting USD to EUR ---
2025-06-04 14:28:30,610 [INFO]: HTTP Request: GET https://api.frankfurter.app/latest?from=USD&to=EUR "HTTP/1.1 200 OK"
2025-06-04 14:28:30,611 [INFO]: ✅ API response: {'amount': 1.0, 'base': 'USD', 'date': '2025-06-03', 'rates': {'EUR': 0.87827}}
Artık uzak bir MCP sunucunuz olduğuna göre aracı oluşturma işlemine geçebilirsiniz. 🤖
6. Aracı Geliştirme Kiti (ADK) ile aracı oluşturma
Dağıtılmış bir MCP sunucunuz var. Artık Agent Development Kit (ADK)'yi kullanarak para birimi aracısı oluşturmanın zamanı geldi.
Agent Development Kit kısa süre önce v1.0.0 kararlı sürümünü yayınladı. Bu dönüm noktası, Python ADK'nın artık üretime hazır olduğunu gösteriyor. Geliştiriciler, bu güvenilir ve sağlam platformda canlı ortamlarda güvenle aracı oluşturup dağıtabilir.
ADK, aracı oluşturmayı son derece kolaylaştırır ve MCP Araçları için yerleşik destek sayesinde aracıların MCP sunucularına kolayca bağlanmasına olanak tanır. Para birimi aracısı, ADK'nın MCPToolset sınıfını kullanarak get_exchange_rate
aracına erişir.
Para birimi aracısının kodu currency_agent/agent.py
konumundadır:
import logging
import os
from dotenv import load_dotenv
from google.adk.agents import LlmAgent
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."
)
def create_agent() -> LlmAgent:
"""Constructs the ADK currency conversion agent."""
logger.info("--- 🔧 Loading MCP tools from MCP Server... ---")
logger.info("--- 🤖 Creating ADK Currency Agent... ---")
return LlmAgent(
model="gemini-2.5-flash",
name="currency_agent",
description="An agent that can help with currency conversions",
instruction=SYSTEM_INSTRUCTION,
tools=[
MCPToolset(
connection_params=StreamableHTTPConnectionParams(
url=os.getenv("MCP_SERVER_URL", "http://localhost:8080/mcp")
)
)
],
)
root_agent = create_agent()
Para birimi aracını hızlıca test etmek için adk web
komutunu çalıştırarak erişebileceğiniz ADK'nın geliştirme kullanıcı arayüzünden yararlanabilirsiniz:
uv run adk web
Tarayıcıda http://localhost:8000
adresine giderek aracıya göz atın ve test edin.
Web kullanıcı arayüzünün sol üst köşesinde aracı olarak currency_agent
seçildiğinden emin olun.
Sohbet alanında temsilcinize "250 Kanada doları kaç ABD doları eder?" gibi bir soru sorun. Temsilcinin yanıt vermeden önce get_exchange_rate
MCP aracımızı aradığını görmelisiniz.
Temsilci çalışıyor. Para birimi dönüştürme 💸 ile ilgili sorguları işleyebilir.
7. Agent2Agent (A2A) Protocol
Agent2Agent (A2A) Protokolü, yapay zeka temsilcileri arasında sorunsuz iletişim ve işbirliği sağlamak için tasarlanmış açık bir standarttır. Bu sayede, farklı çerçeveler kullanılarak ve farklı satıcılar tarafından oluşturulan aracıların ortak bir dilde iletişim kurması sağlanır. Böylece, bilgi siloları ortadan kaldırılır ve birlikte çalışabilirlik teşvik edilir.
A2A, temsilcilerin şunları yapmasına olanak tanır:
- Keşfedin: Standartlaştırılmış Agent Cards'ı kullanarak diğer aracıları bulun ve becerilerini (AgentSkill) ve yeteneklerini (AgentCapabilities) öğrenin.
- İletişim: Mesaj ve verileri güvenli bir şekilde paylaşın.
- Ortak çalışma: Karmaşık hedeflere ulaşmak için görevleri devredin ve işlemleri koordine edin.
A2A protokolü, bu iletişimi kolaylaştırmak için "Aracı Kartları" gibi mekanizmalar kullanır. Bu kartlar, aracıların yeteneklerini ve bağlantı bilgilerini tanıtmak için kullanabileceği dijital kartvizitler olarak işlev görür.
Şimdi, diğer temsilciler ve istemciler tarafından çağrılabilmesi için A2A kullanarak para birimi temsilcisini kullanıma sunma zamanı.
A2A Python SDK
A2A Python SDK, yukarıda belirtilen kaynakların her biri için Pydantic modelleri sağlar: AgentSkill, AgentCapabilities ve AgentCard. Bu, A2A protokolüyle geliştirme ve entegrasyonu hızlandırmak için bir arayüz sağlar.
Bir AgentSkill
, döviz bürosunun get_exchange_rate
için bir aracı olduğunu diğer acentelere nasıl duyuracağınızdır:
# A2A Agent Skill definition
skill = AgentSkill(
id='get_exchange_rate',
name='Currency Exchange Rates Tool',
description='Helps with exchange values between various currencies',
tags=['currency conversion', 'currency exchange'],
examples=['What is exchange rate between USD and GBP?'],
)
Ardından, AgentCard
kapsamında, aracının becerileri ve yetenekleri, aracının işleyebileceği giriş ve çıkış modları gibi ek ayrıntılarla birlikte listelenir:
# A2A Agent Card definition
agent_card = AgentCard(
name='Currency Agent',
description='Helps with exchange rates for currencies',
url=f'http://{host}:{port}/',
version='1.0.0',
defaultInputModes=["text"],
defaultOutputModes=["text"],
capabilities=AgentCapabilities(streaming=True),
skills=[skill],
)
AgentExecutor arayüzü, A2A aracısının istekleri nasıl işlediği ve yanıtları/etkinlikleri nasıl oluşturduğuyla ilgili temel mantığı yönetir. A2A Python SDK, uygulamanız gereken soyut bir temel sınıf a2a.server.agent_execution.AgentExecutor
sağlar.
Artık para birimi aracısıyla her şeyi bir araya getirip A2A'nın gücünü gösterme zamanı!
8. Currency Agent A2A Server
Şimdi bazı kod parçalarına göz atacak ve A2A sunucusunu oluşturan farklı parçaların nasıl bir araya geldiğini göreceksiniz.
Dosyanın içine baktığınızda currency_agent/agent_executor.py
, A2A soyut AgentExecutor
sınıfından devralan ADKAgentExecutor
sınıfını görürsünüz. ADK çalıştırıcısını çağırarak ADK aracısını çağırma, aracıya yapılan istekleri işleme ve ADK'nın kullandığı google.genai.types
ile A2A'nın kullandığı a2a.types
arasında dönüştürme işlemlerini gerçekleştirir.
# ... see file for full code
class ADKAgentExecutor(AgentExecutor):
"""An AgentExecutor that runs an ADK agent."""
def __init__(self, runner: Runner, card: AgentCard):
self.runner = runner
self._card = card
self._running_sessions = {}
def _run_agent(
self, session_id, new_message: types.Content
) -> AsyncGenerator[Event, None]:
return self.runner.run_async(
session_id=session_id, user_id="self", new_message=new_message
)
async def _process_request(
self,
new_message: types.Content,
session_id: str,
task_updater: TaskUpdater,
) -> None:
session = await self._upsert_session(
session_id,
)
session_id = session.id
# Run through all events within the request.
async for event in self._run_agent(session_id, new_message):
if event.is_final_response():
parts = convert_genai_parts_to_a2a(event.content.parts)
logger.debug("✅ Yielding final response: %s", parts)
await task_updater.add_artifact(parts)
await task_updater.complete()
break
# If the agent is not making a function call, yield an update.
if not event.get_function_calls():
logger.debug("⏳ Yielding update response")
await task_updater.update_status(
TaskState.working,
message=task_updater.new_agent_message(
convert_genai_parts_to_a2a(event.content.parts),
),
)
else:
logger.debug("➡️ Skipping event")
async def execute(
self,
context: RequestContext,
event_queue: EventQueue,
):
# Run the agent until either complete or the task is suspended.
updater = TaskUpdater(event_queue, context.task_id, context.context_id)
# Immediately notify that the task is submitted.
if not context.current_task:
updater.submit()
updater.start_work()
await self._process_request(
types.UserContent(
parts=convert_a2a_parts_to_genai(context.message.parts),
),
context.context_id,
updater,
)
logger.debug("--- 💵💱💶 [Currency] execute exiting ---")
# ... see file for full code
currency_agent/__main__.py
içinde AgentSkill'i ve AgentCard'ı başlatır, ADK para birimi temsilcisini oluşturursunuz. A2A sunucusunu da burada kurup başlatırsınız.
A2A Python SDK'sı, A2A uyumlu bir HTTP sunucusunu çalıştırmayı kolaylaştıran bir A2AFastAPIApplication
sınıfı sağlar. Web çerçevesi için FastAPI'yi kullanır ve genellikle Uvicorn gibi bir ASGI sunucusuyla çalıştırılır.
# ... see file for full code
@click.command()
@click.option("--host", "host", default="localhost")
@click.option("--port", "port", default=10000)
def main(host: str, port: int):
# Verify one of Google AI Studio or Vertex AI is being used
if os.getenv("GOOGLE_GENAI_USE_VERTEXAI") != "TRUE" and not os.getenv(
"GOOGLE_API_KEY"
):
raise ValueError(
"GOOGLE_API_KEY environment variable not set and "
"GOOGLE_GENAI_USE_VERTEXAI is not TRUE."
)
# A2A Agent Skill definition
skill = AgentSkill(
id="get_exchange_rate",
name="Currency Exchange Rates Tool",
description="Helps with exchange values between various currencies",
tags=["currency conversion", "currency exchange"],
examples=["What is exchange rate between USD and GBP?"],
)
# A2A Agent Card definition
agent_card = AgentCard(
name="Currency Agent",
description="Helps with exchange rates for currencies",
url=f"http://{host}:{port}/",
version="1.0.0",
defaultInputModes=["text"],
defaultOutputModes=["text"],
capabilities=AgentCapabilities(streaming=True),
skills=[skill],
)
# Create the ADK runner and executor.
runner = Runner(
app_name=agent_card.name,
agent=root_agent,
artifact_service=InMemoryArtifactService(),
session_service=InMemorySessionService(),
memory_service=InMemoryMemoryService(),
)
agent_executor = ADKAgentExecutor(runner, agent_card)
request_handler = DefaultRequestHandler(
agent_executor=agent_executor,
task_store=InMemoryTaskStore(),
)
server = A2AFastAPIApplication(
agent_card=agent_card, http_handler=request_handler
)
uvicorn.run(server.build(), host=host, port=port)
# ... see file for full code
A2A sunucusunu çalıştırmak için yeni bir terminalde aşağıdakileri çalıştırın:
uv run currency_agent/
Sunucu başarıyla başlatılırsa çıkış, 10000 numaralı bağlantı noktasında çalıştığını belirtecek şekilde aşağıdaki gibi görünür:
[INFO]: --- 🔧 Loading MCP tools from MCP Server... ---
[INFO]: --- 🤖 Creating ADK Currency Agent... ---
INFO: Started server process [45824]
INFO: Waiting for application startup.
INFO: Application startup complete.
INFO: Uvicorn running on http://localhost:10000 (Press CTRL+C to quit)
Döviz temsilcisi artık A2A protokolü kullanılarak diğer temsilciler veya istemciler tarafından çağrılabilen bir A2A sunucusu olarak başarıyla çalışıyor.
A2A sunucusunu test etme
Artık A2A'yı kullanarak sunucuya bazı istekler göndererek sunucuyu test edebilirsiniz.
A2A Python SDK'sı, bu işlemi sizin için basitleştiren bir a2a.client.A2AClient
sınıfı sağlar.
currency_agent/test_client.py
dosyası, A2A sunucusuna karşı çeşitli farklı test senaryoları üzerinden çalışan kodu içerir.
# ... see file for full code
# Example test using A2AClient
async def run_single_turn_test(client: A2AClient) -> None:
"""Runs a single-turn non-streaming test."""
send_message_payload = create_send_message_payload(text="how much is 100 USD in CAD?")
request = SendMessageRequest(
id=str(uuid4()), params=MessageSendParams(**send_message_payload)
)
print("--- ✉️ Single Turn Request ---")
# Send Message
response: SendMessageResponse = await client.send_message(request)
print_json_response(response, "📥 Single Turn Request Response")
if not isinstance(response.root, SendMessageSuccessResponse):
print("received non-success response. Aborting get task ")
return
if not isinstance(response.root.result, Task):
print("received non-task response. Aborting get task ")
return
task_id: str = response.root.result.id
print("--- ❔ Query Task ---")
# query the task
get_request = GetTaskRequest(id=str(uuid4()), params=TaskQueryParams(id=task_id))
get_response: GetTaskResponse = await client.get_task(get_request)
print_json_response(get_response, "📥 Query Task Response")
# ----- Main Entrypoint (Create client --> Run tests) -----
async def main() -> None:
"""Main function to run the tests."""
print(f'--- 🔄 Connecting to agent at {AGENT_URL}... ---')
try:
async with httpx.AsyncClient() as httpx_client:
client = await A2AClient.get_client_from_agent_card_url(
httpx_client, AGENT_URL
)
print('--- ✅ Connection successful. ---')
await run_single_turn_test(client)
await run_streaming_test(client)
await run_multi_turn_test(client)
except Exception as e:
traceback.print_exc()
print(f'--- ❌ An error occurred: {e} ---')
print('Ensure the agent server is running.')
Aşağıdaki komutu kullanarak testleri çalıştırın:
uv run currency_agent/test_client.py
Başarılı bir test çalıştırması şu sonuçları verir:
--- 🔄 Connecting to agent at http://localhost:10000... ---
--- ✅ Connection successful. ---
--- ✉️ Single Turn Request ---
--- 📥 Single Turn Request Response ---
{"id":"3bc92d7b-d857-4e93-9ff0-b2fb865f6e35","jsonrpc":"2.0","result":{"artifacts":[{"artifactId":"35e89e14-b977-4397-a23b-92c84bc32379","parts":[{"kind":"text","text":"Based on the current exchange rate, 1 USD is equivalent to 1.3704 CAD. Therefore, 100 USD would be 137.04 CAD.\n"}]}],"contextId":"2d66f277-152c-46ef-881d-7fe32866e9f5","history":[{"contextId":"2d66f277-152c-46ef-881d-7fe32866e9f5","kind":"message","messageId":"59819269f7d04849b0bfca7d43ec073c","parts":[{"kind":"text","text":"how much is 100 USD in CAD?"}],"role":"user","taskId":"52ae2392-84f5-429a-a14b-8413d3d20d97"},{"contextId":"2d66f277-152c-46ef-881d-7fe32866e9f5","kind":"message","messageId":"286095c6-12c9-40cb-9596-a9676d570dbd","parts":[],"role":"agent","taskId":"52ae2392-84f5-429a-a14b-8413d3d20d97"}],"id":"52ae2392-84f5-429a-a14b-8413d3d20d97","kind":"task","status":{"state":"completed"}}}
// ...
--- ⏩ Single Turn Streaming Request ---
--- ⏳ Streaming Chunk ---
{"id":"21239a5f-abbf-4a5e-a249-c101eb1dfbdd","jsonrpc":"2.0","result":{"contextId":"f268ad8c-b3bf-4439-9a64-5e02dfbb9a62","final":false,"kind":"status-update","status":{"state":"submitted"},"taskId":"761d2275-d58b-46f8-9c8d-68cd72e0667d"}}
--- ⏳ Streaming Chunk ---
{"id":"21239a5f-abbf-4a5e-a249-c101eb1dfbdd","jsonrpc":"2.0","result":{"contextId":"f268ad8c-b3bf-4439-9a64-5e02dfbb9a62","final":false,"kind":"status-update","status":{"state":"working"},"taskId":"761d2275-d58b-46f8-9c8d-68cd72e0667d"}}
--- ⏳ Streaming Chunk ---
{"id":"21239a5f-abbf-4a5e-a249-c101eb1dfbdd","jsonrpc":"2.0","result":{"contextId":"f268ad8c-b3bf-4439-9a64-5e02dfbb9a62","final":false,"kind":"status-update","status":{"message":{"contextId":"f268ad8c-b3bf-4439-9a64-5e02dfbb9a62","kind":"message","messageId":"25f5f972-9475-4e4a-a08d-e13f521d7462","parts":[],"role":"agent","taskId":"761d2275-d58b-46f8-9c8d-68cd72e0667d"},"state":"working"},"taskId":"761d2275-d58b-46f8-9c8d-68cd72e0667d"}}
--- ⏳ Streaming Chunk ---
{"id":"21239a5f-abbf-4a5e-a249-c101eb1dfbdd","jsonrpc":"2.0","result":{"artifact":{"artifactId":"35e89e14-b977-4397-a23b-92c84bc32379","parts":[{"kind":"text","text":"The current exchange rate is 1 EUR to 164.15 JPY. So, 50 EUR would be 8207.5 JPY.\n"}]},"contextId":"f268ad8c-b3bf-4439-9a64-5e02dfbb9a62","kind":"artifact-update","taskId":"761d2275-d58b-46f8-9c8d-68cd72e0667d"}}
// ...
--- 🚀 First turn completed, no further input required for this test case. ---
Çalışıyor! Para birimi aracısıyla A2A sunucusu üzerinden iletişim kurabildiğinizi başarıyla test ettiniz. 🎉
Daha gelişmiş kullanım alanlarını görmek için GitHub'daki a2a-samples deposuna göz atın.
Aracınızı dağıtmak mı istiyorsunuz? Vertex AI Agent Engine, yapay zeka aracılarını üretime dağıtmak için yönetilen bir deneyim sunar.
9. Tebrikler
Tebrikler! Uzak bir MCP sunucusunu başarıyla oluşturup dağıttınız, MCP kullanarak araçlara bağlanan bir para birimi aracısı oluşturmak için Agent Development Kit'i (ADK) kullandınız ve aracınızı Agent2Agent (A2A) protokolünü kullanarak kullanıma sundunuz. Para birimi temsilcisi artık A2A kullanarak herhangi bir çerçevedeki diğer temsilcilerle etkileşim kurabilir.
Tam kod dokümanının bağlantısını burada bulabilirsiniz.
İşlediğimiz konular
- Yerel MCP sunucusu oluşturma
- MCP sunucusunu Cloud Run'a dağıtma
- MCP araçlarını kullanan bir aracı, Agent Development Kit ile oluşturma
- ADK aracısını A2A sunucusu olarak kullanıma sunma
- A2A istemcisini kullanarak A2A sunucusunu test etme
Temizleme
Bu laboratuvarda kullanılan kaynaklar için Google Cloud hesabınızın ücretlendirilmesini istemiyorsanız şu adımları uygulayın:
- Google Cloud Console'da Kaynakları yönetin sayfasına gidin.
- Proje listesinde silmek istediğiniz projeyi seçin ve Sil'i tıklayın.
- İletişim kutusunda proje kimliğini yazın ve projeyi silmek için Kapat'ı tıklayın.