إنشاء وكيل ADK ونشره على Cloud Run

1. مقدمة

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

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

من اليسار إلى اليمين، يظهر أسد وبطريقان وشخص يرتدي قبعة سفاري وفيل ودب يقفون وظهورهم إلى المشاهد وينظرون إلى صاروخ كبير باللونين الأحمر والأبيض ينطلق إلى سماء زرقاء فيها غيوم بيضاء. يمكن أيضًا رؤية صاروخَين أصغر حجمًا ينطلقان من بعيد. يقع المشهد داخل حديقة حيوانات محاطة بسياج خشبي ومنحدرات صخرية.

أخيرًا، سننشر وكيل دليل الجولات على Cloud Run من Google، بدلاً من تشغيله محليًا فقط.

المتطلبات الأساسية

  • الإلمام بلغة Python وواجهات سطر الأوامر
  • مشروع Google Cloud تم تفعيل الفوترة فيه
  • أدوات واجهة سطر الأوامر المثبَّتة: gcloud وgsutil وuv

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

  • كيفية تنظيم مشروع Python لنشر ADK
  • كيفية تنفيذ وكيل يستخدم أدوات باستخدام google-adk
  • كيفية نشر تطبيق Python كحاوية بدون خادم إلى Cloud Run
  • كيفية ضبط مصادقة آمنة بين الخدمات باستخدام أدوار إدارة الهوية وإمكانية الوصول
  • كيفية حذف موارد Cloud لتجنُّب تحمّل تكاليف مستقبلية

المتطلبات

  • حساب على Google Cloud ومشروع على Google Cloud
  • متصفّح ويب، مثل Chrome

2. لماذا يجب النشر على Cloud Run؟

‫Cloud Run هو خيار رائع لاستضافة وكلاء ADK لأنّه نظام أساسي بدون خادم، ما يعني أنّه يمكنك التركيز على الرمز البرمجي وليس على إدارة البنية الأساسية. نتولّى نحن العمليات التشغيلية نيابةً عنك.

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

الميزات الرئيسية

تشغيل الحاويات في أي مكان:

  • يمكنك إحضار حاوية (صورة Docker) تحتوي على تطبيقك.
  • ويشغّلها Cloud Run على البنية الأساسية من Google.
  • لا داعي للقلق بشأن تصحيح نظام التشغيل أو إعداد الآلة الافتراضية أو توسيع نطاقها.

التوسّع التلقائي:

  • إذا لم يكن هناك أي مستخدمين لتطبيقك → لا يتم تشغيل أي مثيلات (يتم تقليل عدد المثيلات إلى صفر، ما يجعله خيارًا فعّالاً من حيث التكلفة).
  • إذا وصل إليها 1,000 طلب، سيتم إنشاء العدد المطلوب من النُسخ.

عدم الاحتفاظ بالحالة تلقائيًا:

  • يمكن أن ينتقل كل طلب إلى مثيل مختلف.
  • إذا كنت بحاجة إلى تخزين الحالة، استخدِم خدمة خارجية مثل Cloud SQL أو Firestore أو Memorystore.

يتوافق مع أي لغة أو إطار عمل:

  • وطالما أنّ التطبيق يعمل في حاوية Linux، لا يهمّ Cloud Run ما إذا كان مكتوبًا بلغة Python أو Go أو Node.js أو Java أو ‎ .Net.

الدفع مقابل الاستخدام:

3- إعداد المشروع

حساب Google

إذا لم يكن لديك حساب Google شخصي، عليك إنشاء حساب Google.

استخدام حساب شخصي بدلاً من حساب تابع للعمل أو حساب تديره المؤسسة التعليمية

تسجيل الدخول إلى Google Cloud Console

سجِّل الدخول إلى Google Cloud Console باستخدام حساب Google شخصي.

تفعيل الفوترة

إعداد حساب فوترة شخصي

إذا أعددت الفوترة باستخدام أرصدة Google Cloud، يمكنك تخطّي هذه الخطوة.

لإعداد حساب فوترة شخصي، انتقِل إلى هنا لتفعيل الفوترة في Cloud Console.

بعض الملاحظات:

  • يجب أن تبلغ تكلفة إكمال هذا الدرس التطبيقي أقل من دولار أمريكي واحد في موارد السحابة الإلكترونية.
  • يمكنك اتّباع الخطوات في نهاية هذا المختبر لحذف الموارد وتجنُّب تحصيل المزيد من الرسوم.
  • يمكن للمستخدمين الجدد الاستفادة من الفترة التجريبية المجانية بقيمة 300 دولار أمريكي.

إنشاء مشروع (اختياري)

إذا لم يكن لديك مشروع حالي تريد استخدامه في هذا المختبر، يمكنك إنشاء مشروع جديد هنا.

