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

1. مقدمة

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

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

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

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

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

  • مشروع Google Cloud تم تفعيل الفوترة فيه

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

  • كيفية تنظيم مشروع 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 وVertex AI و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.
  • تتيح Vertex AI API (aiplatform.googleapis.com) لتطبيقك الذي تم نشره التواصل مع نماذج Gemini لتنفيذ مهام الذكاء الاصطناعي الأساسية. توفّر هذه المنصة واجهة برمجة تطبيقات موحّدة لجميع خدمات الذكاء الاصطناعي في Google Cloud.
  • توفّر واجهة برمجة التطبيقات Compute Engine (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" وإعادة تشغيل جلسة الوحدة الطرفية. عليك التأكّد من إعادة فتح نافذة الوحدة الطرفية، والتحقّق من أنّك في الدليل الصحيح ~/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
    

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

قبل إنشاء الوكيل، عليك إنشاء حساب خدمة وضبط الأذونات اللازمة. يضمن ذلك أن يتمكّن الوكيل من استدعاء نماذج Vertex AI وأن يتمكّن 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. امنح حساب الخدمة دور مستخدم Vertex AI ليتمكّن الوكيل من استدعاء 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. تحديد وكلاء Specialist: أضِف الرمز التالي إلى أسفل 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 على ويكيبيديا. تظهر رموز الحيوانات على واجهة الخادم. يحتوي المكتب على لوحات لمس زرقاء متوهجة متعددة. تُظهر الخلفية أفق مدينة من خلال نوافذ كبيرة.
  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_VERTEXAI=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. الاستطلاع

إخراج:

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

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