إنشاء استوديو إبداعي متعدد الوكلاء باستخدام مجموعة أدوات Agent Stack من Google: ADK وA2A وMCP على Cloud Run وAgent Runtime

1. نظرة عامة

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

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

الوكلاء الذين ستنشئهم

الوكيل

الدور

محلّل إستراتيجي للعلامة التجارية

البحث على الويب عن إحصاءات الجمهور وتحليل المنافسين والمؤشرات الحالية

كاتب الإعلانات

كتابة أوصاف على Instagram تتضمّن علامات هاشتاغ وعبارات تحث المستخدم على اتّخاذ إجراء، وذلك باستخدام إحدى مهارات ADK التي تحمّل إرشادات المنصة وصيغ الأوصاف عند الطلب

Designer

إنشاء مفاهيم مرئية وإنشاء صور حقيقية من خلال Gemini، وتخزينها في GCS

ناقد

نسخ المراجعات والعناصر المرئية - تعرض APPROVED أو NEEDS_REVISION مع ملاحظات محدّدة

مدير مشروع

إنشاء مخطط زمني للمشروع وتقسيم المهام، ويمكن مزامنته اختياريًا مع Notion من خلال MCP

مدير تصميم الإعلان

تنسيق جميع المتخصصين الخمسة بالتسلسل: ما عليك سوى تقديم طلب واحد، وسيتولّى تنسيق الباقي

يتم نشر الوكلاء الخمسة كخدمات دقيقة مستقلة على Cloud Run. تتواصل هذه الوكلاء عبر بروتوكول A2A، وهو معيار مفتوح لا يعتمد على لغة معيّنة، ما يتيح لأي وكيل الاتصال بأي وكيل آخر بغض النظر عن إطار العمل. يعمل "المدير الإبداعي" على Agent Runtime ويتواصل مع كل خبير عن بُعد.

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

بنية النظام

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

  • إنشاء وكلاء نماذج لغوية كبيرة باستخدام Google ADK - Agent وتعليمات النظام والأدوات المضمّنة
  • يمكنك تجميع معلومات الوكيل القابلة لإعادة الاستخدام في ملفات نموذجية باستخدام مهارات ADK (SkillToolset).
  • إنشاء صور حقيقية من خلال ربط وكيل نصي بنموذج صور باستخدام FunctionTool
  • يمكنك دمج واجهات برمجة التطبيقات الخارجية بدون رمز ربط مخصّص باستخدام بروتوكول سياق النموذج (MCP).
  • يمكنك تحويل أي وكيل إلى خدمة يمكن استدعاؤها عبر الشبكة باستخدام بروتوكول الوكيل إلى الوكيل (A2A) عبر HTTPS.
  • يمكنك تنسيق الوكلاء الموزّعين باستخدام RemoteA2aAgent وAgentTool.
  • يمكنك تجميع الوكلاء المستقلين ونشرهم كخدمات مصغّرة في Cloud Run.
  • استضافة أداة تنسيق ذات حالة على Agent Runtime
  • يمكنك الحفاظ على مهام سير العمل الطويلة التي تتضمّن وكلاء متعدّدين ضمن حدود السياق باستخدام ضغط السياق.
  • إنشاء حلقة مراقبة الجودة: مراجعات النقاد → مراجعة تلقائية عند الحاجة

المتطلبات

  • مشروع Google Cloud تم تفعيل الفوترة فيه
  • دور المالك أو المحرّر في إدارة الهوية وإمكانية الوصول (IAM)
  • معرفة أساسية بلغة Python

2. إعداد البيئة

في هذا الدرس التطبيقي حول الترميز، سنستخدم Cloud Shell.

ما هي Cloud Shell؟

‫Cloud Shell هي بيئة Linux مجانية مستندة إلى المتصفّح تتضمّن كل ما تحتاج إليه مثبّتًا مسبقًا: gcloud وgit وPython وDocker وغير ذلك. ولن تحتاج إلى تثبيت أي شيء على جهازك.

لفتح Cloud Shell، انقر على رمز الوحدة الطرفية في شريط الأدوات أعلى يسار "وحدة تحكّم Google Cloud Platform":

فتح Cloud Shell من شريط أدوات GCP Console

عند فتح Cloud Shell للمرة الأولى، سيُطلب منك إثبات ملكية حسابك. انقر على إثبات الملكية:

مربّع حوار تأكيد الحساب

بعد ذلك، انقر على تفويض للسماح لـ Cloud Shell بإجراء طلبات إلى Google Cloud API:

مربّع حوار تفويض Cloud Shell

أصبح Cloud Shell جاهزًا الآن. ستظهر لك رسالة ترحيب في نافذة الوحدة الطرفية: أصبحت نافذة Cloud Shell الطرفية جاهزة

المصادقة على مشروعك وإعداده

تمّت مصادقة Cloud Shell باستخدام حسابك على Google. تأكَّد من حسابك النشط واعثر على رقم تعريف مشروعك باتّباع الخطوات التالية:

gcloud config list

يمكنك أيضًا الاطّلاع على رقم تعريف المشروع في لوحة بيانات وحدة تحكّم Google Cloud Platform على اللوحة الجانبية اليمنى. انسخها، ستحتاج إليها في الأمر التالي:

العثور على رقم تعريف مشروعك في GCP Console وتعيينه في Cloud Shell

الآن، اضبط مشروعك على النحو التالي:

export PROJECT_ID=$(gcloud config get-value project)
export REGION="us-central1"        # Cloud Run deployment region
echo "Project: $PROJECT_ID"

الناتج المتوقّع:

Project: my-project-123

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

gcloud services enable \
    aiplatform.googleapis.com \
    apphub.googleapis.com \
    run.googleapis.com \
    cloudbuild.googleapis.com \
    artifactregistry.googleapis.com \
    generativelanguage.googleapis.com \
    iam.googleapis.com \
    cloudresourcemanager.googleapis.com \
    storage.googleapis.com \
    secretmanager.googleapis.com

يستغرق ذلك حوالي دقيقتين. ستظهر لك علامة Operation finished successfully عند اكتمال العملية.

إعداد "بيانات الاعتماد التلقائية للتطبيق" (ADC)

ستتصل الوكلاء بمنصة Gemini Enterprise Agent Platform باستخدام مكتبة Google Auth، التي تتطلّب بيانات الاعتماد التلقائية للتطبيق، وهي منفصلة عن مصادقة واجهة سطر الأوامر gcloud.

نفِّذ هذا الأمر مرة واحدة:

gcloud auth application-default login

ستفتح علامة تبويب متصفّح تطلب منك تأكيد الإجراء. انقر على سماح. وسترى ما يلي:

Credentials saved to file: ~/.config/gcloud/application_default_credentials.json

إنشاء نسخة طبق الأصل من مستودع التطبيق النموذجي

يستخدم هذا الدرس التطبيقي حول الترميز مستودعًا أوليًا، وهو عبارة عن مشروع هيكلي يتضمّن جميع البنية الأساسية (ملفات Dockerfile وpyproject.toml وبرامج النشر)، ولكن عليك كتابة منطق الوكيل.

git clone https://github.com/Saoussen-CH/mas-a2a-gcp.git ~/ai-creative-studio
cd ~/ai-creative-studio/workshop/starter

يحتوي كل agent.py على عناصر نائبة # TODO حيث ستكتب منطق الوكيل. اكتملت النصوص البرمجية Dockerfile وpyproject.toml ونشرها.

ضبط متغيرات البيئة

انسخ المثال المقدَّم وأدخِل رقم تعريف مشروعك في خطوة واحدة:

cp .env.example .env
sed -i "s|GOOGLE_CLOUD_PROJECT=your-project-id|GOOGLE_CLOUD_PROJECT=$(gcloud config get-value project)|" .env

بعد ذلك، أنشِئ حزمة GCS حيث سيخزّن "المصمّم" الصور التي تم إنشاؤها وعدِّل .env باسمها:

export PROJECT_ID=$(gcloud config get-value project)
export BUCKET_NAME="${PROJECT_ID}-campaign-images"

gcloud storage buckets create gs://${BUCKET_NAME} \
    --location=us-central1 \
    --project=${PROJECT_ID}

sed -i "s|GCS_IMAGES_BUCKET=your-project-id-campaign-images|GCS_IMAGES_BUCKET=${BUCKET_NAME}|" .env

بعد ذلك، يمكنك إعداد ميزة "عناوين URL الموقّعة للصور". ينشئ "المدير الإبداعي" روابط HTTPS قابلة للنقر لكل صورة في الملخّص النهائي للحملة. يتطلّب ذلك استخدام حساب خدمة لتوقيع عناوين URL. شغِّل الأوامر التالية لإعداده:

export PROJECT_NUMBER=$(gcloud projects describe $(gcloud config get-value project) --format="value(projectNumber)")
export SA_EMAIL="${PROJECT_NUMBER}-compute@developer.gserviceaccount.com"
export AGENT_RUNTIME_SA="service-${PROJECT_NUMBER}@gcp-sa-aiplatform-re.iam.gserviceaccount.com"

# Allow your user account to sign URLs locally (adk web)
gcloud iam service-accounts add-iam-policy-binding ${SA_EMAIL} \
  --member="user:$(gcloud config get-value account)" \
  --role="roles/iam.serviceAccountTokenCreator"

# Allow Agent Runtime to sign URLs when deployed
gcloud beta services identity create --service=aiplatform.googleapis.com
gcloud projects add-iam-policy-binding $(gcloud config get-value project) \
  --member="serviceAccount:${AGENT_RUNTIME_SA}" \
  --role="roles/iam.serviceAccountTokenCreator"

# Save SA email and project number to .env
grep -q "^SIGNING_SERVICE_ACCOUNT" .env \
  && sed -i "s|^SIGNING_SERVICE_ACCOUNT=.*|SIGNING_SERVICE_ACCOUNT=${SA_EMAIL}|" .env \
  || echo "SIGNING_SERVICE_ACCOUNT=${SA_EMAIL}" >> .env

grep -q "^GOOGLE_CLOUD_PROJECT_NUMBER" .env \
  && sed -i "s|^GOOGLE_CLOUD_PROJECT_NUMBER=.*|GOOGLE_CLOUD_PROJECT_NUMBER=${PROJECT_NUMBER}|" .env \
  || echo "GOOGLE_CLOUD_PROJECT_NUMBER=${PROJECT_NUMBER}" >> .env

افتح .env في المحرّر لمراجعة جميع الإعدادات:

cloudshell edit .env

سيؤدي ذلك إلى فتح .env كعلامة تبويب في "محرِّر Cloud Shell". انقر على الزر فتح المحرِّر في شريط الأدوات إذا لم تكن لوحة المحرِّر مرئية:

انقر على "فتح المحرِّر" في شريط أدوات Cloud Shell

أداة Cloud Shell Editor مع شجرة ملفات المشروع

تأكَّد من إعداد المشروع بشكلٍ صحيح:

grep GOOGLE_CLOUD_PROJECT .env

تثبيت الحِزم التابعة

نستخدم uv، وهي أداة سريعة وحديثة لإدارة حِزم Python تتعامل مع البيئات الافتراضية وتثبّت الحِزم في أداة واحدة. وهي أسرع من pip بحوالي 10 إلى 100 مرة، كما أنّها الطريقة المُقترَحة لإدارة مشاريع Python.

تم تثبيت uv مسبقًا في Cloud Shell. تتشارك جميع البرامج الوسيطة في التبعيات الأساسية نفسها، لذا ثبِّت التبعيات مرة واحدة وستعمل مع كل برنامج وسيط في هذا الدرس العملي:

uv sync

يقرأ الأمر uv sync الملف pyproject.toml وينشئ الدليل .venv/ مع جميع العناصر التابعة. يحتوي كل متخصص أيضًا على pyproject.toml خاص به تستخدمه إصدارات Docker حصريًا، ويشمل التثبيت المشترَك أعلاه كل ما تحتاج إليه للاختبار المحلي.

3- التعرّف على حزمة تطوير التطبيقات (ADK) من Google

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

ما هي "حزمة تطوير التطبيقات" (ADK)؟

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

