1. مقدمة
نظرة عامة
في هذا الدرس التطبيقي، ستتجاوز روبوتات المحادثة البسيطة وتنشئ نظامًا موزّعًا يستند إلى عدّة وكلاء.
مع أنّ نموذجًا لغويًا كبيرًا واحدًا يمكنه الإجابة عن الأسئلة، إلا أنّ التعقيد في العالم الحقيقي غالبًا ما يتطلّب أدوارًا متخصّصة. لا تطلب من مهندس الخلفية تصميم واجهة المستخدم، ولا تطلب من المصمّم تحسين طلبات البحث في قاعدة البيانات. وبالمثل، يمكننا إنشاء وكلاء متخصصين مستندين إلى الذكاء الاصطناعي يركزون على مهمة واحدة وينسقون مع بعضهم البعض لحل المشاكل المعقدة.
ستنشئ نظام إنشاء دورات تدريبية يتألف من:
- وكيل الباحث: استخدام
google_searchللعثور على معلومات محدّثة - الوكيل الحَكَم: ينتقد البحث من حيث الجودة والاكتمال.
- Content Builder Agent: تحويل البحث إلى دورة تدريبية منظَّمة
- وكيل التنسيق: إدارة سير العمل والتواصل بين هؤلاء المتخصصين
المتطلبات الأساسية
- الإلمام بأساسيات لغة Python
- الإلمام بوحدة تحكّم Google Cloud
الإجراءات التي ستنفذّها
- حدِّد وكيلًا يستخدم أدوات (
researcher) يمكنه البحث على الويب. - استخدِم الناتج المنظَّم مع Pydantic من أجل
judge. - الاتصال بالوكلاء البعيدين باستخدام بروتوكول من وكيل إلى وكيل (A2A)
- أنشئ
LoopAgentلإنشاء حلقة ملاحظات وآراء بين الباحث والحكم. - تشغيل النظام الموزّع محليًا باستخدام "حزمة تطوير التطبيقات" (ADK)
- انشر النظام المتعدد الوكلاء على Google Cloud Run.
مبادئ التصميم والتنسيق
قبل كتابة الرمز، دعونا نتعرّف على كيفية عمل هؤلاء الوكلاء معًا. نحن بصدد إنشاء مسار إنشاء الدورات التدريبية.
تصميم النظام

