الكلمة الرئيسية في مؤتمر Next‏ 2026 للمطوّرين: تحسين أداء الوكلاء باستخدام ميزة "الذاكرة"

1. مقدمة

في هذا الدرس العملي، ستنتقل بمساعدي ADK إلى المستوى التالي من خلال إضافة معرفة مستمرة ومتخصصة. ستتعرّف على كيفية إدارة حالة المحادثة باستخدام "جلسات منصة الوكيل"، وتفعيل التعلّم على المدى الطويل باستخدام "بنك الذاكرة"، ودمج بيانات معقّدة لقواعد المدينة باستخدام Spark وAlloyDB من أجل التوليد المعزّز بالاسترجاع (RAG).

الإجراءات التي ستنفذّها

  • اضبط جلسات منصة الوكيل لضمان استمرار المحادثة.
  • تنفيذ بنك الذاكرة للسماح للوكلاء بالاستفادة من التفاعلات السابقة
  • استخدِم Spark Lightning Engine لنقل بيانات مستندات قواعد المدينة ومعالجتها.
  • إنشاء نظام توليد معزّز بالاسترجاع (RAG) باستخدام AlloyDB والبحث المتّجه
  • انشر الوكيل المحسّن في "منصة الوكلاء".

المتطلبات

المدة المقدَّرة: 60 دقيقة

يجب أن تكون تكلفة الموارد التي تم إنشاؤها في هذا الدرس التطبيقي حول الترميز أقل من 5 دولارات أمريكية.

2. قبل البدء

إنشاء مشروع على Google Cloud

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

بدء Cloud Shell

Cloud Shell هي بيئة سطر أوامر تعمل في Google Cloud ومحمّلة مسبقًا بالأدوات اللازمة.

  1. انقر على تفعيل Cloud Shell في أعلى "وحدة تحكّم Google Cloud".
  2. بعد الاتصال بـ Cloud Shell، تحقَّق من مصادقتك باتّباع الخطوات التالية:
    gcloud auth list
    
  3. تأكَّد من إعداد مشروعك باتّباع الخطوات التالية:
    gcloud config get project
    
  4. إذا لم يتم ضبط مشروعك على النحو المتوقّع، اضبطه باتّباع الخطوات التالية:
    export PROJECT_ID=<YOUR_PROJECT_ID>
    gcloud config set project $PROJECT_ID
    

إثبات صحة المصادقة:

gcloud auth list

أكِّد مشروعك:

gcloud config get project

اضبطه إذا لزم الأمر:

export PROJECT_ID=<YOUR_PROJECT_ID>
gcloud config set project $PROJECT_ID

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

نفِّذ الأمر التالي لتفعيل جميع واجهات برمجة التطبيقات المطلوبة لإدارة الجلسات ومعالجة Spark وAlloyDB:

gcloud services enable \
  aiplatform.googleapis.com \
  run.googleapis.com \
  alloydb.googleapis.com \
  dataproc.googleapis.com \
  documentai.googleapis.com \
  storage.googleapis.com \
  secretmanager.googleapis.com

3- إعداد البيئة

في هذا الدرس التطبيقي حول الترميز، ستستخدم البيئة التي تم إعدادها مسبقًا في مستودع keynote.

  1. أنشئ نسخة طبق الأصل من المستودع وانتقِل إلى مجلد المشروع:
git clone https://github.com/GoogleCloudPlatform/next-26-keynotes
cd next-26-keynotes/devkey/enhancing-agents-with-memory
  1. إعداد بيئة Python افتراضية وتثبيت حِزم ADK المطلوبة:
uv venv
source .venv/bin/activate
uv sync

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

يتطلّب العامل إعدادات معيّنة للاتصال بمنصة Agent وAlloyDB.

  1. انسخ ملف البيئة النموذجية:
cp .env.example .env
  1. افتح .env وعدِّل الحقول التالية:
    • GOOGLE_CLOUD_PROJECT: رقم تعريف مشروعك.
    • GOOGLE_CLOUD_LOCATION: us-central1.
    • ALLOYDB_CLUSTER_ID: rules-db.
