1. مقدمة
في هذا الدرس التطبيقي حول الترميز، ستربط نموذج Jev من TypeSafe AI بـ AlloyDB AI باستخدام وظائف الذكاء الاصطناعي الأصلية في AlloyDB (ai.if وai.analyze_sentiment وml_predict_row). يتيح لك ذلك تنفيذ استنتاج مجمّع فعال باستخدام نموذج Jev مباشرةً على بياناتك التشغيلية في AlloyDB، بدون نقل بياناتك أو كتابة رمز معقّد على مستوى التطبيق.
الإجراءات التي ستنفذّها
- توفير Private Service Access (PSA) ومجموعة ومثيل أساسي من AlloyDB for PostgreSQL
- إنشاء قاعدة جدار حماية في شبكة VPC تسمح لخدمة Cloudshell بالاتصال الداخلي
- حمِّل نموذجًا لمجموعة بيانات التجارة الإلكترونية باستخدام
gcloud alloydb clusters import - تفعيل Google Secret Manager وإضافة
google_ml_integrationفي AlloyDB - تخزين مفتاح واجهة برمجة التطبيقات TypeSafe AI ومنح إذن الوصول إليه في Secret Manager
- إنشاء دوال تحويل الإدخال والإخراج في PL/pgSQL للعناصر الأساسية
noul(منطقي) وchoice(تحليل المشاعر) في Jev - تسجيل نقطة نهاية نموذج
jev-modelالمخصّص في AlloyDB - تشغيل طلبات البحث الدلالية العددية والمجمّعة في مصفوفات (
ai.ifوai.analyze_sentiment) مباشرةً في SQL - طلب البحث عن مراجعات المنتجات الحقيقية من العملاء لتصنيف الآراء باستخدام
ai.analyze_sentiment - (مكافأة) تسجيل نقطة نهاية عامة (
jev-systemone) وتقييم شدة رضا العملاء المستمر باستخدام العنصر الأساسيscoreفي Jev
المتطلبات
- متصفّح ويب، مثل Chrome
- مشروع Google Cloud تم تفعيل الفوترة فيه
- مفتاح واجهة برمجة تطبيقات TypeSafe AI (من TypeSafe AI)
2. قبل البدء
اختيار مشروعك على Google Cloud
في Google Cloud Console، اختَر مشروع Google Cloud الذي تريد استخدامه أو أنشِئ مشروعًا جديدًا.
بدء Cloud Shell
انقر على تفعيل Cloud Shell في أعلى يسار "وحدة تحكّم Google Cloud".
تأكَّد من مصادقة جلسة Cloud Shell:
gcloud auth list
اضبط رقم تعريف مشروعك ومتغيّرات البيئة:
export PROJECT_ID=$(gcloud config get-value project)
gcloud config set project $PROJECT_ID
export REGION="us-west4"
export ADBCLUSTER="my-alloydb-cluster"
export ADBINSTANCE="my-alloydb-primary"
تفعيل واجهات Google Cloud APIs المطلوبة
نفِّذ الأمر التالي لتفعيل جميع واجهات برمجة التطبيقات اللازمة لخدمة Google Cloud:
gcloud services enable \
alloydb.googleapis.com \
servicenetworking.googleapis.com \
secretmanager.googleapis.com \
compute.googleapis.com
3- توفير مجموعة AlloyDB والمثيل الأساسي
في هذه الخطوة، ستخصّص نطاق IP لاتصال الخدمات الخاصة في شبكة VPC، وتنشئ ربطًا خاصًا، وتوفّر لمجموعة AlloyDB ومثيلها الأساسي إمكانية الوصول إلى الإنترنت الصادر.
1. إنشاء نطاق عناوين IP لخدمة Private Service Access (PSA)
يتطلّب AlloyDB تخصيص نطاق عناوين IP خاصة في شبكة السحابة الإلكترونية الخاصة الافتراضية (VPC). بافتراض أنّك تستخدم شبكة default VPC:
إنشاء تخصيص لنطاق عناوين IP الخاصة:
gcloud compute addresses create psa-range \
--global \
--purpose=VPC_PEERING \
--prefix-length=24 \
--description="VPC private service access" \
--network=default
أنشئ اتصالاً خاصًا لتبادل المعلومات بين شبكتَي VPC:
gcloud services vpc-peerings connect \
--service=servicenetworking.googleapis.com \
--ranges=psa-range \
--network=default
2. إنشاء مجموعة AlloyDB
أنشئ كلمة مرور آمنة لقاعدة البيانات الخاصة postgres بمستخدم المشرف الأوّلي:
export PGPASSWORD="$(openssl rand -hex 8)@1aA"
echo "Your generated AlloyDB postgres password is: $PGPASSWORD"
أنشئ مجموعة AlloyDB Free Trial:
gcloud alloydb clusters create $ADBCLUSTER \
--password=$PGPASSWORD \
--network=default \
--region=$REGION
3- إنشاء "النسخة الأساسية" باستخدام علامات الذكاء الاصطناعي وإمكانية الاتصال الخارجي
تتصل AlloyDB مباشرةً بنقطة نهاية SaaS الآمنة من TypeSafe AI (https://api.typesafe.ai/v1/systemone) عبر بروتوكول HTTPS الصادر. لذلك، يجب تحديد --outbound-public-ip. بالإضافة إلى ذلك، اضبط علامات قاعدة بيانات AlloyDB AI للبيئة:
gcloud alloydb instances create $ADBINSTANCE \
--instance-type=PRIMARY \
--cpu-count=2 \
--region=$REGION \
--cluster=$ADBCLUSTER \
--outbound-public-ip \
--ssl-mode=ALLOW_UNENCRYPTED_AND_ENCRYPTED \
--database-flags=\
google_ml_integration.enable_model_support=on,\
google_ml_integration.enable_ai_query_engine=on,\
google_ml_integration.enable_ai_function_acceleration=on,\
google_ml_integration.enable_cost_optimized_ai_functions=on,\
parameterized_views.enabled=on,\
password.enforce_complexity=on,\
password.min_uppercase_letters=1,\
password.min_numerical_chars=1,\
password.min_pass_length=10
4. تحميل عيّنة بيانات التجارة الإلكترونية
لاختبار طلبات البحث الدلالية الواقعية، استورِد مجموعة بيانات نموذجية للتجارة الإلكترونية تحتوي على كتالوجات المنتجات ومراجعات العملاء مباشرةً من Cloud Storage:
gcloud alloydb clusters import $ADBCLUSTER \
--region=$REGION \
--project=$PROJECT_ID \
--gcs-uri="gs://sample-data-and-media/ecomm-retail/ecom_generic.sql" \
--sql \
--database=postgres \
--user=postgres
4. تخزين مفتاح TypeSafe AI API في Secret Manager
تتكامل ميزة "إدارة نقاط نهاية النماذج" في AlloyDB مع خدمة Google Secret Manager بشكلٍ أصلي للمصادقة على طلبات البيانات من واجهات برمجة التطبيقات الخارجية بدون عرض بيانات الاعتماد بنص عادي في رمز قاعدة البيانات أو سجلات الإعداد.
1. إنشاء الرمز السري
في Cloud Shell، أنشئ سرًا جديدًا باسم typesafe-jev-api-key:
gcloud secrets create typesafe-jev-api-key \
--replication-policy="automatic"
أضِف مفتاح واجهة برمجة التطبيقات TypeSafe AI كإصدار سري:
echo -n "<YOUR_TYPESAFE_API_KEY>" | \
gcloud secrets versions add typesafe-jev-api-key --data-file=-
2. منح إذن الوصول إلى حساب خدمة AlloyDB
تستخدم AlloyDB وكيل خدمة المشروع لاسترداد الأسرار أثناء تنفيذ طلب البحث. ابحث عن رقم مشروعك وامنح دور Secret Accessor:
PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format="value(projectNumber)")
ALLOYDB_SA="service-${PROJECT_NUMBER}@gcp-sa-alloydb.iam.gserviceaccount.com"
gcloud secrets add-iam-policy-binding typesafe-jev-api-key \
--member="serviceAccount:${ALLOYDB_SA}" \
--role="roles/secretmanager.secretAccessor"
من المفترض أن تظهر لك نتيجة تؤكّد أنّ وكيل الخدمة قد تلقّى roles/secretmanager.secretAccessor.
5- الاتصال بـ AlloyDB من خلال AlloyDB Studio وتهيئة إضافات قاعدة البيانات
للتفاعل مع قاعدة بيانات AlloyDB مباشرةً من المتصفّح بدون ضبط أدوات العميل المحلية أو أنفاق الخادم الوكيل، استخدِم AlloyDB Studio في Google Cloud Console.
1. فتح AlloyDB Studio
- في Google Cloud Console، انتقِل إلى AlloyDB for PostgreSQL > المجموعات.
- انقر على مجموعتك (
my-alloydb-cluster). - في قائمة التنقّل اليمنى، انقر على AlloyDB Studio.
- المصادقة على قاعدة البيانات:
- قاعدة البيانات:
postgres - المستخدم:
postgres - كلمة المرور: أدخِل
$PGPASSWORDالتي تم إنشاؤها أثناء إنشاء المجموعة (على سبيل المثال، شغِّلecho $PGPASSWORDفي Cloud Shell لعرضها).
- قاعدة البيانات:
- انقر على مصادقة.
أنت الآن في محرر استعلامات SQL التفاعلي في AlloyDB Studio.
2. تفعيل إضافات وقواعد بيانات
في محرّر طلبات البحث في AlloyDB Studio، الصِق العبارات التالية وشغِّلها لتفعيل الإضافة google_ml_integration وضبط إعدادات وقت التشغيل:
-- Enable the AlloyDB AI integration extension
CREATE EXTENSION IF NOT EXISTS google_ml_integration;
-- Enable preview AI functions (ai.analyze_sentiment, ai.classify)
SET google_ml_integration.enable_preview_ai_functions = 'on';
-- Disable async batching for the session to use custom transform functions directly
SET google_ml_integration.enable_async_operation = 'off';
انقر على تنفيذ لتنفيذ الاستعلام.
3- تسجيل الرمز السري في AlloyDB MEM
أخبِر AlloyDB بمكان العثور على مفتاح واجهة برمجة التطبيقات TypeSafe AI:
CALL google_ml.create_sm_secret(
secret_id => 'jev_api_key',
secret_path => 'projects/<YOUR_PROJECT_ID>/secrets/typesafe-jev-api-key/versions/latest'
);
6. إنشاء دوال تحويل SQL
تقبل واجهة System One API من TypeSafe AI تنسيق JSON منظَّمًا مع عناصر أساسية مميزة للاستدلال (noul للقيود المنطقية، وchoice للتصنيف المتعدد الفئات).
تستخدم ميزة "إدارة نقاط نهاية النماذج" في AlloyDB أربع دوال تحويل (إدخال عددي، وإخراج عددي، وإدخال مجمّع، وإخراج مجمّع) لربط تواقيع دوال PostgreSQL ai.* العادية بتنسيق Jev REST API.
1. تحويل الإدخال العددي
أضِف الدالة التالية لتحويل طلبات ai.if وai.analyze_sentiment ذات الصف الواحد إلى حمولات طلبات Jev:
CREATE OR REPLACE FUNCTION public.jev_model_input_transform(
model_id VARCHAR(100),
input_text TEXT,
generation_config JSON,
system_instruction TEXT
) RETURNS JSON
LANGUAGE plpgsql IMMUTABLE AS $$
DECLARE
full_instruction TEXT;
enum_json JSON;
criteria_obj JSONB := '{}'::JSONB;
elem TEXT;
q_obj JSON;
BEGIN
-- Combine optional system instructions with the input prompt
IF system_instruction IS NOT NULL AND length(trim(system_instruction)) > 0 THEN
full_instruction := system_instruction || E'\n\n' || input_text;
ELSE
full_instruction := input_text;
END IF;
-- Inspect generation_config to determine whether caller expects a multi-class choice or boolean
enum_json := COALESCE(
generation_config->'generationConfig'->'responseSchema'->'enum',
generation_config->'responseSchema'->'enum'
);
IF enum_json IS NOT NULL AND json_typeof(enum_json) = 'array' THEN
-- Multi-class classification (ai.analyze_sentiment) -> Jev choice primitive
FOR elem IN SELECT json_array_elements_text(enum_json) LOOP
criteria_obj := criteria_obj || jsonb_build_object(elem, 'Category: ' || elem);
END LOOP;
q_obj := json_build_object(
'type', 'choice',
'instructions', full_instruction,
'criteria', criteria_obj::JSON
);
ELSE
-- Boolean filtering (ai.if) -> Jev noul primitive
q_obj := json_build_object(
'type', 'noul',
'instructions', full_instruction
);
END IF;
RETURN json_build_object(
'model', 'jev-latest',
'state', COALESCE(generation_config->>'state', 'Evaluate the question accurately based on the provided text.'),
'questions', json_build_object('q_1', q_obj)
);
END;
$$;
2. تحويل الإخراج القياسي
أضِف الدالة لفك حزمة ردّ JSON من Jev إلى نتيجة PostgreSQL TEXT:
CREATE OR REPLACE FUNCTION public.jev_model_output_transform(
model_id VARCHAR(100),
response_json JSON
) RETURNS TEXT
LANGUAGE plpgsql IMMUTABLE AS $$
DECLARE
q_ans JSON := response_json->'answers'->'q_1';
ans_type TEXT := q_ans->>'type';
BEGIN
IF ans_type = 'choice' THEN
RETURN q_ans->>'choice';
ELSIF ans_type = 'noul' THEN
-- Convert probability score (0.00 to 1.00) to boolean text
RETURN CASE WHEN (q_ans->>'noul')::FLOAT >= 0.50 THEN 'true' ELSE 'false' END;
ELSE
RAISE EXCEPTION 'Unexpected Jev response payload: %', response_json::TEXT;
END IF;
END;
$$;
3- تحويل الإدخال المجمّع
يمكن لـ Jev تقييم عشرات الأسئلة في الوقت نفسه ضمن رحلة HTTP واحدة بدون تدهور في الأداء.
أضِف عملية تحويل إدخال الدُفعات لتحويل مصفوفات prompts TEXT[] PostgreSQL إلى أسئلة q_1 .. q_N Jev متوازية:
CREATE OR REPLACE FUNCTION public.jev_model_batch_input_transform(
model_id VARCHAR(100),
prompts TEXT[],
generation_config JSON,
system_instructions JSON
) RETURNS JSON
LANGUAGE plpgsql IMMUTABLE AS $$
DECLARE
questions_obj JSONB := '{}'::JSONB;
enum_json JSON;
criteria_obj JSONB := '{}'::JSONB;
elem TEXT;
is_choice BOOLEAN := FALSE;
i INT;
BEGIN
enum_json := COALESCE(
generation_config->'generationConfig'->'responseSchema'->'items'->'enum',
generation_config->'generationConfig'->'responseSchema'->'enum',
generation_config->'responseSchema'->'items'->'enum',
generation_config->'responseSchema'->'enum'
);
IF enum_json IS NOT NULL AND json_typeof(enum_json) = 'array' THEN
IF NOT (enum_json::JSONB = '["true", "false"]'::JSONB OR enum_json::JSONB = '["false", "true"]'::JSONB) THEN
is_choice := TRUE;
FOR elem IN SELECT json_array_elements_text(enum_json) LOOP
criteria_obj := criteria_obj || jsonb_build_object(elem, 'Category: ' || elem);
END LOOP;
END IF;
END IF;
-- Construct parallel questions for every prompt in the array
FOR i IN 1 .. COALESCE(array_length(prompts, 1), 0) LOOP
IF is_choice THEN
questions_obj := questions_obj || jsonb_build_object(
'q_' || i::TEXT,
jsonb_build_object(
'type', 'choice',
'instructions', prompts[i],
'criteria', criteria_obj
)
);
ELSE
questions_obj := questions_obj || jsonb_build_object(
'q_' || i::TEXT,
jsonb_build_object(
'type', 'noul',
'instructions', prompts[i]
)
);
END IF;
END LOOP;
RETURN json_build_object(
'model', 'jev-latest',
'state', COALESCE(generation_config->>'state', 'Evaluate each question independently based on the record data.'),
'questions', questions_obj::JSON
);
END;
$$;
4. تحويل الإخراج المجمّع
أضِف الدالة لاستخراج الإجابات بترتيب فهرس مصفوفة 1..N المناسب:
CREATE OR REPLACE FUNCTION public.jev_model_batch_output_transform(
model_id VARCHAR(100),
response JSON
) RETURNS TEXT[]
LANGUAGE plpgsql IMMUTABLE AS $$
DECLARE
results TEXT[] := ARRAY[]::TEXT[];
answers JSON := response->'answers';
i INT := 1;
q_ans JSON;
ans_type TEXT;
BEGIN
LOOP
q_ans := answers->('q_' || i::TEXT);
EXIT WHEN q_ans IS NULL;
ans_type := q_ans->>'type';
IF ans_type = 'choice' THEN
results := array_append(results, q_ans->>'choice');
ELSE
results := array_append(results, CASE WHEN (q_ans->>'noul')::FLOAT >= 0.50 THEN 'true' ELSE 'false' END);
END IF;
i := i + 1;
END LOOP;
RETURN results;
END;
$$;
7. تسجيل نقطة نهاية النموذج المخصّص في AlloyDB
ستربط الآن دوال التحويل وبيانات الاعتماد السرية ونقطة نهاية TypeSafe AI REST معًا في نموذج مسجّل باسم jev-model.
1. تسجيل jev-model
في محرّر طلبات البحث في AlloyDB Studio، الصِق ما يلي ونفِّذه:
-- Drop previous registration if updating
DO $$
BEGIN
IF EXISTS (SELECT 1 FROM google_ml.model_info_view WHERE model_id = 'jev-model') THEN
CALL google_ml.drop_model('jev-model');
END IF;
END $$;
-- Register custom LLM endpoint
CALL google_ml.create_model(
model_id => 'jev-model',
model_request_url => 'https://api.typesafe.ai/v1/systemone',
model_provider => 'custom',
model_type => 'llm',
model_qualified_name => 'jev-latest',
model_auth_type => 'secret_manager',
model_auth_id => 'jev_api_key',
model_in_transform_fn => 'jev_model_input_transform',
model_out_transform_fn => 'jev_model_output_transform',
model_batch_in_transform_fn => 'jev_model_batch_input_transform',
model_batch_out_transform_fn => 'jev_model_batch_output_transform'
);
2. إثبات صحة التسجيل
أرسِل طلب بحث إلى طريقة عرض سجلّ النماذج للتأكّد من أنّ jev-model نشط ومعترف به:
SELECT model_id, model_type, model_provider, model_auth_type
FROM google_ml.model_info_view
WHERE model_id = 'jev-model';
من المفترض أن تظهر لك نتيجة مشابهة لما يلي:
model_id | model_type | model_provider | model_auth_type ----------+------------+----------------+----------------- jev-model | llm | custom | secret_manager (1 row)
8. تشغيل طلبات بحث اختبارية على Jev
بعد تسجيل jev-model، يمكنك الآن تنفيذ عمليات دلالية مباشرةً داخل استعلامات PostgreSQL العادية.
1. اختبار فلترة القيم المنطقية العددية (ai.if)
تقييم عبارة نصية واحدة باستخدام ai.if:
SELECT ai.if(
prompt => 'Is the product "North Face Waterproof Gore-Tex Hiking Jacket ($249)" suitable for rainy outdoor conditions?',
model_id => 'jev-model'
) AS is_suitable;
من المفترض أن تظهر لك نتيجة مشابهة لما يلي:
is_suitable ------------- true (1 row)
2. اختبار تحليل المشاعر العددية (ai.analyze_sentiment)
تقييم ملاحظات العملاء باستخدام تصنيف فئوي (positive أو negative أو neutral):
SET google_ml_integration.enable_preview_ai_functions = 'on';
SELECT ai.analyze_sentiment(
input => 'The stitching on this jacket tore on the second day and the zipper jammed completely.',
model_id => 'jev-model'
) AS sentiment;
من المفترض أن تظهر لك نتيجة مشابهة لما يلي:
sentiment ----------- negative (1 row)
3- اختبار التصفية المنطقية المجمّعة في مصفوفة
يمكنك تقييم عناصر متعددة في طلب بحث واحد من خلال تمرير مصفوفة من الطلبات:
SET google_ml_integration.enable_async_operation = 'off';
SELECT unnest(prompts) AS product_prompt,
unnest(ai.if(prompts => prompts, model_id => 'jev-model')) AS is_cold_weather
FROM (
SELECT ARRAY[
'Is "Arctic Expedition Down Parka (-30F)" cold-weather winter outerwear?',
'Is "Men''s Boardshorts Beach Swim Trunk" cold-weather winter outerwear?',
'Is "Merino Wool Thermal Base Layer" cold-weather winter outerwear?'
] AS prompts
) b;
من المفترض أن تظهر لك نتيجة مشابهة لما يلي:
product_prompt | is_cold_weather -------------------------------------------------------------------------+----------------- Is "Arctic Expedition Down Parka (-30F)" cold-weather winter outerwear? | true Is "Men's Boardshorts Beach Swim Trunk" cold-weather winter outerwear? | false Is "Merino Wool Thermal Base Layer" cold-weather winter outerwear? | false (3 rows)
4. اختبار طلبات البحث في الجداول باستخدام تجميع المصفوفات
الآن، أرسِل طلب بحث إلى جدول ecomm.products الذي تم تحميله سابقًا أثناء توفير المجموعة، وذلك باستخدام ai.if على مجموعة من العناصر للتحقّق من المنتجات في الكتالوج التي تُعدّ من معدّات الطقس البارد.
لتنفيذ فلترة دلالية عالية الإنتاجية على بيانات الجدول (مثل 50 صفًا لكل مجموعة)، استخدِم دالة row_number() window في PostgreSQL لتقسيم الصفوف إلى مجموعات:
-- Evaluate a 50-row batch of real catalog items from ecomm.products
WITH numbered AS (
SELECT
id,
name,
category,
product_description,
((row_number() OVER (ORDER BY id) - 1) / 50) AS batch_id
FROM ecomm.products
ORDER BY id DESC
LIMIT 50
),
batched AS (
SELECT
batch_id,
array_agg(id ORDER BY id) AS ids,
array_agg(name ORDER BY id) AS names,
array_agg(category ORDER BY id) AS categories,
array_agg(product_description ORDER BY id) AS descs,
ai.if(
prompts => array_agg('Is "' || name || '" designed for cold weather winter outerwear?' ORDER BY id),
model_id => 'jev-model'
) AS decisions
FROM numbered
GROUP BY batch_id
),
unrolled AS (
SELECT
b.batch_id,
u.id,
u.name,
u.category,
u.product_description,
u.decision AS cold_weather_gear
FROM batched b
CROSS JOIN LATERAL unnest(b.ids, b.names, b.categories, b.descs, b.decisions)
AS u(id, name, category, product_description, decision)
)
SELECT id, name, category, product_description, cold_weather_gear
FROM unrolled
WHERE cold_weather_gear = TRUE
LIMIT 5;
من المفترض أن تظهر لك نتيجة مشابهة لما يلي:
id | name | category | product_description | cold_weather_gear -------+----------------------------------------------------------------------+-------------+--------------------------------------------------------------------------------------------------------------------+------------------- 29071 | Winter Striped Beanie with Pom | Accessories | Brave the chill in style with the SoleStyle Winter Striped Beanie! This cozy beanie adds a pop of personality... | true 29077 | Knit Collegiate Rugby Stripe Winter Scarf & Beanie Hat Set | Accessories | Stay cozy and show off your sporty side with our Knit Collegiate Rugby Stripe Scarf & Beanie Set... | true 29083 | Junction Finds Men's Muscle Wool Blend Trapper Hat | Accessories | Brave the elements in style with the Junction Finds Trapper Hat! This wool-blend hat will keep you warm... | true 29086 | Mens Soft Thermal Insulated Wrist Length Leather Gloves - Black | Accessories | Brave the chill in style with these supple leather gloves from Gavel Goods! Lined with a soft, thermal knit... | true 29090 | Long Beanie-Red W16S24E | Accessories | Stay cozy and stylish all season long with this vibrant red beanie from Enchant! This isn't just any hat... | true (5 rows)
5- طلب البحث عن مراجعات المنتج حسب مدى توافق الآراء
الآن، حلِّل مراجعات العملاء من الجدول ecomm.product_reviews باستخدام ai.analyze_sentiment المستند إلى العنصر الأساسي choice من Jev:
SET google_ml_integration.enable_preview_ai_functions = 'on'
SELECT
r.id,
p.name AS product_name,
r.rating AS customer_star_rating,
substring(r.review_text FROM 1 FOR 70) || '...' AS review_snippet,
ai.analyze_sentiment(
input => r.review_text,
model_id => 'jev-model'
) AS detected_sentiment
FROM ecomm.product_reviews r
JOIN ecomm.products p ON r.product_id = p.id
ORDER BY r.id
LIMIT 5;
من المفترض أن تظهر لك نتيجة مشابهة لما يلي:
id | product_name | customer_star_rating | review_snippet | detected_sentiment ----+------------------------------------------------+----------------------+-------------------------------------------------------------------------+-------------------- 1 | Hugs & Kisses Juniors Peplum Skirt | 1 | This skirt was poorly made and the fabric felt extremely cheap for for...| negative 2 | Bonkers Larry Full Length Pull on Pants | 1 | These pants are way too expensive for the terrible quality you get. Th...| negative 3 | Gifts and Garb Brah Bra Extenders | 3 | These extenders are okay but nothing special. They do add a bit of ext...| neutral 4 | Auto Forge Men's Tall Duck Traditional Coat | 1 | This coat is terribly stiff and heavy, making it very uncomfortable to...| negative 5 | Weaver's Way Men's Shetland Zip Neck Sweater | 2 | This sweater is just okay and not really worth the high price tag. The...| negative (5 rows)
9. مكافأة: تسجيل الانطباعات بشكل مستمر باستخدام Jev score
في حين أنّ وظائف الذكاء الاصطناعي في AlloyDB، مثل ai.analyze_sentiment، تعرض فئات مجزّأة (positive وnegative وneutral)، فإنّ العنصر الأساسي score في TypeSafe AI يقيّم الفروق الدقيقة في مقياس مرتّب ويعرض تقييمًا متواصلاً مرجّحًا حسب التوقعات يتراوح بين 0 و100.
بما أنّ score تعرض بيانات وصفية رقمية بدلاً من تصنيف نصي، يمكنك تسجيل نقطة نهاية نموذج generic مخصّصة (jev-systemone) واستدعاؤها باستخدام google_ml.predict_row.
1. تسجيل نقطة النهاية العامة
في AlloyDB Studio، سجِّل jev-systemone باستخدام model_type => 'generic':
DO $$
BEGIN
IF EXISTS (SELECT 1 FROM google_ml.model_info_view WHERE model_id = 'jev-systemone') THEN
CALL google_ml.drop_model('jev-systemone');
END IF;
EXCEPTION WHEN OTHERS THEN
NULL;
END $$;
CALL google_ml.create_model(
model_id => 'jev-systemone',
model_request_url => 'https://api.typesafe.ai/v1/systemone',
model_provider => 'custom',
model_type => 'generic',
model_qualified_name => 'jev-latest',
model_auth_type => 'secret_manager',
model_auth_id => 'jev_api_key'
);
2. إجراء تقييم متعدد المهام (قيمة منطقية + نتيجة مستمرة)
تقييم كلّ من عملية التحقّق من القيمة المنطقية للعيوب (noul) وشدة المشاعر المستمرة (score) في طلب HTTP واحد في الوقت نفسه:
SELECT jsonb_pretty(google_ml.predict_row(
model_id => 'jev-systemone',
request_body => json_build_object(
'model', 'jev-latest',
'state', 'Review for North Face Parka: "The zipper broke on day 3 and customer service refused an exchange, though the fabric itself is very soft."',
'questions', json_build_object(
'has_defect', json_build_object(
'type', 'noul',
'instructions', 'Does this review report a physical product defect or failure?'
),
'satisfaction_score', json_build_object(
'type', 'score',
'instructions', 'Rate the customer sentiment and satisfaction on a 1-5 scale.',
'criteria', json_build_array(
'1: Extremely dissatisfied / defect failure',
'2: Dissatisfied',
'3: Mixed or neutral',
'4: Satisfied',
'5: Delighted'
)
)
)
)
)::jsonb) AS jev_analysis;
من المفترَض أن تظهر لك نتيجة مشابهة لما يلي (قد تختلف النتائج):
{
"model": "jev-1.13.0",
"usage": {
"input_tokens": 388,
"output_tokens": 39
},
"answers": {
"has_defect": {
"noul": 0.98,
"type": "noul"
},
"satisfaction_score": {
"type": "score",
"score": 0.11,
"legend": {
"0": "1: Extremely dissatisfied / defect failure",
"1": "2: Dissatisfied",
"2": "3: Mixed or neutral",
"3": "4: Satisfied",
"4": "5: Delighted"
},
"confidence": 0.91,
"probabilities": {
"0": 0.9,
"1": 0.08,
"2": 0.02,
"3": 0.0,
"4": 0.0
}
}
}
}
لاحظ أنّ satisfaction_score تم تقييمه على أنّه 11 / 100، ما يعكس بدقة أنّ العميل مرّ بتجربة سلبية في الغالب على الرغم من إقراره بأنّ القماش ناعم.
10. تَنظيم
لتجنُّب تكبُّد رسوم مستمرة مقابل الموارد التي تم إنشاؤها خلال هذا الدرس التطبيقي حول الترميز، عليك تنظيف البيانات السرية وعناصر قاعدة البيانات وحذف مجموعة AlloyDB.
1. حذف موارد Secret Manager
في Cloud Shell، احذف السرّ الذي تم إنشاؤه لمفتاح واجهة برمجة التطبيقات TypeSafe AI:
gcloud secrets delete typesafe-jev-api-key --quiet
2. حذف المثيل الأساسي ومجموعة AlloyDB
احذف النسخة الأساسية أولاً:
gcloud alloydb instances delete $ADBINSTANCE \
--cluster=$ADBCLUSTER \
--region=$REGION \
--quiet
بعد اكتمال عملية حذف الجهاز الظاهري، احذف المجموعة:
gcloud alloydb clusters delete $ADBCLUSTER \
--region=$REGION \
--quiet
11. تهانينا
تهانينا! لقد وفّرت مجموعة Google Cloud AlloyDB بنجاح ودمجتها مع TypeSafe AI System One (Jev).
ما تعلّمته
- كيفية إنشاء Private Service Access (PSA) وتوفير مجموعة ومثيل أساسي في AlloyDB for PostgreSQL
- كيفية تفعيل
--outbound-public-ipلكي تتمكّن AlloyDB من الوصول إلى واجهات برمجة تطبيقات خارجية لبرامج كخدمة (SaaS) تستخدم HTTPS - كيفية تخزين بيانات اعتماد مقدّم خدمة الذكاء الاصطناعي التابع لجهة خارجية بشكل آمن في Google Secret Manager وربطها بـ AlloyDB
- كيفية كتابة دوال تحويل PL/pgSQL التي تربط بين دوال الذكاء الاصطناعي العادية في PostgreSQL (
ai.ifوai.analyze_sentiment) وواجهات REST API الخارجية - كيفية تسجيل نقاط نهاية نماذج اللغات الكبيرة المخصّصة في AlloyDB باستخدام
google_ml.create_model - كيفية تنفيذ طلبات بحث SQL الدلالية المجمّعة ذات معدل النقل العالي وطلبات بحث SQL العددية مباشرةً في PostgreSQL
- كيفية تحليل مراجعات المنتجات من العملاء الفعليين لتحديد المشاعر الفئوية
- كيفية تسجيل نقطة نهاية نموذج عام وتقييم نتائج رضا العملاء المستمرة (
0..100) من خلالgoogle_ml.predict_row
الخطوات التالية
- يمكنك الاطّلاع على مزيد من المعلومات حول إمكانات "وظائف AlloyDB AI" في مستندات AlloyDB AI.
- يمكنك الاطّلاع على مرجع TypeSafe AI API لمعرفة المزيد حول منطق قيود Noul وتسجيل المشاعر.