التنسيق باستخدام الوكلاء
تعمل الوكلاء العاديون (مثل "الباحث"). تتولّى وكلاء التنسيق (مثل LoopAgent أو SequentialAgent) إدارة الوكلاء الآخرين. ليس لديهم أدواتهم الخاصة، بل "أداتهم" هي التفويض.
LoopAgent: تعمل هذه السمة مثل حلقةwhileفي الرمز. يتم تشغيل سلسلة من الوكلاء بشكل متكرر إلى أن يتم استيفاء شرط معيّن (أو يتم الوصول إلى الحد الأقصى لعدد التكرارات). نستخدم هذه الميزة في حلقة البحث:- الباحث يعثر على المعلومات.
- يقدم القاضي ملاحظات نقدية حولها.
- إذا عرضت Judge الحالة "تعذّر"، ستسمح EscalationChecker باستمرار التكرار.
- إذا قال Judge "مقبول"، سيوقف EscalationChecker التكرار.
-
SequentialAgent: يعمل هذا الإجراء مثل تنفيذ نص برمجي عادي. يتم تشغيل البرامج الوكيلة واحدًا تلو الآخر. نستخدم هذه المعلومات في المسار عالي المستوى:- أولاً، شغِّل حلقة البحث (إلى أن تنتهي ببيانات جيدة).
- بعد ذلك، شغِّل أداة إنشاء المحتوى (لكتابة الدورة التدريبية).
ومن خلال الجمع بين هذه التقنيات، ننشئ نظامًا قويًا يمكنه تصحيح الأخطاء تلقائيًا قبل إنشاء الناتج النهائي.
2. الإعداد
إعداد البيئة
- فتح Cloud Shell: انقر على رمز تفعيل Cloud Shell في أعلى يسار Google Cloud Console.
الحصول على الرمز المُعد مسبقًا للمبتدئين
- استنسِخ مستودع الرموز البرمجية الأولية في الدليل الرئيسي:
cd ~ git clone --depth 1 --filter=blob:none --sparse https://github.com/GoogleCloudPlatform/devrel-demos.git temp-repo && cd temp-repo && git sparse-checkout set agents/build-with-ai/production-ready-ai/prai-roadshow-lab-1-starter && cd .. && mv temp-repo/agents/build-with-ai/production-ready-ai/prai-roadshow-lab-1-starter . && rm -rf temp-repo cd prai-roadshow-lab-1-starter - تفعيل واجهات برمجة التطبيقات: نفِّذ الأمر التالي لتفعيل خدمات Google Cloud اللازمة:
gcloud services enable \ run.googleapis.com \ artifactregistry.googleapis.com \ cloudbuild.googleapis.com \ aiplatform.googleapis.com \ compute.googleapis.com - افتح هذا المجلد في المحرِّر.
تثبيت الحِزم التابعة
نستخدم uv لإدارة التبعيات بسرعة.
- ثبِّت تبعيات المشروع:
# Ensure you have uv installed: pip install uv uv sync - إعداد متغيرات البيئة
- ملاحظة: يمكنك العثور على رقم تعريف مشروعك في لوحة بيانات Cloud Console، أو من خلال تنفيذ
gcloud config get-value project.
.envلتخزين هذه المتغيرات حتى تتمكّن من إعادة تحميلها بسهولة في حال انقطاع اتصال جلستك.cat <<EOF > .env export GOOGLE_CLOUD_PROJECT=$(gcloud config get-value project) export GOOGLE_CLOUD_LOCATION=us-central1 export GOOGLE_GENAI_USE_VERTEXAI=true EOF - ملاحظة: يمكنك العثور على رقم تعريف مشروعك في لوحة بيانات Cloud Console، أو من خلال تنفيذ
- تحديد مصدر متغيرات البيئة:
تحذير: لا يتم الاحتفاظ بمتغيرات البيئة في جلسات طرفية جديدة. إذا فتحت علامة تبويب جديدة في نافذة Terminal، شغِّل الأمرsource .envsource .envلاستعادة هذه الملفات.
3- 🕵️ وكيل الباحث

الباحث هو شخص متخصص. مهمتها الوحيدة هي العثور على المعلومات. ولإجراء ذلك، يحتاج إلى الوصول إلى أداة، وهي "بحث Google".
لماذا يجب فصل حساب الباحث؟
نظرة تفصيلية: لماذا لا نستخدم وكيلاً واحدًا لإنجاز كل المهام؟
من السهل تقييم وتصحيح الأخطاء في البرامج الصغيرة والمحدودة النطاق. إذا كان البحث سيئًا، يمكنك تكرار طلب "الباحث". إذا كان تنسيق الدورة التدريبية سيئًا، يمكنك تكرار عملية إنشاء المحتوى باستخدام "أداة إنشاء المحتوى". في الطلب الموحّد "الذي ينجز كل شيء"، غالبًا ما يؤدي إصلاح مشكلة واحدة إلى حدوث مشكلة أخرى.
- إذا كنت تعمل في Cloud Shell، نفِّذ الأمر التالي لفتح محرِّر Cloud Shell:
إذا كنت تعمل في بيئتك المحلية، افتح بيئة التطوير المتكاملة المفضّلة لديك.cloudshell workspace . - فتح "
agents/researcher/agent.py" - سيظهر لك هيكل عظمي مع قائمة مهام.
- أضِف الرمز التالي لتحديد
researcherالوكيل:# ... existing imports ... # Define the Researcher Agent researcher = Agent( name="researcher", model=MODEL, description="Gathers information on a topic using Google Search.", instruction=""" You are an expert researcher. Your goal is to find comprehensive and accurate information on the user's topic. Use the `google_search` tool to find relevant information. Summarize your findings clearly. If you receive feedback that your research is insufficient, use the feedback to refine your next search. """, tools=[google_search], ) root_agent = researcher
المفهوم الأساسي: استخدام الأدوات
لاحظ أنّنا نمرّر tools=[google_search]. تتولّى حزمة تطوير التطبيقات (ADK) مهمة وصف هذه الأداة للنموذج اللغوي الكبير. عندما يقرّر النموذج أنّه بحاجة إلى معلومات، ينشئ طلبًا منظَّمًا لاستخدام أداة، وتنفّذ حزمة تطوير التطبيقات (ADK) دالة Python google_search، وتُعيد النتيجة إلى النموذج.
4. ⚖️ وكيل القاضي