GOOGLE_CLOUD_PROJECT=<YOUR_PROJECT_ID>
GOOGLE_CLOUD_LOCATION=global
GOOGLE_GENAI_USE_VERTEXAI=TRUE
GOOGLE_CLOUD_REGION=us-central1
ALLOYDB_CLUSTER_ID=rules-db
  1. نفِّذ النص البرمجي المساعد التالي لإنشاء مثيل من Agent Engine سيتم استخدامه لجلسات المحادثة والذاكرة الطويلة الأمد. سيؤدي ذلك إلى تعبئة AGENT_ENGINE_ID تلقائيًا في ملف .env:
uv run utils/setup_agent_engine.py

بعد إكمال العملية بنجاح، من المفترض أن يظهر لك ما يلي:

Creating Agent Engine instance...
Successfully created Agent Engine. ID: 1234567890
Updated .env with AGENT_ENGINE_ID=1234567890

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

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

تهيئة خدمة "الوكيل" و"الجلسة"

فتح "planner_agent/agent.py" ستتعرّف على كيفية إضافة فئة ADK لدمج جلسات "منصّة الوكيل". يمنحنا ذلك القدرة على جعل برامجنا الآلية تحتفظ بحالتها بمرور الوقت، وتعديل السياق حسب الحاجة.

from google.adk.agents import LlmAgent
from google.adk.sessions import VertexAiSessionService
from vertexai.agent_engines import AdkApp

PROJECT_ID = os.environ.get("GOOGLE_CLOUD_PROJECT")
REGION = os.environ.get("GOOGLE_CLOUD_REGION", "us-central1")

# Initialize Vertex AI for regional services
if PROJECT_ID:
    vertexai.init(project=PROJECT_ID, location=REGION)

# Define the agent logic
root_agent = LlmAgent(
    name="planner_agent",
    model="gemini-3-flash-preview",
    instruction="You are a helpful marathon planning assistant...",
    tools=[] # We will add tools in the next steps
)

def session_service_builder():
    """Builder for Agent Platform Sessions."""
    return VertexAiSessionService(project=PROJECT_ID, location=REGION)

# Wrap the agent in an AdkApp to manage stateful context
app = AdkApp(
    agent=root_agent,
    session_service_builder=session_service_builder
)

5- تفعيل ميزة "التعلم على المدى الطويل" باستخدام "بنك الذاكرة"

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

بدء خدمة "بنك الذاكرة"

تتيح "ذاكرة الوكيل" للوكيل تذكُّر السياق في جلسات مختلفة. عدِّل planner_agent/agent.py لتضمين خدمة الذاكرة:

from google.adk.memory import VertexAiMemoryBankService

def memory_service_builder():
    """Builder for Agent Platform Memory Bank."""
    return VertexAiMemoryBankService(
        project=PROJECT_ID,
        location=REGION,
        agent_engine_id=AGENT_ENGINE_ID
    )

تنفيذ عملية استيعاب الذاكرة التلقائية

لضمان استفادة البرنامج من كل تفاعل، نضيف after_agent_callback. يتم تفعيل هذه الوظيفة بعد أن يكمل الوكيل ردًا، ما يسمح له "بمعالجة" الجلسة وحفظ الذكريات ذات الصلة في البنك.

  1. حدِّد دالة رد الاتصال:
async def auto_save_memories(callback_context):
    """Callback to ingest the session into the memory bank after the turn."""
    # In AdkApp, the memory service is available via the invocation context
    if hasattr(callback_context._invocation_context, 'memory_service') and callback_context._invocation_context.memory_service:
        await callback_context._invocation_context.memory_service.add_session_to_memory(
            callback_context._invocation_context.session
        )
  1. أرفِق دالة رد الاتصال بالرمز LlmAgent:
root_agent = LlmAgent(
    # ... other params
    after_agent_callback=[auto_save_memories],
)

6. إعداد AlloyDB لتطبيقات توليد معزّز بالاسترجاع

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

1. إنشاء مجموعة AlloyDB والمثيل الأساسي

نفِّذ الأوامر التالية في Cloud Shell لإنشاء مجموعتك ونسختها الأساسية:

# Create the cluster
gcloud alloydb clusters create rules-db \
  --password=postgres \
  --region=us-central1

# Create the primary instance with IAM authentication enabled
gcloud alloydb instances create rules-db-primary \
  --instance-type=PRIMARY \
  --cpu-count=2 \
  --region=us-central1 \
  --cluster=rules-db \
  --database-flags=alloydb.iam_authentication=on

2. منح أدوار "إدارة الهوية وإمكانية الوصول" المطلوبة

