بدء استخدام ميزتَي "إدارة العملاء المتعدّدين" و"إعلانات شبكة البحث" و"الإعلانات على شبكة البحث من Google"

1. نظرة عامة

تتزايد شعبية وكلاء الذكاء الاصطناعي بسرعة، إذ أحدثوا ثورة في أتمتة المهام واتخاذ القرارات بفضل قدرتهم على العمل بشكل مستقل والتعلم والتفاعل مع البيئة المحيطة بهم لتحقيق الأهداف.

ولكن كيف يمكن إنشاء وكيل؟ سيساعدك هذا الدرس التطبيقي حول الترميز في البدء من خلال توضيح كيفية إنشاء وكيل عملة يمكنه التحويل بين عملات البلدان المختلفة. بعد ذلك، ستنشئ وكيل وكالة سفر وتربطه بوكيل العملة. الهدف هو إرشادك إلى أحدث التقنيات لمساعدتك في فهم الاختصارات التي ربما رأيتها منتشرة على الإنترنت (MCP وADK وA2A) والتعرّف على كيفية عملها معًا.

الهندسة المعمارية

بروتوكول سياق النموذج (MCP)

بروتوكول سياق النموذج (MCP) هو بروتوكول مفتوح يوحّد طريقة تقديم التطبيقات للسياق إلى النماذج اللغوية الكبيرة. يوفّر بروتوكول سياق النموذج طريقة موحّدة لربط نماذج الذكاء الاصطناعي بالمراجع والطلبات والأدوات.

حزمة تطوير الوكلاء (ADK)

Agent Development Kit (ADK) هي إطار عمل مرن لتنظيم عملية تطوير وكلاء الذكاء الاصطناعي ونشرهم. لا يعتمد ADK على نموذج معيّن، ولا على عملية نشر معيّنة، وهو مصمّم ليتوافق مع أُطر العمل الأخرى. تم تصميم ADK لجعل عملية تطوير الوكلاء تبدو أقرب إلى تطوير البرامج، وذلك لتسهيل إنشاء ونشر وتنظيم البُنى القائمة على الذكاء الاصطناعي الوكيل التي تتراوح بين المهام البسيطة وسير العمل المعقّد.

بروتوكول Agent2Agent (A2A)

بروتوكول Agent2Agent (A2A) هو معيار مفتوح مصمّم لإتاحة التواصل والتعاون السلسَين بين وكلاء الذكاء الاصطناعي. تمامًا مثلما توفّر MCP طريقة موحّدة لمنح نماذج اللغات الكبيرة إذن الوصول إلى البيانات والأدوات، توفّر A2A طريقة موحّدة للوكلاء للتواصل مع وكلاء آخرين. في عالم يتم فيه إنشاء الوكلاء باستخدام أُطر متنوعة ومن قِبل مورّدين مختلفين، يوفّر A2A لغة مشتركة، ما يؤدي إلى إزالة الحواجز وتعزيز قابلية التشغيل التفاعلي.

أهداف الدورة التعليمية

  • كيفية إنشاء خادم MCP محلي
  • نشر خادم MCP على Cloud Run
  • كيفية إنشاء وكيل باستخدام حزمة Agent Development Kit التي تستخدم أدوات MCP
  • كيفية إتاحة وكيل ADK كخادم A2A
  • اختبار خادم A2A باستخدام عميل A2A
  • كيفية إنشاء وكيل للتواصل مع وكيل آخر باستخدام بروتوكول A2A

المتطلبات

  • متصفّح، مثل Chrome أو Firefox
  • مشروع Google Cloud تم تفعيل الفوترة فيه

2. قبل البدء

إنشاء مشروع

إذا لم يكن لديك مشروع على Google Cloud، أنشِئ مشروعًا.

في Google Cloud Console، في صفحة اختيار المشروع، اختَر مشروعًا على Google Cloud أو أنشِئ مشروعًا.

تأكَّد أيضًا من تفعيل الفوترة لمشروعك على السحابة الإلكترونية. كيفية التحقّق من تفعيل الفوترة في مشروع