يبذل "الباحث" جهدًا كبيرًا، ولكن يمكن أن تكون النماذج اللغوية الكبيرة كسولة. نحتاج إلى حكم لمراجعة العمل. يقبل "القاضي" البحث ويعرض تقييمًا منظَّمًا بنتيجة "اجتياز" أو "عدم اجتياز".
الناتج المنظَّم
نظرة تفصيلية: لأتمتة مهام سير العمل، نحتاج إلى مخرجات يمكن توقّعها. من الصعب تحليل مراجعة نصية طويلة بشكل آلي. من خلال فرض مخطط JSON (باستخدام Pydantic)، نضمن أن تعرض أداة Judge القيمة المنطقية pass أو fail التي يمكن أن يستند إليها الرمز البرمجي بشكل موثوق.
- فتح "
agents/judge/agent.py" - حدِّد مخطط
JudgeFeedbackوالوكيلjudge.# 1. Define the Schema class JudgeFeedback(BaseModel): """Structured feedback from the Judge agent.""" status: Literal["pass", "fail"] = Field( description="Whether the research is sufficient ('pass') or needs more work ('fail')." ) feedback: str = Field( description="Detailed feedback on what is missing. If 'pass', a brief confirmation." ) # 2. Define the Agent judge = Agent( name="judge", model=MODEL, description="Evaluates research findings for completeness and accuracy.", instruction=""" You are a strict editor. Evaluate the 'research_findings' against the user's original request. If the findings are missing key info, return status='fail'. If they are comprehensive, return status='pass'. """, output_schema=JudgeFeedback, # Disallow delegation because it should only output the schema disallow_transfer_to_parent=True, disallow_transfer_to_peers=True, ) root_agent = judge
المفهوم الأساسي: تقييد سلوك الوكيل
لقد ضبطنا disallow_transfer_to_parent=True وdisallow_transfer_to_peers=True. يفرض ذلك على القاضي فقط إرجاع JudgeFeedback المنظَّمة. ولا يمكنه اتّخاذ قرار "المحادثة" مع المستخدم أو تفويض وكيل آخر. وهذا يجعلها عنصرًا حتميًا في مسار المنطق.
5- 🧪 الاختبار في بيئة معزولة
قبل ربطها، يمكننا التأكّد من أنّ كل وكيل يعمل. تتيح لك "حزمة تطوير البرامج" تشغيل الوكلاء بشكل فردي.
المفهوم الأساسي: وقت التشغيل التفاعلي
تنشئ adk run بيئة بسيطة تكون فيها أنت "المستخدم". يتيح لك ذلك اختبار تعليمات الوكيل واستخدام الأدوات بشكل منفصل. إذا تعذّر على الوكيل تنفيذ هذه الخطوة (على سبيل المثال، تعذّر عليه استخدام "بحث Google")، سيتعذّر عليه بالتأكيد تنفيذ عملية التنسيق.
- تشغيل "الباحث" بشكل تفاعلي يُرجى العِلم أنّنا نشير إلى دليل الوكلاء المحدّد:
# This runs the researcher agent in interactive mode uv run adk run agents/researcher - في طلب المحادثة، اكتب:
يجب أن تستخدم الأداة "بحث Google" وتعرض الإجابة.ملاحظة: إذا ظهر لك خطأ يشير إلى عدم ضبط المشروع والموقع الجغرافي واستخدام Vertex، تأكَّد من ضبط رقم تعريف مشروعك ونفِّذ ما يلي:Find the population of Tokyo in 2020export GOOGLE_CLOUD_PROJECT=$(gcloud config get-value project) export GOOGLE_CLOUD_LOCATION=us-central1 export GOOGLE_GENAI_USE_VERTEXAI=true - الخروج من المحادثة (Ctrl+C)
- تشغيل Judge بشكل تفاعلي:
uv run adk run agents/judge - في طلب المحادثة، حاكِ الإدخال:
يجب أن تعرضTopic: Tokyo. Findings: Tokyo is a city.status='fail'لأنّ النتائج موجزة جدًا.
6. ✍️ أداة "إنشاء المحتوى"