4. فتح Cloud Shell Editor

  1. انقر على هذا الرابط للانتقال مباشرةً إلى محرّر Cloud Shell
  2. إذا طُلب منك منح الإذن في أي وقت اليوم، انقر على تفويض للمتابعة. انقر لتفويض Cloud Shell
  3. إذا لم تظهر النافذة الطرفية في أسفل الشاشة، افتحها باتّباع الخطوات التالية:
    • انقر على عرض.
    • انقر على Terminalفتح نافذة طرفية جديدة في "محرّر Cloud Shell".

5- ضبط مشروعك

  1. في الوحدة الطرفية، اضبط مشروعك باستخدام الأمر التالي:
    gcloud config set project [PROJECT_ID]
    
    مثال: gcloud config set project lab-project-id-example ضبط رقم تعريف المشروع في نافذة Cloud Shell Editor
  2. من المفترض أن تظهر لك هذه الرسالة:
    Updated property [core/project].
    

6. تفعيل واجهات برمجة التطبيقات

لاستخدام Cloud Run وArtifact Registry وCloud Build وGemini Enterprise Agent Platform وCompute Engine، عليك تفعيل واجهات برمجة التطبيقات الخاصة بها في مشروعك على Google Cloud.

  • في وحدة التحكّم، فعِّل واجهات برمجة التطبيقات:
    gcloud services enable \
      run.googleapis.com \
      artifactregistry.googleapis.com \
      cloudbuild.googleapis.com \
      aiplatform.googleapis.com \
      compute.googleapis.com
    
    عند انتهاء عملية التشغيل، من المفترض أن تظهر لك نتيجة مشابهة لما يلي:
    Operation "operations/acat.p2-[GUID]" finished successfully.
    

لمحة عن واجهات برمجة التطبيقات

  • تتيح لك Cloud Run Admin API (run.googleapis.com) تشغيل خدمات الواجهة الأمامية والخلفية أو مهام الدفعات أو المواقع الإلكترونية في بيئة مُدارة بالكامل. تتولّى هذه الخدمة البنية الأساسية لنشر تطبيقاتك المحفوظة في حاويات وتوسيع نطاقها.
  • توفّر Artifact Registry API (artifactregistry.googleapis.com) مستودعًا آمنًا وخاصًا لتخزين صور الحاويات. وهي تمثّل تطوّر Container Registry وتتكامل بسلاسة مع Cloud Run وCloud Build.
  • واجهة برمجة تطبيقات Cloud Build (cloudbuild.googleapis.com) هي منصة CI/CD بدون خادم تنفّذ عمليات الإنشاء على بنية Google Cloud الأساسية. يُستخدَم لإنشاء صورة الحاوية في السحابة الإلكترونية من ملف Dockerfile.
  • تتيح واجهة برمجة التطبيقات لمنصة وكيل Gemini Enterprise (aiplatform.googleapis.com) لتطبيقك الذي تم نشره التواصل مع نماذج Gemini لتنفيذ مهام الذكاء الاصطناعي الأساسية. توفّر هذه المنصة واجهة برمجة تطبيقات موحّدة لجميع خدمات الذكاء الاصطناعي في Google Cloud.
  • توفّر Compute Engine API (compute.googleapis.com) أجهزة افتراضية آمنة وقابلة للتخصيص تعمل على بنية Google التحتية. على الرغم من أنّ Cloud Run مُدارة، غالبًا ما تكون واجهة برمجة التطبيقات Compute Engine مطلوبة كعنصر أساسي يعتمد عليه العديد من موارد الشبكات والحوسبة.

7. تجهيز بيئة التطوير

إنشاء الدليل

  1. في وحدة التحكّم، أنشئ دليل المشروع والأدلة الفرعية اللازمة:
    cd && mkdir zoo_guide_agent && cd zoo_guide_agent
    
  2. في الوحدة الطرفية، نفِّذ الأمر التالي لفتح الدليل zoo_guide_agent في مستكشف "محرِّر Cloud Shell":
    cloudshell open-workspace ~/zoo_guide_agent
    
  3. سيتم إعادة تحميل لوحة "المستكشف" على اليمين. من المفترض أن يظهر لك الآن الدليل الذي أنشأته.
    لقطة شاشة للدليل الجديد في اللوحة الجانبية للمستكشف
    CRITICAL: يؤدي فتح مساحة عمل جديدة إلى إعادة ضبط Cloud Shell Editor وإعادة تشغيل جلسة الوحدة الطرفية. عليك التأكّد من إعادة فتح نافذة الوحدة الطرفية، والتحقّق من أنّك في الدليل الصحيح ~/zoo_guide_agent (نفِّذ الأمرَين pwd وcd ~/zoo_guide_agent إذا لزم الأمر)، ومن أنّ مشروع gcloud لا يزال محدّدًا (نفِّذ الأمر gcloud config set project [PROJECT_ID] إذا لزم الأمر).