تفعيل Cloud Shell

‫Google Cloud Shell هي بيئة تطوير تفاعلية مستندة إلى المتصفح يتم توفيرها مباشرةً في Google Cloud Console. إنّها أسهل طريقة لبدء استخدام Google Cloud بدون الحاجة إلى تثبيت الأدوات على الجهاز.

فعِّل Cloud Shell من خلال النقر على هذا الرابط. يمكنك التبديل بين "نافذة Cloud Shell" (لتنفيذ أوامر السحابة الإلكترونية) و"المحرّر" (لإنشاء المشاريع) من خلال النقر على الزر المناسب من Cloud Shell.

بعد الاتصال بـ Cloud Shell، يمكنك التأكّد من إكمال عملية المصادقة وأنّ المشروع مضبوط على رقم تعريف مشروعك باستخدام الأمر التالي:

gcloud auth list

نفِّذ الأمر التالي في Cloud Shell للتأكّد من أنّ أمر gcloud يعرف مشروعك.

gcloud config list project

استخدِم الأمر التالي لضبط مشروعك:

export PROJECT_ID=<YOUR_PROJECT_ID>
gcloud config set project $PROJECT_ID

تفعيل واجهات Cloud API

فعِّل واجهات برمجة التطبيقات المطلوبة باستخدام الأمر التالي. قد يستغرق هذا بضع دقائق.

gcloud services enable cloudresourcemanager.googleapis.com \
                       servicenetworking.googleapis.com \
                       run.googleapis.com \
                       cloudbuild.googleapis.com \
                       artifactregistry.googleapis.com \
                       aiplatform.googleapis.com \
                       compute.googleapis.com

يمكنك الرجوع إلى المستندات لمعرفة أوامر gcloud وطريقة استخدامها.

الحصول على الشفرة‏

استنسِخ المستودع:

git clone https://github.com/jackwotherspoon/currency-agent.git
cd currency-agent

يتم استخدام uv لإدارة الاعتماديات، وهو مثبَّت مسبقًا في Cloud Shell، ولكن إذا كنت تنفّذ الدرس التطبيقي حول الترميز على جهازك، يمكنك تثبيته على النحو التالي:

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

اضبط متغيّرات البيئة باستخدام ملف .env من خلال تنفيذ ما يلي:

echo "GOOGLE_GENAI_USE_ENTERPRISE=TRUE" >> .env \
&& echo "GOOGLE_CLOUD_PROJECT=$PROJECT_ID" >> .env \
&& echo "GOOGLE_CLOUD_LOCATION=global" >> .env

3- إنشاء خادم MCP محلي

قبل البدء في تنسيق وكيل العملة، عليك أولاً إنشاء خادم MCP لعرض الأدوات التي يحتاجها الوكيل.

يتيح لك خادم MCP كتابة برامج بسيطة لعرض إمكانات معيّنة (مثل استرداد أسعار صرف العملات) كأدوات. يمكن لوكيل واحد أو حتى عدة وكلاء الوصول إلى هذه الأدوات باستخدام بروتوكول سياق النموذج (MCP) الموحّد.

يمكن الاستفادة من حزمة FastMCP Python لإنشاء خادم MCP يعرض أداة واحدة باسم get_exchange_rate. تُجري أداة get_exchange_rate طلبًا عبر الإنترنت إلى Frankfurter API للحصول على سعر الصرف الحالي بين عملتَين.

يمكن العثور على رمز خادم MCP في الملف mcp-server/server.py:

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="http",
            host="0.0.0.0",
            port=os.getenv("PORT", 8080),
        )
    )

لبدء تشغيل خادم MCP محليًا، افتح وحدة طرفية ونفِّذ الأمر التالي (سيتم بدء تشغيل الخادم على http://localhost:8080):

uv run mcp-server/server.py

اختبِر ما إذا كان خادم MCP يعمل بشكل صحيح وما إذا كان يمكن الوصول إلى أداة get_exchange_rate باستخدام بروتوكول سياق النموذج.

في نافذة وحدة طرفية جديدة (حتى لا توقف خادم MCP المحلي)، شغِّل ما يلي:

uv run mcp-server/test_server.py

من المفترض أن يظهر لك سعر الصرف الحالي لدولار أمريكي واحد مقابل اليورو:

--- 🛠️ 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
  }
} ---

