إنشاء وكيل "مخطِّط اختبار تأكيد الجودة" باستخدام "حزمة تطوير التطبيقات" و"منصة المحتوى التجريبي" وGemini 2.5 Flash مع "وضع التفكير"

1. مقدمة

782957a0266b13f6.png

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

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

خلال هذا الدرس العملي، ستتّبع نهجًا خطوة بخطوة على النحو التالي:

  1. إعداد مشروعك على Google Cloud وتفعيل جميع واجهات برمجة التطبيقات المطلوبة فيه
  2. إعداد مساحة عمل لبيئة الترميز
  3. إعداد خادم mcp-server محلي لتطبيق Confluence
  4. تنظيم الرمز المصدري لوكيل ADK والطلب والأدوات للاتصال بخادم MCP
  5. فهم استخدام "خدمة العناصر" و"سياقات الأدوات"
  6. اختبار الوكيل باستخدام واجهة مستخدم تطوير الويب المحلية في ADK
  7. إدارة متغيّرات البيئة وإعداد الملفات المطلوبة لتفعيل التطبيق على Cloud Run
  8. نشر التطبيق على Cloud Run

نظرة عامة على البنية

af793beb2740233.jpeg

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

  • إجادة العمل باستخدام Python
  • فهم أساسي لبنية التطبيقات المتكاملة باستخدام خدمة HTTP

ما ستتعلمه

  • تصميم وكيل ADK مع الاستفادة من إمكاناته المتعدّدة
  • استخدام الأدوات مع أداة مخصّصة وبروتوكول سياق النموذج (MCP)
  • إعداد إخراج الملفات بواسطة الوكيل باستخدام إدارة خدمة Artifact
  • استخدام BuiltInPlanner لتحسين تنفيذ المهام من خلال التخطيط باستخدام قدرات التفكير في Gemini 2.5 Flash
  • التفاعل وتصحيح الأخطاء من خلال واجهة الويب الخاصة بحزمة تطوير التطبيقات (ADK)
  • نشر التطبيق على Cloud Run باستخدام Dockerfile وتوفير متغيرات البيئة

المتطلبات

  • متصفّح الويب Chrome
  • حساب Gmail
  • مشروع على السحابة الإلكترونية تم تفعيل الفوترة فيه
  • (اختياري) مساحة Confluence تتضمّن صفحات "مستندات متطلبات المنتج"

يستخدم هذا الدرس التطبيقي حول الترميز، المصمّم للمطوّرين من جميع المستويات (بما في ذلك المبتدئين)، لغة Python في تطبيق المثال. ومع ذلك، لا يُشترط معرفة لغة Python لفهم المفاهيم المقدَّمة. لا داعي للقلق بشأن مساحة Confluence إذا لم يكن لديك واحدة، وسنقدّم لك بيانات الاعتماد لتجربة هذا الدرس العملي.

2. قبل البدء

اختيار مشروع نشط في Cloud Console

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

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

66ddfbce2eeba53e.png

إعداد مشروع Cloud في نافذة Cloud Shell

  1. ستستخدم Cloud Shell، وهي بيئة سطر أوامر تعمل في Google Cloud. انقر على "تفعيل Cloud Shell" في أعلى "وحدة تحكّم Google Cloud".

26f20e837ff06119.png

  1. بعد الاتصال بـ Cloud Shell، يمكنك التأكّد من إكمال عملية المصادقة وأنّ المشروع مضبوط على رقم تعريف مشروعك باستخدام الأمر التالي:
gcloud auth list
  1. نفِّذ الأمر التالي في Cloud Shell للتأكّد من أنّ أمر gcloud يعرف مشروعك.
gcloud config list project
  1. إذا لم يتم ضبط مشروعك، استخدِم الأمر التالي لضبطه:
gcloud config set project <YOUR_PROJECT_ID>

بدلاً من ذلك، يمكنك أيضًا الاطّلاع على معرّف PROJECT_ID في وحدة التحكّم.

bb98435b79995b15.jpeg

انقر عليه وسيظهر لك كل مشروعك ورقم تعريف المشروع على الجانب الأيسر

ffa73dee57de5307.jpeg

  1. فعِّل واجهات برمجة التطبيقات المطلوبة من خلال الأمر الموضّح أدناه. قد تستغرق هذه العملية بضع دقائق، لذا يُرجى الانتظار.