متطلبات التثبيت

  1. نفِّذ الأمر التالي في الوحدة الطرفية لإنشاء ملف requirements.txt.
    cloudshell edit requirements.txt
    
  2. أضِف ما يلي إلى ملف requirements.txt الذي تم إنشاؤه حديثًا
    google-adk==2.4.0
    langchain-community==0.3.27
    wikipedia==1.4.0
    
  3. في وحدة التحكّم، أنشئ بيئة افتراضية وفعّلها باستخدام uv. يضمن ذلك عدم تعارض تبعيات مشروعك مع لغة Python في النظام.
    uv venv
    source .venv/bin/activate
    
  4. ثبِّت الحِزم المطلوبة في بيئتك الافتراضية في وحدة التحكّم.
    uv pip install -r requirements.txt
    

إنشاء حساب خدمة وضبط أذونات "إدارة الهوية وإمكانية الوصول"

قبل إنشاء الوكيل، عليك إنشاء حساب خدمة وضبط الأذونات اللازمة. يضمن ذلك أن يتمكّن الوكيل من استدعاء نماذج "منصة وكيل Gemini Enterprise" وأن يتمكّن Cloud Build من نشر تطبيقك بنجاح.

  1. في وحدة التحكّم، أنشئ حساب خدمة مخصّصًا لخدمة Cloud Run:
    SA_NAME=lab-service-account
    PROJECT_ID=$(gcloud config get-value project)
    gcloud iam service-accounts create ${SA_NAME} \
        --display-name="Service Account for Zoo Agent"
    
  2. امنح حساب الخدمة دور مستخدم منصة وكيل Gemini Enterprise لكي يتمكّن الوكيل من استدعاء Gemini:
    gcloud projects add-iam-policy-binding $PROJECT_ID \
      --member="serviceAccount:${SA_NAME}@${PROJECT_ID}.iam.gserviceaccount.com" \
      --role="roles/aiplatform.user"
    
  3. ضبط أذونات Cloud Build بما أنّ مشاريع Google Cloud الحديثة تقيّد أذونات حساب الخدمة التلقائي، عليك منح حساب خدمة Compute Engine التلقائي الأدوار المطلوبة لإنشاء الحاوية ونشرها. نفِّذ الأوامر التالية في الوحدة الطرفية:
    PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format="value(projectNumber)")
    
    # Grant Artifact Registry Writer role
    gcloud projects add-iam-policy-binding $PROJECT_ID \
      --member="serviceAccount:${PROJECT_NUMBER}-compute@developer.gserviceaccount.com" \
      --role="roles/artifactregistry.writer"
    
    # Grant Storage Object Viewer role
    gcloud projects add-iam-policy-binding $PROJECT_ID \
      --member="serviceAccount:${PROJECT_NUMBER}-compute@developer.gserviceaccount.com" \
      --role="roles/storage.objectViewer"
    
    # Grant Logs Writer role
    gcloud projects add-iam-policy-binding $PROJECT_ID \
      --member="serviceAccount:${PROJECT_NUMBER}-compute@developer.gserviceaccount.com" \
      --role="roles/logging.logWriter"
    

إعداد متغيّرات البيئة

الآن، ستنشئ ملف .env يحتوي على متغيرات البيئة التي يستخدمها الوكيل وبرنامج النشر النصي.

  1. بما أنّك حدّدت المتغيّرات في جلسة الوحدة الطرفية خلال الخطوة السابقة، يمكنك إنشاء الملف .env مباشرةً:
    cat <<EOF > .env
    PROJECT_ID=$PROJECT_ID
    PROJECT_NUMBER=$PROJECT_NUMBER
    SA_NAME=$SA_NAME
    SERVICE_ACCOUNT=${SA_NAME}@${PROJECT_ID}.iam.gserviceaccount.com
    MODEL="gemini-3.5-flash"
    EOF
    

8. إنشاء سير عمل للوكيل

إنشاء ملف __init__.py

  1. أنشئ ملف init.py من خلال تنفيذ ما يلي في الوحدة الطرفية:
    cloudshell edit __init__.py
    
    يُعلم هذا الملف لغة Python أنّ دليل zoo_guide_agent هو حزمة.
  2. أضِف الرمز التالي إلى ملف __init__.py الجديد:
    from . import agent
    