تتولّى حزمة ADK الأجزاء المعقّدة، مثل استدعاء الأدوات والمحادثات المترابطة وإدارة السياق والبث، حتى تتمكّن من التركيز على منطق الوكيل.

المكوّنات الأساسية لوكيل ADK

يتألف كل وكيل من أربع وحدات أساسية:

حظر

الدور

الطراز

النموذج اللغوي الكبير الذي يحلّل الأهداف ويحدّد خطة وينشئ ردودًا

الأدوات

الدوال التي تسترد البيانات أو تنفّذ إجراءات من خلال طلب البيانات من واجهات برمجة التطبيقات أو الخدمات

التنسيق

يحافظ على الذاكرة والحالة خلال المحادثات، ويوجه طلبات استخدام الأدوات، ويعيد النتائج إلى النموذج

وقت التشغيل

يتم تنفيذ النظام عند استدعائه، إما محليًا من خلال adk web أو كخدمة تم نشرها.

تعريف الوكيل

يتم تعريف كل من العملاء الخمسة في هذا الدرس البرمجي بالطريقة نفسها:

from google.adk.agents import Agent
from google.adk.tools.google_search_tool import google_search

root_agent = Agent(
    name="brand_strategist",                              # unique identifier
    model=os.getenv("GEMINI_MODEL", "gemini-3.5-flash"), # the LLM powering this agent
    instruction=SYSTEM_INSTRUCTION,                       # the agent's persona, constraints, and output format
    description="Brand strategist for market research, trend analysis, and competitive insights",
    tools=[google_search],                                # functions the LLM can call
)

الحقل

الغرض

name

المعرّف الفريد: تستخدمه أدوات التنسيق لتوجيه المكالمات

model

نموذج Gemini الذي يستند إليه هذا الوكيل

instruction

طلب النظام: يحدّد دور الوكيل والقيود وتنسيق الرسالة

description

ملخّص من سطر واحد: يقرأ المنسّق هذا الملخّص لتحديد الخبير الذي يجب التواصل معه

tools

الدوال التي يمكن للنموذج اللغوي الكبير استدعاؤها (المضمّنة مثل google_search أو دوال Python المخصّصة)

طريقة تشغيل ADK للوكيل

User message
     
     
  Agent (LLM)   reads instruction + conversation history
     
     ├─► needs more info?  calls a tool  gets result  continues reasoning
     
     └─► done reasoning  returns final text response

يقرّر النموذج اللغوي الكبير بشكل مستقل ما إذا كان سيستدعي أداة معيّنة، وأي أداة، وما هي الوسيطات التي سيستخدمها. ما عليك سوى كتابة التعليمات، وسيتولّى "حزمة تطوير التطبيقات لنظام Android" تنفيذ بقية الخطوات.

4. إنشاء وكيل "استراتيجي العلامة التجارية" واختباره

لنبدأ بالوكيل الأول: "استراتيجي العلامة التجارية". هذه أداة بحث فقط للعثور على إحصاءات الجمهور المستهدَف وتحليل المنافسين والمواضيع الرائجة باستخدام "بحث Google".

افتح ملف الوكيل الأساسي في "محرِّر Cloud Shell":

cloudshell edit agents/brand_strategist/agent.py

سيظهر لك قسمان # TODO لتملأهما.

المهمة 1: كتابة تعليمات النظام

أولاً، عليك كتابة تعليمات النظام للوكيل. تعليمات النظام هي سلسلة تحدّد دور الوكيل وقيوده وتنسيق الإخراج.

SYSTEM_INSTRUCTION = f"""You are a Brand Strategist specializing in market research and trend analysis.

IMPORTANT: Today's date is {datetime.date.today().strftime("%B %d, %Y")}.
When conducting research, focus on current trends from {datetime.date.today().year}.
Use search queries like "[topic] trends {datetime.date.today().year}" for recent insights.

IMPORTANT: Your role is RESEARCH ONLY. You do NOT create campaign content, captions, or designs.
After providing research insights, your work is complete.

Your expertise:
- Identifying target audience insights and behaviors
- Analyzing competitor strategies
- Researching current social media trends
- Understanding platform algorithms and best practices

You have access to:
- google_search: Search the web for competitors, trends, and market insights

When given a campaign brief:
1. Use google_search to research the target audience's current interests
2. Search for and analyze 2-3 competitor brands
3. Identify 3-5 trending topics related to the product category
4. Provide high-level strategic insights - NOT specific campaign content

DO NOT create captions, copy, designs, or any campaign content.

Format your output as:
**Audience Insights:**
[Key behaviors and preferences based on research]

**Competitive Analysis:**
[What 2-3 competitors are doing - strengths and weaknesses]

**Trending Topics:**
[3-5 relevant trends to consider]

**Key Strategic Insights:**
[High-level themes and positioning opportunities]
"""

TODO 2 - Create the root_agent

بعد ذلك، استبدِل root_agent غير المكتمل بما يلي:

root_agent = Agent(
    name="brand_strategist",
    model=os.getenv("GEMINI_MODEL", "gemini-3.5-flash"),
    instruction=SYSTEM_INSTRUCTION,
    description="Brand strategist for market research, trend analysis, and competitive insights",
    tools=[google_search],
)

الاختبار محليًا باستخدام واجهة مستخدم الويب لحزمة ADK

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

uv run adk web agents --allow_origins='*'

وسترى ما يلي:

INFO: Started server process
INFO: Uvicorn running on http://localhost:8000

يعمل الخادم الآن داخل Cloud Shell:

لفتحها في المتصفّح، استخدِم معاينة الويب:

  1. انظر إلى شريط أدوات Cloud Shell في أعلى الصفحة
  2. انقر على رمز معاينة الويب (يبدو كمربّع يحتوي على سهم للأعلى، أعلى يسار شريط أدوات Cloud Shell).
  3. انقر على "تغيير المنفذ" وأدخِل 8000، ثم انقر على "تغيير ومعاينة".

يتم فتح علامة تبويب متصفّح جديدة تحتوي على واجهة مستخدم ADK على الويب. انقر على القائمة المنسدلة "اختيار وكيل" في أعلى يمين الصفحة، وستظهر لك قائمة بجميع وكلائك:

اختَر brand_strategist لبدء الاختبار:

جرِّب الطلبات الاختبارية التالية

في مربّع المحادثة بواجهة مستخدم الويب الخاصة بـ ADK، جرِّب ما يلي:

  • Research the eco-friendly water bottle market for health-conscious millennials
  • What are the top Instagram trends in the wellness space in for this year?

من المفترض أن ترى الوكيل يتصل بمحرّك بحث Google ويعرض نتائج بحث منظَّمة تتضمّن أقسام "إحصاءات الجمهور" و"تحليل تنافسي" و"المواضيع الرائجة".

5- إنشاء تطبيق Copywriter - مهارات ADK

الدور: تحويل أبحاث العلامات التجارية إلى تعليقات على Instagram ينشئ كاتب الإعلانات 3 صيغ مختلفة للتعليق تغطي نبرات مختلفة (ملهمة، تعليمية، مجتمعية)، كلّ منها يتضمّن علامات هاشتاغ وعبارة تحثّ على اتّخاذ إجراء.

المفهوم: مهارات ADK

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

تتيح لك مهارات ADK (SkillToolset، تم طرحها في الإصدار 1.25.0 من ADK) تجميع هذه المعرفة في ملفات نموذجية بثلاثة مستويات من التحميل:

  • المستوى 1 - المواد التمهيدية (name + description في SKILL.md): متوفّرة دائمًا، وتُستخدم لاكتشاف المهارات
  • المستوى 2 - التعليمات (نص SKILL.md): يتم تحميله عندما يفعّل الوكيل المهارة
  • المستوى 3 - الموارد (ملفات references/ وassets/): يتم تحميلها فقط عندما يقرأها الوكيل بشكل صريح

يتم تقليص تعليمات النظام إلى بيان دور قصير بالإضافة إلى "تحميل المهارة قبل الكتابة". لا يتم إدخال تفاصيل النظام الأساسي في قدرة الاستيعاب إلا عندما يحتاج إليها الوكيل فعلاً.

تتوفّر مهارة "كاتب الإعلانات" في agents/copywriter/skills/instagram-copywriting/:

skills/
  instagram-copywriting/
    SKILL.md                        L1 frontmatter (discovery) + L2 instructions (loaded on trigger)
    references/
      platform-guide.md             L3: character limits, hashtag tiers, algorithm signals
      caption-formulas.md           L3: hook formulas, CTA patterns, full caption structures
    assets/
      brand-voice-examples.md       L3: annotated real-world caption examples

افتح الملف مباشرةً في محرِّر Cloud Shell:

cloudshell edit agents/copywriter/agent.py

TODO 1 - استيراد load_skill_from_dir وskill_toolset

ابحث عن التعليق # TODO 1: Import load_skill_from_dir and skill_toolset وأضِف عمليتَي الاستيراد التاليتَين:

from google.adk.skills import load_skill_from_dir
from google.adk.tools import skill_toolset

TODO 2 - تحميل المهارة وإنشاء SkillToolset

ابحث عن التعليقَين أدناه:

# TODO 2: Load the instagram-copywriting skill from the skills/ directory
# TODO 2: Create a SkillToolset with the loaded skill

استبدِلها بما يلي:

_instagram_skill = load_skill_from_dir(
    pathlib.Path(__file__).parent / "skills" / "instagram-copywriting"
)
_copywriting_skills = skill_toolset.SkillToolset(skills=[_instagram_skill])

يقرأ load_skill_from_dir SKILL.md بالإضافة إلى أي ملفات في references/ وassets/. تعمل العلامة SkillToolset على تحويلها إلى التنسيق الذي تقبله وكلاء ADK، أي مجموعة أدوات وليس مهارة أولية.

TODO 3 - تسجيل مجموعة الأدوات لدى الوكيل

ابحث عن tools=[], # TODO 3: Add the SkillToolset here واستبدله بما يلي:

tools=[_copywriting_skills],

افتح ملف المهارة للاطّلاع على طريقة تنظيمه:

cloudshell edit agents/copywriter/skills/instagram-copywriting/SKILL.md

استمرار تشغيل واجهة مستخدم الويب الخاصة بـ ADK استخدِم القائمة المنسدلة الخاصة بالوكيل للتبديل إلى copywriter بدون إعادة تشغيل الخادم.

إذا لم يكن قيد التشغيل، ابدأه مرة أخرى:

uv run adk web agents --allow_origins='*'

جرِّب ذلك: بدِّل القائمة المنسدلة إلى copywriter وأرسِل:

You are writing captions for EcoFlow Smart Water Bottle targeting health-conscious millennials aged 25-35.
Audience insight: they prioritize sustainability, track health metrics, and share lifestyle content.
Competitor insight: Hydro Flask dominates with lifestyle branding; S'well leads on premium aesthetics.
Write 3 Instagram captions - one inspirational, one educational, one community-focused. Include 5 hashtags each and a CTA.

6. Build the Designer - Multimodal Image Generation

استمرار تشغيل واجهة مستخدم الويب الخاصة بـ ADK استخدِم القائمة المنسدلة الخاصة بالوكيل للتبديل بين الوكلاء بدون إعادة تشغيل الخادم.

الدور: إنشاء مفاهيم مرئية لكل تعليق توضيحي وإنشاء الصور الفعلية باستخدام ميزة إنشاء الصور الأصلية في Gemini تنتج أداة Designer مفهومًا مرئيًا واحدًا بالضبط لكل تعليق توضيحي، مع طلب تفصيلي وأسلوب ولوحة ألوان ومزاج وتنسيق Instagram، ثم تستدعي أداة generate_image على الفور لإنتاج الصورة الفعلية وتحميلها إلى GCS.

المفهوم: ربط وكيل نصي بنموذج صور من خلال أداة

