1. نظرة عامة
في مجال البيع بالتجزئة السريع التطور اليوم، من الضروري تقديم خدمة عملاء ممتازة وتوفير تجارب تسوّق مخصّصة. سنأخذك في رحلة فنية عبر إنشاء تطبيق محادثة مستند إلى المعرفة ومصمّم للإجابة عن أسئلة العملاء وتوجيههم لاكتشاف المنتجات وتخصيص نتائج البحث. يجمع هذا الحلّ المبتكر بين قوة AlloyDB لتخزين البيانات، ومحرّك إحصاءات داخلي لفهم السياق، وGemini (نموذج لغوي كبير) للتحقّق من الصلة بالموضوع، وAgent Builder من Google لتوفير مساعد حواري ذكي بسرعة.
التحدي: يتوقّع عملاء البيع بالتجزئة الحديثون الحصول على إجابات فورية واقتراحات لمنتجات تتوافق مع تفضيلاتهم الفريدة. غالبًا ما تعجز طرق البحث التقليدية عن توفير هذا المستوى من التخصيص.
الحل: يتصدّى تطبيق الدردشة المستند إلى المعرفة هذا للتحدي مباشرةً. تستفيد هذه الأداة من قاعدة معرفة غنية مستمدّة من بيانات البيع بالتجزئة لفهم نوايا العملاء والردّ بذكاء وتقديم نتائج فائقة الصلة.
ما ستنشئه
في إطار هذا الدرس التطبيقي (الجزء 1)، ستنفّذ ما يلي:
- إنشاء آلة افتراضية في AlloyDB وتحميل مجموعة بيانات التجارة الإلكترونية
- تفعيل إضافات pgvector ونموذج الذكاء الاصطناعي التوليدي في AlloyDB
- إنشاء تضمينات من وصف المنتج
- إجراء بحث في الوقت الفعلي عن تشابه جيب التمام لنص بحث المستخدم
- نشر الحل في "دوال Cloud Run" بدون خادم
سيتناول الجزء الثاني من المختبر خطوات "أداة إنشاء الوكيل".
المتطلبات
2. الهندسة المعمارية
تدفّق البيانات: لنلقِ نظرة عن كثب على كيفية انتقال البيانات عبر نظامنا:
الاستيعاب:
خطوتنا الأولى هي نقل بيانات Retail (المستودع وأوصاف المنتجات وتفاعلات العملاء) إلى AlloyDB.
محرك التحليلات:
سنستخدم AlloyDB كمحرّك إحصاءات لتنفيذ ما يلي:
- استخراج السياق: يحلّل المحرّك البيانات المخزَّنة في AlloyDB لفهم العلاقات بين المنتجات والفئات وسلوك العملاء وما إلى ذلك حسب الاقتضاء.
- إنشاء التضمينات: يتم إنشاء تضمينات (تمثيلات رياضية للنصوص) لكل من طلب المستخدم والمعلومات المخزّنة في AlloyDB.
- البحث المستند إلى المتجهات: ينفّذ محرّك البحث عملية بحث عن التشابه، ويقارن تضمين طلب البحث بتضمينات أوصاف المنتجات والمراجعات والبيانات الأخرى ذات الصلة. يحدّد هذا الإجراء 25 "جارًا أقرب" الأكثر صلةً.
التحقّق من صحة Gemini:
يتم إرسال هذه الردود المحتملة إلى Gemini لتقييمها. يحدّد Gemini ما إذا كانت هذه المعلومات ملائمة وآمنة حقًا لمشاركتها مع المستخدم.
إنشاء الردود:
يتم تنظيم الردود التي تم التحقّق من صحتها في مصفوفة JSON، ويتم تجميع المحرّك بأكمله في دالة Cloud Run غير مستنِدة إلى خادم يتم استدعاؤها من Agent Builder.
التفاعل الحواري:
يعرض Agent Builder الردود على المستخدم بتنسيق لغة طبيعية، ما يسهّل إجراء حوار ذهابًا وإيابًا. سنتناول هذا الجزء في درس تطبيقي لاحق.
3- قبل البدء
إنشاء مشروع
- في Google Cloud Console، في صفحة اختيار المشروع، اختَر أو أنشِئ مشروعًا على Google Cloud.
- تأكَّد من تفعيل الفوترة لمشروعك على السحابة الإلكترونية. تعرَّف على كيفية التحقّق مما إذا كانت الفوترة مفعَّلة في مشروع .
- ستستخدم Cloud Shell، وهي بيئة سطر أوامر تعمل في Google Cloud ومحمّلة مسبقًا بأداة bq. انقر على "تفعيل Cloud Shell" في أعلى "وحدة تحكّم Google Cloud".