إنشاء ملف agent.py

  1. أنشئ ملف agent.py الرئيسي من خلال لصق الأمر التالي في الوحدة الطرفية.
    cloudshell edit agent.py
    
  2. عمليات الاستيراد والإعداد الأوّلي: أضِف الرمز التالي إلى ملف agent.py الفارغ حاليًا:
    import os
    import logging
    from dotenv import load_dotenv
    
    from google.adk import Agent
    from google.adk.agents import SequentialAgent
    from google.adk.tools.tool_context import ToolContext
    from google.adk.tools.langchain_tool import LangchainTool
    
    from langchain_community.tools import WikipediaQueryRun
    from langchain_community.utilities import WikipediaAPIWrapper
    
    import google.auth
    import google.auth.transport.requests
    import google.oauth2.id_token
    
    # --- Setup Logging and Environment ---
    
    load_dotenv()
    
    model_name = os.getenv("MODEL")
    
    تستدعي هذه المجموعة الأولى من ملف agent.py جميع المكتبات الضرورية من ADK وGoogle Cloud. يتم أيضًا إعداد التسجيل وتحميل متغيّرات البيئة من ملف .env، وهو أمر بالغ الأهمية للوصول إلى نموذجك وعنوان URL الخاص بالخادم.
  3. تحديد الأدوات: لا يمكن أن يكون الوكيل فعّالاً إلا إذا كانت الأدوات التي يمكنه استخدامها فعّالة. أضِف الرمز التالي إلى أسفل agent.py لتحديد الأدوات:
    # Greet user and save their prompt
    
    def add_prompt_to_state(
        tool_context: ToolContext, prompt: str
    ) -> dict[str, str]:
        """Saves the user's initial prompt to the state."""
        tool_context.state["PROMPT"] = prompt
        logging.info(f"[State updated] Added to PROMPT: {prompt}")
        return {"status": "success"}
    
    # Configuring the Wikipedia Tool
    api_wrapper = WikipediaAPIWrapper(top_k_results=1, doc_content_chars_max=1000)
    api_wrapper.wiki_client.set_user_agent("ZooTourGuideAgent/1.0")
    wikipedia_tool = LangchainTool(
        tool=WikipediaQueryRun(api_wrapper=api_wrapper)
    )
    
    شرح الأدوات
    • ‫add_prompt_to_state 📝: تتذكّر هذه الأداة أسئلة زوّار حديقة الحيوانات. عندما يسأل أحد الزوّار "أين الأسود؟"، تحفظ هذه الأداة هذا السؤال المحدّد في ذاكرة الوكيل لكي تعرف الوكلاء الآخرين في سير العمل ما يجب البحث عنه.
      الطريقة: هي دالة Python تكتب طلب الزائر في قاموس tool_context.state المشترَك. يمثّل سياق الأداة هذا الذاكرة القصيرة المدى للوكيل في محادثة واحدة. يمكن للوكيل التالي في سير العمل قراءة البيانات التي حفظها الوكيل السابق في الحالة.
    • ‫LangchainTool 🌍: يمنح هذا الخيار وكيل دليل الجولات السياحية معرفة عامة بالعالم. عندما يطرح زائر سؤالاً غير متوفّر في قاعدة بيانات حديقة الحيوانات، مثل "ماذا تأكل الأسود في البرية؟"، تتيح هذه الأداة للوكيل البحث عن الإجابة على Wikipedia. (يمكنك الاطّلاع على مزيد من المعلومات حول إعداد أداة Wikipedia واستخدامها في دليل استخدام أداة Wikipedia).
      طريقة العمل: تعمل هذه الأداة كمحوّل، ما يسمح للوكيل باستخدام أداة WikipediaQueryRun المُنشأة مسبقًا من مكتبة LangChain.
      يحمل الروبوت الودود المظهر دفترًا عليه رسومات حيوانات وفقاعة تفكير فيها أسد، ويتحدث إلى رجل وولد صغير يحمل حقيبة ظهر. تظهر الزرافات وعناصر أخرى من حديقة الحيوانات في الخلفية، مع أشجار النخيل التي تحيط بالمدخل.
  4. تحديد وكلاء الاختصاص: أضِف الرمز التالي إلى أسفل agent.py لتحديد الوكيلَين comprehensive_researcher وresponse_formatter:
    # 1. Researcher Agent
    comprehensive_researcher = Agent(
        name="comprehensive_researcher",
        model=model_name,
        description="The primary researcher that can access both internal zoo data and external knowledge from Wikipedia.",
        instruction="""
        You are a helpful research assistant. Your goal is to fully answer the user's PROMPT.
        You have access to two tools:
        1. A tool for getting specific data about animals AT OUR ZOO (names, ages, locations).
        2. A tool for searching Wikipedia for general knowledge (facts, lifespan, diet, habitat).
    
        First, analyze the user's PROMPT.
        - If the prompt can be answered by only one tool, use that tool.
        - If the prompt is complex and requires information from both the zoo's database AND Wikipedia,
          you MUST use both tools to gather all necessary information.
        - Synthesize the results from the tool(s) you use into preliminary data outputs.
    
        PROMPT:
        { PROMPT }
        """,
        tools=[
            wikipedia_tool
        ],
        output_key="research_data" # A key to store the combined findings
    )
    
    # 2. Response Formatter Agent
    response_formatter = Agent(
        name="response_formatter",
        model=model_name,
        description="Synthesizes all information into a friendly, readable response.",
        instruction="""
        You are the friendly voice of the Zoo Tour Guide. Your task is to take the
        RESEARCH_DATA and present it to the user in a complete and helpful answer.
    
        - First, present the specific information from the zoo (like names, ages, and where to find them).
        - Then, add the interesting general facts from the research.
        - If some information is missing, just present the information you have.
        - Be conversational and engaging.
    
        RESEARCH_DATA:
        { research_data }
        """
    )
    
    • comprehensive_researcher هو "العقل المدبّر" لعملياتنا. يأخذ هذا المكوّن طلب المستخدم من State المشترَكة، ويفحصه باستخدام "أداة Wikipedia"، ويقرّر أيًّا من الأدوات سيستخدمها للعثور على الإجابة.
    • دور الوكيل response_formatter هو تقديم العروض التقديمية. يستخدم هذا الوكيل البيانات الأولية التي جمعها وكيل الباحث (والتي تم تمريرها عبر الحالة) ويستفيد من مهارات اللغة لدى النموذج اللغوي الكبير لتحويلها إلى ردّ ودّي وحواري.
      يجلس الروبوت، الذي تلمع عيناه باللون الأزرق، أمام شاشة منحنية كبيرة تعرض MCP ZOO SERVER على اليمين وصفحة ZOO Wikipedia على اليسار. تظهر رموز الحيوانات على واجهة الخادم. يحتوي المكتب على لوحات لمس زرقاء متوهجة متعددة. تُظهر الخلفية أفق مدينة من خلال نوافذ كبيرة.
  5. تحديد وكيل سير العمل: أضِف مجموعة الرموز البرمجية هذه إلى أسفل agent.py لتحديد الوكيل التسلسلي tour_guide_workflow:
    tour_guide_workflow = SequentialAgent(
        name="tour_guide_workflow",
        description="The main workflow for handling a user's request about an animal.",
        sub_agents=[
            comprehensive_researcher, # Step 1: Gather all data
            response_formatter,       # Step 2: Format the final response
        ]
    )
    
    يعمل وكيل سير العمل كمدير "المكتب الخلفي" لجولة حديقة الحيوانات. يأخذ هذا المكوّن طلب البحث ويضمن أن يؤدي الوكيلان اللذان حدّدناهما أعلاه وظائفهما بالترتيب الصحيح: البحث أولاً، ثم التنسيق. يؤدي ذلك إلى إنشاء عملية يمكن توقّعها وموثوقة للإجابة عن سؤال أحد الزوّار.
    طريقة العمل: هي SequentialAgent، وهو نوع خاص من البرامج لا يفكّر بنفسه. مهمتها الوحيدة هي تشغيل قائمة sub_agents (الباحث والمنسّق) بتسلسل ثابت، مع نقل الذاكرة المشتركة تلقائيًا من أحدهما إلى الآخر.
  6. تجميع سير العمل الرئيسي: أضِف مجموعة الرموز النهائية هذه إلى أسفل agent.py لتحديد root_agent:
    root_agent = Agent(
        name="greeter",
        model=model_name,
        description="The main entry point for the Zoo Tour Guide.",
        instruction="""
        - Let the user know you will help them learn about the animals we have in the zoo.
        - When the user responds, use the 'add_prompt_to_state' tool to save their response.
        After using the tool, transfer control to the 'tour_guide_workflow' agent.
        """,
        tools=[add_prompt_to_state],
        sub_agents=[tour_guide_workflow]
    )
    
    يستخدم إطار عمل ADK root_agent كنقطة بداية لجميع المحادثات الجديدة. ويتمثل دورها الأساسي في تنسيق العملية بشكل عام. يعمل هذا العنصر كعنصر تحكّم أولي، ويدير الجولة الأولى من المحادثة.
    تظهر ثلاثة روبوتات: روبوت الترحيب على اليمين يكتب على دفتر ملاحظات مع فقاعة أفكار على شكل أسد، وروبوت الباحث في الوسط يجلس على مكتب مع كمبيوتر يعرض بيانات وسهم طلب يشير إليه، وروبوت العرض التقديمي على اليسار يبتسم وهو يحمل مخططًا بعنوان &quot;البيانات التي تم تحليلها&quot;، مع سهم يشير إليه من روبوت الباحث. تظهر الزرافات والفيلة في الخلفية، وتزيّن أشجار النخيل المشهد.