يعمل "المصمّم" على gemini-3-flash-preview (نموذج النص الذي تم ضبطه من خلال GEMINI_MODEL في .env)، ولكن يتطلّب إنشاء الصور نموذجًا مخصّصًا (gemini-3.1-flash-image). لا يتيح نموذج الصور هذا ميزة "استدعاء الدوال البرمجية"، لذا لا يمكن استخدامه مباشرةً كوكيل في "حزمة تطوير التطبيقات" (ADK). بدلاً من ذلك، يتم تضمينها في دالة Python عادية وتسجيلها كـ FunctionTool.

هذا هو النمط المتبّع مع أي نموذج أو واجهة برمجة تطبيقات لا يمكن للنموذج اللغوي الكبير استدعاؤها مباشرةً: يتم تضمينها في أداة، ويسمح للوكيل بتحديد وقت استدعائها، ثم يتم الحصول على نتيجة منظَّمة.

Designer agent (text model)
        
          decides visual concept, writes image prompt
        
  generate_image tool
        
          calls gemini-3.1-flash-image
          uploads result to GCS
        
  {"status": "success", "gcs_uri": "gs://..."}
        
          returned to agent, included in response
        
  Critic (receives gcs_uri, passes to Vertex AI for multimodal review)

افتح الملف مباشرةً في محرِّر Cloud Shell:

cloudshell edit agents/designer/image_gen_tool.py

يتم توفير توقيع الدالة وإعداد البيئة وإدخال نسبة العرض إلى الارتفاع. نفِّذ المهام الثلاث المدرَجة في قائمة المهام بالترتيب:

TODO 1 - استدعاء نموذج الصور في Gemini

ابحث عن التعليق # TODO 1 واستبدِله بما يلي:

        client = genai.Client(vertexai=True, project=project_id, location=location)

        response = client.models.generate_content(
            model=image_model,
            contents=prompt_with_aspect,
            config=types.GenerateContentConfig(
                response_modalities=["IMAGE", "TEXT"],
                http_options=types.HttpOptions(
                    retry_options=types.HttpRetryOptions(
                        attempts=5, exp_base=2, initial_delay=30,
                        http_status_codes=[429, 500, 503, 504],
                    ),
                    timeout=180_000,
                ),
            ),
        )

TODO 2 - استخراج وحدات بايت الصورة من الرد

ابحث عن التعليق # TODO 2 واستبدِله بما يلي:

        image_bytes = None
        mime_type = "image/png"
        for part in response.candidates[0].content.parts:
            if part.inline_data is not None:
                image_bytes = part.inline_data.data
                mime_type = part.inline_data.mime_type or "image/png"
                break

        if not image_bytes:
            return {"status": "error", "error": "Gemini returned no image data"}

TODO 3 - تحميل إلى GCS وعرض معرّف الموارد المنتظم

ابحث عن التعليق # TODO 3 واستبدِله بما يلي:

        ext = "jpg" if "jpeg" in mime_type else "png"
        from google.cloud import storage
        gcs_client = storage.Client(project=project_id)
        bucket = gcs_client.bucket(bucket_name)
        blob_name = f"campaign-images/{concept_name}-{uuid.uuid4().hex[:8]}.{ext}"
        blob = bucket.blob(blob_name)
        blob.upload_from_file(io.BytesIO(image_bytes), content_type=mime_type)
        gcs_uri = f"gs://{bucket_name}/{blob_name}"

جرِّب ذلك: بدِّل القائمة المنسدلة إلى designer وأرسِل:

Create a visual concept and generate the image for an EcoFlow Smart Water Bottle Instagram post targeting health-conscious millennials.
Style: clean, modern, lifestyle-focused. Include a detailed prompt with color palette, mood, and format (1080x1080 or 1080x1350).

7. إنشاء أداة Critic - Structured Output

الدور: ضمان جودة النصوص والصور قبل تسليمها إلى مدير المشروع يقيّم الناقد كلاً من المنتجات التي تم تسليمها ويعرض APPROVED أو NEEDS_REVISION مع اقتراحات محدّدة. عندما تكون قيم gcs_uri متوفّرة في الإدخال، تستدعي الأداة review_image لفحص كل صورة تم إنشاؤها بصريًا قبل تقييمها.

المفهوم: متى يجب استخدام نموذج Pydantic لنتائج Gemini؟

تتعلّق القاعدة بالمستخدمين الذين يستهلكون الناتج:

  • يستهلك رمز Python البرمجي هذا التنسيق → استخدِم response_schema + Pydantic. لا يمكن للرمز البرمجي التعامل مع الغموض، لذا تحتاج إلى بنية مضمونة لاستخراج الحقول بشكل موثوق.
  • يستهلك النموذج اللغوي الكبير (LLM) هذا المحتوى → يكون تنسيق النص بالإضافة إلى تعليمات النظام كافيًا. تستطيع النماذج اللغوية الكبيرة فهم قواعد التنسيق وتقبّل الاختلافات.

في review_image، يحتاج رمز Python البرمجي إلى score وapproval_status وwhat_works وissues وsuggestions كقيم مكتوبة. يؤدي تمرير response_schema=_GeminiReview إلى فرض قيود على Gemini على مستوى واجهة برمجة التطبيقات لعرض JSON صالح، بينما يحلّل model_validate_json() JSON إلى كائن مكتوب يمكن أن يستخدمه الرمز البرمجي بشكل موثوق.

class _GeminiReview(BaseModel):
    score: int = Field(ge=1, le=10)
    approval_status: Literal["APPROVED", "NEEDS_REVISION"]
    what_works: str
    issues: str
    suggestions: str

افتح الملف مباشرةً في محرِّر Cloud Shell:

cloudshell edit agents/critic/image_review_tool.py

يتم توفير نماذج Pydantic والطلب. نفِّذ المهام الثلاث المدرَجة في قائمة المهام بالترتيب:

TODO 1 - Create an image part from the GCS URI

ابحث عن التعليق # TODO 1 واستبدِله بما يلي:

        image_part = types.Part.from_uri(file_uri=gcs_uri, mime_type=mime_type)

TODO 2 - Call Gemini with a structured response schema

ابحث عن التعليق # TODO 2 واستبدِله بما يلي:

        response = client.models.generate_content(
            model=model,
            contents=[image_part, prompt],
            config=types.GenerateContentConfig(
                response_schema=_GeminiReview,
                response_mime_type="application/json",
            ),
        )

TODO 3 - تحليل الردّ وعرض النتيجة

ابحث عن التعليق # TODO 3 واستبدِله بما يلي:

        review = _GeminiReview.model_validate_json(response.text)
        return ImageReviewResult(status="success", concept_name=concept_name, **review.model_dump())

جرِّب ذلك: بدِّل القائمة المنسدلة إلى critic وأرسِل:

Review this Instagram caption for an eco-friendly water bottle brand targeting millennials:
"Hydrate smarter, live greener. 💧 Our EcoFlow bottle tracks your intake, keeps your drink cold for 24h, and never touches single-use plastic. Because what you drink from matters as much as what you drink. #EcoFlow #HydrationGoals #SustainableLiving #ZeroWaste #HealthyHabits - Shop link in bio."
Score it and indicate APPROVED or NEEDS_REVISION with specific feedback.

تأكَّد من أنّ الردّ يتضمّن **POSTS REVIEW:** وStatus: APPROVED (أو NEEDS_REVISION) و**OVERALL ASSESSMENT:**. إذا كانت هذه الأقسام متوفّرة، يكون Critic جاهزًا للاتصال بمنسّق العمليات.

عند الانتهاء من اختبار جميع البرامج الثلاثة، اضغط على Ctrl+C لإيقاف الخادم.

8. إنشاء وكيل مدير المشاريع باستخدام MCP

تقدّم "أداة إدارة المشاريع" مفهومًا جديدًا: بروتوكول سياق النموذج (MCP).

افتح الملف:

cloudshell edit agents/project_manager/agent.py

هذا الملف أكثر تعقيدًا، إذ يتضمّن الدالة create_project_manager_agent() مع فرعين: أحدهما بدون Notion (جداول زمنية نصية فقط) والآخر مع مجموعة أدوات Notion MCP. عليك ملء كليهما.

المشكلة التي يحلّها MCP

يحتاج الوكيل إلى طلب خدمة خارجية، مثل إنشاء صفحة في Notion. يمكنك كتابة رمز Python برمجي يستدعي Notion REST API مباشرةً. بعد ذلك:

  • يكتب كل مطوّر برنامج تضمين مختلفًا
  • عليك الحفاظ على رمز الدمج المخصّص
  • لا تعرف النماذج اللغوية الكبيرة أنّ واجهة برمجة التطبيقات متوفّرة إلا إذا وصفت كل نقطة نهاية يدويًا

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

ما هو برنامج MCP؟

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

خادم MCP هو برنامج صغير يعمل على:

  1. تغليف واجهة برمجة تطبيقات خارجية (Notion وGitHub وقواعد البيانات وأنظمة الملفات وما إلى ذلك)
  2. تعرض واجهة برمجة التطبيقات هذه على شكل قائمة أدوات موثّقة ومحدّدة النوع
  3. يتواصل مع الوكيل من خلال بروتوكول بسيط (stdio أو HTTP)

يتصل الوكيل بخادم بروتوكول سياق النموذج (MCP)، ويكتشف تلقائيًا الأدوات المتاحة، ويمكنه استدعاؤها مثل أي أداة أخرى، إذ ترى نماذج اللغات الكبيرة API-post-page(...) كدالة قابلة للاستدعاء.

ما الفرق بين A2A وMCP؟

وهذا من أكثر النقاط التي يحدث فيها التباس. في ما يلي الفرق الرئيسي:

A2A

MCP

ما يتم ربطه

الوكيل ↔ الوكيل

الوكيل ↔ أداة أو خدمة خارجية

الجانب الآخر هو

وكيل آخر للنموذج اللغوي الكبير

برنامج تضمين لواجهة برمجة التطبيقات (بدون نموذج لغوي كبير)

مثال

مدير التصميم يتصل بمحلّل استراتيجي للعلامة التجارية

مدير المشروع يرسل طلبات إلى واجهة برمجة التطبيقات في Notion

البروتوكول

JSON-RPC over HTTPS

بث stdio أو HTTP

التعريف

Google

Anthropic

فكر في الأمر بهذه الطريقة:

  • التواصل بين التطبيقات: طريقة تواصل الوكلاء مع بعضهم البعض
  • MCP = طريقة تواصل الوكلاء مع الأدوات والخدمات

في هذا المشروع، يتم استخدام كليهما معًا:

Creative Director
    
      (A2A)  Brand Strategist ─── (google_search tool built into ADK)
      (A2A)  Copywriter
      (A2A)  Designer
      (A2A)  Critic
      (A2A)  Project Manager
                   
                     (MCP)  notion-mcp-server ──► Notion REST API

طريقة عمل MCP في هذا المشروع

عند تشغيل الوكيل، يطلق ADK عملية notion-mcp-server كعملية فرعية. تتيح هذه العملية للنموذج اللغوي الكبير الوصول إلى هذه الأدوات مباشرةً:

الأداة

وظيفتها

API-retrieve-a-database

يجلب المخطط (أسماء السمات وأنواعها وقيمها الصالحة)

API-post-database-query

طلبات البحث في الصفحات الحالية

API-post-page

إنشاء صفحة جديدة

API-patch-page

تعديل صفحة حالية

تستدعي نماذج اللغات الكبيرة هذه الدوال مثل أي دالة أخرى، فهي لا تعرف أنّها تمرّ عبر MCP إلى واجهة برمجة تطبيقات REST في Notion في الخلفية.

لماذا stdio؟ لماذا لا نستخدم بروتوكول HTTP فقط؟

يعمل خادم MCP كعملية فرعية للوكيل، ويتواصل عبر stdin/stdout. وهذا يعني ما يلي:

  • لا حاجة إلى منفذ شبكة إضافي
  • يدير الوكيل دورة الحياة (بدء التشغيل عند الطلب، والإيقاف عند الخروج)
  • يتم شحن كل شيء في صورة Docker واحدة، بدون الحاجة إلى خدمة منفصلة لنشرها.

(اختياري) تفعيل عملية الدمج مع Notion

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