- بعد الاتصال بـ Cloud Shell، يمكنك التأكّد من أنّك قد تم التحقّق من هويتك وأنّه تم ضبط المشروع على رقم تعريف مشروعك باستخدام الأمر التالي:
gcloud auth list
- نفِّذ الأمر التالي في Cloud Shell للتأكّد من أنّ أمر gcloud يعرف مشروعك.
gcloud config list project
- إذا لم يتم ضبط مشروعك، استخدِم الأمر التالي لضبطه:
gcloud config set project <YOUR_PROJECT_ID>
- فعِّل واجهات برمجة التطبيقات المطلوبة.
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 وطريقة استخدامها.
4. إعداد قاعدة البيانات
في هذا الدرس التطبيقي، سنستخدم AlloyDB كقاعدة بيانات للاحتفاظ ببيانات البيع بالتجزئة. يستخدم المجموعات للاحتفاظ بجميع الموارد، مثل قواعد البيانات والسجلات. تحتوي كل مجموعة على مثيل أساسي يوفّر نقطة وصول إلى البيانات. ستحتوي الجداول على البيانات الفعلية.
لننشئ مجموعة ومثيل وجدول AlloyDB سيتم تحميل مجموعة بيانات التجارة الإلكترونية فيها.
إنشاء مجموعة ومثيل
- انتقِل إلى صفحة AlloyDB في Cloud Console. تتمثّل إحدى الطرق السهلة للعثور على معظم الصفحات في Cloud Console في البحث عنها باستخدام شريط البحث في وحدة التحكّم.
- اختَر "إنشاء مجموعة" من تلك الصفحة:

- ستظهر لك شاشة مشابهة للشاشة أدناه. أنشئ مجموعة ومثيل بالقيم التالية:
- رقم تعريف المجموعة: "
shopping-cluster" - كلمة المرور: "
alloydb" - متوافق مع PostgreSQL 15
- المنطقة: "
us-central1" - الشبكات: "
default"

- عند اختيار الشبكة التلقائية، ستظهر لك شاشة مثل الشاشة أدناه. انقر على "إعداد الاتصال".

- من هناك، اختَر "استخدام نطاق عناوين IP تم تخصيصه تلقائيًا" ثم انقر على "متابعة". بعد مراجعة المعلومات، انقر على "إنشاء ربط".

- بعد إعداد شبكتك، يمكنك مواصلة إنشاء مجموعتك. انقر على CREATE CLUSTER (إنشاء مجموعة) لإكمال إعداد المجموعة كما هو موضّح أدناه:

احرص على تغيير معرّف المثيل إلى "shopping-instance"".
يُرجى العِلم أنّ إنشاء المجموعة سيستغرق حوالي 10 دقائق. بعد اكتمال العملية بنجاح، من المفترض أن تظهر لك شاشة مشابهة لما يلي:

5- نقل البيانات
حان الوقت الآن لإضافة جدول يتضمّن بيانات حول المتجر. انتقِل إلى AlloyDB، واختَر المجموعة الأساسية، ثم AlloyDB Studio:

قد تحتاج إلى الانتظار إلى أن يكتمل إنشاء مثيلك. بعد ذلك، سجِّل الدخول إلى AlloyDB باستخدام بيانات الاعتماد التي أنشأتها عند إنشاء المجموعة. استخدِم البيانات التالية للمصادقة على PostgreSQL:
- اسم المستخدم : "
postgres" - قاعدة البيانات : "
postgres" - كلمة المرور : "
alloydb"
بعد إكمال عملية المصادقة بنجاح في AlloyDB Studio، يتم إدخال أوامر SQL في "المحرّر". يمكنك إضافة نوافذ "المحرّر" متعددة باستخدام علامة الجمع على يسار النافذة الأخيرة.