ملف agent.py الكامل

اكتمل الآن ملف agent.py. من خلال إنشاء النظام بهذه الطريقة، يمكنك معرفة الدور المحدّد لكل مكوّن، أي الأدوات ووكلاء العاملين ووكلاء المدراء، في إنشاء النظام النهائي الذكي.

يجب أن يبدو الملف الكامل على النحو التالي:

import os
import logging
from dotenv import load_dotenv

from google.adk import Agent
from google.adk.agents import SequentialAgent
from google.adk.tools.tool_context import ToolContext
from google.adk.tools.langchain_tool import LangchainTool

from langchain_community.tools import WikipediaQueryRun
from langchain_community.utilities import WikipediaAPIWrapper

import google.auth
import google.auth.transport.requests
import google.oauth2.id_token

# --- Setup Logging and Environment ---

load_dotenv()

model_name = os.getenv("MODEL")

# Greet user and save their prompt

def add_prompt_to_state(
    tool_context: ToolContext, prompt: str
) -> dict[str, str]:
    """Saves the user's initial prompt to the state."""
    tool_context.state["PROMPT"] = prompt
    logging.info(f"[State updated] Added to PROMPT: {prompt}")
    return {"status": "success"}

# Configuring the Wikipedia Tool
api_wrapper = WikipediaAPIWrapper(top_k_results=1, doc_content_chars_max=1000)
api_wrapper.wiki_client.set_user_agent("ZooTourGuideAgent/1.0")
wikipedia_tool = LangchainTool(
    tool=WikipediaQueryRun(api_wrapper=api_wrapper)
)