أداة إنشاء المحتوى هي الكاتب الإبداعي. يتم تحويل الأبحاث التي تمت الموافقة عليها إلى دورات تدريبية.
- فتح "
agents/content_builder/agent.py" - حدِّد وكيل
content_builder.content_builder = Agent( name="content_builder", model=MODEL, description="Transforms research findings into a structured course.", instruction=""" You are an expert course creator. Take the approved 'research_findings' and transform them into a well-structured, engaging course module. **Formatting Rules:** 1. Start with a main title using a single `#` (H1). 2. Use `##` (H2) for main section headings. 3. Use bullet points and clear paragraphs. 4. Maintain a professional but engaging tone. Ensure the content directly addresses the user's original request. """, ) root_agent = content_builder
المفهوم الأساسي: نقل السياق
قد تتساءل: "كيف يعرف تطبيق Content Builder ما عثر عليه تطبيق Researcher؟" في حزمة تطوير التطبيقات (ADK)، تشترك الوكلاء في مسار معالجة في session.state. في وقت لاحق، سنضبط الباحث والحكم في Orchestrator لحفظ نواتجهما في هذه الحالة المشتركة. يمكن الوصول إلى هذا السجلّ من خلال طلب "أداة إنشاء المحتوى".
7. 🎻 المنظّم

المنسّق هو مدير فريقنا المتعدّد الوكلاء. على عكس الوكلاء المتخصّصين (الباحث، والحكم، وصانع المحتوى) الذين ينفّذون مهام محددة، تتمثل مهمة "المنسّق" في تنسيق سير العمل وضمان تدفّق المعلومات بشكل صحيح بين الوكلاء.
🌐 البنية: من وكيل إلى وكيل (A2A)

في هذا الدرس التطبيقي، سننشئ نظامًا موزّعًا. بدلاً من تشغيل جميع البرامج في عملية Python واحدة، ننشرها كخدمات مصغّرة مستقلة. يتيح ذلك لكل وكيل توسيع نطاقه بشكل مستقل وتعطُّله بدون إيقاف النظام بأكمله.
ولتحقيق ذلك، نستخدم بروتوكول Agent-to-Agent (A2A).
بروتوكول A2A
نظرة تفصيلية: في نظام الإنتاج، تعمل البرامج على خوادم مختلفة (أو حتى على سُحب مختلفة). يوفّر بروتوكول A2A طريقة موحّدة لتتمكّن هذه الأجهزة من العثور على بعضها البعض والتواصل معها عبر HTTP. RemoteA2aAgent هو برنامج ADK للعميل لهذا البروتوكول.
- فتح "
agents/orchestrator/agent.py" - ابحث عن التعليق
# TODO: Define connections to remote agentsأو القسم الخاص بتعريفات الوكيل البعيد. - أضِف الرمز التالي لتحديد عمليات الربط. احرص على وضع هذا السطر بعد عمليات الاستيراد وقبل أي تعريفات أخرى للوكيل.
# ... existing code ... # Connect to the Researcher (Localhost port 8001) researcher_url = os.environ.get("RESEARCHER_AGENT_CARD_URL", "http://localhost:8001/a2a/agent/.well-known/agent-card.json") researcher = RemoteA2aAgent( name="researcher", agent_card=researcher_url, description="Gathers information using Google Search.", # IMPORTANT: Save the output to state for the Judge to see after_agent_callback=create_save_output_callback("research_findings"), # IMPORTANT: Use authenticated client for communication httpx_client=create_authenticated_client(researcher_url) ) # Connect to the Judge (Localhost port 8002) judge_url = os.environ.get("JUDGE_AGENT_CARD_URL", "http://localhost:8002/a2a/agent/.well-known/agent-card.json") judge = RemoteA2aAgent( name="judge", agent_card=judge_url, description="Evaluates research.", after_agent_callback=create_save_output_callback("judge_feedback"), httpx_client=create_authenticated_client(judge_url) ) # Content Builder (Localhost port 8003) content_builder_url = os.environ.get("CONTENT_BUILDER_AGENT_CARD_URL", "http://localhost:8003/a2a/agent/.well-known/agent-card.json") content_builder = RemoteA2aAgent( name="content_builder", agent_card=content_builder_url, description="Builds the course.", httpx_client=create_authenticated_client(content_builder_url) )
8. 🛑 أداة التحقّق من حالة التصعيد
يجب أن تتضمّن الحلقة طريقة لإيقافها. إذا قال القاضي "مقبول"، نريد الخروج من الحلقة على الفور والانتقال إلى "أداة إنشاء المحتوى".
المنطق المخصّص باستخدام BaseAgent
نظرة تفصيلية: لا يستخدم جميع موظّفي الدعم نماذج اللغات الكبيرة. في بعض الأحيان، تحتاج إلى منطق بسيط في Python. تتيح لك BaseAgent تحديد وكيل ينفّذ الرمز فقط. في هذه الحالة، نتحقّق من حالة الجلسة ونستخدم EventActions(escalate=True) للإشارة إلى LoopAgent بالتوقّف.
- لا يزال في
agents/orchestrator/agent.py. - ابحث عن العنصر النائب
EscalationCheckerTODO. - استبدِلها بالتنفيذ التالي:
class EscalationChecker(BaseAgent): """Checks the judge's feedback and escalates (breaks the loop) if it passed.""" async def _run_async_impl( self, ctx: InvocationContext ) -> AsyncGenerator[Event, None]: # Retrieve the feedback saved by the Judge feedback = ctx.session.state.get("judge_feedback") print(f"[EscalationChecker] Feedback: {feedback}") # Check for 'pass' status is_pass = False if isinstance(feedback, dict) and feedback.get("status") == "pass": is_pass = True # Handle string fallback if JSON parsing failed elif isinstance(feedback, str) and '"status": "pass"' in feedback: is_pass = True if is_pass: # 'escalate=True' tells the parent LoopAgent to stop looping yield Event(author=self.name, actions=EventActions(escalate=True)) else: # Continue the loop yield Event(author=self.name) escalation_checker = EscalationChecker(name="escalation_checker")
المفهوم الأساسي: التحكّم في تدفّق البيانات من خلال الأحداث
لا تتواصل البرامج مع المستخدمين من خلال النصوص فقط، بل من خلال الأحداث. من خلال عرض حدث باستخدام escalate=True، يرسل هذا العامل إشارة إلى العنصر الرئيسي (LoopAgent). تمت برمجة LoopAgent لتلقّي هذه الإشارة وإنهاء الحلقة.
9- 🔁 حلقة البحث