ستُدخل أوامر AlloyDB في نوافذ المحرّر، باستخدام الخيارات "تشغيل" و"تنسيق" و"محو" حسب الحاجة.
تفعيل الإضافات
لإنشاء هذا التطبيق، سنستخدم الإضافتين pgvector وgoogle_ml_integration. تتيح لك إضافة pgvector تخزين عمليات التضمين المتجهة والبحث عنها. توفّر إضافة google_ml_integration دوال يمكنك استخدامها للوصول إلى نقاط نهاية التوقّعات في Vertex AI من أجل الحصول على توقّعات في SQL. فعِّل هذه الإضافات من خلال تنفيذ تعريفات البيانات التالية:
CREATE EXTENSION IF NOT EXISTS google_ml_integration CASCADE;
CREATE EXTENSION IF NOT EXISTS vector;
إذا أردت التحقّق من الإضافات التي تم تفعيلها في قاعدة البيانات، نفِّذ أمر SQL التالي:
select extname, extversion from pg_extension;
إنشاء جدول
أنشئ جدولاً باستخدام عبارة DDL أدناه:
CREATE TABLE
apparels ( id BIGINT,
category VARCHAR(100),
sub_category VARCHAR(50),
uri VARCHAR(200),
image VARCHAR(100),
content VARCHAR(2000),
pdt_desc VARCHAR(5000),
embedding vector(768) );
بعد تنفيذ الأمر أعلاه بنجاح، يجب أن تتمكّن من عرض الجدول في قاعدة البيانات. في ما يلي نموذج لقطة شاشة:

نقل البيانات
في هذا التمرين العملي، لدينا بيانات اختبار تتضمّن حوالي 200 سجلّ في ملف SQL هذا. تتضمّن id, category, sub_category, uri, image وcontent. سيتم ملء الحقول الأخرى لاحقًا في الدرس التطبيقي.
انسخ الأسطر/عبارات الإدراج العشرين من هناك، ثم الصِق هذه الأسطر في علامة تبويب فارغة في المحرّر وانقر على "تنفيذ".
للاطّلاع على محتوى الجدول، وسِّع قسم "المستكشف" إلى أن يظهر لك الجدول المسمّى "الملابس". انقر على رمز النقاط الثلاث العمودية (⋮) للاطّلاع على خيار "طلب البحث في الجدول". سيتم فتح عبارة SELECT في علامة تبويب "المحرّر" جديدة.

منح الإذن
نفِّذ العبارة أدناه لمنح حقوق التنفيذ على الدالة embedding للمستخدم postgres:
GRANT EXECUTE ON FUNCTION embedding TO postgres;
منح دور "مستخدم Vertex AI" لحساب خدمة AlloyDB
انتقِل إلى وحدة 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"
6. السياق
ارجع إلى صفحة "آلة AlloyDB الافتراضية".
لإنشاء تضمين، يجب أن يتوفّر لدينا context، أي كل المعلومات التي نريد تضمينها في حقل واحد. سننفّذ ذلك من خلال إنشاء وصف للمنتج (سنسمّيه pdt_desc). في حالتنا، سنستخدم جميع المعلومات المتعلّقة بكل منتج، ولكن عند تنفيذ ذلك باستخدام بياناتك الخاصة، يمكنك تصميم البيانات بأي طريقة تراها مناسبة لنشاطك التجاري.
نفِّذ العبارة التالية من AlloyDB studio للآلة الافتراضية التي أنشأتها حديثًا. سيؤدي ذلك إلى تعديل الحقل pdt_desc باستخدام بيانات السياق:
UPDATE
apparels
SET
pdt_desc = CONCAT('This product category is: ', category, ' and sub_category is: ', sub_category, '. The description of the product is as follows: ', content, '. The product image is stored at: ', uri)
WHERE
id IS NOT NULL;
تنشئ لغة معالجة البيانات هذه ملخّصًا بسيطًا للسياق باستخدام المعلومات من جميع الحقول المتاحة في الجدول والتبعيات الأخرى (إذا كانت هناك أي تبعيات في حالة الاستخدام). للحصول على مجموعة أكثر دقة من المعلومات وإنشاء سياق، يمكنك تصميم البيانات بأي طريقة تراها مناسبة لنشاطك التجاري.
7. إنشاء تضمينات للسياق
فمن الأسهل على أجهزة الكمبيوتر معالجة الأرقام مقارنةً بمعالجة النصوص. يحوّل نظام التضمين النص إلى سلسلة من الأرقام النقطية العائمة التي من المفترض أن تمثّل النص، بغض النظر عن صياغته أو اللغة المستخدَمة فيه أو غير ذلك.
يمكنك وصف موقع جغرافي على شاطئ البحر. قد يُطلق عليها اسم "على الماء" أو "على شاطئ البحر" أو "يمكنك المشي من غرفتك إلى المحيط" أو "sur la mer" أو "на берегу океана" وما إلى ذلك. تبدو هذه العبارات مختلفة، ولكن يجب أن يكون معناها الدلالي أو ما يُعرف في مصطلحات تعلُّم الآلة باسم "التضمينات" قريبًا جدًا من بعضه البعض.
بعد أن أصبحت البيانات والسياق جاهزين، سننفّذ طلب بحث SQL لإضافة تضمينات وصف المنتج إلى الجدول في الحقل embedding. تتوفّر مجموعة متنوعة من نماذج التضمين التي يمكنك استخدامها. نحن نستخدم text-embedding-004 من Vertex AI. احرص على استخدام نموذج التضمين نفسه طوال مدة المشروع.
ملاحظة: إذا كنت تستخدم مشروعًا حاليًا على Google Cloud تم إنشاؤه منذ فترة، قد تحتاج إلى مواصلة استخدام إصدارات قديمة من نموذج تضمين النص، مثل textembedding-gecko.
UPDATE
apparels
SET
embedding = embedding( 'text-embedding-004',
pdt_desc)
WHERE
TRUE;
انظر إلى جدول apparels مرة أخرى للاطّلاع على بعض التضمينات. احرص على إعادة تنفيذ عبارة SELECT للاطّلاع على التغييرات.
SELECT
id,
category,
sub_category,
content,
embedding
FROM
apparels;
من المفترض أن يؤدي ذلك إلى عرض متجه التضمين، الذي يبدو كصفيف من الأرقام العشرية، للنص النموذجي في طلب البحث كما هو موضّح أدناه:

ملاحظة: قد تواجه مشاريع Google Cloud التي تم إنشاؤها حديثًا ضمن الإصدار المجاني مشاكل في الحصة عندما يتعلق الأمر بعدد طلبات التضمين المسموح بها في الثانية لنماذج التضمين. نقترح استخدام طلب بحث فلترة للمعرّف ثم اختيار 1 إلى 5 سجلّات بشكل انتقائي وهكذا، أثناء إنشاء التضمين.
8. إجراء بحث عن المتّجهات
بعد أن أصبح الجدول والبيانات والتضمينات جاهزة، لننفّذ الآن البحث المتّجه في الوقت الفعلي عن نص بحث المستخدم.
لنفترض أنّ المستخدم يسأل:
"أريد قمصانًا نسائية وردية اللون من القطن الخالص فقط".
يمكنك العثور على نتائج مطابقة لذلك من خلال تنفيذ طلب البحث أدناه:
SELECT
id,
category,
sub_category,
content,
pdt_desc AS description
FROM
apparels
ORDER BY
embedding <=> embedding('text-embedding-004',
'I want womens tops, pink casual only pure cotton.')::vector
LIMIT
5;
لنلقِ نظرة على هذا الاستعلام بالتفصيل:
في هذا الاستعلام،
- نص البحث الذي أدخله المستخدم هو: "أريد قمصانًا نسائية وردية اللون من القطن الخالص فقط".
- نحن نحولها إلى تضمينات باستخدام الطريقة
embedding()والنموذجtext-embedding-004. يجب أن تبدو هذه الخطوة مألوفة بعد الخطوة الأخيرة، حيث طبّقنا دالة التضمين على جميع العناصر في الجدول. - يمثّل "
<=>" استخدام طريقة قياس المسافة COSINE SIMILARITY. يمكنك العثور على جميع مقاييس التشابه المتاحة في مستندات pgvector. - نحوّل نتيجة طريقة التضمين إلى نوع متّجه لجعلها متوافقة مع المتّجهات المخزّنة في قاعدة البيانات.
- يشير LIMIT 5 إلى أنّنا نريد استخراج 5 جيران أقرب للنص المطلوب البحث عنه.
تبدو النتيجة على النحو التالي:

كما تلاحظ في نتائجك، تكون المطابقات قريبة جدًا من نص البحث. جرِّب تغيير اللون لمعرفة كيف تتغيّر النتائج.
ملاحظة مهمة:
لنفترض الآن أنّنا نريد تحسين أداء نتيجة "البحث المتّجه" هذه (وقت طلب البحث) وكفاءتها ودقتها باستخدام فهرس ScaNN. يُرجى قراءة الخطوات الواردة في هذه المدونة لمقارنة الفرق في النتائج مع الفهرس وبدونه. في ما يلي خطوات إنشاء الفهرس لتسهيل الأمر عليك:
- بما أنّ لدينا المجموعة والنموذج والسياق والتضمينات التي تم إنشاؤها، ما علينا سوى تثبيت إضافة ScaNN باستخدام العبارة التالية:
CREATE EXTENSION IF NOT EXISTS alloydb_scann;
- بعد ذلك، سننشئ الفهرس (ScaNN):
CREATE INDEX apparel_index ON apparels
USING scann (embedding cosine)
WITH (num_leaves=54);
في تعريف البيانات أعلاه، apparel_index هو اسم الفهرس
"apparels" هو اسم الجدول
"scann" هي طريقة الفهرسة
"التضمين" هو العمود في الجدول الذي أريد فهرسته
"cosine" هي طريقة قياس المسافة التي أريد استخدامها مع الفهرس
"54" هو عدد الأقسام التي سيتم تطبيقها على هذا الفهرس. اضبط القيمة على أي رقم بين 1 و1048576. لمزيد من المعلومات حول كيفية تحديد هذه القيمة، اطّلِع على ضبط فهرس ScaNN.
استخدمت الجذر التربيعي لعدد نقاط البيانات على النحو الموصى به في مستودع ScaNN (عند التقسيم، يجب أن يكون عدد الأوراق مساويًا تقريبًا للجذر التربيعي لعدد نقاط البيانات).
- تحقَّق مما إذا كان الفهرس قد تم إنشاؤه باستخدام طلب البحث التالي:
SELECT * FROM pg_stat_ann_indexes;
- نفِّذ "البحث المتّجهي" باستخدام طلب البحث نفسه الذي استخدمناه بدون الفهرس:
select * from apparels
ORDER BY embedding <=> CAST(embedding('textembedding-gecko', 'white tops for girls without any print') as vector(768))
LIMIT 20
طلب البحث أعلاه هو نفسه الذي استخدمناه في المختبر في الخطوة 8. ومع ذلك، تم الآن فهرسة الحقل.
- اختبِر باستخدام طلب بحث بسيط مع الفهرس وبدونه (عن طريق حذف الفهرس):
white tops for girls without any print
يؤدي نص البحث أعلاه في طلب "البحث المتّجه" على بيانات التضمينات المفهرسة إلى الحصول على نتائج بحث عالية الجودة وفعّالة. تتحسّن الكفاءة بشكل كبير (من حيث وقت التنفيذ: 10.37 ملي ثانية بدون ScaNN و0.87 ملي ثانية باستخدام ScaNN) مع الفهرس. لمزيد من المعلومات حول هذا الموضوع، يُرجى الاطّلاع على هذه المدونة.
9- مطابقة بيانات التحقّق مع النموذج اللغوي الكبير
قبل المتابعة وإنشاء خدمة لعرض أفضل النتائج المطابقة لتطبيق، لنستخدِم نموذج ذكاء اصطناعي توليدي للتحقّق مما إذا كانت هذه الردود المحتملة مناسبة حقًا وآمنة للمشاركة مع المستخدم.
التأكّد من إعداد المثيل لاستخدام Gemini
تحقَّق أولاً مما إذا كانت ميزة "دمج تعلُّم الآلة من Google" مفعَّلة حاليًا للمجموعة والمثيل. في AlloyDB Studio، أدخِل الأمر التالي:
show google_ml_integration.enable_model_support;
إذا كانت القيمة معروضة على أنّها "مفعّلة"، يمكنك تخطّي الخطوتَين التاليتَين والانتقال مباشرةً إلى إعداد عملية دمج AlloyDB وVertex AI Model.
- انتقِل إلى الآلة الافتراضية الأساسية لمجموعة AlloyDB وانقر على "تعديل الآلة الافتراضية الأساسية" (EDIT PRIMARY INSTANCE).

- انتقِل إلى قسم "العلامات" في "خيارات الإعداد المتقدّمة". وتأكَّد من ضبط
google_ml_integration.enable_model_support flagعلى "on" كما هو موضّح أدناه:

إذا لم يكن الخيار مضبوطًا على "مفعّل"، اضبطه على "مفعّل" ثم انقر على الزر تعديل الجهاز الافتراضي. ستستغرق هذه الخطوة بضع دقائق.
دمج AlloyDB مع نماذج Vertex AI
يمكنك الآن الاتصال بـ AlloyDB Studio وتنفيذ عبارة DML التالية لإعداد إذن الوصول إلى نموذج Gemini من AlloyDB، وذلك باستخدام رقم تعريف مشروعك حيثما يُشار إليه. قد يتم تحذيرك من خطأ في البنية قبل تنفيذ الأمر، ولكن من المفترض أن يتم تنفيذه بشكلٍ سليم.
أولاً، ننشئ اتصال نموذج Gemini 1.5 كما هو موضّح أدناه. تذكَّر استبدال $PROJECT_ID في الأمر أدناه برقم تعريف مشروع Google Cloud.
CALL
google_ml.create_model( model_id => 'gemini-1.5',
model_request_url => 'https://us-central1-aiplatform.googleapis.com/v1/projects/$PROJECT_ID/locations/us-central1/publishers/google/models/gemini-1.5-pro:streamGenerateContent',
model_provider => 'google',
model_auth_type => 'alloydb_service_agent_iam');
يمكنك التحقّق من النماذج التي تم ضبطها للوصول إليها باستخدام الأمر التالي في AlloyDB Studio:
select model_id,model_type from google_ml.model_info_view;
أخيرًا، علينا منح إذن لمستخدمي قاعدة البيانات بتنفيذ الدالة ml_predict_row لتشغيل التوقعات من خلال نماذج Google Vertex AI. نفِّذ الأمر التالي:
GRANT EXECUTE ON FUNCTION ml_predict_row to postgres;
ملاحظة: إذا كنت تستخدم مشروعًا حاليًا على Google Cloud ومجموعة/مثيلاً حاليًا من AlloyDB تم إنشاؤه منذ فترة، قد تحتاج إلى حذف المراجع القديمة لنموذج Gemini 1.5 وإعادة إنشائها باستخدام عبارة CALL أعلاه، وتشغيل grant execute على الدالة ml_predict_row مرة أخرى في حال واجهت مشاكل في عمليات استدعاء Gemini 1.5 القادمة.
تقييم الردود
مع أنّنا سنستخدم طلب بحث كبيرًا واحدًا في القسم التالي لضمان أن تكون الردود من طلب البحث معقولة، قد يكون من الصعب فهم طلب البحث. سنتناول الأجزاء الآن وسنرى كيف تتكامل معًا في غضون بضع دقائق.
- أولاً، سنرسل طلبًا إلى قاعدة البيانات للحصول على 5 نتائج مطابقة الأقرب إلى طلب بحث المستخدم. سنقوم بتضمين طلب البحث في الرمز البرمجي لإبقاء هذا الإجراء بسيطًا، ولكن لا تقلق، سنقوم بإدخاله في طلب البحث لاحقًا. سنضمّن وصف المنتج من الجدول
apparelsونضيف حقلَين جديدَين، أحدهما يجمع الوصف مع الفهرس والآخر مع الطلب الأصلي. يتم حفظ كل ذلك في جدول باسمxyz(وهو مجرد اسم جدول مؤقت).
CREATE TABLE
xyz AS
SELECT
id || ' - ' || pdt_desc AS literature,
pdt_desc AS content,
'I want womens tops, pink casual only pure cotton.' AS user_text
FROM
apparels
ORDER BY
embedding <=> embedding('text-embedding-004',
'I want womens tops, pink casual only pure cotton.')::vector
LIMIT
5;
ستكون نتيجة طلب البحث هذا هي 5 صفوف الأكثر تشابهًا مع طلب بحث المستخدم. سيتضمّن الجدول الجديد xyz 5 صفوف، وسيتضمّن كل صف الأعمدة التالية:
literaturecontentuser_text
- لتحديد مدى صحة الردود، سنستخدم طلب بحث معقّدًا نشرح فيه كيفية تقييم الردود. يستخدم هذا المثال
user_textوcontentفي جدولxyzكجزء من طلب البحث.
"Read this user search text: ', user_text,
' Compare it against the product inventory data set: ', content,
' Return a response with 3 values: 1) MATCH: if the 2 contexts are at least 85% matching or not: YES or NO 2) PERCENTAGE: percentage of match, make sure that this percentage is accurate 3) DIFFERENCE: A clear short easy description of the difference between the 2 products. Remember if the user search text says that some attribute should not be there, and the record has it, it should be a NO match."
- باستخدام هذا الاستعلام، سنراجع بعد ذلك "جودة" الردود في الجدول
xyz.
CREATE TABLE
x AS
SELECT
json_array_elements( google_ml.predict_row( model_id => 'gemini-1.5',
request_body => CONCAT('{
"contents": [
{ "role": "user",
"parts":
[ { "text": "Read this user search text: ', user_text, ' Compare it against the product inventory data set: ', content, ' Return a response with 3 values: 1) MATCH: if the 2 contexts are at least 85% matching or not: YES or NO 2) PERCENTAGE: percentage of match, make sure that this percentage is accurate 3) DIFFERENCE: A clear short easy description of the difference between the 2 products. Remember if the user search text says that some attribute should not be there, and the record has it, it should be a NO match."
} ]
}
] }'
)::json))-> 'candidates' -> 0 -> 'content' -> 'parts' -> 0 -> 'text'
AS LLM_RESPONSE
FROM
xyz;
- تعرض الدالة
predict_rowالنتيجة بتنسيق JSON. يُستخدم الرمز "-> 'candidates' -> 0 -> 'content' -> 'parts' -> 0 -> 'text'"" لاستخراج النص الفعلي من ملف JSON. للاطّلاع على ملف JSON الفعلي الذي يتم عرضه، يمكنك إزالة هذه التعليمة البرمجية. - أخيرًا، للحصول على حقل النموذج اللغوي الكبير، ما عليك سوى استخراجه من الجدول x:
SELECT
LLM_RESPONSE
FROM
x;
- ويمكن دمج ذلك في طلب بحث واحد على النحو التالي.
عليك حذف/إزالة الجدولَين xyz وx من قاعدة بيانات AlloyDB قبل تنفيذ هذا الإجراء، إذا كنت قد نفّذت طلبات البحث أعلاه للتحقّق من النتائج الوسيطة.
SELECT
LLM_RESPONSE
FROM (
SELECT
json_array_elements( google_ml.predict_row( model_id => 'gemini-1.5',
request_body => CONCAT('{
"contents": [
{ "role": "user",
"parts":
[ { "text": "Read this user search text: ', user_text, ' Compare it against the product inventory data set: ', content, ' Return a response with 3 values: 1) MATCH: if the 2 contexts are at least 85% matching or not: YES or NO 2) PERCENTAGE: percentage of match, make sure that this percentage is accurate 3) DIFFERENCE: A clear short easy description of the difference between the 2 products. Remember if the user search text says that some attribute should not be there, and the record has it, it should be a NO match."
} ]
}
] }'
)::json))-> 'candidates' -> 0 -> 'content' -> 'parts' -> 0 -> 'text'
AS LLM_RESPONSE
FROM (
SELECT
id || ' - ' || pdt_desc AS literature,
pdt_desc AS content,
'I want womens tops, pink casual only pure cotton.' user_text
FROM
apparels
ORDER BY
embedding <=> embedding('text-embedding-004',
'I want womens tops, pink casual only pure cotton.')::vector
LIMIT
5 ) AS xyz ) AS X;
على الرغم من أنّ ذلك قد يبدو صعبًا، نأمل أن تتمكّن من فهمه بشكل أفضل. توضّح النتائج ما إذا كان هناك تطابق أم لا، والنسبة المئوية للتطابق، وبعض التفسيرات حول التقييم.
لاحظ أنّ نموذج Gemini يتيح البث تلقائيًا، لذا يتم توزيع الرد الفعلي على عدة أسطر: 
10. نقل التطبيق إلى الويب
هل أنت مستعد لنقل هذا التطبيق إلى الويب؟ اتّبِع الخطوات التالية لجعل Knowledge Engine Serverless متوافقًا مع "وظائف Cloud Run":
- انتقِل إلى "وظائف Cloud Run" في Google Cloud Console لإنشاء وظيفة Cloud Run جديدة أو استخدِم الرابط: https://console.cloud.google.com/functions/add.
- اختَر البيئة على أنّها "دالة Cloud Run". قدِّم اسم الدالة "retail-engine" واختَر المنطقة "us-central1". اضبط المصادقة على "السماح باستدعاءات غير مصادَق عليها" وانقر على التالي. اختَر Java 17 كوقت تشغيل وInline Editor للرمز المصدر.
- سيتم ضبط نقطة الدخول تلقائيًا على "
gcfv2.HelloHttpFunction". استبدِل رمز العنصر النائب فيHelloHttpFunction.javaوpom.xmlمن "دالة Cloud Run" بالرمز من ملف Java وXML على التوالي. - تذكَّر تغيير العنصر النائب $PROJECT_ID وبيانات اعتماد الاتصال بـ AlloyDB بالقيم الخاصة بك في ملف Java. بيانات اعتماد AlloyDB هي تلك التي استخدمناها في بداية هذا الدرس العملي. إذا كنت قد استخدمت قيمًا مختلفة، يُرجى تعديلها في ملف Java.
- انقر على نشر.
بعد نشر Cloud Function، سننشئ موصّل VPC للسماح لوظيفة Cloud Function بالوصول إلى مثيل قاعدة بيانات AlloyDB.
خطوة مهمة:
بعد إعداد عملية النشر، من المفترض أن تتمكّن من رؤية الدوال في وحدة تحكّم وظائف Cloud Run من Google. ابحث عن الدالة التي تم إنشاؤها حديثًا (retail-engine)، وانقر عليها، ثم انقر على تعديل وغيِّر ما يلي:
- الانتقال إلى إعدادات وقت التشغيل والإنشاء والاتصالات والأمان
- زيادة المهلة إلى 180 ثانية
- انتقِل إلى علامة التبويب "عمليات الربط":