gcloud services enable aiplatform.googleapis.com \
                       run.googleapis.com \
                       cloudbuild.googleapis.com \
                       cloudresourcemanager.googleapis.com

عند تنفيذ الأمر بنجاح، من المفترض أن تظهر لك رسالة مشابهة للرسالة الموضّحة أدناه:

Operation "operations/..." finished successfully.

يمكنك بدلاً من استخدام أمر gcloud، استخدام وحدة التحكّم من خلال البحث عن كل منتج أو استخدام هذا الرابط.

إذا فاتك أي واجهة برمجة تطبيقات، يمكنك تفعيلها في أي وقت أثناء عملية التنفيذ.

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

الانتقال إلى "محرّر Cloud Shell" وإعداد دليل عمل التطبيق

الآن، يمكننا إعداد محرّر الرموز البرمجية لتنفيذ بعض مهام الترميز. سنستخدم "محرّر Cloud Shell" لهذا الغرض.

  1. انقر على الزر "فتح المحرِّر"، وسيؤدي ذلك إلى فتح "محرِّر Cloud Shell"، ويمكننا كتابة الرمز هنا 168eacea651b086c.png
  2. تأكَّد من ضبط مشروع Cloud Code في أسفل يمين (شريط الحالة) محرر Cloud Shell، كما هو موضّح في الصورة أدناه، ومن ضبطه على مشروع Google Cloud النشط الذي تم تفعيل الفوترة فيه. منح الإذن إذا طُلب منك ذلك إذا كنت تتبع الأمر السابق، قد يشير الزر أيضًا مباشرةً إلى مشروعك المفعّل بدلاً من زر تسجيل الدخول.

613a4889dbcade3d.png

  1. بعد ذلك، لنستنسخ دليل العمل الخاص بالنموذج لهذا الدرس التطبيقي حول الترميز من Github، وننفّذ الأمر التالي. سيتم إنشاء دليل العمل في الدليل qa-test-planner-agent
git clone https://github.com/alphinside/qa-test-planner-agent.git qa-test-planner-agent
  1. بعد ذلك، انتقِل إلى القسم العلوي من "محرّر Cloud Shell" وانقر على ملف->فتح مجلد (File->Open Folder)، وابحث عن دليل اسم المستخدم، ثم ابحث عن دليل qa-test-planner-agent وانقر على الزر "حسنًا" (OK). سيؤدي ذلك إلى جعل الدليل الذي تم اختياره هو دليل العمل الرئيسي. في هذا المثال، اسم المستخدم هو alvinprayuda، وبالتالي يظهر مسار الدليل أدناه

c87d2b76896d0c59.pngefd32490d592dbb9.png

من المفترض أن يظهر "محرّر Cloud Shell" الآن على النحو التالي

a1a380fb20ce3308.png

إعداد البيئة

إعداد بيئة Python الافتراضية

الخطوة التالية هي إعداد بيئة التطوير. يجب أن تكون نافذة الجهاز النشطة الحالية داخل دليل العمل qa-test-planner-agent. سنستخدم الإصدار 3.12 من Python في هذا الدرس التطبيقي حول الترميز، كما سنستخدم أداة إدارة مشاريع Python‏ uv لتسهيل عملية إنشاء إصدار Python وبيئة افتراضية وإدارتهما.

  1. إذا لم تكن قد فتحت المحطة الطرفية بعد، افتحها بالنقر على المحطة الطرفية -> محطة طرفية جديدة، أو استخدِم Ctrl + Shift + C، وسيؤدي ذلك إلى فتح نافذة محطة طرفية في الجزء السفلي من المتصفح.

8635b60ae2f45bbc.jpeg

  1. نزِّل uv وثبِّت الإصدار 3.12 من Python باستخدام الأمر التالي
curl -LsSf https://astral.sh/uv/0.7.19/install.sh | sh && \
source $HOME/.local/bin/env && \
uv python install 3.12
  1. لنبدأ الآن بتهيئة البيئة الافتراضية باستخدام uv، وننفّذ الأمر التالي
uv sync --frozen

سيؤدي ذلك إلى إنشاء الدليل .venv وتثبيت الموارد التابعة. ستمنحك نظرة خاطفة سريعة على pyproject.toml معلومات حول التبعيات المعروضة على النحو التالي

dependencies = [
    "google-adk>=1.5.0",
    "mcp-atlassian>=0.11.9",
    "pandas>=2.3.0",
    "python-dotenv>=1.1.1",
]
  1. لاختبار البيئة الافتراضية، أنشئ ملفًا جديدًا باسم main.py وانسخ الرمز التالي