لاستخدام خادم MCP المُدار في AlloyDB، يجب أن تتوفّر في هويتك أذونات معيّنة. نفِّذ الأوامر التالية لمنح الأدوار المطلوبة:

export USER_EMAIL=$(gcloud config get-value account)

# Role to use MCP tools
gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member="user:$USER_EMAIL" \
  --role="roles/mcp.toolUser"

# Role to execute SQL in AlloyDB
gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member="user:$USER_EMAIL" \
  --role="roles/alloydb.admin"

# Role for IAM database authentication
gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member="user:$USER_EMAIL" \
  --role="roles/alloydb.databaseUser"

# Create the IAM-based database user
gcloud alloydb users create "$USER_EMAIL" \
  --cluster=rules-db \
  --region=us-central1 \
  --type=IAM_BASED

3- إنشاء قاعدة بيانات وجداول من خلال AlloyDB Studio

بما أنّ قواعد بيانات وجداول AlloyDB تتم إدارتها من خلال SQL، سنستخدم AlloyDB Studio في Google Cloud Console لوضع اللمسات الأخيرة على المخطط.

  1. انتقِل إلى AlloyDB > المجموعات وانقر على rules-db.
  2. في قائمة التنقّل اليمنى، انقر على AlloyDB Studio.
  3. سجِّل الدخول باستخدام المستخدم postgres وكلمة المرور التي ضبطتها (postgres).
  4. نفِّذ لغة SQL التالية لإنشاء قاعدة البيانات:
    CREATE DATABASE city_rules;
    
  5. بدِّل اتصال قاعدة البيانات إلى city_rules في AlloyDB Studio ونفِّذ عبارة SQL التالية لتثبيت الإضافات وإنشاء جدول rules:
    -- Install extensions for vector search and ML
    CREATE EXTENSION IF NOT EXISTS vector;
    CREATE EXTENSION IF NOT EXISTS google_ml_integration CASCADE;
    
    -- Create the rules table
    CREATE TABLE IF NOT EXISTS rules (
        id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
        text TEXT NOT NULL,
        city TEXT NOT NULL,
        embedding vector(3072) DEFAULT NULL
    );
    
    -- Grant your IAM user access to the table (replace with your email)
    GRANT ALL PRIVILEGES ON TABLE rules TO "YOUR_EMAIL_ADDRESS";
    

7. استيعاب بيانات قواعد المدن باستخدام Spark Lightning Engine

لتقديم تخطيط دقيق، يحتاج الوكيل إلى أكثر من مجرد طلب مصمّم جيدًا، بل يحتاج إلى الاستناد إلى البيانات والسياق التنظيمي. في هذه الخطوة، ستستخدم Spark Lightning Engine على Dataproc Serverless لمعالجة ملفات PDF الكبيرة الخاصة بقواعد المدن واستيعابها في AlloyDB.

لماذا Spark Lightning Engine؟

يتطلّب تحديد المصدر للوكلاء على نطاق واسع معالجة كميات هائلة من البيانات غير المنظَّمة. ‫Spark Lightning Engine هو محرك تنفيذ عالي الأداء لـ Spark يعمل على تسريع أحمال العمل هذه بشكل كبير. نستخدمها هنا لإجراء التقسيم الدلالي للمستندات باستخدام Document AI من Google.

استكشاف Spark Pipeline

يتم تحديد منطق الاستيعاب في spark-setup/spark_alloydb_processor.py. تتّبع عملية المعالجة الخطوات التالية:

  1. قائمة بملفات PDF: تسترد هذه الطريقة معرّفات الموارد المنتظمة (URI) للمستندات من حزمة Google Cloud Storage.
  2. الاستخراج الدلالي: يستخدم دالة معرَّفة من قِبل المستخدم (UDF) لاستدعاء Document AI API.
  3. الكتابة إلى AlloyDB: تحفظ هذه العملية أجزاء النص المستخرَجة في جدول AlloyDB باسم rules.
# Extract from spark_alloydb_processor.py
def process_document(gcs_uri: str):
    # ... calls Document AI to parse PDF ...
    return chunks

# Parallel processing with Spark Lightning Engine
process_udf = udf(process_document, chunk_schema)
chunked_df = uri_df.withColumn("chunks", process_udf(col("gcs_uri"))) \
                   .select(explode(col("chunks")).alias("chunk")) \
                   .select("chunk.*")