رائع! لديك خادم MCP يعمل بشكل سليم ويتضمّن أداة يمكن أن يصل إليها الوكيل.

قبل الانتقال إلى المحطة التالية، أوقِف خادم MCP الذي يتم تشغيله محليًا عن طريق تنفيذ Ctrl+C (أو Command+C على جهاز Mac) في الوحدة الطرفية التي بدأت تشغيله فيها.

4. نشر خادم MCP على Cloud Run

أنت الآن على استعداد لنشر خادم MCP كخادم MCP بعيد على Cloud Run 🚀☁️

مزايا تشغيل خادم MCP عن بُعد

يمكن أن يوفّر تشغيل خادم MCP عن بُعد على Cloud Run العديد من المزايا:

  • 📈قابلية التوسّع: تم تصميم Cloud Run للتوسّع بسرعة من أجل التعامل مع جميع الطلبات الواردة. ستوسّع خدمة Cloud Run نطاق خادم MCP تلقائيًا استنادًا إلى الطلب.
  • 👥الخادم المركزي: يمكنك مشاركة إذن الوصول إلى خادم MCP مركزي مع أعضاء الفريق من خلال أذونات IAM، ما يتيح لهم الاتصال به من أجهزتهم المحلية بدلاً من تشغيل جميع الخوادم الخاصة بهم محليًا. في حال إجراء تغيير على خادم MCP، سيستفيد منه جميع أعضاء الفريق.
  • 🔐الأمان: توفّر Cloud Run طريقة سهلة لفرض طلبات مصادقة. يسمح ذلك فقط بالاتصالات الآمنة بخادم MCP، ما يمنع الوصول غير المصرَّح به.

انتقِل إلى الدليل mcp-server:

cd mcp-server

نشِّر خادم MCP على Cloud Run:

gcloud run deploy mcp-server --no-allow-unauthenticated --region=us-central1 --source .

إذا تم نشر خدمتك بنجاح، ستظهر لك رسالة مثل ما يلي:

Service [mcp-server] revision [mcp-server-12345-abc] has been deployed and is serving 100 percent of traffic.

مصادقة برامج MCP

بما أنّك حدّدت --no-allow-unauthenticated لطلب المصادقة، سيحتاج أي برنامج MCP يتصل بخادم MCP عن بُعد إلى المصادقة.

تقدّم المستندات الرسمية حول استضافة خوادم MCP على Cloud Run المزيد من المعلومات حول هذا الموضوع استنادًا إلى المكان الذي يتم فيه تشغيل عميل MCP.

عليك تشغيل خادم وكيل Cloud Run لإنشاء نفق مصادق عليه إلى خادم MCP البعيد على جهازك المحلي.

بشكلٍ تلقائي، يتطلّب عنوان URL لخدمات Cloud Run أن يتمّ تفويض جميع الطلبات باستخدام دور مستدعي Cloud Run (roles/run.invoker) في "إدارة الهوية وإمكانية الوصول" (IAM). يضمن ربط سياسة إدارة الهوية وإمكانية الوصول (IAM) هذا استخدام آلية أمان قوية لمصادقة برنامج MCP المحلي.

عليك التأكّد من أنّك أو أيّ من أعضاء الفريق الذين يحاولون الوصول إلى خادم MCP البعيد لديهم roles/run.invoker دور إدارة الهوية وإمكانية الوصول (IAM) المرتبط بكيان IAM الأساسي (حساب Google Cloud).

gcloud run services proxy mcp-server --region=us-central1

من المفترض أن يظهر لك الناتج التالي:

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 وإعادة توجيهها إلى خادم MCP البعيد.

اختبار خادم MCP البعيد