نحتاج إلى حلقة ملاحظات: البحث -> التقييم -> (فشل) -> البحث -> ...
- لا يزال في
agents/orchestrator/agent.py. - أضِف تعريف
research_loop. ضَع هذا بعد الفئةEscalationCheckerوالمثيلescalation_checker.research_loop = LoopAgent( name="research_loop", description="Iteratively researches and judges until quality standards are met.", sub_agents=[researcher, judge, escalation_checker], max_iterations=3, )
المفهوم الأساسي: LoopAgent
يتنقّل LoopAgent بين sub_agents بالترتيب.
-
researcher: للبحث عن البيانات -
judge: لتقييم البيانات. escalation_checker: تحدّد ما إذا كان سيتمyield Event(escalate=True). في حال حدوثescalate=True، يتم إيقاف التكرار مبكرًا. بخلاف ذلك، تتم إعادة التشغيل عند الباحث (بحد أقصىmax_iterations).
10. 🔗 مسار التعلّم النهائي

أخيرًا، اجمع كل ذلك معًا.
- لا يزال في
agents/orchestrator/agent.py. - حدِّد
root_agentفي أسفل الملف. تأكَّد من أنّ هذا العنصر النائب يحلّ محلّ أي عنصر نائب حاليroot_agent = None.root_agent = SequentialAgent( name="course_creation_pipeline", description="A pipeline that researches a topic and then builds a course from it.", sub_agents=[research_loop, content_builder], )
المفهوم الأساسي: التركيب الهرمي
يُرجى العِلم أنّ research_loop هو نفسه وكيل (LoopAgent)، ونعامله مثل أي وكيل فرعي آخر في SequentialAgent. تتيح لك هذه الإمكانية إنشاء منطق معقّد من خلال دمج أنماط بسيطة (حلقات داخل تسلسلات، وتسلسلات داخل موجّهات، وما إلى ذلك).
11. 💻 التشغيل محليًا
قبل تشغيل كل شيء، دعونا نلقي نظرة على كيفية محاكاة حزمة تطوير التطبيقات (ADK) للبيئة الموزّعة محليًا.
نظرة متعمّقة: طريقة عمل التطوير المحلي
في بنية الخدمات المصغّرة، يتم تشغيل كل وكيل كخادم مستقل. عند النشر، سيكون لديك 4 خدمات مختلفة على Cloud Run. يمكن أن تكون محاكاة ذلك محليًا أمرًا صعبًا إذا كان عليك فتح 4 علامات تبويب في الوحدة الطرفية وتنفيذ 4 أوامر.
يبدأ هذا النص البرمجي uvicorn عمليات لكل من Researcher (المنفذ 8001) وJudge (المنفذ 8002) وContent Builder (المنفذ 8003). يضبط هذا البرنامج متغيّرات البيئة، مثل RESEARCHER_AGENT_CARD_URL، ويمررها إلى Orchestrator (المنفذ 8004). هذه هي الطريقة التي سنضبط بها الإعدادات في السحابة الإلكترونية لاحقًا.

