لمحة عن هذا الدرس التطبيقي حول الترميز
1. نظرة عامة
في مختلف المجالات، يشكّل البحث السياقي وظيفة أساسية تشكل جوهر تطبيقات هذه المجالات. لطالما كان إنشاء المحتوى المعزّز لاسترداد المعلومات عاملاً رئيسيًا في هذا التطور التكنولوجي المهم، وذلك من خلال آليات الاسترجاع المستندة إلى الذكاء الاصطناعي التوليدي. تعمل النماذج التوليدية، بفضل نوافذ السياق الكبيرة وجودة الإخراج المُبهرة، على تطوير الذكاء الاصطناعي. توفّر تقنية RAG طريقة منهجية لإدخال السياق في تطبيقات الذكاء الاصطناعي ووكلاء الذكاء الاصطناعي، مع الاعتماد على قواعد بيانات منظَّمة أو معلومات من وسائط مختلفة. هذه البيانات السياقية ضرورية لوضوح الحقيقة ودقة النتيجة، ولكن ما مدى دقة هذه النتائج؟ هل يعتمد نشاطك التجاري بشكل كبير على دقة المطابقات السياقية ومدى الصلة بموضوع البحث؟ إذاً، هذا المشروع سيعجبك.
لنتخيل الآن أنّه يمكننا الاستفادة من قدرات النماذج التوليدية وإنشاء وكلاء تفاعليين قادرين على اتّخاذ قرارات مستقلة مستندة إلى هذه المعلومات المهمة للسياق، وهذا ما سننشئه اليوم. سننشئ تطبيقًا شاملاً لموظّف دعم يعمل بالذكاء الاصطناعي باستخدام Agent Development Kit (مجموعة تطوير موظّفي الدعم) المستندة إلى تقنية RAG المتقدّمة في AlloyDB لتطبيق تحليل براءات الاختراع.
يساعد مساعد تحليل براءات الاختراع المستخدم في العثور على براءات الاختراع ذات الصلة بالسياق لنص البحث، وعند الطلب، يقدّم شرحًا واضحًا وموجزًا وتفاصيل إضافية إذا لزم الأمر لبراءة اختراع محدّدة. هل أنت مستعد لمعرفة كيفية إجراء ذلك؟ لنطّلِع على التفاصيل.
الهدف
الهدف بسيط. السماح للمستخدم بالبحث عن براءات اختراع استنادًا إلى وصف نصي، ثم الحصول على شرح مفصّل لبراءة اختراع معيّنة من نتائج البحث، وكل ذلك باستخدام وكيل الذكاء الاصطناعي الذي تم إنشاؤه باستخدام Java ADK وAlloyDB وVector Search (مع الفهارس المتقدّمة) وGemini والتطبيق بأكمله الذي تم نشره بدون خادم على Cloud Run
ما ستُنشئه
كجزء من هذا الدرس التطبيقي، عليك تنفيذ ما يلي:
- إنشاء مثيل AlloyDB وتحميل بيانات مجموعة بيانات Patents Public Dataset
- تنفيذ ميزة "البحث بالاستناد إلى المتجهات" المتقدّمة في AlloyDB باستخدام ميزتَي تقييم "الاستكشاف" و"الاسترجاع"
- إنشاء وكيل باستخدام Java ADK
- تنفيذ المنطق من جهة خادم قاعدة البيانات في دوال Cloud بدون خادم من Java
- نشر الوكيل واختباره في Cloud Run
يمثّل الرسم البياني التالي تدفّق البيانات والخطوات المُتعلّقة بالتنفيذ.
High level diagram representing the flow of the Patent Search Agent with AlloyDB & ADK
المتطلبات
2. قبل البدء
إنشاء مشروع
- في Google Cloud Console، في صفحة أداة اختيار المشاريع، اختَر مشروعًا على Google Cloud أو أنشِئه.
- تأكَّد من تفعيل الفوترة لمشروعك على Cloud. تعرَّف على كيفية التحقّق مما إذا كانت الفوترة مفعَّلة في أحد المشاريع .
- ستستخدم Cloud Shell، وهي بيئة سطر أوامر تعمل في Google Cloud. انقر على "تفعيل Cloud Shell" في أعلى "وحدة تحكّم Google Cloud".
- بعد الاتصال بخدمة Cloud Shell، عليك التحقّق من أنّك سبق أن تم مصادقة حسابك وأنّ المشروع قد تم ضبطه على معرّف مشروعك باستخدام الأمر التالي:
gcloud auth list
- شغِّل الأمر التالي في Cloud Shell للتأكّد من أنّ الأمر gcloud يعرف مشروعك.
gcloud config list project
- إذا لم يتم ضبط مشروعك، استخدِم الأمر التالي لضبطه:
gcloud config set project <YOUR_PROJECT_ID>
- فعِّل واجهات برمجة التطبيقات المطلوبة. يمكنك استخدام أمر gcloud في وحدة تحكّم Cloud Shell الطرفية:
gcloud services enable alloydb.googleapis.com compute.googleapis.com cloudresourcemanager.googleapis.com servicenetworking.googleapis.com run.googleapis.com cloudbuild.googleapis.com cloudfunctions.googleapis.com aiplatform.googleapis.com
يمكنك استخدام وحدة التحكّم للبحث عن كل منتج أو استخدام هذا الرابط كبديل لأمر gcloud.
راجِع المستندات لمعرفة أوامر gcloud وكيفية استخدامها.
3. إعداد قاعدة البيانات
في هذا التمرين، سنستخدم AlloyDB كقاعدة بيانات لبيانات براءات الاختراع. ويستخدم المجموعات لتخزين جميع الموارد، مثل قواعد البيانات والسجلّات. تحتوي كل مجموعة على مثيل أساسي يقدّم نقطة وصول إلى البيانات. ستحتوي الجداول على البيانات الفعلية.
لننشئ مجموعة ومثيلًا وجدولًا في AlloyDB حيث سيتم تحميل مجموعة بيانات براءات الاختراع.
إنشاء مجموعة ومثيل
- انتقِل إلى صفحة AlloyDB في Cloud Console. إنّ البحث عن معظم الصفحات في Cloud Console باستخدام شريط البحث في وحدة التحكّم هو طريقة سهلة للعثور عليها.
- اختَر إنشاء مجموعة من هذه الصفحة:
- ستظهر لك شاشة مثل الشاشة أدناه. أنشئ مجموعة ومثيلًا بالقيم التالية (تأكَّد من تطابق القيم في حال كنت تُنشئ نسخة طبق الأصل من رمز التطبيق من المستودع):
- معرّف المجموعة: "
vector-cluster
" - كلمة المرور: "
alloydb
" - PostgreSQL 15 / أحدث إصدار ننصح به
- المنطقة: "
us-central1
" - التواصل: "
default
"
- عند اختيار الشبكة التلقائية، ستظهر لك شاشة مثل الشاشة أدناه.
انقر على إعداد عملية الربط.
- من هناك، اختَر "استخدام نطاق IP مخصّص تلقائيًا" ثم انقر على "متابعة". بعد مراجعة المعلومات، انقر على "إنشاء اتصال".
- بعد إعداد شبكتك، يمكنك مواصلة إنشاء مجموعتك. انقر على إنشاء مجموعة لإكمال إعداد المجموعة كما هو موضّح أدناه:
احرص على تغيير رقم تعريف المثيل (الذي يمكنك العثور عليه في وقت ضبط المجموعة أو المثيل) إلى
vector-instance
. إذا لم تتمكّن من تغييره، تذكَّر استخدام رقم تعريف المثيل في جميع الإحالات القادمة.
يُرجى العِلم أنّ إنشاء المجموعة سيستغرق 10 دقائق تقريبًا. بعد اكتمال العملية بنجاح، من المفترض أن تظهر لك شاشة تعرض نظرة عامة على المجموعة التي أنشأتها للتو.
4. نقل البيانات
حان الوقت الآن لإضافة جدول يحتوي على بيانات المتجر. انتقِل إلى AlloyDB، واختَر المجموعة الأساسية ثم AlloyDB Studio:
قد تحتاج إلى الانتظار حتى تكتمل عملية إنشاء المثيل. بعد ذلك، سجِّل الدخول إلى AlloyDB باستخدام بيانات الاعتماد التي أنشأتها عند إنشاء المجموعة. استخدِم البيانات التالية لمصادقة PostgreSQL:
- اسم المستخدم : "
postgres
" - قاعدة البيانات : "
postgres
" - كلمة المرور : "
alloydb
"
بعد المصادقة بنجاح في AlloyDB Studio، يتم إدخال أوامر SQL في المحرِّر. يمكنك إضافة عدّة نوافذ في "المحرِّر" باستخدام رمز الإضافة على يسار النافذة الأخيرة.
عليك إدخال أوامر AlloyDB في نوافذ المحرِّر، باستخدام خيارات "التشغيل" و"التنسيق" و"المحو" حسب الحاجة.
تفعيل الإضافات
لإنشاء هذا التطبيق، سنستخدم الإضافة pgvector
والإضافة google_ml_integration
. تتيح لك إضافة pgvector تخزين عمليات تضمين المتجهات والبحث عنها. توفّر إضافة google_ml_integration الدوالّ التي تستخدمها للوصول إلى نقاط نهاية التوقّعات في Vertex AI للحصول على توقّعات في SQL. فعِّل هذه الإضافات من خلال تنفيذ عبارات DDL التالية:
CREATE EXTENSION IF NOT EXISTS google_ml_integration CASCADE;
CREATE EXTENSION IF NOT EXISTS vector;
إذا كنت تريد التحقّق من الإضافات التي تم تفعيلها في قاعدة بياناتك، نفِّذ أمر SQL التالي:
select extname, extversion from pg_extension;
إنشاء جدول
يمكنك إنشاء جدول باستخدام عبارة DDL أدناه في AlloyDB Studio:
CREATE TABLE patents_data ( id VARCHAR(25), type VARCHAR(25), number VARCHAR(20), country VARCHAR(2), date VARCHAR(20), abstract VARCHAR(300000), title VARCHAR(100000), kind VARCHAR(5), num_claims BIGINT, filename VARCHAR(100), withdrawn BIGINT, abstract_embeddings vector(768)) ;
سيسمح عمود abstract_embeddings بتخزين قيم المتجهات للنص.
منح الإذن
شغِّل العبارة أدناه لمنح إذن التنفيذ للدالة "embedding":
GRANT EXECUTE ON FUNCTION embedding TO postgres;
منح دور مستخدم Vertex AI لحساب خدمة AlloyDB
من وحدة تحكّم إدارة الهوية وإمكانية الوصول في Google Cloud، امنح حساب خدمة AlloyDB (الذي يبدو على النحو التالي: service-<<PROJECT_NUMBER>>@gcp-sa-alloydb.iam.gserviceaccount.com) إذن الوصول إلى الدور "مستخدم Vertex AI". سيحتوي متغير PROJECT_NUMBER على رقم مشروعك.
بدلاً من ذلك، يمكنك تنفيذ الأمر التالي من وحدة Cloud Shell الطرفية:
PROJECT_ID=$(gcloud config get-value project)
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:service-$(gcloud projects describe $PROJECT_ID --format="value(projectNumber)")@gcp-sa-alloydb.iam.gserviceaccount.com" \
--role="roles/aiplatform.user"
تحميل بيانات براءات الاختراع إلى قاعدة البيانات
سيتم استخدام مجموعات البيانات العامة لبراءات اختراع Google على BigQuery كمجموعة بياناتنا. سنستخدم AlloyDB Studio لتشغيل استفساراتنا. يتم الحصول على البيانات من ملف insert_scripts.sql
هذا وسنشغّله لتحميل بيانات براءات الاختراع.
- في Google Cloud Console، افتح صفحة AlloyDB.
- اختَر المجموعة التي تم إنشاؤها حديثًا وانقر على المثيل.
- في قائمة التنقّل في AlloyDB، انقر على AlloyDB Studio. سجِّل الدخول باستخدام بيانات الاعتماد.
- افتح علامة تبويب جديدة بالنقر على رمز علامة تبويب جديدة على يسار الصفحة.
- انسخ عبارة طلب البحث
insert
من النص البرمجيinsert_scripts.sql
المذكور أعلاه إلى المحرِّر. يمكنك نسخ من 10 إلى 50 عبارة إدراج لإجراء عرض توضيحي سريع لهذه الحالة. - انقر على تشغيل. تظهر نتائج طلب البحث في جدول النتائج.
5. إنشاء عمليات تضمين لبيانات براءات الاختراع
أولاً، لنختبر دالة التضمين من خلال تنفيذ نموذج الاستعلام التالي:
SELECT embedding('text-embedding-005', 'AlloyDB is a managed, cloud-hosted SQL database service.');
من المفترض أن يعرض هذا الطلب متجه "العناصر المضمّنة"، الذي يبدو مثل صفيف من الأعداد العشرية، لعينة النص في الطلب. يظهر على النحو التالي:
تعديل حقل Vector في abstract_embeddings
شغِّل طلب البحث المحدَّد بتنسيق DML أدناه لتعديل ملخّصات براءات الاختراع في الجدول باستخدام عمليات التضمين المقابلة:
UPDATE patents_data set abstract_embeddings = embedding( 'text-embedding-005', abstract);
6. إجراء بحث في Vector
بعد أن أصبح الجدول والبيانات والعناصر المضمّنة جاهزة، لننفِّذ "البحث بالاستناد إلى المتجهات" في الوقت الفعلي عن نص بحث المستخدم. يمكنك اختبار ذلك من خلال تنفيذ الاستعلام أدناه:
SELECT id || ' - ' || title as title FROM patents_data ORDER BY abstract_embeddings <=> embedding('text-embedding-005', 'Sentiment Analysis')::vector LIMIT 10;
في هذا الطلب،
- النص الذي بحث عنه المستخدم هو: "تحليل المشاعر".
- نحن نحوّله إلى عناصر مضمّنة في الطريقة embedding() باستخدام النموذج: text-embedding-005.
- يشير "<=>" إلى استخدام طريقة المسافة "تشابه جيب التمام".
- نحن بصدد تحويل نتيجة طريقة التضمين إلى نوع متجه لجعلها متوافقة مع المتجهات المخزّنة في قاعدة البيانات.
- يشير LIMIT 10 إلى أنّنا نختار أقرب 10 نتائج مطابقة لنص البحث.
تنقل AlloyDB ميزة "البحث المتجه" في نموذج RAG إلى المستوى التالي:
تمّ تقديم عدد كبير من الميزات. إليك مثالان على الفعاليات التي تركّز على المطوّرين:
- الفلترة المضمّنة
- تقييم التذكُّر
الفلترة المضمّنة
في السابق، كان على المطوّر تنفيذ طلب البحث باستخدام تقنية "البحث المتجه" والتعامل مع الفلترة والاسترجاع. يحدِّد "مُحسِّن طلبات البحث في AlloyDB" خيارات حول كيفية تنفيذ طلب بحث باستخدام فلاتر. الفلترة المضمّنة هي أسلوب جديد لتحسين طلبات البحث يسمح لمُحسِّن طلبات البحث في AlloyDB بتقييم كلّ من شروط فلترة البيانات الوصفية وبحث المتجهات إلى جانب الاستفادة من كلّ من فهارس المتجهات والفهارس في أعمدة البيانات الوصفية. وقد أدّى ذلك إلى زيادة أداء التذكُّر، ما سمح للمطوّرين بالاستفادة من الميزات المتوفّرة في AlloyDB بدون الحاجة إلى إجراء أي تعديلات.
إنّ الفلترة المضمّنة هي الأفضل للحالات التي تتطلب انتقائية متوسطة. أثناء بحث AlloyDB في فهرس المتجهات، لا تحسب سوى المسافات للمتجهات التي تتطابق مع شروط فلترة البيانات الوصفية (الفلاتر الوظيفية في طلب البحث التي تتم معالجتها عادةً في عبارة WHERE). يؤدي ذلك إلى تحسين أداء طلبات البحث هذه بشكل كبير، ما يكمل مزايا الفلترة اللاحقة أو الفلترة المسبقة.
- تثبيت إضافة pgvector أو تحديثها
CREATE EXTENSION IF NOT EXISTS vector WITH VERSION '0.8.0.google-3';
إذا سبق تثبيت إضافة pgvector، عليك ترقية إضافة vector إلى الإصدار 0.8.0.google-3 أو إصدار أحدث للحصول على إمكانات تقييم الاسترجاع.
ALTER EXTENSION vector UPDATE TO '0.8.0.google-3';
لا يجب تنفيذ هذه الخطوة إلا إذا كانت إضافة الرسومات المتجهّة ذات الإصدار <0.8.0.google-3.
ملاحظة مهمة: إذا كان عدد الصفوف أقل من 100، لن تحتاج إلى إنشاء فهرس ScaNN في المقام الأول لأنّه لن ينطبق على عدد صفوف أقل. يُرجى تخطّي الخطوات التالية في هذه الحالة.
- لإنشاء فهارس ScaNN، ثبِّت إضافة alloydb_scann.
CREATE EXTENSION IF NOT EXISTS alloydb_scann;
- أولاً، شغِّل طلب البحث باستخدام نموذج "البحث بالاستناد إلى نموذج متجه" بدون الفهرس وبدون تفعيل "فلتر مضمّن":
SELECT id || ' - ' || title as title FROM patents_data
WHERE num_claims >= 15
ORDER BY abstract_embeddings <=> embedding('text-embedding-005', 'Sentiment Analysis')::vector LIMIT 10;
يجب أن تكون النتيجة مشابهة لما يلي:
- يمكنك إجراء تحليل Explain Analyze عليه: (بدون فهرس أو فلترة مضمّنة)
وقت التنفيذ هو 2.4 ملي ثانية
- لننشئ فهرسًا عاديًا في حقل num_claims لنتمكّن من الفلترة حسبه:
CREATE INDEX idx_patents_data_num_claims ON patents_data (num_claims);
- لننشئ فهرس ScaNN لتطبيق "بحث براءات الاختراع". شغِّل ما يلي من AlloyDB Studio:
CREATE INDEX patent_index ON patents_data
USING scann (abstract_embeddings cosine)
WITH (num_leaves=32);
ملاحظة مهمة: ينطبق (num_leaves=32)
على إجمالي مجموعة البيانات التي تضم أكثر من 1000 صف. إذا كان عدد الصفوف أقل من 100، لن تحتاج إلى إنشاء فهرس في المقام الأول لأنّه لن ينطبق على عدد صفوف أقل.
- اضبط الفلترة المضمّنة على أنّها مفعّلة في فهرس ScaNN:
SET scann.enable_inline_filtering = on
- الآن، لننفِّذ طلب البحث نفسه مع الفلتر وميزة "بحث المتجهات":
SELECT id || ' - ' || title as title FROM patents_data
WHERE num_claims >= 15
ORDER BY abstract_embeddings <=> embedding('text-embedding-005', 'Sentiment Analysis')::vector LIMIT 10;
كما يمكنك ملاحظة انخفاض وقت التنفيذ بشكل كبير لـ "بحث المتجهات" نفسه. وقد تمكّنت من إجراء ذلك من خلال فهرس ScaNN المزوّد بميزة الفلترة المضمّنة في "بحث المتجهات".
بعد ذلك، لنقيّم نسبة استرجاع "بحث المتجهات" المفعَّل به ScaNN.
تقييم التذكُّر
في البحث عن التشابه، يشير التذكر إلى النسبة المئوية للحالات ذات الصلة التي تم استرجاعها من عملية بحث، أي عدد الحالات الموجبة الصحيحة. هذا هو المقياس الأكثر شيوعًا المستخدَم لقياس جودة نتائج البحث. ينتج أحد مصادر فقدان الاسترجاع عن الفرق بين البحث عن الجار الأقرب التقريبي أو aNN والبحث عن الجار الأقرب (الدقيق) أو kNN. تُنفِّذ مؤشرات المتجهات، مثل ScaNN في AlloyDB، خوارزميات الشبكات العصبية التجميعية، ما يتيح لك تسريع البحث عن المتجهات في مجموعات البيانات الكبيرة مقابل تنازل بسيط في نسبة الاسترجاع. توفّر لك AlloyDB الآن إمكانية قياس هذا المفاضلة مباشرةً في قاعدة البيانات للاستعلامات الفردية والتأكّد من ثباتها بمرور الوقت. يمكنك تعديل مَعلمات الطلب والفهرس استجابةً لهذه المعلومات لتحقيق نتائج وأداء أفضل.
يمكنك العثور على نسبة استرجاع طلب بحث متجه في فهرس متجه لإعدادات معيّنة باستخدام الدالة evaluate_query_recall. تتيح لك هذه الدالة ضبط مَعلماتك لتحقيق نتائج استرجاع طلب البحث بالاستناد إلى المتجهات التي تريدها. "معدل الاسترجاع" هو المقياس المستخدَم لجودة البحث، ويتم تعريفه على أنّه النسبة المئوية للنتائج المعروضة التي تكون أقرب بشكل موضوعي إلى متجهات طلبات البحث. تكون الدالة evaluate_query_recall مفعّلة تلقائيًا.
ملاحظة مهمة:
إذا واجهت خطأ "الوصول مرفوض" في فهرس HNSW في الخطوات التالية، تخطّى قسم تقييم الاسترجاع بالكامل في الوقت الحالي. قد يكون ذلك بسبب قيود الوصول في الوقت الحالي، لأنّه تم طرحه للتو في وقت توثيق هذا الدليل التعليمي.
- اضبط علامة "تفعيل فحص الفهرس" في فهرس ScaNN وفهرس HNSW:
SET scann.enable_indexscan = on
SET hnsw.enable_index_scan = on
- نفِّذ الاستعلام التالي في AlloyDB Studio:
SELECT
*
FROM
evaluate_query_recall($$
SELECT
id || ' - ' || title AS title,
abstract
FROM
patents_data
where num_claims >= 15
ORDER BY
abstract_embeddings <=> embedding('text-embedding-005',
'sentiment analysis')::vector
LIMIT 25 $$,
'{"scann.num_leaves_to_search":1, "scann.pre_reordering_num_neighbors":10}',
ARRAY['scann']);
تأخذ الدالة evaluate_query_recall طلب البحث كمَعلمة وتُرجع نسبة استرجاعه. أستخدم طلب البحث نفسه الذي استخدمته للتحقّق من الأداء كطلب بحث إدخال الدالة. لقد أضفتُ SCaNN كطريقة الفهرسة. لمزيد من خيارات المَعلمات، يُرجى الرجوع إلى المستندات.
إليك معلومات حول طلب البحث عن المتجهات الذي كنّا نستخدمه:
أرى أنّ نسبة الاسترجاع هي %70. يمكنني الآن استخدام هذه المعلومات لتغيير مَعلمات الفهرس والأساليب ومَعلمات طلب البحث وتحسين تذكري لـ "بحث المتجهات" هذا.
لقد عدّلتُ عدد الصفوف في مجموعة النتائج إلى 7 (من 10 سابقًا) وألاحظ تحسُّنًا طفيفًا في نسبة الاسترجاع، أي 86%.
وهذا يعني أنّه يمكنني في الوقت الفعلي تغيير عدد المطابقات التي تظهر للمستخدمين لتحسين مدى صلة المطابقات بسياق بحث المستخدمين.
حسنًا. حان وقت نشر منطق قاعدة البيانات والانتقال إلى الوكيل.
7. نقل منطق قاعدة البيانات إلى الويب بدون خادم
هل أنت مستعد لنشر هذا التطبيق على الويب؟ يُرجى اتّباع الخطوات التالية:
- انتقِل إلى "وظائف Cloud Run" في Google Cloud Console لإنشاء "وظيفة Cloud Run" جديدة أو استخدِم الرابط: https://console.cloud.google.com/functions/add.
- اختَر "دالة Cloud Run" للبيئة. أدخِل اسم الدالة "patent-search" واختَر المنطقة "us-central1". اضبط المصادقة على "السماح بطلبات البيانات غير المعتمَدة" وانقر على "التالي". اختَر Java 17 كوقت تشغيل و"أداة التعديل المضمّن" للرمز المصدر.
- سيتم ضبط نقطة الدخول تلقائيًا على "gcfv2.HelloHttpFunction". استبدِل الرمز النائب في HelloHttpFunction.java وpom.xml لدالة Cloud Run برمز من PatentSearch.java وpom.xml على التوالي. غيِّر اسم ملف الفئة إلى PatentSearch.java.
- تذكَّر تغيير العنصر النائب ************* وبيانات اعتماد اتصال AlloyDB باستخدام قيمك في ملف Java. بيانات اعتماد AlloyDB هي البيانات التي استخدمناها في بداية هذا البرنامج التعليمي. إذا كنت قد استخدمت قيمًا مختلفة، يُرجى تعديلها في ملف Java.
- انقر على نشر.
خطوة مهمة:
بعد نشر الوظائف، سننشئ موصِّل VPC للسماح لوظيفة Cloud بالوصول إلى مثيل قاعدة بيانات AlloyDB.
بعد الانتهاء من الإعداد للنشر، من المفترض أن تتمكّن من الاطّلاع على الدوالّ في وحدة تحكّم Google Cloud Run Functions. ابحث عن الدالة التي تم إنشاؤها حديثًا (patent-search)، وانقر عليها، ثم انقر على رمز التعديل (القلم) في أعلى وحدة تحكّم Cloud Run Functions لتعديل المراجعات الجديدة ونشرها، وغيِّر ما يلي:
- انتقِل إلى علامة التبويب "الاتصال بالشبكات" (Networking):
- اختَر الاتصال بشبكة VPC للزيارات الصادرة، ثمّ اختَر استخدام موصّلات إمكانية الوصول إلى VPC بدون خادم.
- ضمن القائمة المنسدلة "الشبكة"، انقر على القائمة المنسدلة "الشبكة" واختَر إضافة موصل VPC جديد (إذا لم يسبق لك ضبط الإعداد التلقائي) واتّبِع التعليمات التي تظهر في مربّع الحوار المنبثق:
- أدخِل اسمًا لموصِّل VPC وتأكَّد من أنّ المنطقة هي نفسها التي تستخدمها في المثيل. اترك قيمة "الشبكة" على الإعداد التلقائي واضبط "الشبكة الفرعية" على "نطاق IP مخصّص" باستخدام نطاق IP 10.8.0.0 أو أي نطاق مشابه متاح.
- وسِّع SETTINGS FOR SCALING (إعدادات التكبير/التصغير) وتأكَّد من ضبط الإعدادات على ما يلي بالضبط:
- انقر على إنشاء، ومن المفترض أن يظهر هذا الموصّل في إعدادات الخروج الآن.
- اختَر الموصّل الذي تم إنشاؤه حديثًا.
- اختَر توجيه جميع الزيارات من خلال موصِّل VPC هذا.
- انقر على التالي ثم على نشر.
- بعد نشر Cloud Function المعدَّلة، من المفترض أن تظهر لك نقطة النهاية التي تم إنشاؤها. انسخ هذا النص واستبدِله في الأمر التالي:
PROJECT_ID=$(gcloud config get-value project)
curl -X POST <<YOUR_ENDPOINT>> \
-H 'Content-Type: application/json' \
-d '{"search":"Sentiment Analysis"}'
هذا كل شيء! بهذه البساطة، يمكنك إجراء بحث متقدّم باستخدام "متجه التشابه السياقي" باستخدام نموذج "عمليات التضمين" في بيانات AlloyDB.
8. لننشئ موظّف الدعم باستخدام Java ADK
أولاً، لنبدأ بمشروع Java في المحرِّر.
- الانتقال إلى وحدة Cloud Shell الطرفية
https://shell.cloud.google.com/?fromcloudshell=true&show=ide%2Cterminal
- منح الإذن عند طلب ذلك
- يمكنك التبديل إلى "محرر Cloud Shell" من خلال النقر على رمز المحرر في أعلى وحدة تحكّم Cloud Shell.
- في وحدة تحكّم Cloud Shell Editor، أنشئ مجلدًا جديدًا واسمه "adk-agents".
انقر على "إنشاء مجلد جديد" في الدليل الجذر لوحدة تحكّم السحابة الإلكترونية كما هو موضّح أدناه:
أدخِل اسمًا له، مثل "adk-agents":
- أنشئ بنية المجلدات التالية والملفات الفارغة بأسماء الملفات المقابلة لها في البنية أدناه:
adk-agents/
└—— pom.xml
└—— src/
└—— main/
└—— java/
└—— agents/
└—— App.java
- افتح مستودع GitHub في علامة تبويب منفصلة وانسخ رمز المصدر للملفَين App.java وpom.xml.
- إذا كنت قد فتحت المحرِّر في علامة تبويب جديدة باستخدام رمز "الفتح في علامة تبويب جديدة" في أعلى يسار الصفحة، يمكنك فتح وحدة التحكّم في أسفل الصفحة. يمكنك فتح المحرِّر والوحدة الطرفية بشكلٍ متزامن ما يتيح لك العمل بحرية.
- بعد الاستنساخ، ارجع إلى وحدة تحكّم محرِّر Cloud Shell.
- بما أنّنا سبق أن أنشأنا وظيفة Cloud Run، لست بحاجة إلى نسخ ملفات وظيفة Cloud Run من مجلد المستودع.
بدء استخدام حزمة تطوير البرامج (SDK) لـ ADK Java
إنّ العملية بسيطة إلى حدٍ ما. عليك في المقام الأول التأكّد من تضمين ما يلي في خطوة الاستنساخ:
- إضافة التبعيات:
أدرِج العنصرَين google-adk وgoogle-adk-dev (لواجهة مستخدِم الويب) في ملف pom.xml.
<!-- The ADK core dependency -->
<dependency>
<groupId>com.google.adk</groupId>
<artifactId>google-adk</artifactId>
<version>0.1.0</version>
</dependency>
<!-- The ADK dev web UI to debug your agent -->
<dependency>
<groupId>com.google.adk</groupId>
<artifactId>google-adk-dev</artifactId>
<version>0.1.0</version>
</dependency>
احرص على الإشارة إلى pom.xml من مستودع المصدر لأنّ هناك تبعيات وإعدادات أخرى مطلوبة ليتمكّن التطبيق من التشغيل.
- ضبط المشروع:
تأكَّد من ضبط إصدار Java (ننصح باستخدام الإصدار 17 والإصدارات الأحدث) وإعدادات مُجمِّع Maven بشكل صحيح في pom.xml. يمكنك ضبط مشروعك ليتبع البنية التالية:
adk-agents/
└—— pom.xml
└—— src/
└—— main/
└—— java/
└—— agents/
└—— App.java
- تحديد الوكيل وأدواته (App.java):
هذا هو المكان الذي يتجلّى فيه سحر حزمة ADK Java SDK. نحن نحدّد مهام موظّف الدعم وقدراته (التعليمات) والأدوات التي يمكنه استخدامها.
يمكنك العثور هنا على نسخة مبسّطة من بعض مقتطفات الرموز البرمجية لفئة موظّف الدعم الرئيسية. للاطّلاع على المشروع الكامل، يُرجى الرجوع إلى مستودع المشروع هنا.
// App.java (Simplified Snippets)
package agents;
import com.google.adk.agents.LlmAgent;
import com.google.adk.agents.BaseAgent;
import com.google.adk.agents.InvocationContext;
import com.google.adk.tools.Annotations.Schema;
import com.google.adk.tools.FunctionTool;
// ... other imports
public class App {
static FunctionTool searchTool = FunctionTool.create(App.class, "getPatents");
static FunctionTool explainTool = FunctionTool.create(App.class, "explainPatent");
public static BaseAgent ROOT_AGENT = initAgent();
public static BaseAgent initAgent() {
return LlmAgent.builder()
.name("patent-search-agent")
.description("Patent Search agent")
.model("gemini-2.0-flash-001") // Specify your desired Gemini model
.instruction(
"""
You are a helpful patent search assistant capable of 2 things:
// ... complete instructions ...
""")
.tools(searchTool, explainTool)
.outputKey("patents") // Key to store tool output in session state
.build();
}
// --- Tool: Get Patents ---
public static Map<String, String> getPatents(
@Schema(name="searchText",description = "The search text for which the user wants to find matching patents")
String searchText) {
try {
String patentsJson = vectorSearch(searchText); // Calls our Cloud Run Function
return Map.of("status", "success", "report", patentsJson);
} catch (Exception e) {
// Log error
return Map.of("status", "error", "report", "Error fetching patents.");
}
}
// --- Tool: Explain Patent (Leveraging InvocationContext) ---
public static Map<String, String> explainPatent(
@Schema(name="patentId",description = "The patent id for which the user wants to get more explanation for, from the database")
String patentId,
@Schema(name="ctx",description = "The list of patent abstracts from the database from which the user can pick the one to get more explanation for")
InvocationContext ctx) { // Note the InvocationContext
try {
// Retrieve previous patent search results from session state
String previousResults = (String) ctx.session().state().get("patents");
if (previousResults != null && !previousResults.isEmpty()) {
// Logic to find the specific patent abstract from 'previousResults' by 'patentId'
String[] patentEntries = previousResults.split("\n\n\n\n");
for (String entry : patentEntries) {
if (entry.contains(patentId)) { // Simplified check
// The agent will then use its instructions to summarize this 'report'
return Map.of("status", "success", "report", entry);
}
}
}
return Map.of("status", "error", "report", "Patent ID not found in previous search.");
} catch (Exception e) {
// Log error
return Map.of("status", "error", "report", "Error explaining patent.");
}
}
public static void main(String[] args) throws Exception {
InMemoryRunner runner = new InMemoryRunner(ROOT_AGENT);
// ... (Session creation and main input loop - shown in your source)
}
}
أبرز مكوّنات رمز Java في ADK:
- LlmAgent.builder(): واجهة برمجة تطبيقات Fluent لضبط موظّف الدعم
- .instruction(...): يوفّر الطلب الأساسي والإرشادات للنماذج اللغوية الكبيرة، بما في ذلك الحالات التي تستدعي استخدام أداة معيّنة.
- FunctionTool.create(App.class, "methodName"): تسجِّل هذه الوظيفة بسهولة إجراءات Java كأدوات يمكن للوكيل استخدامها. يجب أن تتطابق سلسلة اسم الطريقة مع طريقة ثابتة عامة فعلية.
- @Schema(description = ...): لإضافة تعليقات توضيحية على مَعلمات الأداة، ما يساعد النموذج اللغوي الكبير في فهم الإدخالات التي تتوقعها كل أداة. هذا الوصف مهم لاختيار الأداة بدقة وملء المَعلمات.
- InvocationContext ctx: يتم تمريرها تلقائيًا إلى طُرق الأداة، ما يتيح الوصول إلى حالة الجلسة (ctx.session().state()) ومعلومات المستخدم وغير ذلك.
- .outputKey("patents"): عندما تعرض إحدى الأدوات بيانات، يمكن لخدمة ADK تخزينها تلقائيًا في حالة الجلسة ضمن هذا المفتاح. هذه هي الطريقة التي يمكن بها لـ explainPatent الوصول إلى النتائج من getPatents.
- VECTOR_SEARCH_ENDPOINT: هذا متغيّر يحتوي على المنطق الوظيفي الأساسي لميزة "الأسئلة والأجوبة السياقية" للمستخدم في حالة استخدام البحث عن براءات الاختراع.
- إجراء مطلوب هنا: عليك ضبط قيمة نقطة نهاية مُعدَّلة تم نشرها بعد تنفيذ خطوة "وظيفة Java Cloud Run" من القسم السابق.
- searchTool: يتفاعل هذا الإجراء مع المستخدم للعثور على مطابقات براءات اختراع ذات صلة بالسياق من قاعدة بيانات براءات الاختراع لنص بحث المستخدم.
- explainTool: يطلب هذا الإجراء من المستخدم اختيار براءة اختراع معيّنة للتعمّق فيها. بعد ذلك، يلخّص الذكاء الاصطناعي ملخّص براءة الاختراع ويمكنه الإجابة عن المزيد من أسئلة المستخدم استنادًا إلى تفاصيل براءة الاختراع التي يمتلكها.
ملاحظة مهمة: احرص على استبدال المتغيّر VECTOR_SEARCH_ENDPOINT بنقطة نهاية CRF المنشورة.
الاستفادة من InvocationContext للتفاعلات التي تتضمّن حالة
إنّ إدارة الحالة على مدار أدوار متعدّدة في المحادثة هي إحدى الميزات المهمة لبناء موظّفي دعم فعّالين. تسهِّل InvocationContext في ADK إجراء ذلك.
في App.java:
- عند تحديد initAgent()، نستخدم .outputKey("patents"). يُعلم ذلك أداة ADK بأنّه عندما تعرض إحدى الأدوات (مثل getPatents) بيانات في حقل التقرير، يجب تخزين هذه البيانات في حالة الجلسة ضمن المفتاح "patents".
- في طريقة أداة explainPatent، نحقّق من InvocationContext ctx:
public static Map<String, String> explainPatent(
@Schema(description = "...") String patentId, InvocationContext ctx) {
String previousResults = (String) ctx.session().state().get("patents");
// ... use previousResults ...
}
يتيح ذلك لأداة explainPatent الوصول إلى قائمة براءات الاختراع التي جلبتها أداة getPatents في دور سابق، ما يجعل المحادثة ذات حالة متّسقة.
9. اختبار سطر الأوامر المحلي
تحديد متغيّرات البيئة
عليك تصدير متغيّرَي بيئة:
- مفتاح Gemini الذي يمكنك الحصول عليه من AI Studio:
لإجراء ذلك، انتقِل إلى https://aistudio.google.com/apikey واحصل على مفتاح واجهة برمجة التطبيقات لمشروعك النشط على Google Cloud الذي تنفِّذ فيه هذا التطبيق واحفظ المفتاح في مكان ما:
- بعد الحصول على المفتاح، افتح Cloud Shell Terminal وانتقِل إلى الدليل الجديد الذي أنشأناه للتو adk-agents من خلال تنفيذ الأمر التالي:
cd adk-agents
- متغيّر لتحديد أنّنا لا نستخدم Vertex AI هذه المرة
export GOOGLE_GENAI_USE_VERTEXAI=FALSE
export GOOGLE_API_KEY=AIzaSyDF...
- تشغيل أول وكيل على وحدة تحكّم سطر الأوامر
لتشغيل هذا الوكيل الأوّل، استخدِم الأمر Maven التالي في الوحدة الطرفية:
mvn compile exec:java -DmainClass="agents.App"
سيظهر لك الردّ التفاعلي من موظّف الدعم في المحطة الطرفية.
10. النشر على Cloud Run
يشبه نشر وكيل Java في ADK على Cloud Run نشر أي تطبيق Java آخر:
- ملف Dockerfile: يمكنك إنشاء ملف Dockerfile لحزمة تطبيق Java.
- إنشاء صورة Docker ودفعها: استخدِم Google Cloud Build وArtifact Registry.
- يمكنك تنفيذ الخطوة أعلاه ونشر التطبيق على Cloud Run باستخدام أمر واحد فقط:
gcloud run deploy --source . --set-env-vars GOOGLE_API_KEY=<<Your_Gemini_Key>>
وبالمثل، يمكنك نشر دالة Java Cloud Run (gcfv2.PatentSearch). بدلاً من ذلك، يمكنك إنشاء ونشر دالة Java Cloud Run لوظيفة قاعدة البيانات مباشرةً من وحدة تحكّم Cloud Run Function.
11. الاختبار باستخدام واجهة مستخدِم الويب
تأتي أداة ADK مع واجهة مستخدم مفيدة على الويب لإجراء الاختبار المحلي وتصحيح أخطاء موظّف الدعم. عند تشغيل App.java محليًا (مثل mvn exec:java -Dexec.mainClass="agents.App" في حال ضبط الإعدادات، أو تشغيل الطريقة الرئيسية فقط)، يبدأ ADK عادةً خادم ويب محليًا.
تتيح لك واجهة مستخدم ADK على الويب إجراء ما يلي:
- أرسِل رسائل إلى موظّف الدعم.
- اطّلِع على الأحداث (رسالة المستخدم، طلب الأداة، استجابة الأداة، استجابة LLM).
- فحص حالة الجلسة
- عرض السجلّات والتتبّعات
وهذا أمر لا يقدر بثمن أثناء التطوير لفهم كيفية معالجة موظّف الدعم للطلبات واستخدامه لأدواته. يفترض ذلك ضبط mainClass في pom.xml على com.google.adk.web.AdkWebServer وأن يكون وكيلك مسجّلاً به، أو أنّك تشغّل أداة اختبار محلية تعرض ذلك.
عند تشغيل App.java باستخدام InMemoryRunner وScanner لإدخال وحدة التحكّم، يعني ذلك أنّك تختبر منطق الوكيل الأساسي. واجهة مستخدم الويب هي مكوّن منفصل لتجربة تصحيح أخطاء مرئية أكثر، ويتم استخدامها غالبًا عندما يقدّم ADK وكيلك عبر HTTP.
يمكنك استخدام أمر Maven التالي من الدليل الجذر لبدء الخادم المحلي SpringBoot:
mvn compile exec:java -Dexec.args="--adk.agents.source-dir=src/main/java/ --logging.level.com.google.adk.dev=TRACE --logging.level.com.google.adk.demo.agents=TRACE"
يمكن الوصول إلى الواجهة غالبًا من خلال عنوان URL الذي يعرضه الأمر أعلاه. إذا كان مُنشئًا على Cloud Run، من المفترض أن تتمكّن من الوصول إليه من خلال رابط الإنشاء على Cloud Run.
من المفترض أن تظهر لك النتيجة في واجهة تفاعلية.
يمكنك مشاهدة الفيديو أدناه الذي يعرض موظّف دعم براءات الاختراع:
12. تَنظيم
لتجنُّب تحصيل رسوم من حسابك على Google Cloud مقابل الموارد المستخدَمة في هذه المشاركة، اتّبِع الخطوات التالية:
- في Google Cloud Console، انتقِل إلى https://console.cloud.google.com/cloud-resource-manager?utm_campaign=CDR_0x1d2a42f5_default_b419133749&utm_medium=external&utm_source=blog.
- https://console.cloud.google.com/cloud-resource-manager?utm_campaign=CDR_0x1d2a42f5_default_b419133749&utm_medium=external&utm_source=blog.
- في قائمة المشاريع، اختَر المشروع الذي تريد حذفه، ثم انقر على حذف.
- في مربّع الحوار، اكتب رقم تعريف المشروع، ثم انقر على إيقاف لحذف المشروع.
13. تهانينا
تهانينا! لقد نجحت في إنشاء وكيل تحليل براءات الاختراع في Java من خلال الجمع بين إمكانات ADK وhttps://cloud.google.com/alloydb/docs?utm_campaign=CDR_0x1d2a42f5_default_b419133749&utm_medium=external&utm_source=blog وVertex AI وVector Search، وقد قطعنا أيضًا خطوة كبيرة إلى الأمام في جعل عمليات البحث عن التشابه السياقي فعّالة ومؤثرة ومستندة إلى المعنى.
ابدأ اليوم
مستندات ADK: [Link to Official ADK Java Docs]
رمز المصدر لوكيل تحليل براءات الاختراع: [رابط إلى مستودع GitHub (المتاح الآن للجميع)]
Java Sample Agents: [link to the adk-samples repo]
انضم إلى منتدى ADK: https://www.reddit.com/r/agentdevelopmentkit/
مع أطيب التحيّات،