في نافذة طرفية جديدة، ارجع إلى المجلد الجذر وأعِد تشغيل الملف mcp-server/test_server.py للتأكّد من أنّ خادم MCP البعيد يعمل.

cd ..
uv run mcp-server/test_server.py

من المفترض أن تظهر لك نتيجة مشابهة لتلك التي ظهرت عند تشغيل الخادم محليًا:

--- 🛠️ 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
  }
} ---

يمكنك طلب البحث في سجلات خادم MCP الذي تم نشره على Cloud Run إذا أردت التأكّد من أنّه تم بالفعل استدعاء الخادم البعيد:

gcloud run services logs read mcp-server --region us-central1 --limit 5

من المفترض أن يظهر لك الناتج التالي في السجلات:

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

بعد إعداد خادم MCP بعيد، يمكنك الانتقال إلى إنشاء وكيل. 🤖

5- إنشاء وكيل باستخدام ADK

بعد نشر خادم MCP، حان الوقت لإنشاء وكيل العملة باستخدام حزمة تطوير الوكلاء (ADK).

تسهّل "حزمة تطوير التطبيقات" إنشاء وكلاء خفيفي الوزن للغاية وتسمح لهم بالاتصال بخوادم MCP مع توفير دعم مدمج لأدوات MCP. سيصل وكيل العملة إلى أداة get_exchange_rate باستخدام فئة MCPToolset في حزمة تطوير الوكلاء (ADK).

يمكن العثور على رمز وكيل العملة في currency_agent/agent.py:

import logging
import os

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

logger.info("--- 🔧 Loading MCP tools from MCP Server... ---")
logger.info("--- 🤖 Creating ADK Currency Agent... ---")

root_agent = LlmAgent(
    model="gemini-3.7-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")
            )
        )
    ],
)

لاختبار وكيل العملة بسرعة، يمكنك الاستفادة من واجهة المستخدم المخصّصة للمطوّرين في "حزمة تطوير التطبيقات"، والتي يمكن الوصول إليها من خلال تنفيذ adk web:

uv run adk web --allow_origins "regex:https://.*\.cloudshell\.dev"

في المتصفّح، انتقِل إلى http://localhost:8000 للاطّلاع على الوكيل واختباره.

تأكَّد من اختيار currency_agent كبرنامج في أعلى يمين واجهة المستخدم على الويب.

واجهة مستخدم ADK على الويب

اطرح على الوكيل في مساحة المحادثة سؤالاً مثل "ما هو سعر 250 دولار كندي بالدولار الأمريكي؟". من المفترض أن ترى الموظف يتصل بأداة get_exchange_rate MCP قبل أن تقدّم الأداة ردًا.

ADK Web Currency Agent

يعمل الوكيل بشكل صحيح. يمكنه التعامل مع طلبات البحث التي تدور حول تحويل العملات 💸.

6. بروتوكول Agent2Agent (A2A)

بروتوكول Agent2Agent (A2A) هو معيار مفتوح مصمّم لإتاحة التواصل والتعاون السلسَين بين وكلاء الذكاء الاصطناعي. يتيح ذلك للوكلاء الذين تم إنشاؤهم باستخدام أُطر متنوعة ومن قِبل مورّدين مختلفين التواصل مع بعضهم البعض بلغة مشتركة، ما يؤدي إلى إزالة الحواجز وتعزيز إمكانية التشغيل التفاعلي.

بروتوكول A2A

تتيح واجهة برمجة التطبيقات A2A للوكلاء ما يلي:

  • الاستكشاف: يمكنك العثور على وكلاء آخرين والتعرّف على مهاراتهم (AgentSkill) وإمكاناتهم (AgentCapabilities) باستخدام بطاقات الوكيل الموحّدة.
  • التواصل: تبادُل الرسائل والبيانات بأمان
  • التعاون: تفويض المهام وتنسيق الإجراءات لتحقيق أهداف معقّدة