- ضِمن إعدادات Ingress، تأكَّد من اختيار "السماح بكل الزيارات".
- ضمن إعدادات Egress، انقر على القائمة المنسدلة "الشبكة" (Network) واختَر الخيار "إضافة موصّل VPC جديد" (Add New VPC Connector) واتّبِع التعليمات التي تظهر في مربّع الحوار المنبثق:

- أدخِل اسمًا لموصِّل VPC وتأكَّد من أنّ المنطقة هي نفسها منطقة مثيلك. اترك قيمة "الشبكة" على الوضع التلقائي واضبط "الشبكة الفرعية" على "نطاق IP مخصّص" مع نطاق IP 10.8.0.0 أو نطاق مشابه متوفّر.
- وسِّع SHOW SCALING SETTINGS وتأكَّد من ضبط الإعدادات على ما يلي بالضبط:

- انقر على "إنشاء"، ومن المفترض أن يظهر هذا الرابط في إعدادات الخروج الآن.
- اختَر الموصّل الذي تم إنشاؤه حديثًا
- اختَر توجيه كل حركة البيانات من خلال موصّل شبكة VPC هذا.
- انقر على التالي ثم على نشر.
11. اختبار التطبيق
بعد نشر "دالة Cloud" المعدَّلة، من المفترض أن يظهر لك نقطة النهاية بالتنسيق التالي:
https://us-central1-YOUR_PROJECT_ID.cloudfunctions.net/retail-engine
يمكنك اختباره من "وحدة طرفية Cloud Shell" عن طريق تنفيذ الأمر التالي:
gcloud functions call retail-engine --region=us-central1 --gen2 --data '{"search": "I want some kids clothes themed on Disney"}'
بدلاً من ذلك، يمكنك اختبار وظيفة Cloud Run على النحو التالي:
PROJECT_ID=$(gcloud config get-value project)
curl -X POST https://us-central1-$PROJECT_ID.cloudfunctions.net/retail-engine \
-H 'Content-Type: application/json' \
-d '{"search":"I want some kids clothes themed on Disney"}' \
| jq .
والنتيجة هي:

هذا كل شيء! بهذه البساطة يمكنك إجراء "بحث المتّجهات حسب التشابه" باستخدام نموذج "عمليات التضمين" على بيانات AlloyDB.
إنشاء الوكيل الحواري
يتم إنشاء الوكيل في الجزء 2 من هذا الدرس التطبيقي.
12. تَنظيم
إذا كنت تخطّط لإكمال الجزء 2 من هذا الدرس العملي، تخطَّ هذه الخطوة لأنّها ستؤدي إلى حذف المشروع الحالي.
لتجنُّب تحمّل رسوم في حسابك على Google Cloud مقابل الموارد المستخدَمة في هذه المشاركة، اتّبِع الخطوات التالية:
- في Google Cloud Console، انتقِل إلى صفحة إدارة الموارد.
- في قائمة المشاريع، اختَر المشروع الذي تريد حذفه، ثم انقر على حذف.
- في مربّع الحوار، اكتب رقم تعريف المشروع، ثم انقر على إيقاف لحذف المشروع.
13. تهانينا
تهانينا! لقد أجريت عملية بحث عن التشابه بنجاح باستخدام AlloyDB وpgvector و"البحث المتّجه". من خلال الجمع بين إمكانات AlloyDB وVertex AI وVector Search، حقّقنا تقدّمًا كبيرًا في إتاحة عمليات البحث السياقية والمتّجهة، وجعلها فعّالة ومستندة إلى المعنى. يتناول الجزء التالي من هذا الدرس التطبيقي خطوات إنشاء الوكيل.