# Save to AlloyDB for Vector Search
chunked_df.write.format("jdbc") \
    .option("url", jdbc_url) \
    .option("dbtable", "rules") \
    .mode("append") \
    .save()

تشغيل مهمة نقل البيانات

ابدأ عملية الاستيعاب باستخدام النص البرمجي المقدَّم:

./spark-setup/run_dataproc.sh

8. التوليد المعزّز بالاسترجاع (RAG) باستخدام AlloyDB

بعد أن أصبحت بيانات قواعد المدن متوفرة في AlloyDB، يمكن للوكيل استخدامها لتنفيذ التوليد المعزّز بالاسترجاع (RAG). يضمن ذلك التزام خطة الماراثون برموز مدن معيّنة.

مزايا استخدام AlloyDB في التوليد المعزّز بالاسترجاع

تتفوّق AlloyDB في البحث المستند إلى المتّجهات، ما يتيح لنا تخزين كلّ من البيانات المنظَّمة وعمليات التضمين المستندة إلى المتّجهات في المكان نفسه. يمكن للوكيل استخدام الدالة embedding المضمّنة في AlloyDB للعثور على معلومات القواعد الأكثر صلة.

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

SELECT
    text,
    (embedding <=> 
     embedding('gemini-embedding-001', 
               'Restrictions for running a race on the Las Vegas strip')::vector) 
    as distance
FROM
    rules
WHERE city = 'Las Vegas'
ORDER BY
    distance ASC
LIMIT 5;

تأسيس الوكيل على القواعد المحلية باستخدام أداة التوليد المعزّز بالاسترجاع

لإتاحة الأداة للوكيل، يجب تحديدها في planner_agent/tools.py ثم تسجيلها في planner_agent/agent.py. سنستخدم خادم MCP المُدار عن بُعد في AlloyDB من Google Cloud للاتصال بقاعدة البيانات.

  1. عرِّف الأداة في planner_agent/tools.py باستخدام نمط "الاسترجاع المختلط". سنستخدم بروتوكول streamable_http للاتصال بخادم AlloyDB MCP المُدار:
from mcp import ClientSession
from mcp.client.streamable_http import streamablehttp_client

async def get_local_and_traffic_rules(query: str) -> str:
    """Uses vector search in AlloyDB via managed MCP server."""
    # Vector search query using built-in AlloyDB embedding functions
    sql = f"SELECT text FROM rules WHERE city = 'Las Vegas' ORDER BY embedding <=> google_ml.embedding('gemini-embedding-001', '{query}')::vector ASC LIMIT 5;"
    
    # Establish a streamable HTTP connection to the MCP server
    async with streamablehttp_client(url, headers=get_auth_headers()) as (read_stream, write_stream, _):
        async with ClientSession(read_stream, write_stream) as session:
            await session.initialize()
            result = await session.call_tool(
                "execute_sql",
                arguments={
                    "instance": full_instance_name,
                    "database": "city_rules",
                    "sqlStatement": sql
                }
            )
            return "\n".join([c.text for c in result.content if hasattr(c, 'text')])
  1. سجِّل الأداة وأكمِل عملية planner_agent/agent.py:
# ... imports ...

# Assemble the Agent
root_agent = LlmAgent(
    name="planner_agent",
    model="gemini-3-flash-preview",
    instruction="You are a helpful marathon planning assistant...",
    tools=[
        get_local_and_traffic_rules,
    ],
    after_agent_callback=[auto_save_memories],
)

# 2. Wrap the agent in an AdkApp to manage the stateful lifecycle
app = AdkApp(
    agent=root_agent,
    session_service_builder=session_service_builder,
    memory_service_builder=memory_service_builder
)

9- إرشادات من الخبراء باستخدام مهارات الوكيل

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

توفّر Google مهارات مُعدّة مسبقًا لمنتجات Google (مثل AlloyDB وBigQuery) لضمان اتّباع وكيلك لأفضل الممارسات في المجال عند طلب البيانات وإدارة الموارد. يمكنك استكشاف هذه الأنماط المتخصّصة وغيرها في مستودع مهارات Google. يمكنك الاطّلاع على المهارات الأساسية في AlloyDB هنا.

1. استكشاف ملف المهارة