# 1. Researcher Agent
comprehensive_researcher = Agent(
    name="comprehensive_researcher",
    model=model_name,
    description="The primary researcher that can access both internal zoo data and external knowledge from Wikipedia.",
    instruction="""
    You are a helpful research assistant. Your goal is to fully answer the user's PROMPT.
    You have access to two tools:
    1. A tool for getting specific data about animals AT OUR ZOO (names, ages, locations).
    2. A tool for searching Wikipedia for general knowledge (facts, lifespan, diet, habitat).

    First, analyze the user's PROMPT.
    - If the prompt can be answered by only one tool, use that tool.
    - If the prompt is complex and requires information from both the zoo's database AND Wikipedia,
        you MUST use both tools to gather all necessary information.
    - Synthesize the results from the tool(s) you use into preliminary data outputs.

    PROMPT:
    { PROMPT }
    """,
    tools=[
        wikipedia_tool
    ],
    output_key="research_data" # A key to store the combined findings
)

# 2. Response Formatter Agent
response_formatter = Agent(
    name="response_formatter",
    model=model_name,
    description="Synthesizes all information into a friendly, readable response.",
    instruction="""
    You are the friendly voice of the Zoo Tour Guide. Your task is to take the
    RESEARCH_DATA and present it to the user in a complete and helpful answer.

    - First, present the specific information from the zoo (like names, ages, and where to find them).
    - Then, add the interesting general facts from the research.
    - If some information is missing, just present the information you have.
    - Be conversational and engaging.

    RESEARCH_DATA:
    { research_data }
    """
)

tour_guide_workflow = SequentialAgent(
    name="tour_guide_workflow",
    description="The main workflow for handling a user's request about an animal.",
    sub_agents=[
        comprehensive_researcher, # Step 1: Gather all data
        response_formatter,       # Step 2: Format the final response
    ]
)

root_agent = Agent(
    name="greeter",
    model=model_name,
    description="The main entry point for the Zoo Tour Guide.",
    instruction="""
    - Let the user know you will help them learn about the animals we have in the zoo.
    - When the user responds, use the 'add_prompt_to_state' tool to save their response.
    After using the tool, transfer control to the 'tour_guide_workflow' agent.
    """,
    tools=[add_prompt_to_state],
    sub_agents=[tour_guide_workflow]
)

والآن، سنتحدّث عن عملية النشر.

9. تجهيز التطبيق للنشر

التحقّق من البنية النهائية

قبل النشر، تأكَّد من أنّ دليل مشروعك يحتوي على الملفات الصحيحة.

  • تأكَّد من أنّ مجلد zoo_guide_agent يظهر على النحو التالي:
    zoo_guide_agent/
    ├── .env
    ├── __init__.py
    ├── agent.py
    └── requirements.txt
    

ضبط ملف ‎ .gcloudignore وتحميل متغيرات البيئة

  1. أنشئ ملف .gcloudignore في الدليل zoo_guide_agent لمنع تحميل بيئتك الافتراضية (.venv/) والملفات الأخرى غير الضرورية إلى Google Cloud:
    cloudshell edit .gcloudignore
    
  2. أضِف المحتوى التالي إلى .gcloudignore:
    .gcloudignore
    .git
    .gitignore
    .venv/
    venv/
    __pycache__/
    .env
    
  3. حمِّل متغيرات البيئة في جلسة الوحدة الطرفية:
    source .env
    

10. نشر الوكيل باستخدام واجهة سطر الأوامر لحزمة ADK