إذا كان لديك حساب على Notion وأردت تجربة عملية الدمج مع بروتوكول سياق النموذج (MCP)، أكمِل عملية الإعداد أدناه الآن. تشير المهام التي تلي ذلك إلى أرقام تعريف قاعدة بيانات Notion، وهي المكان الذي يمكنك الحصول عليها منه.

الخطوة 1: إنشاء قاعدة بيانات Notion من نموذج

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

انقر على الرابط أدناه لإضافة القالب إلى مساحة عملك في Notion:

→ إضافة نموذج "المشاريع والمهام" إلى Notion

نموذج "المشاريع والمهام" في Notion في Marketplace

بعد إضافتها، سيكون لديك قاعدتا بيانات مرتبطتان: المشاريع والمهام. يتضمّن النموذج إدخالات نموذجية، لذا احذفها كلها قبل المتابعة لكي يبدأ الوكيل بمساحة عمل فارغة (اختَر الكل → حذف).

الخطوة 2: إنشاء عملية دمج في Notion

إنشاء عملية الدمج:

  1. انتقِل إلى notion.so/my-integrations
  2. انقر على عملية دمج جديدة → أطلق عليها اسمًا AI Creative Studio
  3. ربطها بمساحة عملك
  4. انقر على ضبط الإعدادات → تأكَّد من وضع علامة في مربّعات الاختيار بجانب الإذن قراءة المحتوى وتعديل المحتوى وإدراج المحتوى

إعدادات الدمج في Notion: أطلِق عليها اسم "استوديو الإبداع بالذكاء الاصطناعي" وانسخ الرمز المميّز

  1. انسخ رمز التكامل الداخلي (ntn_...) والصقه في ملف .env:
NOTION_TOKEN=ntn_your-token-here

ربط عملية الدمج بقواعد البيانات:

  1. افتح صفحة النموذج التي نسختها للتو، ثم انقر على قاعدة بيانات المشاريع.
  2. انقر على قائمة ... (في أعلى يسار الصفحة) → عمليات الربطإضافة عملية ربط → اختَر AI Creative Studio

انقر على "عمليات الربط" في قائمة قاعدة البيانات للمشاركة مع عملية الدمج.

يظهر "استوديو إبداعي بالذكاء الاصطناعي" كعملية ربط نشطة

  1. كرِّر الخطوات نفسها لقاعدة بيانات المهام

الحصول على أرقام تعريف قاعدة البيانات:

  1. انقر على رابط قاعدة بيانات المشاريع لفتحها، وسيتم فتحها في صفحة منفصلة بعنوان URL على النحو التالي:
https://www.notion.so/9887b6a94f7f83f68f8581e038d1aaa4?v=2c37b6a94f7f838685f1086e312c7278

فتح قاعدة بيانات "المشاريع" من صفحة النموذج

رقم تعريف قاعدة البيانات هو أول معرّف UUID في عنوان URL، أي كل ما يسبق ?v=:

https://www.notion.so/{DATABASE_ID}?v=...
                       ^^^^^^^^^^^^^^^^
                       9887b6a94f7f83f68f8581e038d1aaa4  ← this is your DATABASE_ID
  1. كرِّر الخطوات نفسها مع رابط قاعدة بيانات المهام للحصول على رقم تعريف قاعدة البيانات.
  2. أضِف القيم الثلاث إلى .env:
NOTION_TOKEN=ntn_your-token-here
NOTION_PROJECT_DATABASE_ID=9887b6a94f7f83f68f8581e038d1aaa4   # <-- your Projects DB ID
NOTION_TASKS_DATABASE_ID=your-tasks-db-id                      # <-- your Tasks DB ID

الخطوة 3: تثبيت خادم MCP في Notion

يتصل "مدير المشروع" بتطبيق Notion من خلال حزمة @notionhq/notion-mcp-server Node.js الرسمية. تثبيته على مستوى العالم:

npm install -g @notionhq/notion-mcp-server@1.9.1

التحقّق من عملية التثبيت:

npm list -g @notionhq/notion-mcp-server

الناتج المتوقّع:

└── @notionhq/notion-mcp-server@1.9.1

notion-mcp-server: command not found

? تأكَّد من تثبيت Node.js (node --version) وأنّ مجلد npm global bin مدرَج في PATH (export PATH=$PATH:$(npm bin -g)).

الخطوة 4: التحقّق من ملف ‎ .env

افتح .env وتأكَّد من ضبط جميع قيم Notion الثلاث (أضفتها في الخطوة 2):

cloudshell edit .env
NOTION_TOKEN=ntn_...                           # integration token
NOTION_PROJECT_DATABASE_ID=...                 # Projects database ID
NOTION_TASKS_DATABASE_ID=...                   # Tasks database ID

يرصد وكيل "مدير المشروع" هذه المتغيرات تلقائيًا عند بدء التشغيل ويُفعّل مجموعة أدوات Notion MCP.

طريقة عمل ميزة "اكتشاف المخطط"

يستخدم "مدير المشروع" اكتشاف المخطط الديناميكي، ولا يرمز أبدًا إلى أسماء خصائص Notion:

Step 1: Call API-retrieve-a-database to discover exact property names
Step 2: Read the "properties" object in the response
Step 3: Use ONLY discovered property names (case-sensitive) in API calls
Step 4: For select/status fields, use only values from the options array

وهذا يعني أنّ الوكيل يتكيّف مع أي بنية لقاعدة بيانات Notion تلقائيًا، فإذا أعدت تسمية خصائصك إلى الفرنسية أو العربية أو أي لغة أخرى، سيظل الوكيل يعمل.

المهمة 1: كتابة تعليمات النظام

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

مهمتك هي استبدال العنصر النائب return بتعليمات نظام حقيقية تستخدم {notion_section}:

    return f"""You are a Project Manager specializing in creative campaign execution.

Today's date is {datetime.date.today().strftime("%B %d, %Y")}.
Use this as the starting point for all timelines.

Your goal: create a complete project plan for the campaign.
{notion_section}
**Project Timeline:**
Phase 1: Strategy & Research | [date]  [date] | [key activities]
Phase 2: Content Creation    | [date]  [date] | [key activities]
Phase 3: Review & Revision   | [date]  [date] | [key activities]
Phase 4: Launch & Monitoring | [date]  [date] | [key activities]

**Task List:**
| Task | Owner | Deadline | Status |
[list each task with realistic deadlines from today; set Owner to TBD]

**Budget Breakdown:**
[by category with approximate allocations]

**Milestones:**
[3-5 key checkpoints with dates]

**Notion Status:**
[What happened - e.g. "Project created (ID: xxx), 8 tasks linked" or "Notion not configured - text timeline only"]
"""

TODO 2 - Agent without Notion

داخل create_project_manager_agent()، في الفرع if not notion_token، استبدِل الوكيل غير المكتمل بما يلي:

        return Agent(
            name="project_manager",
            model=os.getenv("GEMINI_MODEL", "gemini-3.5-flash"),
            generate_content_config=GENERATE_CONTENT_CONFIG,
            instruction=get_system_instruction(),
            description="Project manager that creates campaign timelines and task breakdowns",
        )

‫TODO 3 - وكيل باستخدام Notion MCP

ملاحظة: يحتوي ملف البداية على عملية ردّ الاتصال handle_notion_error المكتوبة مسبقًا فوق create_project_manager_agent(). تعترض هذه الأداة أخطاء واجهة برمجة التطبيقات في Notion (400/404) وتستبدل حمولات الأخطاء الأولية برسائل واضحة وقابلة للتنفيذ، ما يتيح للنموذج اللغوي الكبير تصحيح الأخطاء بنفسه. ما عليك سوى توصيله عبر after_tool_callback.

أولاً، اقرأ معرّفَي قاعدة البيانات في أعلى create_project_manager_agent():

    notion_token           = os.getenv("NOTION_TOKEN")
    notion_project_db_id   = os.getenv("NOTION_PROJECT_DATABASE_ID")
    notion_tasks_db_id     = os.getenv("NOTION_TASKS_DATABASE_ID")

بعد ذلك، في فرع else، أنشئ مجموعة أدوات MCP والوكيل:

        from google.adk.tools.mcp_tool import McpToolset, StdioConnectionParams
        from mcp import StdioServerParameters

        server_params = StdioServerParameters(
            command="notion-mcp-server",
            env={
                "NOTION_TOKEN": notion_token,
                "PATH": os.environ.get("PATH", ""),
            }
        )
        notion_toolset = McpToolset(
            connection_params=StdioConnectionParams(
                server_params=server_params,
                timeout=30.0
            )
        )

        return Agent(
            name="project_manager",
            model=os.getenv("GEMINI_MODEL", "gemini-3.5-flash"),
            generate_content_config=GENERATE_CONTENT_CONFIG,
            after_tool_callback=handle_notion_error,
            instruction=get_system_instruction(
                project_database_id=notion_project_db_id,
                tasks_database_id=notion_tasks_db_id,
            ),
            description="Project manager with Notion integration for task tracking",
            tools=[notion_toolset],
        )

أفضل الممارسات: لا تتوقّف عن العمل بشكل نهائي عند حدوث خطأ في عمليات الدمج الاختيارية. يكون المخطط الزمني النصي دائمًا هو المنتج الأساسي، بينما يكون Notion مكمّلاً له.

اختبار "مدير المشاريع" محليًا باستخدام ADK Web

uv run adk web agents --allow_origins='*'

افتح "معاينة الويب" على المنفذ 8000. استخدِم القائمة المنسدلة الخاصة بالوكيل لاختيار project_manager، ثم جرِّب ما يلي:

Create a project plan for a GreenBrew organic coffee brand Instagram campaign.
Budget: $2,500. Launch in 3 weeks. Target audience: eco-conscious millennials aged 22-30.
Include phases, tasks with deadlines from today, and milestones.

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

9. التعرّف على بروتوكول A2A

سنستخدم بروتوكول Agent-to-Agent (A2A) لربط النماذج الوكيلة المختلفة في نظامنا. لنتعرّف على طريقة عملها.

المشكلة التي يحلّها تطبيق A2A

لنفترض أنّ لديك وكيل "خبير استراتيجي في مجال العلامات التجارية" تم إنشاؤه باستخدام ADK ووكيل "كاتب إعلانات" تم إنشاؤه باستخدام LangGraph. كيف يمكن لأحدهما الاتصال بالآخر؟ وهي تتحدّث بلغات داخلية مختلفة. وستحتاج إلى كتابة رمز ربط مخصّص في كل مرة.

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

ما هي واجهة برمجة التطبيقات A2A؟

‫Agent-to-Agent (A2A) هو معيار مفتوح للتواصل بين الوكلاء نشرته Google. يحدّد ما يلي:

  1. كيف يصف الوكيل نفسه - بطاقة الوكيل في /.well-known/agent.json
  2. كيفية استدعاء وكيل آخر له - JSON-RPC عبر HTTPS
  3. طريقة عرض النتائج - بث مباشر أو ردّ واحد

ما يجعل A2A مرنًا:

  • متوافق مع لغات متعددة: يمكن لوكلاء Python التواصل مع وكلاء TypeScript
  • متوافق مع جميع الأُطر: يمكن لوكلاء ADK التحدث مع وكلاء LangGraph أو CrewAI
  • لا تعتمد على البنية التحتية، إذ يمكن للوكلاء المحليين التحدّث مع الوكلاء السحابيين

طريقة العمل - خطوة بخطوة

Creative Director                  Brand Strategist
      │                                  │
      │  1. GET /.well-known/agent.json  │
      │ ────────────────────────────────►│
      │  ◄──── agent card (name, url,    │
      │         skills, capabilities) ───│
      │                                  │
      │  2. POST /                       │
      │     {"method": "tasks/send",     │
      │      "params": {"message": ...}} │
      │ ────────────────────────────────►│
      │                                  │  LLM does
      │                                  │  the work...
      │  3. streaming response chunks    │
      │  ◄───────────────────────────────│
      │  ◄───────────────────────────────│
      │  ◄───────────────────────────────│

الخطوة 1 - الاكتشاف: يستردّ المنسّق بطاقة الوكيل مرة واحدة للتعرّف على اسم الوكيل وعنوان URL وإمكاناته.