- شغِّل نص التنسيق البرمجي:
يبدأ هذا الإجراء 4 عمليات منفصلة../run_local.sh - اختبار الميزة:
- في حال استخدام Cloud Shell: انقر على الزر معاينة الويب (أعلى يسار نافذة الوحدة الطرفية) -> المعاينة على المنفذ 8080 -> تغيير المنفذ إلى
8000. - في حال التشغيل محليًا: افتح
http://localhost:8000في المتصفّح. - الطلب: "أنشئ دورة تدريبية حول تاريخ القهوة".
- المراقبة: سيتصل Orchestrator بـ Researcher. يتم إرسال الناتج إلى "القاضي". إذا لم ينجح القاضي في ذلك، تستمر الحلقة.
- "خطأ في الخادم الداخلي" / أخطاء المصادقة: إذا ظهرت لك أخطاء في المصادقة (مثل الأخطاء المتعلقة بـ
google-auth)، تأكَّد من تنفيذgcloud auth application-default loginإذا كنت تستخدم جهازًا محليًا. في Cloud Shell، تأكَّد من ضبط متغيّر البيئةGOOGLE_CLOUD_PROJECTبشكل صحيح. - أخطاء في نافذة Terminal: إذا تعذّر تنفيذ الأمر في نافذة Terminal جديدة، تذكَّر إعادة تصدير متغيّرات البيئة (
GOOGLE_CLOUD_PROJECTوما إلى ذلك).
- في حال استخدام Cloud Shell: انقر على الزر معاينة الويب (أعلى يسار نافذة الوحدة الطرفية) -> المعاينة على المنفذ 8080 -> تغيير المنفذ إلى
- اختبار الوكلاء بشكل منفصل: حتى عند تشغيل النظام الكامل، يمكنك اختبار وكلاء محدّدين من خلال استهداف منافذهم مباشرةً. ويكون ذلك مفيدًا لتصحيح خطأ في مكوّن معيّن بدون تشغيل السلسلة بأكملها.ملاحظة: هذه نقاط نهاية لواجهة برمجة التطبيقات وليست صفحات ويب. ولا يمكنك الوصول إليها من خلال متصفّح. بدلاً من ذلك، استخدِم
curlللتأكّد من أنّها تعمل (مثلاً، من خلال استرداد بطاقة الوكيل).- الباحثون فقط (المنفذ 8001):
- التحقّق من الحالة (والعثور على نقطة النهاية
url):curl http://localhost:8001/a2a/agent/.well-known/agent-card.json - إرسال طلب بحث (باستخدام بروتوكول A2A JSON-RPC):
curl -X POST http://localhost:8001/a2a/agent \ -H "Content-Type: application/json" \ -d '{ "jsonrpc": "2.0", "method": "message/send", "id": 1, "params": { "message": { "message_id": "test-1", "role": "user", "parts": [ { "text": "What is the capital of France?", "kind": "text" } ] } } }'
- التحقّق من الحالة (والعثور على نقطة النهاية
- التقييم فقط (المنفذ 8002):
- التحقّق من الحالة:
curl http://localhost:8002/a2a/agent/.well-known/agent-card.json - إرسال طلب بحث:
curl -X POST http://localhost:8002/a2a/agent \ -H "Content-Type: application/json" \ -d '{ "jsonrpc": "2.0", "method": "message/send", "id": 1, "params": { "message": { "message_id": "test-2", "role": "user", "parts": [ { "text": "Topic: Tokyo. Findings: Tokyo is the capital of Japan.", "kind": "text" } ] } } }'
- التحقّق من الحالة:
- أداة إنشاء المحتوى فقط (المنفذ 8003):
curl http://localhost:8003/a2a/agent/.well-known/agent-card.json - المنسّق (المنفذ 8004):
curl http://localhost:8004/a2a/agent/.well-known/agent-card.json
- الباحثون فقط (المنفذ 8001):
12. 🚀 النشر على Cloud Run
تتم عملية التحقّق النهائية في السحابة الإلكترونية. سننفّذ كل وكيل كخدمة منفصلة.
التعرّف على إعدادات النشر
عند نشر الوكلاء على Cloud Run، نمرّر العديد من متغيرات البيئة لضبط سلوكهم واتصالهم:
GOOGLE_CLOUD_PROJECT: يضمن هذا الخيار أنّ الوكيل يستخدم مشروع Google Cloud الصحيح لتسجيل البيانات وإجراء طلبات إلى Vertex AI.GOOGLE_GENAI_USE_VERTEXAI: يطلب من إطار عمل الوكيل (ADK) استخدام Vertex AI لاستنتاج النموذج بدلاً من استدعاء واجهات Gemini API مباشرةً.-
[AGENT]_AGENT_CARD_URL: هذا الإعداد مهم جدًا لخدمة Orchestrator. يخبر هذا الملف أداة Orchestrator بمكان العثور على الوكلاء عن بُعد. من خلال ضبط هذه السمة على عنوان URL الذي تم نشره على Cloud Run (وتحديدًا مسار بطاقة الوكيل)، نتيح لخدمة Orchestrator إمكانية العثور على Researcher وJudge وContent Builder والتواصل معها عبر الإنترنت.
- نشر الوكلاء الفرعيين (بالتوازي): لتوفير الوقت، سننشر "الباحث" و"المقيّم" و"منشئ المحتوى" في الوقت نفسه.افتح ثلاث علامات تبويب جديدة في نافذة الأوامر. في كل علامة تبويب جديدة، نفِّذ ما يلي لإعداد بيئتك:
علامة التبويب 1: تنفيذ عملية نشر Researcher:cd ~/prai-roadshow-lab-1-starter source .env علامة التبويب 2: تنفيذ عملية نشر Judge:gcloud run deploy researcher \ --source agents/researcher/ \ --region us-central1 \ --allow-unauthenticated \ --labels dev-tutorial=prod-ready-1 \ --set-env-vars GOOGLE_CLOUD_PROJECT=$GOOGLE_CLOUD_PROJECT \ --set-env-vars GOOGLE_GENAI_USE_VERTEXAI="true" الخطوة 3: تنفيذ عملية نشر Content Builder:gcloud run deploy judge \ --source agents/judge/ \ --region us-central1 \ --allow-unauthenticated \ --labels dev-tutorial=prod-ready-1 \ --set-env-vars GOOGLE_CLOUD_PROJECT=$GOOGLE_CLOUD_PROJECT \ --set-env-vars GOOGLE_GENAI_USE_VERTEXAI="true"gcloud run deploy content-builder \ --source agents/content_builder/ \ --region us-central1 \ --allow-unauthenticated \ --labels dev-tutorial=prod-ready-1 \ --set-env-vars GOOGLE_CLOUD_PROJECT=$GOOGLE_CLOUD_PROJECT \ --set-env-vars GOOGLE_GENAI_USE_VERTEXAI="true" - التقاط عناوين URL: بعد انتهاء عمليات النشر الثلاث، ارجع إلى الوحدة الطرفية الأصلية (حيث ستنشر Orchestrator). نفِّذ الأوامر التالية لالتقاط عناوين URL الخاصة بالخدمة:
RESEARCHER_URL=$(gcloud run services describe researcher --region us-central1 --format='value(status.url)') JUDGE_URL=$(gcloud run services describe judge --region us-central1 --format='value(status.url)') CONTENT_BUILDER_URL=$(gcloud run services describe content-builder --region us-central1 --format='value(status.url)') echo "Researcher: $RESEARCHER_URL" echo "Judge: $JUDGE_URL" echo "Content Builder: $CONTENT_BUILDER_URL" - نشر Orchestrator: استخدِم متغيرات البيئة التي تم الحصول عليها لضبط Orchestrator.
تسجيل عنوان URL:gcloud run deploy orchestrator \ --source agents/orchestrator/ \ --region us-central1 \ --allow-unauthenticated \ --labels dev-tutorial=prod-ready-1 \ --set-env-vars RESEARCHER_AGENT_CARD_URL=$RESEARCHER_URL/a2a/agent/.well-known/agent-card.json \ --set-env-vars JUDGE_AGENT_CARD_URL=$JUDGE_URL/a2a/agent/.well-known/agent-card.json \ --set-env-vars CONTENT_BUILDER_AGENT_CARD_URL=$CONTENT_BUILDER_URL/a2a/agent/.well-known/agent-card.json \ --set-env-vars GOOGLE_CLOUD_PROJECT=$GOOGLE_CLOUD_PROJECT \ --set-env-vars GOOGLE_GENAI_USE_VERTEXAI="true"ORCHESTRATOR_URL=$(gcloud run services describe orchestrator --region us-central1 --format='value(status.url)') echo $ORCHESTRATOR_URL - نشر الواجهة الأمامية:
gcloud run deploy course-creator \ --source app \ --region us-central1 \ --allow-unauthenticated \ --labels dev-tutorial=prod-ready-1 \ --set-env-vars AGENT_SERVER_URL=$ORCHESTRATOR_URL \ --set-env-vars GOOGLE_CLOUD_PROJECT=$GOOGLE_CLOUD_PROJECT - اختبار النشر عن بُعد: افتح عنوان URL الخاص بـ Orchestrator الذي تم نشره. تعمل هذه الخدمة الآن بالكامل على السحابة الإلكترونية، وتستفيد من البنية الأساسية بدون خادم من Google لتوسيع نطاق عمل برامجك.تلميح: ستجد جميع الخدمات المصغّرة وعناوين URL الخاصة بها في واجهة Cloud Run.
13. ملخّص
تهانينا! لقد أنشأت ونشرت بنجاح نظامًا موزّعًا يستند إلى عدّة وكلاء وجاهزًا للاستخدام في بيئة الإنتاج.
إنجازاتنا
- تقسيم مهمة معقّدة: بدلاً من طلب واحد كبير، قسّمنا العمل إلى أدوار متخصّصة (باحث، وحكم، ومنشئ محتوى).
- تنفيذ مراقبة الجودة: استخدمنا
LoopAgentوJudgeمنظَّمًا لضمان وصول المعلومات العالية الجودة فقط إلى الخطوة النهائية. - مصمَّم للإنتاج: باستخدام بروتوكول التواصل بين الوكلاء (A2A) وCloud Run، أنشأنا نظامًا يكون فيه كل وكيل عبارة عن خدمة مصغّرة مستقلة وقابلة للتوسيع. وهذا أكثر فعالية من تنفيذ كل شيء في نص برمجي واحد بلغة Python.
- التنسيق: استخدمنا
SequentialAgentوLoopAgentلتحديد أنماط واضحة لسير التحكّم.
الخطوات التالية
بعد أن أصبحت لديك الأساسيات، يمكنك توسيع نطاق هذا النظام باتّباع الخطوات التالية:
- إضافة المزيد من الأدوات: يمكنك منح الباحث إذن الوصول إلى المستندات الداخلية أو واجهات برمجة التطبيقات.
- تحسين أداة Judge: أضِف معايير أكثر تحديدًا أو حتى خطوة "مراجعة من قِبل موظف".
- تبديل النماذج: جرِّب استخدام نماذج مختلفة لوكلاء مختلفين (مثل نموذج أسرع لـ "القاضي"، ونموذج أقوى لـ "كاتب المحتوى").
أنت الآن جاهز لإنشاء عمليات سير عمل معقّدة وموثوقة مستندة إلى وكلاء على Google Cloud.