يسهّل بروتوكول A2A عملية التواصل هذه من خلال آليات مثل "بطاقات الوكيل" التي تعمل كبطاقات أعمال رقمية يمكن للوكلاء استخدامها للإعلان عن إمكاناتهم ومعلومات الاتصال الخاصة بهم.

بطاقة وكيل A2A

حان الوقت الآن لعرض وكيل العملة باستخدام A2A حتى تتمكّن البرامج الوكيلة والعملاء الآخرون من استدعائه.

A2A Python SDK

توفّر حزمة تطوير البرامج (SDK) من A2A بلغة Python نماذج Pydantic لكل مورد من الموارد المذكورة أعلاه، وهي AgentSkill وAgentCapabilities وAgentCard. يوفر ذلك واجهة لتسريع عملية التطوير والتكامل مع بروتوكول A2A.

AgentSkill هي الطريقة التي ستعلن بها للوكلاء الآخرين أنّ وكيل العملة لديه أداة get_exchange_rate:

# 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?'],
)

بعد ذلك، سيتم إدراج مهارات الوكيل وقدراته ضمن AgentCard إلى جانب تفاصيل إضافية، مثل أوضاع الإدخال والإخراج التي يمكن للوكيل التعامل معها:

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

حان الوقت لربط كل ذلك مع وكيل العملة وعرض قوة A2A!

7. السماح بالوصول إلى "وكيل العملة" كخادم A2A

تسهّل حزمة تطوير التطبيقات (ADK) عملية إنشاء الوكلاء وربطهم باستخدام بروتوكول A2A. يمكن إتاحة (عرض) وكيل ADK حالي كـ خادم A2A باستخدام الدالة to_a2a(root_agent) في ADK (راجِع مستندات ADK للحصول على التفاصيل الكاملة).

تحوّل الدالة to_a2a وكيلًا حاليًا للعمل مع A2A، وتتيح إمكانية عرضه كخادم من خلال uvicorn. وهذا يعني أنّه يمكنك التحكّم بشكل أكبر في ما تريد عرضه إذا كنت تخطّط لطرح وكيلك في مرحلة الإنتاج. تنشئ الدالة to_a2a() تلقائيًا بطاقة وكيل استنادًا إلى رمز الوكيل باستخدام حزمة تطوير البرامج (SDK) للغة Python من A2A في الخلفية.

إذا ألقيت نظرة داخل الملف currency_agent/agent.py، يمكنك الاطّلاع على استخدام to_a2a وكيفية عرض وكيل العملة كخادم A2A باستخدام سطرين فقط من الرمز البرمجي.

from google.adk.a2a.utils.agent_to_a2a import to_a2a
# ... see file for full code

# Make the agent A2A-compatible
a2a_app = to_a2a(root_agent, port=10000)

لتشغيل خادم A2A، نفِّذ ما يلي في وحدة طرفية جديدة:

uv run uvicorn currency_agent.agent:a2a_app --host localhost --port 10000

في حال بدء تشغيل الخادم بنجاح، ستظهر النتيجة على النحو التالي، ما يشير إلى أنّه يعمل على المنفذ 10000:

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

يعمل الآن وكيل العملة بنجاح كخادم A2A، مع إمكانية استدعائه من قِبل وكلاء أو عملاء آخرين باستخدام بروتوكول A2A.

التحقّق من تشغيل Remote Agent

يمكنك التأكّد من أنّ الوكيل يعمل بشكل صحيح من خلال الانتقال إلى عنوان URL الخاص ببطاقة الوكيل لعملة تم إنشاؤها تلقائيًا باستخدام وظيفة to_a2a().

في المتصفّح، انتقِل إلى http://localhost:10000/.well-known/agent-card.json

من المفترض أن تظهر لك بطاقة الوكيل التالية:

{
  "capabilities": {

  },
  "defaultInputModes": [
    "text/plain"
  ],
  "defaultOutputModes": [
    "text/plain"
  ],
  "description": "An agent that can help with currency conversions",
  "name": "currency_agent",
  "preferredTransport": "JSONRPC",
  "protocolVersion": "0.3.0",
  "skills": [
    {
      "description": "An agent that can help with currency conversions I am a specialized assistant for currency conversions. my 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 I 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.",
      "id": "currency_agent",
      "name": "model",
      "tags": [
        "llm"
      ]
    },
    {
      "description": "Use this to get current exchange rate.\n\nArgs:\n    currency_from: The currency to convert from (e.g., \"USD\").\n    currency_to: The currency to convert to (e.g., \"EUR\").\n    currency_date: The date for the exchange rate or \"latest\". Defaults to \"latest\".\n\nReturns:\n    A dictionary containing the exchange rate data, or an error message if the request fails.",
      "id": "currency_agent-get_exchange_rate",
      "name": "get_exchange_rate",
      "tags": [
        "llm",
        "tools"
      ]
    }
  ],
  "supportsAuthenticatedExtendedCard": false,
  "url": "http://localhost:10000",
  "version": "0.0.1"
}

اختبار خادم A2A

يمكنك الآن اختبار الخادم عن طريق إرسال بعض الطلبات إليه باستخدام A2A.

توفّر حزمة تطوير البرامج (SDK) الخاصة بميزة "التطبيقات إلى التطبيقات" في Python فئة a2a.client.Client تسهّل عليك هذه العملية.

يحتوي الملف currency_agent/test_a2aclient.py على رمز برمجي يوضّح كيفية جلب بطاقة الوكيل وإرسال رسالة إلى خادم A2A.

# ... see file for full code

async def get_agent_card():
    """Get the agent card."""
    print(f"🔄 Fetching the agent card at {AGENT_URL}")

    async with httpx.AsyncClient() as httpx_client:
        resolver = A2ACardResolver(
            httpx_client=httpx_client,
            base_url=AGENT_URL,
        )
        public_agent_card = await resolver.get_agent_card()
        print("✅ Successfully fetched the agent card")
    return public_agent_card


async def send_message(text_query: str) -> None:
    """
    Send a text query to the agent and print the response.
    """
    public_agent_card = await get_agent_card()

    print("🔄 Initializing a non-streaming client")
    config = ClientConfig(streaming=False)
    client = await create_client(agent=public_agent_card, client_config=config)

    message = new_text_message(text_query, role=Role.ROLE_USER)
    print("Sending request:")
    request = SendMessageRequest(message=message)
    print(request)

    print("Response:")
    async for chunk in client.send_message(request):
        print(chunk)
    await client.close()

شغِّل الاختبارات باستخدام الأمر التالي:

uv run currency_agent/test_a2aclient.py

سيؤدي التشغيل التجريبي الناجح إلى ما يلي:

🔄 Fetching the agent card at http://localhost:10000
 Successfully fetched the agent card
====================================================
                     AgentCard                      
====================================================
--- General ---
Name        : currency_agent
Description : An agent that can help with currency conversions
Version     : 0.0.1

--- Interfaces ---
  [0] http://localhost:10000  (JSONRPC 1.0)

--- Capabilities ---
Streaming           : False
Push notifications  : False
Extended agent card : False

--- I/O Modes ---
Input  : text/plain
Output : 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
====================================================
🔄 Fetching the agent card at http://localhost:10000
 Successfully fetched the agent card
🔄 Initializing a non-streaming client
Sending request:
message {
  message_id: "5d190c88-336e-4a22-925d-e2af49cf4bad"
  role: ROLE_USER
  parts {
    text: "how much is 100 USD in GBP?"
  }
}