بعد أن يصبح الرمز البرمجي المحلي جاهزًا ومشروع Google Cloud معدًا، يحين وقت نشر الوكيل. ستستخدِم الأمر adk deploy cloud_run، وهو أداة سهلة الاستخدام تعمل على أتمتة عملية نشر التطبيق بالكامل. تتضمّن هذه العملية المكوّنة من خطوة واحدة تجميع الرمز البرمجي وإنشاء صورة حاوية وتحميلها إلى Artifact Registry وتشغيل الخدمة على Cloud Run، ما يتيح الوصول إليها على الويب.

  1. نفِّذ الأمر التالي في الوحدة الطرفية لنشر وكيلك:
    # Run the deployment command
    uvx --from google-adk==2.4.0 \
    adk deploy cloud_run \
      --project=$PROJECT_ID \
      --region=europe-west1 \
      --service_name=zoo-tour-guide \
      --with_ui \
      . \
      -- \
      --allow-unauthenticated \
      --set-env-vars=MODEL=$MODEL,GOOGLE_GENAI_USE_ENTERPRISE=true,GOOGLE_CLOUD_PROJECT=$PROJECT_ID,GOOGLE_CLOUD_LOCATION=global \
      --labels=dev-tutorial=codelab-adk \
      --service-account=$SERVICE_ACCOUNT
    
    يتيح لك الأمر uvx تشغيل أدوات سطر الأوامر المنشورة كحِزم Python بدون الحاجة إلى تثبيت هذه الأدوات على مستوى العالم.
  2. إذا ظهرت لك الرسالة التالية:
    Deploying from source requires an Artifact Registry Docker repository to store built containers. A repository named [cloud-run-source-deploy] in region 
    [europe-west1] will be created.
    
    Do you want to continue (Y/n)?
    
    إذا كان الأمر كذلك، اكتب Y واضغط على مفتاح ENTER.
  3. بعد التنفيذ بنجاح، سيوفر الأمر عنوان URL لخدمة Cloud Run التي تم نشرها. (سيبدو على النحو التالي: https://zoo-tour-guide-123456789.europe-west1.run.app).
  4. انسخ عنوان URL لخدمة Cloud Run التي تم نشرها للمهمة التالية.

11. اختبار الوكيل الذي تم نشره

بعد نشر وكيلك على Cloud Run، ستجري اختبارًا للتأكّد من أنّ عملية النشر تمت بنجاح وأنّ الوكيل يعمل على النحو المتوقّع. ستستخدم عنوان URL العام للخدمة (مثل https://zoo-tour-guide-123456789.europe-west1.run.app/) للوصول إلى واجهة الويب الخاصة بـ ADK والتفاعل مع الوكيل.

  1. افتح عنوان URL لخدمة Cloud Run العامة في متصفّح الويب. بما أنّك استخدمت --with_ui flag، من المفترض أن تظهر لك واجهة مستخدم مطوّر حزمة ADK.
  2. فعِّل Token Streaming في أعلى يسار الشاشة.
    يمكنك الآن التفاعل مع وكيل Zoo.
  3. اكتب hello واضغط على Enter لبدء محادثة جديدة.
  4. لاحظ النتيجة. يجب أن يستجيب الوكيل بسرعة مع رسالة الترحيب، والتي ستكون على النحو التالي:
    "Hello! I'm your Zoo Tour Guide. I can help you learn about the amazing animals we have here. What would you like to know or explore today?"
    
  5. اطرح على الوكيل أسئلة مثل:
    Where can I find the polar bears in the zoo and what is their diet?
    
    لقطة شاشة لوكيل ADK ينفّذ سلسلة من الإجراءات: add_prompt_to_state وtransfer_to_agent وwikipedia وget_animals_by_species يقول الردّ الأول: &quot;لا يمكنني إخبارك بمكان العثور على الدببة القطبية في حديقة الحيوانات هذه، ولكن يمكنني إخبارك بنظامها الغذائي&quot;. يقول الردّ الثاني: &quot;يمكنك العثور على الدببة القطبية في معرض القطب الشمالي على طريق القطب الشمالي&quot;. لا يمكنني استرداد معلومات حول نظامهم الغذائي باستخدام الأدوات المتاحة.' أما الردّ الثالث والأكثر شمولاً فيقول: &quot;يسرّني أن أقدّم لك معلومات عن دببة القطب الشمالي. يمكنك العثور على الدببة القطبية في معرض القطب الشمالي على طريق القطب الشمالي. لدينا ثلاثة دببة قطبية هنا: &quot;ندفة الثلج&quot;، وعمرها 7 سنوات. &quot;بليزارد&quot;، الذي يبلغ من العمر 5 سنوات &quot;آيسبيرغ&quot;، الذي يبلغ من العمر 9 سنوات أما بالنسبة إلى نظامها الغذائي، فإنّ الدببة القطبية هي في الغالب من الحيوانات آكلة اللحوم. وهي تتخصّص في افتراس الفقمات، لا سيما فقمات الحلقات. وتتغذى أيضًا على الفظ والحيتان البيضاء وبعض الحيوانات البرية.

شرح "مسار الوكيل"

يعمل نظامك كفريق ذكي متعدّد الوكلاء. تتم إدارة العملية من خلال تسلسل واضح لضمان سيرها بسلاسة وفعالية من سؤال المستخدم إلى الإجابة النهائية التفصيلية.

1. موظف الاستقبال في حديقة الحيوان (مكتب الاستقبال)

تبدأ العملية بأكملها مع وكيل الترحيب.

  • مهمتها: بدء المحادثة. تتمثل تعليماتها في الترحيب بالمستخدم وسؤاله عن الحيوان الذي يريد التعرّف عليه.
  • الأداة: عندما يردّ المستخدم، يستخدم Greeter أداة add_prompt_to_state لالتقاط كلماته بالضبط (مثل "أريد معرفة معلومات عن الأسود") وحفظها في ذاكرة النظام.
  • التسليم: بعد حفظ الطلب، يتم على الفور نقل التحكّم إلى الوكيل الفرعي، أي tour_guide_workflow.

2. الباحث الشامل (الباحث الفائق)

هذه هي الخطوة الأولى في سير العمل الرئيسي و "عقل" العملية. بدلاً من فريق كبير، لديك الآن وكيل واحد يتمتّع بمهارات عالية ويمكنه الوصول إلى جميع المعلومات المتاحة.

  • مهمتها: تحليل سؤال المستخدم ووضع خطة ذكية. تستفيد هذه الميزة من إمكانية استخدام الأدوات في النموذج اللغوي لتحديد ما إذا كانت بحاجة إلى:
    • المعرفة العامة من الويب (عبر Wikipedia API)
    • أو كليهما للأسئلة المعقّدة.

3- أداة تنسيق الردود (المُقدِّم)

بعد أن يجمع Comprehensive Researcher كل الحقائق، يكون هذا هو الوكيل النهائي الذي سيتم تشغيله.

  • مهمة هذا النموذج: أن يؤدي دور المرشد السياحي الودود في جولة حديقة الحيوانات. تأخذ هذه العملية البيانات الأولية (التي يمكن أن تكون من مصدر واحد أو كلا المصدرين) وتعدّلها.
  • الإجراء: يجمع هذا الوضع كل المعلومات في إجابة واحدة متماسكة وجذابة. وبعد اتّباع تعليماته، يعرض أولاً معلومات محددة عن حديقة الحيوانات، ثم يضيف الحقائق العامة المثيرة للاهتمام.
  • النتيجة النهائية: النص الذي ينشئه هذا الوكيل هو الإجابة الكاملة والمفصّلة التي يراها المستخدم في نافذة المحادثة.

إذا كنت مهتمًا بمعرفة المزيد حول إنشاء وكلاء، يمكنك الاطّلاع على الموارد التالية:

  1. مستندات ADK
  2. إنشاء أدوات مخصّصة لوكلاء ADK

12. تنظيف البيئة

لتجنُّب تحمّل رسوم في حسابك على Google Cloud مقابل الموارد المستخدَمة في هذا البرنامج التعليمي، يمكنك إما حذف المشروع الذي يحتوي على الموارد أو الاحتفاظ بالمشروع وحذف الموارد الفردية.

حذف خدمات Cloud Run والصور والموارد

إذا أردت الاحتفاظ بمشروع Google Cloud ولكن إزالة الموارد المحدّدة التي تم إنشاؤها في هذا المختبر، عليك حذف الخدمة قيد التشغيل ومستودع صور الحاويات وحزمة التخزين المؤقت للملفات المصدر وحساب الخدمة.

  • نفِّذ الأوامر التالية في الوحدة الطرفية:
    gcloud run services delete zoo-tour-guide --region=europe-west1 --quiet
    gcloud artifacts repositories delete cloud-run-source-deploy --location=europe-west1 --quiet
    gsutil rm -r gs://run-sources-${PROJECT_ID}-europe-west1
    gcloud iam service-accounts delete lab-service-account@${PROJECT_ID}.iam.gserviceaccount.com --quiet
    

حذف المشروع (اختياري)

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

  • في الوحدة الطرفية، نفِّذ الأمر التالي (استبدِل [YOUR_PROJECT_ID] برقم تعريف مشروعك الفعلي):
    gcloud projects delete $PROJECT_ID
    

13. تهانينا

لقد نجحت في إنشاء تطبيق ذكاء اصطناعي متعدد الوكلاء ونشره على Google Cloud.

ملخّص

في هذا التمرين العملي، انتقلت من دليل فارغ إلى خدمة ذكاء اصطناعي مباشرة ومتاحة للجميع. في ما يلي نظرة على ما أنشأته:

  • إنشاء فريق متخصص: بدلاً من استخدام ذكاء اصطناعي عام، أنشأت "باحثًا" للعثور على الحقائق و "منسّقًا" لتحسين الإجابة.
  • تزويدهم بالأدوات: ربطت وكلاءك بالعالم الخارجي باستخدام واجهة برمجة التطبيقات الخاصة بموقع Wikipedia.
  • تم نشر التطبيق: لقد أخذت رمز Python المحلي ونشرته كحاوية بدون خادم على Cloud Run، مع تأمينها باستخدام حساب خدمة مخصّص.

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

  • كيفية تنظيم مشروع Python لنشره باستخدام ADK
  • كيفية تنفيذ سير عمل متعدد الوكلاء باستخدام [SequentialAgent](https://google.github.io/adk-docs/agents/workflow-agents/sequential-agents/)
  • كيفية دمج أدوات خارجية، مثل واجهة برمجة التطبيقات الخاصة بموقع Wikipedia
  • كيفية نشر وكيل إلى Cloud Run باستخدام الأمر adk deploy

14. استطلاع

إخراج:

كيف ستستخدم هذا البرنامج التعليمي؟

قراءة المحتوى فقط قراءة المحتوى وإكمال التمارين