def main():
   print("Hello from qa-test-planner-agent")

if __name__ == "__main__":
   main()
  1. بعد ذلك، شغِّل الأمر التالي
uv run main.py

ستظهر لك نتيجة مشابهة لما يلي

Using CPython 3.12
Creating virtual environment at: .venv
Hello from qa-test-planner-agent!

يشير ذلك إلى أنّه يتم إعداد مشروع Python بشكل صحيح.

يمكننا الآن الانتقال إلى الخطوة التالية، وهي إنشاء الوكيل ثم الخدمات

3- إنشاء الوكيل باستخدام Google ADK وGemini 2.5

مقدّمة حول بنية دليل ADK

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

  • إعداد بنية دليل الوكلاء
  • تجربة التفاعل بسرعة من خلال إدخال وإخراج CLI
  • إعداد واجهة مستخدم الويب لتطوير التطبيقات على الجهاز المحلي بسرعة

لننشئ الآن بنية دليل الوكيل باستخدام أمر واجهة سطر الأوامر. نفِّذ الأمر التالي

uv run adk create qa_test_planner \
   --model gemini-2.5-flash \
   --project {your-project-id} \
   --region global

سيؤدي ذلك إلى إنشاء بنية دليل الوكيل التالية في دليل العمل الحالي

qa_test_planner/
├── __init__.py
├── .env
├── agent.py

وإذا فحصت الملفين init.py وagent.py، سيظهر لك هذا الرمز

# __init__.py

from . import agent
# agent.py

from google.adk.agents import Agent

root_agent = Agent(
    model='gemini-2.5-flash',
    name='root_agent',
    description='A helpful assistant for user questions.',
    instruction='Answer user questions to the best of your knowledge',
)

إنشاء وكيل "مخطِّط اختبار تأكيد الجودة"

لنبدأ بإنشاء وكيل "مخطِّط اختبار تأكيد الجودة". افتح الملف qa_test_planner/agent.py وانسخ الرمز أدناه الذي سيتضمّن root_agent.

# qa_test_planner/agent.py

from google.adk.agents import Agent
from google.adk.tools.mcp_tool.mcp_toolset import (
    MCPToolset,
    StdioConnectionParams,
    StdioServerParameters,
)
from google.adk.planners import BuiltInPlanner
from google.genai import types
from dotenv import load_dotenv
import os
from pathlib import Path
from pydantic import BaseModel
from typing import Literal
import tempfile
import pandas as pd
from google.adk.tools import ToolContext


load_dotenv(dotenv_path=Path(__file__).parent / ".env")

confluence_tool = MCPToolset(
    connection_params=StdioConnectionParams(
        server_params=StdioServerParameters(
            command="uvx",
            args=[
                "mcp-atlassian",
                f"--confluence-url={os.getenv('CONFLUENCE_URL')}",
                f"--confluence-username={os.getenv('CONFLUENCE_USERNAME')}",
                f"--confluence-token={os.getenv('CONFLUENCE_TOKEN')}",
                "--enabled-tools=confluence_search,confluence_get_page,confluence_get_page_children",
            ],
            env={},
        ),
        timeout=60,
    ),
)


class TestPlan(BaseModel):
    test_case_key: str
    test_type: Literal["manual", "automatic"]
    summary: str
    preconditions: str
    test_steps: str
    expected_result: str
    associated_requirements: str