الخطوة 2 - الاستدعاء: يرسل المنسّق مهمةً عبر JSON-RPC POST. يتضمّن النص الرسالة (الطلب المقدَّم إلى الاختصاصي).

الخطوة 3 - الرد: يبثّ الاختصاصي الرد على شكل أجزاء، تمامًا كما يحدث في طلب عادي من نموذج لغوي كبير.

بطاقة الوكيل

ينشر كل وكيل وصفًا ذاتيًا في /.well-known/agent.json. هذا التعريف يشبه بطاقة العمل، فهو يخبر العالم بما يمكن أن يفعله الوكيل ومكان الوصول إليه:

{
  "name": "brand_strategist",
  "description": "Market research and competitive analysis",
  "url": "https://brand-strategist-xyz.run.app",
  "capabilities": { "streaming": true },
  "skills": [
    {
      "id": "market_research",
      "description": "Research target audiences, competitors, and trends"
    }
  ]
}

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

عرض وكيل من خلال A2A في ADK

تلتف العلامة to_a2a() حول أي وكيل ADK في تطبيق FastAPI متوافق مع A2A، وذلك في سطر واحد:

from google.adk.a2a.utils.agent_to_a2a import to_a2a

# root_agent = your normal ADK Agent(...)
a2a_app = to_a2a(root_agent, host=PUBLIC_HOST, port=PUBLIC_PORT, protocol=PROTOCOL)
uvicorn.run(a2a_app, host=HOST, port=PORT)

يؤدي ذلك إلى إنشاء ما يلي تلقائيًا:

  • /.well-known/agent.json - بطاقة الوكيل
  • /: نقطة نهاية JSON-RPC (تنتقل جميع طلبات مهام A2A إلى المسار الجذر)

10. عرض الوكلاء كخدمات A2A

لعرض الوكلاء كخدمات من تطبيق إلى تطبيق، يمكنك استخدام الدالة المساعدة to_a2a() من ADK.

طريقة عمل to_a2a()

from google.adk.a2a.utils.agent_to_a2a import to_a2a

a2a_app = to_a2a(root_agent, host=PUBLIC_HOST, port=PUBLIC_PORT, protocol=PROTOCOL)
uvicorn.run(a2a_app, host=HOST, port=PORT)

تغلّف to_a2a() وكيل ADK في تطبيق FastAPI يعرض تلقائيًا ما يلي:

  • /.well-known/agent.json - بطاقة الوكيل (الاسم والوصف والإمكانات)
  • /a2a/{agent_name}: نقطة نهاية JSON-RPC لتلقّي المهام

يتضمّن رمز الهيكل لكل وكيل حاليًا كتلة __main__ تعمل على تضمين الوكيل في خادم A2A باستخدام to_a2a(). لست بحاجة إلى كتابة هذا الرمز، بل سيتم توفيره لك.

التعرّف على إعداد عنوان URL المزدوج

عند تشغيل python agent.py، يستخدم الحظر __main__ إعدادَين منفصلَين لعناوين URL:

# Where the server actually listens (network interface):
HOST = "0.0.0.0"
PORT = 8082  # Brand Strategist (others use 80838086 locally)

# What gets advertised in the agent card (the address other agents use to reach it):
PUBLIC_HOST = os.getenv("PUBLIC_HOST", "localhost")
PUBLIC_PORT = int(os.getenv("PUBLIC_PORT", str(PORT)))
PROTOCOL    = os.getenv("PROTOCOL", "http")

a2a_app = to_a2a(root_agent, host=PUBLIC_HOST, port=PUBLIC_PORT, protocol=PROTOCOL)
uvicorn.run(a2a_app, host=HOST, port=PORT)

البيئة

HOST:PORT (عدد مرات الاستماع)

PUBLIC_HOST:PUBLIC_PORT (معلن عنه في بطاقة الوكيل)

بالتوقيت المحلي

0.0.0.0:8082

http://localhost:8082

Cloud Run

0.0.0.0:8080

https://brand-strategist-xyz.run.app:443

محليًا، يشير كلاهما إلى الجهاز نفسه. في Cloud Run، يستمع الحاوي داخليًا على 8080، ولكن يجب أن تعلن بطاقة الوكيل عن عنوان URL العام الذي يستخدم HTTPS، وإلا لن يتمكّن "المدير الإبداعي" من التواصل مع الخبير من خارج الحاوية.

ابدأ تشغيل جميع خوادم A2A المتخصصة الخمسة

لننفّذ جميع العمليات التي يجريها الخبراء الخمسة كخوادم A2A في الوقت نفسه، ثم نختبر "المدير الإبداعي" محليًا مع توجيهه إلى هذه الخوادم.

افتح 5 نوافذ طرفية منفصلة في Cloud Shell (انقر على الرمز + في شريط علامات تبويب النافذة الطرفية) وشغِّل وكيلاً واحدًا لكل نافذة طرفية.

uv run يفعّل .venv تلقائيًا، بدون الحاجة إلى source يدوي في كل نافذة طرفية.

الوحدة الطرفية 1 - استراتيجي العلامة التجارية (المنفذ 8082):

cd ~/ai-creative-studio/workshop/starter
PORT=8082 uv run agents/brand_strategist/agent.py

الطرفية 2 - كاتب الإعلانات (المنفذ 8083):

cd ~/ai-creative-studio/workshop/starter
PORT=8083 uv run agents/copywriter/agent.py

الوحدة الطرفية 3 - المصمم (المنفذ 8084):

cd ~/ai-creative-studio/workshop/starter
PORT=8084 uv run agents/designer/agent.py

الوحدة الطرفية 4 - الناقد (المنفذ 8085):

cd ~/ai-creative-studio/workshop/starter
PORT=8085 uv run agents/critic/agent.py

الوحدة الطرفية 5 - مدير المشروع (المنفذ 8086):

cd ~/ai-creative-studio/workshop/starter
PORT=8086 uv run agents/project_manager/agent.py

ضبط عناوين URL الخاصة بالمضيف المحلي في ملف ‎ .env

في المحطة 6، عدِّل .env باستخدام عناوين URL الخاصة بالوكيل المحلي حتى يتمكّن المدير الإبداعي من العثور عليها:

cd ~/ai-creative-studio/workshop/starter

sed -i \
  -e 's|STRATEGIST_AGENT_URL=.*|STRATEGIST_AGENT_URL=http://localhost:8082|' \
  -e 's|COPYWRITER_AGENT_URL=.*|COPYWRITER_AGENT_URL=http://localhost:8083|' \
  -e 's|DESIGNER_AGENT_URL=.*|DESIGNER_AGENT_URL=http://localhost:8084|' \
  -e 's|CRITIC_AGENT_URL=.*|CRITIC_AGENT_URL=http://localhost:8085|' \
  -e 's|PM_AGENT_URL=.*|PM_AGENT_URL=http://localhost:8086|' \
  .env

فحص الوكلاء باستخدام أداة A2A Inspector

أداة A2A Inspector هي أداة مفتوحة المصدر للمطوّرين تستخدم بروتوكول A2A بشكلٍ أصلي. تتيح لك هذه الأداة الاتصال مباشرةً بأي وكيل A2A نشط وقراءة بطاقة الوكيل وإرسال المهام، وكل ذلك بدون كتابة أي رمز للعميل.

ما يعرضه لك:

  • بطاقة الوكيل: البيانات الوصفية المنظَّمة التي يعلن عنها الوكيل، مثل اسمه ووصفه وأوضاع الإدخال/الإخراج المتوافقة وعنوان URL لنقطة النهاية هذا ما يقرأه "مدير التصميم" عندما يعثر على خبير.
  • واجهة المحادثة: يمكنك إرسال أي رسالة إلى الوكيل عبر A2A والاطّلاع على الرد الأولي. يمكنك اختبار الطلبات بشكل منفصل قبل ربط الوكلاء ببعضهم.
  • التحقّق من صحة البروتوكول: يتحقّق المدقّق من أنّ بطاقة الوكيل تتوافق مع مواصفات A2A، ويعرض الحقول الناقصة أو الردود المشوّهة في وقت مبكر.

أهمية ذلك: عند النشر على Cloud Run لاحقًا، يكتشف "المدير الإبداعي" كل خبير من خلال استرداد بطاقة الوكيل من /.well-known/agent.json. إذا كانت البطاقة غير صحيحة، أي عنوان URL غير صالح أو قدرات غير متوفّرة، سيتعذّر على أداة التنسيق تنفيذ الطلب بدون إظهار أي رسالة خطأ. تتيح لك أداة الفحص رصد هذه المشاكل محليًا قبل أي عملية نشر على السحابة الإلكترونية.

بطاقة وكيل محلّل إستراتيجي للعلامة التجارية

تعرض بطاقة الوكيل هوية الاختصاصي وإمكاناته تمامًا كما يراها الوكلاء الآخرون.

معلومات بطاقة الدفع للوكيل

تثبيت أداة الفحص وبدء استخدامها

cd ~/ai-creative-studio/workshop
./setup_inspector.sh

تعديل .env هو أمر يُنفَّذ لمرة واحدة. استخدِم Terminal 6 لبدء "أداة الفحص" بعد ذلك:

cd ~/a2a-inspector
bash scripts/run.sh

لفتح واجهة مستخدم "أداة الفحص"، استخدِم معاينة الويبتغيير المنفذ → اكتب 5001.

التواصل مع المحلّل الاستراتيجي للعلامة التجارية

أدخِل http://localhost:8082 في حقل عنوان URL الخاص بأداة الفحص وانقر على ربط. يستردّ المدقّق بطاقة الوكيل ويعرض البيانات الوصفية الخاصة بالأخصائي.

أداة A2A Inspector متصلة بمحلّل استراتيجي للعلامات التجارية

المعلومات التي تعرضها بطاقة الوكيل