افتح ملف المهارة المُعدّ مسبقًا في planner_agent/skills/get-local-and-traffic-rules/SKILL.md. إليك الشكل الذي يظهر به:

---
name: get-local-and-traffic-rules
description: Retrieve local rules and traffic information for a specific jurisdiction.
---
# get_local_and_traffic_rules Skill

This skill provides guidelines on how to effectively use the `get_local_and_traffic_rules` tool.

## Overview
The `get_local_and_traffic_rules` tool interfaces with an AlloyDB database to perform vector similarity searches on a corpus of rules and traffic information using a provided natural language query.

## Usage Guidelines
1. **Query Specificity**: When calling the tool, provide specific details in the `query` argument. For example, instead of querying "food rules", use "rules regarding food vendors during public events".
2. **Contextual Use**: Use the tool when planning events or activities that require adherence to local municipal or state rules (e.g., street closures, noise ordinances, environmental rules).
3. **Handling Results**: The tool returns a string containing the text of the top 5 most relevant rules. If no error occurs, parse the returned string to inform your planning tasks.
4. **Error Handling**: If an error string is returned (e.g., "Error querying rules: ..."), you must report this failure or attempt an alternative approach if applicable.

## Underlying Mechanism
- The tool uses `google_ml.embedding` to convert the query into a vector representation.
- It calculates distance (`<=>`) against the `embedding` column in the `rules` table on an AlloyDB instance.
- Results are fetched in descending order of similarity, limited to 5 results.

2. كيفية تسجيل المهارة

في planner_agent/agent.py، يتم تحميل المهارة من الدليل وإضافتها إلى أدوات الوكيل. في ما يلي شكل الرمز:

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

# Load the AlloyDB skill from its directory
alloydb_skill = load_skill_from_dir(pathlib.Path(__file__).parent / "skills" / "get-local-and-traffic-rules")

# Assemble the Agent with the Skill Toolset
root_agent = LlmAgent(
    name="planner_agent",
    model="gemini-3-flash-preview",
    instruction="You are a helpful marathon planning assistant...",
    tools=[
        get_local_and_traffic_rules,
        skill_toolset.SkillToolset(skills=[alloydb_skill])
    ],
    after_agent_callback=[auto_save_memories],
)

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

  1. ابدأ تشغيل الوكيل محليًا:
uv run adk run planner_agent
  1. طرح سؤال حول قواعد المدينة: [user]: What are the rules for running a race on the Las Vegas strip?

سيطلب الوكيل get_local_and_traffic_rules، ويُجري بحثًا عن المتّجهات في AlloyDB، ويعرض إجابة استنادًا إلى أجزاء القواعد الرسمية التي يعالجها Spark.

11. نشر الوكيل

النشر في Agent Platform

uv run adk deploy agent_engine \
  --env_file .env \
  planner_agent

12. تَنظيم

لتجنُّب تحصيل رسوم مستمرة، احذف الموارد التي تم إنشاؤها خلال هذا الدرس البرمجي.

حذف مجموعة AlloyDB

# Delete the AlloyDB Cluster
gcloud alloydb clusters delete rules-db --region=us-central1 --force

حذف تطبيق Agent Runtime

يمكنك حذف مثيل Reasoning Engine من خلال وحدة التحكّم أو باستخدام الأمر gcloud (إذا كان لديك اسم المورد). لتبسيط الأمر، استخدِم وحدة التحكّم:

  1. انتقِل إلى صفحة بيئة تشغيل الوكيل.
  2. انقر على planner_agent –> زر النقاط الثلاث على الجانب الأيسر.
  3. انقر على حذف.

13. تهانينا

تهانينا! لقد حسّنت بنجاح أحد وكلاء ADK من خلال إتاحة إمكانات متقدّمة للوصول إلى الذاكرة وتحديد المصدر.

ما تعلّمته

  • الوكلاء ذوو الحالة: دمج جلسات منصة الوكلاء للحفاظ على سياق المحادثة
  • التعلم على المدى الطويل: ربط بنك ذاكرة منصة الوكيل للسماح للوكيل بالتعلم من تفاعلات المستخدمين
  • نقل البيانات: استخدام محرك Spark Lightning وDocument AI لمعالجة المستندات غير المنظَّمة
  • التوليد المعزّز بالاسترجاع: إنشاء نظام بحث متّجهي في AlloyDB لربط الوكيل بقواعد العالم الحقيقي

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