async def write_test_tool(
    prd_id: str, test_cases: list[dict], tool_context: ToolContext
):
    """A tool to write the test plan into file

    Args:
        prd_id: Product requirement document ID
        test_cases: List of test case dictionaries that should conform to these fields:
            - test_case_key: str
            - test_type: Literal["manual","automatic"]
            - summary: str
            - preconditions: str
            - test_steps: str
            - expected_result: str
            - associated_requirements: str

    Returns:
        A message indicating success or failure of the validation and writing process
    """
    validated_test_cases = []
    validation_errors = []

    # Validate each test case
    for i, test_case in enumerate(test_cases):
        try:
            validated_test_case = TestPlan(**test_case)
            validated_test_cases.append(validated_test_case)
        except Exception as e:
            validation_errors.append(f"Error in test case {i + 1}: {str(e)}")

    # If validation errors exist, return error message
    if validation_errors:
        return {
            "status": "error",
            "message": "Validation failed",
            "errors": validation_errors,
        }

    # Write validated test cases to CSV
    try:
        # Convert validated test cases to a pandas DataFrame
        data = []
        for tc in validated_test_cases:
            data.append(
                {
                    "Test Case ID": tc.test_case_key,
                    "Type": tc.test_type,
                    "Summary": tc.summary,
                    "Preconditions": tc.preconditions,
                    "Test Steps": tc.test_steps,
                    "Expected Result": tc.expected_result,
                    "Associated Requirements": tc.associated_requirements,
                }
            )

        # Create DataFrame from the test case data
        df = pd.DataFrame(data)

        if not df.empty:
            # Create a temporary file with .csv extension
            with tempfile.NamedTemporaryFile(suffix=".csv", delete=False) as temp_file:
                # Write DataFrame to the temporary CSV file
                df.to_csv(temp_file.name, index=False)
                temp_file_path = temp_file.name

            # Read the file bytes from the temporary file
            with open(temp_file_path, "rb") as f:
                file_bytes = f.read()

            # Create an artifact with the file bytes
            await tool_context.save_artifact(
                filename=f"{prd_id}_test_plan.csv",
                artifact=types.Part.from_bytes(data=file_bytes, mime_type="text/csv"),
            )

            # Clean up the temporary file
            os.unlink(temp_file_path)

            return {
                "status": "success",
                "message": (
                    f"Successfully wrote {len(validated_test_cases)} test cases to "
                    f"CSV file: {prd_id}_test_plan.csv"
                ),
            }
        else:
            return {"status": "warning", "message": "No test cases to write"}
    except Exception as e:
        return {
            "status": "error",
            "message": f"An error occurred while writing to CSV: {str(e)}",
        }


root_agent = Agent(
    model="gemini-2.5-flash",
    name="qa_test_planner_agent",
    description="You are an expert QA Test Planner and Product Manager assistant",
    instruction=f"""
Help user search any product requirement documents on Confluence. Furthermore you also can provide the following capabilities when asked:
- evaluate product requirement documents and assess it, then give expert input on what can be improved 
- create a comprehensive test plan following Jira Xray mandatory field formatting, result showed as markdown table. Each test plan must also have explicit mapping on 
    which user stories or requirements identifier it's associated to 

Here is the Confluence space ID with it's respective document grouping:

- "{os.getenv("CONFLUENCE_PRD_SPACE_ID")}" : space to store Product Requirements Documents

Do not making things up, Always stick to the fact based on data you retrieve via tools.
""",
    tools=[confluence_tool, write_test_tool],
    planner=BuiltInPlanner(
        thinking_config=types.ThinkingConfig(
            include_thoughts=True,
            thinking_budget=2048,
        )
    ),
)

إعداد ملفات الإعداد

الآن، سنحتاج إلى إضافة إعدادات ضبط إضافية لهذا المشروع، لأنّ هذا البرنامج سيتطلّب الوصول إلى Confluence

افتح qa_test_planner/.env وأضِف إليه قيم متغيرات البيئة التالية، وتأكَّد من أنّ ملف .env الناتج يبدو على النحو التالي

GOOGLE_GENAI_USE_VERTEXAI=1
GOOGLE_CLOUD_PROJECT={YOUR-CLOUD-PROJECT-ID}
GOOGLE_CLOUD_LOCATION=global
CONFLUENCE_URL={YOUR-CONFLUENCE-DOMAIN}
CONFLUENCE_USERNAME={YOUR-CONFLUENCE-USERNAME}
CONFLUENCE_TOKEN={YOUR-CONFLUENCE-API-TOKEN}
CONFLUENCE_PRD_SPACE_ID={YOUR-CONFLUENCE-SPACE-ID}

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

شرح الرمز

يحتوي هذا النص البرمجي على عملية بدء تشغيل الوكيل حيث نضبط القيم الأولية لما يلي:

  • اضبط النموذج الذي سيتم استخدامه على gemini-2.5-flash
  • إعداد أدوات بروتوكول سياق النموذج (MCP) في Confluence التي ستتواصل عبر Stdio
  • إعداد أداة write_test_tool مخصّصة لكتابة خطة الاختبار وتصدير ملف csv إلى العنصر
  • إعداد وصف الوكيل وتعليماته
  • تفعيل التخطيط قبل إنشاء الردّ النهائي أو تنفيذه باستخدام إمكانات التفكير في Gemini 2.5 Flash

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