بطاقة الوكيل هي أكثر من مجرد بيانات وصفية، فهي عقد القدرة الكاملة الذي يعلن عنه الوكيل على الشبكة. يمكنك التواصل مع مدير المشروع (http://localhost:8086) للاطّلاع على أغنى مثال:

{
  "name": "project_manager",
  "description": "Project manager with Notion integration for task tracking",
  "protocolVersion": "0.3.0",
  "defaultInputModes": ["text/plain"],
  "defaultOutputModes": ["text/plain"],
  "skills": [
    {
      "id": "project_manager",
      "name": "model",
      "tags": ["llm"],
      "description": "... full system instruction including today's date and Notion database IDs ..."
    },
    {
      "id": "project_manager-API-post-page",
      "name": "API-post-page",
      "tags": ["llm", "tools"],
      "description": "Notion | Create a page"
    },
    {
      "id": "project_manager-API-retrieve-a-database",
      "name": "API-retrieve-a-database",
      "tags": ["llm", "tools"],
      "description": "Notion | Retrieve a database"
    }
  ]
}

تبرز ثلاثة أمور:

1. أدوات MCP تصبح مهارات A2A: يتم إدراج كل أداة من أدوات Notion التي يمكن لمدير المشروع الوصول إليها (API-post-page وAPI-retrieve-a-database وما إلى ذلك) كمهارة منفصلة في بطاقة الوكيل. يمكن لأي وكيل آخر على الشبكة معرفة الأدوات التي يمكن لهذا الوكيل استخدامها بالضبط، بدون قراءة أي رمز.

‫2. تعليمات النظام مضمّنة - يحتوي description الخاص بالمهارة الأولى على تعليمات النظام الكاملة، بما في ذلك تاريخ اليوم ومعرّفات قاعدة بيانات Notion. هذه هي الطريقة التي يعرف بها المدير الإبداعي ما يجب تمريره عند استدعاء مدير المشروع.

3. عنوان URL هو نقطة النهاية المباشرة - الحقل url هو بالضبط ما تستخدمه RemoteA2aAgent عندما يتصل مدير التصميم بهذا الاختصاصي. إذا كان عنوان URL في البطاقة غير صحيح، لن يتمكّن منسّق العمليات من الوصول إلى الوكيل.

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

إرسال رسالة اختبار

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

الدردشة مع &quot;المحلّل الاستراتيجي للعلامة التجارية&quot; من خلال &quot;أداة فحص التطبيقات إلى التطبيقات&quot;

وجِّه أداة الفحص إلى أي منفذ محلي (8082–8086) لاختبار كل أداة على حدة.

‫11. إنشاء أداة Creative Director Orchestrator

مدير التصميم هو المنسّق الرئيسي. يقرأ عناوين URL المتخصصة من متغيرات البيئة، ويغلّف كل عنوان URL كـ RemoteA2aAgent، ويعرضها كـ AgentTool يمكن للنموذج اللغوي الكبير استدعاؤها.

تأكَّد من أنّ 5 وكلاء متخصصين لا يزالون يعملون (المحطات 1 إلى 5 من الخطوة 10).

في المبنى 6 (مبنى A2A Inspector)، أوقِف أداة Inspector باستخدام Ctrl+C.

افتح الملف:

cd ~/ai-creative-studio/workshop/starter
cloudshell edit agents/creative_director/agent.py

يحتوي هذا الملف على ثلاث مهام. يجب اتّباعها بالترتيب.

TODO 1 - مراجعة تعليمات النظام المكتوبة مسبقًا

تتوفّر تعليمات النظام في prompt.py في الدليل نفسه، ويتم استيرادها تلقائيًا:

from .prompt import SYSTEM_INSTRUCTION_TEMPLATE

افتح prompt.py لقراءته قبل المتابعة:

cloudshell edit agents/creative_director/prompt.py

من المهم فهمها لأنّها تتحكّم في سلوك التنظيم بأكمله.

لماذا يتحكّم طلب المنسّق في كل شيء؟

افتح prompt.py بجانب هذا القسم، فالأمثلة أدناه تشير إلى أجزاء معيّنة منه.

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

العنصر 0 - التخطيط أولاً، ثم التنفيذ

هذا هو العنصر الأكثر أهمية. قبل الاتصال بأي أخصائي، يتم توجيه المنسّق إلى عرض خطة مرقّمة:

I'll create your campaign by coordinating the specialist agents in sequence:
1. Brand Strategist - develop positioning and audience insights
2. Copywriter - write captions using those insights
3. Visual Designer - create image prompts aligned with the copy
4. Critic - review and score the full package
5. Project Manager - build the timeline and task breakdown

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

العنصر 1 - تعريف الدور بشكل صريح

❌ "You are a helpful creative assistant."
✅ "You orchestrate specialists. You do NOT write captions, designs, or timelines yourself."

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

العنصر 2 - بنية استدعاء الأداة مع إدراج أنماط خاطئة

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

✅ copywriter(request="...")          ← correct
❌ print(copywriter(...))             ← breaks silently
❌ default_api.copywriter(...)        ← breaks silently
❌ copywriter.run(...)                ← breaks silently
❌ agents.copywriter(...)             ← breaks silently

أدّى إدراج الأنماط الخاطئة بشكل صريح إلى خفض عدد طلبات استخدام الأدوات غير الصالحة بنسبة% 95 تقريبًا في مرحلة الإنتاج.

العنصر 3: التنفيذ التسلسلي الموضّح خطوة بخطوة

a) Call the tool
b) Wait for tool_output
c) Verify the output is not an error
d) Confirm to the user: "✓ Brand Strategist complete"
e) Then move to the next agent

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

العنصر 4 - توجيهات الخطأ: STOP وreport وdo not proceed

في الإصدارات الأولى، كان منسّق العمليات يتلقّى خطأً من أحد الخبراء، ويصنع ردًا معقولاً عليه، ثم ينتقل إلى الوكيل التالي. حصل المستخدم على حملة تبدو مكتملة ولكنّها تستند إلى معلومات غير صحيحة. الحلّ واضح: توقّف فورًا. أبلِغ عن الخطأ بالضبط. عدم المتابعة مطلقًا

العنصر 5 - قواعد تمرير السياق

لا يملك الوكلاء عن بُعد سجلّ محادثات. عندما يطلب منسّق العمل من كاتب النصوص عبر A2A، يرى كاتب النصوص الرسالة فقط في هذا الطلب الفردي، ولا يعرف ما قاله خبير استراتيجية العلامة التجارية. يجب أن يجمع المنسّق بشكل صريح النواتج السابقة في كل استدعاء لاحق:

copywriter(request="Create 3 posts for EcoFlow water bottle targeting millennials.
Use these insights from the Brand Strategist: [paste full strategist output here].
Create engaging captions with hashtags.")

توضّح التعليمات ذلك صراحةً: "لا يمكن للوكلاء البعيدين الوصول إلى الذاكرة المشتركة، لذا يجب تمرير النواتج السابقة بشكل صريح". وبدون ذلك، يعمل كل وكيل بدون معرفة السياق.

العنصر 6 - تصنيف الطلب: بسيط مقابل معقّد

لا يحتاج كل طلب إلى جميع الوكلاء الخمسة. يطلب الأمر من أداة التنسيق تصنيف الطلب قبل التخطيط:

SIMPLE  → one agent needed
  "Research the eco-friendly water bottle market" → brand_strategist only
  "Write 3 Instagram captions"                    → copywriter only

COMPLEX → all agents sequentially
  "Create a complete campaign with timeline"      → all 5 agents

بدون هذا التصنيف، سيشغّل المنسّق جميع الوكلاء الخمسة لكل طلب، بما في ذلك "أريد 3 أفكار لمنشورات"، ما يؤدي إلى إضافة وقت استجابة وتكلفة غير ضروريين.

العنصر 7 - قواعد التواصل: عرض النتائج الكاملة بدون فلترة

يجب أن يكون الطلب واضحًا بأنّه على أداة التنسيق عدم تلخيص أو تعديل ما يقدّمه الخبراء:

- DO NOT summarize unless the output exceeds 2000 words
- DO NOT filter or edit agent responses
- Show the user exactly what each specialist produced
- NEVER say results are ready unless you received them in tool_output

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

العنصر 8 - إكمال سير العمل: لا تتوقّف مبكرًا أبدًا

أحد أنماط الأعطال الدقيقة ولكنها مهمة: يعلن المنسّق عن خطة من 5 خطوات، ويكمل 3 خطوات، ثم يعرض النتائج كما لو تم إنجازها. يمنع الطلب ذلك من خلال قائمة تحقّق صريحة يجب اجتيازها قبل أن يتمكّن المنسّق من إنهاء العملية:

✓ Did I announce a plan with N agents?
✓ Have I called ALL N agents from my plan?
✓ Did each agent respond successfully?
✓ Am I presenting complete results from ALL agents?

If any answer is NO → continue executing the remaining agents.

يمنع ذلك أداة التنسيق من التعامل مع عملية التشغيل الجزئية على أنّها مكتملة.

حلقة مراقبة الجودة

إنّ سير عمل المراجعة هو الجزء الأكثر تعقيدًا في prompt.py. افتح قسم ## REVISION WORKFLOW واتّبِع التعليمات.

آلية العمل

بعد أن يقدّم الناقد ملاحظاته، لا يواصل المدير الإبداعي العمل بشكل أعمى مع مدير المشروع. يقرأ هذا البرنامج ناتج برنامج Critic ويتفرّع إلى:

Critic output
      │
      ├── "All Approved: YES"
      │         └──► proceed to Project Manager
      │
      └── "Status: NEEDS_REVISION"
                │
                ├── posts fail   → call copywriter again with feedback
                ├── visuals fail → call designer again with feedback
                └── both fail    → call copywriter, then designer
                          │
                          └──► revised output → Project Manager
                               (1 revision max per deliverable)

هذا الإجراء مستند إلى نماذج لغوية كبيرة، وليس إلى رموز برمجية

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

Look for "Status: NEEDS_REVISION" in the critic's response.
Posts need revision  → call copywriter
Visuals need revision → call designer

يقرأ النموذج اللغوي الكبير هذه السلاسل النصية المحددة في ناتج "الناقد" ويتّبع الفرع. لهذا السبب، لا يمكن التنازل عن تنسيق "الناقد": إذا كتب "الناقد" "مطلوب التعديل" بدلاً من NEEDS_REVISION، لن يعثر النموذج اللغوي الكبير على تطابق في التعليمات وسيتخطّى خطوة المراجعة بدون إشعار.

كيف تتم إعادة توجيه السياق في مكالمة مراجعة؟

يتبع طلب المراجعة قاعدة تمرير السياق نفسها من العنصر 5، أي يجب أن يتضمّن المنسّق كل شيء بشكلٍ صريح لأنّ كاتب النصوص لا يتذكّر الإصدار الأول:

"I need you to revise the Instagram posts based on critic feedback.

ORIGINAL BRIEF:
[the original user request]

YOUR FIRST VERSION:
[the posts the copywriter created]

CRITIC FEEDBACK (Score: 6/10 - NEEDS_REVISION):
[the critic's specific suggestions]

Please revise the posts addressing this feedback while maintaining
the strengths the critic identified."

بدون قسم "النسخة الأولى"، سيكتب Copywriter من البداية بدلاً من تحسين ما أنتجه سابقًا.

الحدّ الأقصى المسموح به للتعديلات وسبب أهميته

بعد جولة مراجعة واحدة، ينتقل المنسّق إلى مدير المشروع بغض النظر عن النتيجة. تتتبّع التعليمات ذلك ذهنيًا:

After calling copywriter for revision once:
→ mark "copywriter_revised = true" in context
→ even if the critic still suggests changes, proceed to PM

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

ما الذي يتم تمريره إلى مدير المشروع؟

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

TODO 2 - Register each specialist as a RemoteA2aAgent + AgentTool

ابحث عن التعليق # TODO 2: For each specialist URL... واستبدِله بما يلي:

    if strategist_url:
        available_agents_list.append(
            "- **brand_strategist**: Market research, competitor analysis, trend identification"
        )
        strategist_agent = RemoteA2aAgent(
            name="brand_strategist",
            description="Researches markets, competitors, and trends using Google Search",
            agent_card=f"{strategist_url}/.well-known/agent.json",
        )
        agent_tools.append(AgentTool(agent=strategist_agent))

    if copywriter_url:
        available_agents_list.append(
            "- **copywriter**: Instagram captions, hashtags, and CTAs"
        )
        copywriter_agent = RemoteA2aAgent(
            name="copywriter",
            description="Creates Instagram captions with hashtags and CTAs",
            agent_card=f"{copywriter_url}/.well-known/agent.json",
        )
        agent_tools.append(AgentTool(agent=copywriter_agent))

    if designer_url:
        available_agents_list.append(
            "- **designer**: Visual concepts and real images generated via Gemini (GCS URIs returned)"
        )
        designer_agent = RemoteA2aAgent(
            name="designer",
            description="Creates visual concepts and generates real images via Gemini, stored in GCS",
            agent_card=f"{designer_url}/.well-known/agent.json",
        )
        agent_tools.append(AgentTool(agent=designer_agent))

    if critic_url:
        available_agents_list.append(
            "- **critic**: Quality review with APPROVED/NEEDS_REVISION scoring"
        )
        critic_agent = RemoteA2aAgent(
            name="critic",
            description="Reviews campaign materials and returns structured quality feedback",
            agent_card=f"{critic_url}/.well-known/agent.json",
        )
        agent_tools.append(AgentTool(agent=critic_agent))

    if pm_url:
        available_agents_list.append(
            "- **project_manager**: Project timelines, task breakdowns, Notion integration"
        )
        pm_agent = RemoteA2aAgent(
            name="project_manager",
            description="Creates project timelines and task breakdowns, optionally in Notion",
            agent_card=f"{pm_url}/.well-known/agent.json",
        )
        agent_tools.append(AgentTool(agent=pm_agent))

TODO 3 - Wrap in an App with context compaction

سبب ضرورة الضغط

يتم إلحاق كل رسالة في المحادثة، أي طلب المستخدم وكل طلب أداة وكل ردّ أداة، بقدرة الاستيعاب التي يقرأها النموذج اللغوي الكبير في الدور التالي. في سير عمل يتضمّن 5 وكلاء، تتراكم هذه التكاليف بسرعة:

Turn 1:  user prompt                           ~200 tokens
Turn 2:  orchestrator plan                     ~300 tokens
Turn 3:  brand_strategist tool_call            ~150 tokens
Turn 4:  brand_strategist tool_output          ~1,500 tokens   full research report
Turn 5:  copywriter tool_call                  ~300 tokens     must include strategist output
Turn 6:  copywriter tool_output                ~2,000 tokens   3 captions
Turn 7:  designer tool_call                    ~500 tokens
Turn 8:  designer tool_output                  ~1,500 tokens
...

بحلول Agent 4 (الناقد)، تحتوي قدرة الاستيعاب على الناتج الكامل لجميع الوكلاء الثلاثة السابقين، أي ما يتراوح غالبًا بين 8,000 و12,000 رمز مميز في ردود الأدوات فقط. حتى مع قدرة الاستيعاب الكبيرة في Gemini، تنخفض جودة الاستدلال في أداة التنسيق لأنّها مضطرة إلى الاطّلاع على سجلّ متزايد باستمرار. بدون ضغط، تصل مسارات العمل الطويلة إلى حدود عملية حول Agent 4.

وظيفة الضغط

بدلاً من الاحتفاظ بكل حدث على حدة، يستدعي "مجموعة تطوير التطبيقات" بشكل دوري نموذج لغة كبيرًا لتلخيص الأحداث القديمة في تمثيل مضغوط. يتم الاحتفاظ في السياق بملخّص الأحداث السابقة بالإضافة إلى الناتج الكامل لأحدث وكيل.

Without compaction:
  [full strategist output] + [full copywriter output] + [full designer output] + → Critic

With compaction (interval=3, overlap=1):
  [summary of strategist + copywriter] + [full designer output] + → Critic

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

الرمز

ابحث عن التعليق # TODO 3: Wrap the agent in an App... واستبدِل العنصر النائب App(...) بما يلي:

    from google.adk.apps import App
    from google.adk.apps.app import EventsCompactionConfig
    from google.adk.apps.llm_event_summarizer import LlmEventSummarizer
    from google.adk.models import Gemini

    compaction_config = EventsCompactionConfig(
        summarizer=LlmEventSummarizer(llm=Gemini(model_id=os.getenv("GEMINI_MODEL", "gemini-3.5-flash"))),
        compaction_interval=3,   # Summarize after every 3 agent completions
        overlap_size=1,          # Keep the most recent agent's output in full
    )

    app = App(
        name="creative_director",
        root_agent=agent,
        events_compaction_config=compaction_config,
        plugins=[LoggingPlugin()],
    )
    return agent, app

compaction_interval=3: يتم تشغيل عملية الضغط بعد كل 3 عمليات إكمال من قِبل الوكيل. بالنسبة إلى مسار مؤلّف من 5 وكلاء، يعني ذلك أنّه يتم تشغيله مرة واحدة (بعد الوكلاء من 1 إلى 3)، ثم يرى "الناقد" و"مدير المنتج" ملخّصًا للوكلاء من 1 إلى 3 بالإضافة إلى الناتج الكامل للوكيل السابق.

overlap_size=1: يتم دائمًا الاحتفاظ بالناتج الكامل لأحدث وكيل كما هو، ولا يتم تلخيصه أبدًا. هذا مهم لأنّ الناقد يحتاج إلى الناتج الكامل للمصمّم، بما في ذلك قيم gcs_uri، لتحميل الصور الفعلية ومراجعتها. سيؤدي الملخّص إلى فقدان معرّفات الموارد الموحّدة هذه.

كيفية عملها في دورة تشغيل حملة كاملة:

Agent 1 (Strategist)  → full context
Agent 2 (Copywriter)  → full context
Agent 3 (Designer)    → full context
                        ↓ compaction fires: summarizes agents 1-2, keeps 3 in full
Agent 4 (Critic)      → sees [summary of 1-2] + [full output of 3]
Agent 5 (PM)          → sees [summary of 1-3] + [full output of 4]

فهم RemoteA2aAgentوAgentTool

RemoteA2aAgent("brand_strategist", agent_card=url)
     
       wraps the remote service so ADK can call it
     
AgentTool(agent=strategist_agent)
     
       exposes it as a callable tool to the LLM
     
Agent(tools=[...])
     
       LLM calls tool("brand_strategist", message=...) when needed
     
brand-strategist-xxxx.run.app   actual HTTP A2A call happens here

يقرّر النموذج اللغوي الكبير متى يستدعي كل أداة استنادًا إلى تعليمات النظام وطلب المستخدم. لا يستدعي المنسّق الوكلاء مباشرةً في الرمز، بل يعتمد على منطق النموذج اللغوي الكبير.

اختبار "مدير الإبداع" على الجهاز

uv run adk web agents --allow_origins='*'

افتح "معاينة الويب" على المنفذ 8000. استخدِم القائمة المنسدلة الخاصة بالوكيل لاختيار creative_director، ثم جرِّب ما يلي:

Research the eco-friendly water bottle market for health-conscious millennials

سيظهر لك أنّ المدير الإبداعي سيوجّه هذا الطلب إلى استراتيجي العلامة التجارية فقط، وستتلقّى ردًا منه.

بالنسبة إلى الحملة الكاملة، جرِّب ما يلي:

Create a complete Instagram campaign for SolarPack portable solar charger targeting
outdoor enthusiasts and digital nomads aged 22-35.
Budget $2,000, launch in 2 weeks.

سترى "المدير الإبداعي" ينسّق عمل جميع الخبراء الخمسة بالتسلسل، حيث يتم نقل نتائج كل خبير إلى الخبير التالي.

عرض توضيحي: تنفيذ حملة شاملة

أوقِف "المدير الإبداعي" (Creative Director) (Ctrl+C) قبل المتابعة، لأنّ أداة فحص A2A تستخدم المنفذ 8000 أيضًا.

أوقِف الخوادم الخمسة المتخصّصة (Ctrl+C في كل وحدة طرفية) عند الانتهاء من الاختبار المحلي.

‫12. نشر وكلاء المتخصّصين واختبارهم

نحن الآن جاهزون لنشر الوكلاء على Google Cloud. ‫Cloud Run هي خدمة رائعة لنشر الوكلاء. وهي بلا خادم وقابلة للتوسيع وسهلة الاستخدام. يتم نشر كل وكيل متخصص كخدمة مستقلة في Cloud Run.

إعدادات النشر

يتّبع Dockerfile كل متخصص النمط التالي:

FROM python:3.12-slim
WORKDIR /app
RUN apt-get update && apt-get install -y --no-install-recommends gcc curl

# Fast dependency install with uv
COPY --from=ghcr.io/astral-sh/uv:latest /uv /usr/local/bin/uv
COPY pyproject.toml .
RUN uv sync --no-install-project --no-dev

COPY . .
RUN useradd -m -u 1000 appuser && chown -R appuser:appuser /app
USER appuser

ENV PYTHONUNBUFFERED=1 PORT=8080 HOST=0.0.0.0
EXPOSE 8080
CMD ["uv", "run", "python", "agent.py"]

نشر جميع الخبراء الخمسة بالتسلسل

cd ~/ai-creative-studio/workshop/starter
source .env

uv run deploy/deploy_all_specialists.py

ينشر هذا النص البرمجي جميع الوكلاء الخمسة واحدًا تلو الآخر (إجمالي المدة من 10 إلى 12 دقيقة تقريبًا). تتجنّب عملية النشر المتسلسلة حصة الاستطلاع في Cloud Build (60 طلبًا في الدقيقة). عند اكتمال العملية، يتم إعادة كتابة عنوان URL الخاص بكل وكيل في Cloud Run إلى .env.

بعد نشر "أداة التصميم"، يمنح النص البرمجي تلقائيًا حساب خدمة Cloud Run إذن roles/storage.objectCreator على حزمة GCS، ما يتيح له تحميل الصور التي تم إنشاؤها.

إذا كنت قد أعددت بيانات اعتماد Notion في .env، سيخزّن النص البرمجي أيضًا بيانات الاعتماد بشكل آمن في Secret Manager (مثل notion-token وnotion-project-db-id وnotion-tasks-db-id) وسيدرجها في خدمة Project Manager من خلال --set-secrets بدلاً من متغيّرات البيئة العادية. وهذا يعني أنّ الرمز المميز لا يظهر أبدًا في علامة التبويب "البيئة" في Cloud Run أو في سجلّ الأوامر gcloud.

التحقّق من عمليات النشر

عند اكتمال عملية النشر، يكتب النص البرمجي تلقائيًا عناوين URL الخاصة بخدمة Cloud Run مرة أخرى إلى .env، ويستبدل عناوين URL الخاصة بالمضيف المحلي من الخطوة السابقة:

source .env

echo "Deployed URLs:"
echo "  Brand Strategist: $STRATEGIST_AGENT_URL"
echo "  Copywriter:       $COPYWRITER_AGENT_URL"
echo "  Designer:         $DESIGNER_AGENT_URL"
echo "  Critic:           $CRITIC_AGENT_URL"
echo "  Project Manager:  $PM_AGENT_URL"

سيستخدم "مدير التصميم" تلقائيًا عناوين URL هذه في Cloud Run عند نشرها في Agent Runtime في الخطوة التالية.

تأكيد بطاقات الوكيل

يعرض كل وكيل تم نشره بطاقة وكيل في /.well-known/agent.json. استرجِعها للتأكّد من أنّ كل شيء متاح:

source .env

for agent_url in $STRATEGIST_AGENT_URL $COPYWRITER_AGENT_URL $DESIGNER_AGENT_URL $CRITIC_AGENT_URL $PM_AGENT_URL; do
    echo "=== Agent Card: $agent_url ==="
    curl -s "${agent_url}/.well-known/agent.json" | python3 -m json.tool | grep -E '"name"|"url"|"description"'
    echo ""
done

الناتج المتوقّع لكل وكيل:

"name": "brand_strategist",
"url": "https://brand-strategist-xxxx.run.app",
"description": "Brand strategist for market research and competitive insights"

الاختبار باستخدام "فاحص التطبيقات إلى التطبيقات" (Cloud Run)

تم تثبيت "أداة فحص التطبيقات إلى التطبيقات" في الخطوة 10. ابدأها:

cd ~/a2a-inspector
bash scripts/run.sh

افتح "معاينة الويب" → تغيير المنفذ5001. أدخِل عنوان URL الخاص بـ Cloud Run في حقل الربط:

https://brand-strategist-xxxx.us-central1.run.app

انقر على ربط - لا حاجة إلى رمز مميز للمصادقة لأنّ الخدمات يتم نشرها باستخدام --allow-unauthenticated.

يتصل المدقّق ببطاقة الوكيل ويتحقّق من صحتها، ويتيح لك الدردشة بشكل تفاعلي عبر A2A.

فحص الوكلاء الذين تم نشرهم على Cloud Run

بعد النشر على Cloud Run، وجِّه أداة الفحص إلى عنوان URL العام لبروتوكول HTTPS للتأكّد من أنّ عملية النشر على السحابة الإلكترونية تعمل:

أداة A2A Inspector مرتبطة بوكيل Cloud Run

تكون خطوات سير العمل متطابقة: الصق عنوان URL الخاص بـ Cloud Run، ثم اربط الحساب وأرسِل رسالة اختبار. إذا تم تحميل بطاقة الوكيل واستجاب الدردشة، يعني ذلك أنّه تم نشر الاختصاصي بشكل صحيح ويمكن التواصل معه.

13. نشر "مدير الإبداع" في "بيئة تشغيل الوكيل"

يتم نشر أداة التنسيق في بيئة تشغيل الوكيل، التي توفّر حالة جلسة مُدارة وتدرّج تلقائي وتتبُّع مدمج.

لماذا يجب استخدام Agent Runtime للمنسّق؟

يتم نشر الخبراء الخمسة على Cloud Run، وهو خدمة خفيفة الوزن ولا تحتفظ بأي بيانات، ويتولى كل خبير مهمة واحدة. يجب أن يستوفي مدير الإبداع المتطلبات التالية:

المتطلبات

سبب الأهمية

حالة الجلسة

يستغرق سير العمل المتعدّد الخطوات 45 ثانية أو أكثر. يحافظ Agent Runtime على حالة المحادثة بين استدعاءات الأدوات في خدمة التنسيق، وبالتالي لا يتم فقدان أي بيانات في منتصف عملية التنفيذ.

تحميل المتغيّر

في بعض الأحيان، حملة واحدة في الساعة، وفي أحيان أخرى، حملات عديدة بالتوازي. يتم توسيع نطاق Agent Runtime إلى صفر عند عدم النشاط، ويتم توسيعه تلقائيًا، لذا لن تدفع مقابل السعة غير المستخدَمة.

إمكانية تتبُّع البيانات

تتوفّر خدمات Cloud Logging وCloud Monitoring وCloud Trace بشكل مدمج. يمكنك الاطّلاع على كل مكالمة A2A وكل رمز مميز مستخدَم وكل ارتفاع في وقت الاستجابة، بدون إضافة أي أدوات قياس.

مهام سير العمل الطويلة الأمد

يبلغ الحد الأقصى لمدة المهلة في طلبات Cloud Run‏ 3600 ثانية. تم تصميم Agent Runtime لمهام سير العمل التي يمكن أن تستغرق دقائق، مع عمليات إعادة محاولة مُدارة واستمرار الحالة.

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

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

نشر أداة التنسيق

cd ~/ai-creative-studio/workshop/starter
source .env

uv run deploy/deploy_orchestrator.py --action deploy

تستغرق هذه العملية من 5 إلى 10 دقائق تقريبًا. عند الانتهاء، يتم حفظ AGENT_ENGINE_ID وAGENT_ENGINE_RESOURCE_NAME في .env.

source .env
echo "Agent Engine ID: $AGENT_ENGINE_ID"
echo "Resource: $AGENT_ENGINE_RESOURCE_NAME"

طريقة عمل عملية النشر

client.agent_engines.create() تحزّم عنصر App وتحمّله مع التبعيات وتنشرها في بنية تحتية مُدارة. في ما يلي وظيفة كل مَعلمة:

import vertexai
from vertexai import Client, agent_engines

vertexai.init(project=PROJECT_ID, location=LOCATION, staging_bucket=STAGING_BUCKET)

# Wrap the App in an AdkApp adapter - enables tracing in Cloud Trace
adk_app = agent_engines.AdkApp(app=root_app, enable_tracing=True)

# Initialize client and deploy
client = Client(project=PROJECT_ID, location=LOCATION)

agent_engine_resource = client.agent_engines.create(
    agent=adk_app,
    config={
        "staging_bucket": STAGING_BUCKET,   # GCS bucket for packaging artifacts
        "display_name": "Creative Director",
        # Python packages installed in the managed runtime - pin for reproducibility
        "requirements": [
            "google-cloud-aiplatform[agent_engines]>=1.132.0,<2.0.0",
            "google-adk[a2a]==1.31.1",
            "google-genai>=1.70.0",
            "google-cloud-storage>=2.10.0",
            "python-dotenv>=1.0.0",
            "pydantic>=2.0.0",
            "cloudpickle>=3.0.0",
        ],
        # Specialist URLs passed as env vars - the orchestrator reads these at runtime
        "env_vars": {
            "COPYWRITER_AGENT_URL": COPYWRITER_URL,
            "DESIGNER_AGENT_URL":   DESIGNER_URL,
            "STRATEGIST_AGENT_URL": STRATEGIST_URL,
            "CRITIC_AGENT_URL":     CRITIC_URL,
            "PM_AGENT_URL":         PM_URL,
        },
    },
)

resource_name = agent_engine_resource.api_resource.name
agent_engine_id = resource_name.split("/")[-1]

ما يحدث في الخلفية:

1. Agent Engine packages your App + requirements into a container
2. Uploads it to the staging bucket in your project
3. Deploys to managed compute (you never see or manage the VM)
4. Returns a resource name: projects/.../locations/.../reasoningEngines/<id>
5. That ID is saved to .env as AGENT_ENGINE_ID

بعد عملية النشر، يتصل المنسّق بالمتخصصين الخمسة في Cloud Run من خلال عناوين URL في متغيرات البيئة.

  • يتم تمرير هذه القيم من خلال .env قبل تشغيل نص النشر.

14. إطلاق حملة شاملة

تم نشر النظام بأكمله. تشغيل حملة كاملة من ساحة تجارب Agent Runtime

فتح الوضع التجريبي لـ Agent Runtime

  1. انتقِل إلى https://console.cloud.google.com/agent-platform/runtimes. يمكنك أيضًا الانتقال إلى Agent Runtime من منصة Agent > الوكلاء > عمليات النشر.
  2. اختيار Agent Runtime الذي تم نشره (creative-director)
  3. انقر على Playground في الشريط الجانبي الأيمن
  4. انقر على جلسة جديدة لفتح محادثة جديدة

إطلاق حملة كاملة

ألصِق هذا الموجز في المحادثة وأرسِله:

Create a complete Instagram campaign for:
- Product: EcoFlow Smart Water Bottle (tracks hydration, keeps drinks cold 24h)
- Target Audience: Health-conscious millennials, 25-35 years old
- Platform: Instagram
- Goal: Brand awareness + drive website traffic
- Brand Voice: Motivational, clean, science-backed
- Budget: $3,000
- Timeline: Launch in 2 weeks

سينفّذ المدير الإبداعي جميع الوكلاء الخمسة بالتسلسل:

  1. محلّل إستراتيجي للعلامة التجارية → أبحاث السوق وتحليل المنافسين وإحصاءات الجمهور
  2. محرّر الإعلانات → 3 منشورات على Instagram مع مقاطع شرح وعلامات هاشتاغ وعبارات تحثّ المستخدم على اتّخاذ إجراء
  3. المصمّم → مفاهيم مرئية + صور حقيقية تم إنشاؤها باستخدام Gemini (معرّفات موارد موحّدة في "خدمة التخزين السحابي من Google") لكل مشاركة
  4. الناقد → مراجعة الجودة مع التقييمات APPROVED / NEEDS_REVISION
  5. (مراجعة إذا لزم الأمر) → التواصل مجددًا مع كاتب النصوص أو المصمّم لتقديم الملاحظات
  6. مدير المشروع → جدول زمني لمدة أسبوعَين، وتقسيم المهام، وتخصيص الميزانية

عرض توضيحي: تشغيل الحملة من خلال دمج Notion

اختبار التوجيه إلى وكيل واحد

أرسِل هذا الطلب الأقصر في جلسة جديدة:

Research the luxury skincare market - top brands and trends for this year.

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

فحص عمليات تتبُّع التنفيذ

في وحدة التحكّم، اتّبِع الخطوات التالية:

  1. انقر على عمليات التتبُّع في الشريط الجانبي الأيمن (بجانب Playground)
  2. ضمن عرض التتبُّع، اختَر عملية التتبُّع للجلسة التي نفّذتها للتو
  3. توسيع شجرة التتبُّع للاطّلاع على كل طلب من الوكيل، ومدخلاته/مخرجاته، ووقت الاستجابة، واستخدام الرموز المميزة

يظهر كل طلب A2A إلى أحد المتخصّصين كفترة منفصلة. يمكنك الاطّلاع على السياق الذي قدّمه المدير الإبداعي لكل وكيل والمحتوى الذي تلقّاه منه.

اختياري: التشغيل من الوحدة الطرفية

يمكنك أيضًا تشغيل الحملة آليًا باستخدام النص البرمجي run_campaign.py المُضمَّن في حزمة البداية.

cd ~/ai-creative-studio/workshop/starter
uv run run_campaign.py

‫15. تنظيف

تنظيف موارد Google Cloud لتجنُّب الرسوم المستمرة

نفِّذ نص الإيقاف المؤقت، إذ يقرأ .env ويحذف كل ما تم إنشاؤه خلال هذا الدرس العملي:

bash deploy/teardown_gcp.sh

سيعرض لك النص البرمجي بالضبط ما سيتم حذفه وسيطلب منك التأكيد قبل تنفيذ أي إجراء:

المورد

البيانات التي يتم حذفها

خدمات Cloud Run

محلّل إستراتيجي للعلامة التجارية، وكاتب نصوص إعلانية، ومصمّم، وناقد، ومدير مشروع

مدة تشغيل الوكيل

محرك استنتاج "مدير الإبداع" + جميع الجلسات

Artifact Registry

cloud-run-source-deploy مستودع + جميع صور Docker

حِزم GCS

{PROJECT_ID}-campaign-images، {PROJECT_ID}-agent-staging، run-sources-{PROJECT_ID}-{REGION}

Secret Manager

notion-token وnotion-project-db-id وnotion-tasks-db-id (يتم تخطّيها إذا لم يتم إنشاؤها)

التأكّد من إزالة كل شيء

gcloud run services list --region=us-central1
gcloud storage buckets list --project=$GCP_PROJECT_ID

الناتج المتوقّع: قوائم فارغة أو مواردك الحالية فقط

‫16. ملخّص

تهانينا! لقد أنشأت نظام ذكاء اصطناعي متعدد الوكلاء مناسبًا لمرحلة الإنتاج ونشرته على Google Cloud.

ما أنشأته

الوكيل

إمكانية

النشر

محلّل استراتيجي للعلامة التجارية

أبحاث السوق من خلال "بحث Google"

Cloud Run

محرّر الإعلانات

إنشاء شرح على Instagram

Cloud Run

مُصمِّم

إنشاء الصور من خلال Gemini + تحميل GCS

Cloud Run

ناقد

مراجعة الجودة مع تسجيل النقاط

Cloud Run

مدير المشاريع

المخطط الزمني + Notion MCP

Cloud Run

مخرج تصميم الإعلان

التنسيق الكامل من خلال A2A

مدة تشغيل الوكيل

الأنماط الرئيسية التي تعلّمتها

  1. ADK Agent: تحديد وكيل نموذج لغوي كبير باستخدام تعليمات وأدوات اختيارية
  2. adk web: تشغيل أي وكيل ADK واختباره محليًا باستخدام واجهة مستخدم مدمجة للمحادثة
  3. SkillToolset: تجميع المعرفة القابلة لإعادة الاستخدام في ملفات مقسّمة إلى وحدات يتم تحميلها عند الطلب
  4. FunctionTool: لتغليف أي دالة Python (أو نموذج خارجي) كأداة وكيل قابلة للاستدعاء
  5. to_a2a() - عرض أي وكيل ADK كخدمة HTTPS متوافقة مع A2A
  6. RemoteA2aAgent + AgentTool: تنسيق الوكلاء البعيدين كأدوات قابلة للاستدعاء
  7. McpToolset: الربط بخدمات خارجية من خلال خوادم MCP stdio
  8. EventsCompactionConfig - التعامل مع حدود الرموز المميزة في إجراءات سير العمل الطويلة التي تتضمّن عدة وكلاء
  9. ناتج منظَّم من الناقد: التحكّم في الجودة بشكل قابل للقراءة آليًا مع مراجعة تلقائية
  10. ‫Cloud Run: نشر الوكلاء المحفوظين في حاويات على نطاق واسع
  11. بيئة تشغيل الوكيل: استضافة أدوات التنسيق مع الجلسات المُدارة والتتبُّع

الخطوات التالية

  • إضافة تعديل الصور في محادثة مترابطة إلى "المصمم" باستخدام إمكانية التعديل في gemini-3.1-flash-image
  • إضافة مصادقة إدارة الهوية وإمكانية الوصول إلى خدمات Cloud Run (إزالة --allow-unauthenticated)
  • استبدال أحد المتخصّصين بوكيل LangGraph أو CrewAI - لا يهمّ إطار العمل المستخدَم في A2A
  • إضافة ملاحظات المستخدمين كأداة ليتمكّن المشاركون من تقييم المخرجات وتكرارها
  • استكشاف تتبُّع وقت تشغيل الوكيل في Cloud Console

الموارد