Response:
task {
  id: "e6f311bb-654a-477f-82a9-81c7a48f7b81"
  context_id: "672e351b-0ff3-4aed-a059-868b383c41a0"
  status {
    state: TASK_STATE_COMPLETED
    timestamp {
      seconds: 1787836031
      nanos: 994786000
    }
  }
  artifacts {
    artifact_id: "e0a05ac8-25c7-471c-a33c-1073fe48cbb8"
    parts {
      text: "100 USD is currently equal to approximately **73.37 GBP** (at an exchange rate of 1 USD = 0.73368 GBP)."
    }
  }
  ...

نجحت! لقد اختبرت بنجاح إمكانية التواصل مع وكيل العملة عبر بروتوكول A2A باستخدام برنامج A2A. 🎉

يمكنك الاطّلاع على مستودع a2a-samples على GitHub للحصول على المزيد من نماذج A2A.

8. استخدام "وكيل العملة" البعيد من خلال A2A

في الخطوة السابقة، استخدمت عميل A2A للتواصل مع "وكيل العملة" عبر A2A.

في هذه الخطوة، سنرى كيف يمكنك استخدام "وكيل العملة" كوكيل بعيد من "وكيل سفر" آخر.

رمز وكيل السفر هو 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

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. "
    "Whenever a user asks about currency exchange rates or money conversions, "
    "delegate the request to the 'currency_agent' sub-agent."
)

CURRENCY_AGENT_URL = os.getenv("CURRENCY_AGENT_URL", "http://localhost:10000")

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.7-flash",
    name="travel_agent",
    description="A travel assistant that can help plan trips and convert currencies via the remote currency agent.",
    instruction=SYSTEM_INSTRUCTION,
    tools=[AgentTool(agent=currency_remote_agent)],
)

لاحظ كيف يتم الوصول إلى "وكيل العملة" باستخدام RemoteA2aAgent.

نفِّذ الأمر adk web لتجربة "وكيل السفر":

uv run adk web --allow_origins "regex:https://.*\.cloudshell\.dev"

في المتصفّح، انتقِل إلى http://localhost:8000 للاطّلاع على الوكيل واختباره.

تأكَّد من اختيار travel_agent كبرنامج في أعلى يمين واجهة المستخدم على الويب.

اطرح على الوكيل في مساحة المحادثة سؤالاً مثل "ما هو سعر 250 دولار كندي بالدولار الأمريكي؟".

يجب أن ترى مكالمات "وكيل السفر" currency_agent عن بُعد قبل أن تقدّم ردّها.

وكيل العملة البعيد على الويب في ADK

يعمل الوكيل بشكل صحيح. يمكنه التعامل مع طلبات البحث التي تدور حول تحويل العملات 💸 من خلال استدعاء وكيل بعيد باستخدام A2A.

9. تهانينا

تهانينا! لقد أنشأت ونشرت بنجاح خادم MCP عن بُعد، وأنشأت وكيل عملة باستخدام "حزمة تطوير الوكلاء" (ADK) يتصل بالأدوات باستخدام MCP، وعرضت وكيلك باستخدام بروتوكول Agent2Agent (A2A). بعد ذلك، أنشأت وكيل سفر للتواصل مع وكيل العملة عن بُعد باستخدام A2A.

إليك رابط يؤدي إلى مستندات الرمز البرمجي الكاملة.

هل تريد نشر وكيلك؟ توفّر بيئة التشغيل الخاصة بالوكلاء في منصة وكيل Gemini Enterprise تجربة مُدارة لتفعيل وكلاء الذكاء الاصطناعي في مرحلة الإنتاج.

المواضيع التي تناولناها

  • كيفية إنشاء خادم MCP محلي
  • نشر خادم MCP على Cloud Run
  • كيفية إنشاء وكيل باستخدام حزمة Agent Development Kit التي تستخدم أدوات MCP
  • كيفية إتاحة وكيل ADK كخادم A2A
  • اختبار خادم A2A باستخدام عميل A2A
  • كيفية إنشاء وكيل للتواصل مع وكيل آخر باستخدام بروتوكول A2A

تَنظيم

لتجنُّب تحمّل رسوم في حسابك على Google Cloud مقابل الموارد المستخدَمة في هذا الدرس التطبيقي، اتّبِع الخطوات التالية:

  1. في Google Cloud Console، انتقِل إلى صفحة إدارة الموارد.
  2. في قائمة المشاريع، اختَر المشروع الذي تريد حذفه، ثم انقر على حذف.
  3. في مربّع الحوار، اكتب رقم تعريف المشروع، ثم انقر على إيقاف لحذف المشروع.