# qa-test-planner/agent.py

from google.adk.planners import BuiltInPlanner
from google.genai import types

...

# Provide the confluence tool to agent

root_agent = Agent(
    model="gemini-2.5-flash",
    name="qa_test_planner_agent",
    ...,
    tools=[confluence_tool, write_test_tool],
    planner=BuiltInPlanner(
        thinking_config=types.ThinkingConfig(
            include_thoughts=True,
            thinking_budget=2048,
        )
    ),

...

وقبل اتخاذ أي إجراءات، يمكننا الاطّلاع على عملية التفكير التي يتبعها

7de7004af0fc8c90.png

أداة Confluence MCP

للاتصال بخادم MCP من ADK، علينا استخدام MCPToolSet الذي يمكن استيراده من الوحدة google.adk.tools.mcp_tool.mcp_toolset. يظهر أدناه الرمز الذي سيتم تهيئته هنا ( تم اقتطاعه لتحسين الكفاءة)

# qa-test-planner/agent.py

from google.adk.tools.mcp_tool.mcp_toolset import (
    MCPToolset,
    StdioConnectionParams,
    StdioServerParameters,
)

...

# Initialize the Confluence MCP Tool via Stdio Output

confluence_tool = MCPToolset(
    connection_params=StdioConnectionParams(
        server_params=StdioServerParameters(
            command="uvx",
            args=[
                "mcp-atlassian",
                f"--confluence-url={os.getenv('CONFLUENCE_URL')}",
                f"--confluence-username={os.getenv('CONFLUENCE_USERNAME')}",
                f"--confluence-token={os.getenv('CONFLUENCE_TOKEN')}",
                "--enabled-tools=confluence_search,confluence_get_page,confluence_get_page_children",
            ],
            env={},
        ),
        timeout=60,
    ),
)


...

# Provide the confluence tool to agent

root_agent = Agent(
    model="gemini-2.5-flash",
    name="qa_test_planner_agent",
    ...,
    tools=[confluence_tool, write_test_tool],

...

باستخدام هذا الإعداد، سيُفعّل الوكيل خادم MCP في Confluence كعملية منفصلة، وسيتعامل مع عمليات التواصل مع هذه العمليات من خلال Studio I/O. يتم توضيح هذا المسار في صورة بنية MCP التالية التي تم وضع علامة عليها داخل المربّع الأحمر أدناه.

8d8d8fd8e23d3c82.png

بالإضافة إلى ذلك، ضمن وسيطات أمر تهيئة MCP، نحصر أيضًا الأدوات التي يمكن استخدامها في هذه الأدوات فقط: confluence_search وconfluence_get_page وconfluence_get_page_children التي تتوافق مع حالات استخدام وكيل اختبار ضمان الجودة. نستخدم Atlassian MCP Server الذي ساهم فيه المنتدى ( يمكنك الاطّلاع على المستندات الكاملة لمزيد من التفاصيل) في هذا الدرس التطبيقي.

أداة "الكتابة"

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

# qa-test-planner/agent.py

...

async def write_test_tool(
    prd_id: str, test_cases: list[dict], tool_context: ToolContext
):
    """A tool to write the test plan into file

    Args:
        prd_id: Product requirement document ID
        test_cases: List of test case dictionaries that should conform to these fields:
            - test_case_key: str
            - test_type: Literal["manual","automatic"]
            - summary: str
            - preconditions: str
            - test_steps: str
            - expected_result: str
            - associated_requirements: str

    Returns:
        A message indicating success or failure of the validation and writing process
    """
    validated_test_cases = []
    validation_errors = []

    # Validate each test case
    for i, test_case in enumerate(test_cases):
        try:
            validated_test_case = TestPlan(**test_case)
            validated_test_cases.append(validated_test_case)
        except Exception as e:
            validation_errors.append(f"Error in test case {i + 1}: {str(e)}")

    # If validation errors exist, return error message
    if validation_errors:
        return {
            "status": "error",
            "message": "Validation failed",
            "errors": validation_errors,
        }

    # Write validated test cases to CSV
    try:
        # Convert validated test cases to a pandas DataFrame
        data = []
        for tc in validated_test_cases:
            data.append(
                {
                    "Test Case ID": tc.test_case_key,
                    "Type": tc.test_type,
                    "Summary": tc.summary,
                    "Preconditions": tc.preconditions,
                    "Test Steps": tc.test_steps,
                    "Expected Result": tc.expected_result,
                    "Associated Requirements": tc.associated_requirements,
                }
            )

        # Create DataFrame from the test case data
        df = pd.DataFrame(data)

        if not df.empty:
            # Create a temporary file with .csv extension
            with tempfile.NamedTemporaryFile(suffix=".csv", delete=False) as temp_file:
                # Write DataFrame to the temporary CSV file
                df.to_csv(temp_file.name, index=False)
                temp_file_path = temp_file.name

            # Read the file bytes from the temporary file
            with open(temp_file_path, "rb") as f:
                file_bytes = f.read()

            # Create an artifact with the file bytes
            await tool_context.save_artifact(
                filename=f"{prd_id}_test_plan.csv",
                artifact=types.Part.from_bytes(data=file_bytes, mime_type="text/csv"),
            )

            # Clean up the temporary file
            os.unlink(temp_file_path)

            return {
                "status": "success",
                "message": (
                    f"Successfully wrote {len(validated_test_cases)} test cases to "
                    f"CSV file: {prd_id}_test_plan.csv"
                ),
            }
        else:
            return {"status": "warning", "message": "No test cases to write"}
    except Exception as e:
        return {
            "status": "error",
            "message": f"An error occurred while writing to CSV: {str(e)}",
        }


...

تم إنشاء الدالة الموضّحة أعلاه لإتاحة الوظائف التالية:

  1. تحقَّق من خطة الاختبار التي تم إنتاجها للتأكّد من أنّها تتوافق مع مواصفات الحقول الإلزامية، ونتحقق من ذلك باستخدام نموذج Pydantic، وفي حال حدوث خطأ، نرسل رسالة الخطأ إلى الوكيل.
  2. تصدير النتيجة إلى ملف CSV باستخدام وظيفة pandas
  3. يتم بعد ذلك حفظ الملف الذي تم إنشاؤه كعنصر باستخدام إمكانات Artifact Service التي يمكن الوصول إليها باستخدام عنصر ToolContext الذي يمكن الوصول إليه في كل مكالمات الأدوات

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

adafec781450c89a.png

باستخدام هذه الميزة، يمكننا إعداد استجابة الملف بشكل ديناميكي من البرنامج الآلي ليتم تقديمها للمستخدم.

4. اختبار الوكيل

لنحاول الآن التواصل مع البرنامج من خلال واجهة سطر الأوامر، وننفّذ الأمر التالي

uv run adk run qa_test_planner

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

Log setup complete: /tmp/agents_log/agent.xxxx_xxx.log
To access latest log: tail -F /tmp/agents_log/agent.latest.log
Running agent qa_test_planner_agent, type exit to exit.
user: hello
[qa_test_planner_agent]: Hello there! How can I help you today?
user: 

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

uv run adk web --port 8080

سيؤدي ذلك إلى إنشاء ناتج مشابه للمثال التالي، ما يعني أنّه يمكننا الوصول إلى واجهة الويب.

INFO:     Started server process [xxxx]
INFO:     Waiting for application startup.

+-----------------------------------------------------------------------------+
| ADK Web Server started                                                      |
|                                                                             |
| For local testing, access at http://localhost:8080.                         |
+-----------------------------------------------------------------------------+

INFO:     Application startup complete.
INFO:     Uvicorn running on http://0.0.0.0:8080 (Press CTRL+C to quit)

الآن، للتحقّق من ذلك، انقر على الزر معاينة الويب في أعلى منطقة "محرّر Cloud Shell"، ثم انقر على معاينة على المنفذ 8080.

edc73e971b9fc60c.png

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

940b1e0391db4871.png

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

  • يُرجى إدراج جميع المنتجات المتاحة
  • " كتابة خطة اختبار لمستند متطلبات المنتج الخاص بتطبيق Snaprecipe "

عند استخدام بعض الأدوات، يمكنك فحص ما يحدث في واجهة مستخدم التطوير

35a3c928bd9dfb87.png

اطّلِع على طريقة ردّ الوكيل عليك، وتفقَّد أيضًا متى نطلب ملف اختبار، إذ سيتم إنشاء خطة الاختبار في ملف CSV كعنصر.

183558cb042cb021.png

يمكنك الآن التحقّق من محتوى ملف CSV من خلال استيراده إلى "جدول بيانات Google" مثلاً.

78933239b66eddb2.png

تهانينا! أصبح لديك الآن وكيل "مخطِّط اختبار تأكيد الجودة" يعمل على جهازك. لنرى الآن كيف يمكننا نشرها على Cloud Run ليتمكّن المستخدمون الآخرون أيضًا من استخدامها.

5- النشر على Cloud Run

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

af793beb2740233.jpeg

في دليل العمل الحالي، تتوفّر لدينا جميع الملفات اللازمة لنشر تطبيقاتنا على Cloud Run، وهي دليل الوكيل وDockerfile وserver.py (نص الخدمة الرئيسي)، لننشره الآن. انتقِل إلى "وحدة طرفية Cloud Shell" وتأكَّد من ضبط المشروع الحالي على مشروعك النشط. وإذا لم يكن كذلك، عليك استخدام الأمر gcloud configure لضبط رقم تعريف المشروع:

gcloud config set project [PROJECT_ID]

بعد ذلك، شغِّل الأمر التالي لنشره على Cloud Run.

gcloud run deploy qa-test-planner-agent \
                  --source . \
                  --port 8080 \
                  --project {YOUR_PROJECT_ID} \
                  --allow-unauthenticated \
                  --region us-central1 \
                  --update-env-vars GOOGLE_GENAI_USE_VERTEXAI=1 \
                  --update-env-vars GOOGLE_CLOUD_PROJECT={YOUR_PROJECT_ID} \
                  --update-env-vars GOOGLE_CLOUD_LOCATION=global \
                  --update-env-vars CONFLUENCE_URL={YOUR_CONFLUENCE_URL} \
                  --update-env-vars CONFLUENCE_USERNAME={YOUR_CONFLUENCE_USERNAME} \
                  --update-env-vars CONFLUENCE_TOKEN={YOUR_CONFLUENCE_TOKEN} \
                  --update-env-vars CONFLUENCE_PRD_SPACE_ID={YOUR_PRD_SPACE_ID} \
                  --memory 1G

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

بعد اكتمال عملية النشر، من المفترض أن تحصل على رابط مشابه لما يلي:

https://qa-test-planner-agent-*******.us-central1.run.app

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

لنحاول الآن إدخال هذه الطلبات المختلفة مرة أخرى بالتسلسل، ونرى ما سيحدث:

  • " هل يمكنك العثور على مستند متطلبات المنتج (PRD) المتعلّق بأداة تقدير الرهن العقاري؟ "
  • " أريد ملاحظات حول ما يمكننا تحسينه في هذا الشأن"
  • "اكتب خطة الاختبار"

بالإضافة إلى ذلك، بما أنّنا نشغّل الوكيل كتطبيق FastAPI، يمكننا أيضًا فحص جميع مسارات واجهة برمجة التطبيقات في المسار /docs. على سبيل المثال، إذا فتحت عنوان URL على النحو التالي https://qa-test-planner-agent-*******.us-central1.run.app/docs، ستظهر لك صفحة مستندات Swagger كما هو موضّح أدناه

82d2d91fb3cb2dde.png

شرح الرمز

الآن، لنفحص الملف الذي نحتاج إليه هنا للنشر، بدءًا من server.py

# server.py

import os

from fastapi import FastAPI
from google.adk.cli.fast_api import get_fast_api_app

AGENT_DIR = os.path.dirname(os.path.abspath(__file__))

app_args = {"agents_dir": AGENT_DIR, "web": True}

app: FastAPI = get_fast_api_app(**app_args)

app.title = "qa-test-planner-agent"
app.description = "API for interacting with the Agent qa-test-planner-agent"


if __name__ == "__main__":
    import uvicorn

    uvicorn.run(app, host="0.0.0.0", port=8080)

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

يمكنك أيضًا ضبط مراحل نشاط التطبيق هنا إذا أردت ذلك. بعد ذلك، يمكننا استخدام uvicorn لتشغيل تطبيق Fast API

بعد ذلك، سيزوّدنا Dockerfile بالخطوات اللازمة لتشغيل التطبيق.

# Dockerfile

FROM python:3.12-slim

RUN pip install --no-cache-dir uv==0.7.13

WORKDIR /app

COPY . .

RUN uv sync --frozen

EXPOSE 8080

CMD ["uv", "run", "uvicorn", "server:app", "--host", "0.0.0.0", "--port", "8080"]

6. التحدي

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

7. تَنظيم

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

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