استفاده از مدل Jev در TypeSafe AI به همراه توابع AI در AlloyDB برای کوئری‌های هوش مصنوعی پرسرعت

۱. مقدمه

در این آزمایشگاه کد، شما مدل Jev مربوط به TypeSafe AI را با استفاده از توابع هوش مصنوعی بومی AlloyDB ( ai.if ، ai.analyze_sentiment و ml_predict_row ) به AlloyDB AI متصل خواهید کرد. این به شما امکان می‌دهد تا استنتاج دسته‌ای کارآمد را با استفاده از مدل Jev مستقیماً روی داده‌های عملیاتی خود در AlloyDB اجرا کنید، بدون اینکه داده‌های خود را جابجا کنید یا کد پیچیده سمت برنامه بنویسید.

کاری که انجام خواهید داد

  • ارائه دسترسی به سرویس خصوصی (PSA) و یک AlloyDB برای کلاستر PostgreSQL و نمونه اولیه
  • یک قانون فایروال VPC ایجاد کنید که به Cloudshell و اتصال داخلی اجازه می‌دهد
  • بارگذاری یک مجموعه داده نمونه تجارت الکترونیک با استفاده gcloud alloydb clusters import
  • فعال کردن افزونه‌ی Google Secret Manager و google_ml_integration از AlloyDB
  • کلید TypeSafe AI API خود را در Secret Manager ذخیره و به آن دسترسی دهید
  • توابع تبدیل ورودی و خروجی PL/pgSQL را برای متغیرهای اولیه noul (بولی) و choice (احساسی) مربوط به Jev ایجاد کنید.
  • نقطه پایانی مدل jev-model سفارشی را در AlloyDB ثبت کنید
  • اجرای کوئری‌های معنایی اسکالر و آرایه‌ای ( ai.if و ai.analyze_sentiment ) به طور مستقیم در SQL
  • با استفاده از ai.analyze_sentiment نظرات واقعی مشتریان در مورد محصولات را برای طبقه‌بندی احساسات جستجو کنید.
  • (امتیاز ویژه) یک نقطه پایانی عمومی ( jev-systemone ) ثبت کنید و شدت رضایت مشتری را با استفاده از score اولیه امتیاز Jev به طور مداوم ارزیابی کنید.

آنچه نیاز دارید

  • یک مرورگر وب مانند کروم
  • یک پروژه گوگل کلود با قابلیت پرداخت صورتحساب
  • یک کلید API هوش مصنوعی TypeSafe (از TypeSafe AI )

۲. قبل از شروع

پروژه گوگل کلود خود را انتخاب کنید

در کنسول گوگل کلود ، پروژه گوگل کلودی که می‌خواهید استفاده کنید را انتخاب یا ایجاد کنید.

شروع پوسته ابری

روی فعال کردن پوسته ابری (Activate 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"

فعال کردن API های مورد نیاز Google Cloud

برای فعال کردن تمام API های لازم سرویس Google Cloud، این دستور را اجرا کنید:

gcloud services enable \
  alloydb.googleapis.com \
  servicenetworking.googleapis.com \
  secretmanager.googleapis.com \
  compute.googleapis.com

۳. آماده‌سازی کلاستر AlloyDB و نمونه اولیه

در این مرحله، شما یک محدوده IP دسترسی به سرویس خصوصی را در شبکه VPC خود اختصاص می‌دهید، اتصال خصوصی را برقرار می‌کنید و خوشه AlloyDB و نمونه اصلی خود را با دسترسی به اینترنت خروجی تأمین می‌کنید.

۱. ایجاد محدوده IP دسترسی به سرویس خصوصی (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

۲. ایجاد خوشه AlloyDB

یک رمز عبور پایگاه داده ایمن برای کاربر اولیه ادمین postgres ایجاد کنید:

export PGPASSWORD="$(openssl rand -hex 8)@1aA"
echo "Your generated AlloyDB postgres password is: $PGPASSWORD"

یک کلاستر آزمایشی رایگان AlloyDB ایجاد کنید:

gcloud alloydb clusters create $ADBCLUSTER \
    --password=$PGPASSWORD \
    --network=default \
    --region=$REGION 

۳. نمونه اصلی را با پرچم‌های هوش مصنوعی و اتصال خروجی ایجاد کنید

AlloyDB مستقیماً از طریق HTTPS خروجی به نقطه پایانی SaaS امن TypeSafe AI ( https://api.typesafe.ai/v1/systemone ) متصل می‌شود. بنابراین، باید --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

۴. بارگذاری داده‌های نمونه تجارت الکترونیک

برای آزمایش پرس‌وجوهای معنایی واقع‌گرایانه، یک مجموعه داده تجارت الکترونیک نمونه شامل کاتالوگ‌های محصولات و نظرات مشتریان را مستقیماً از فضای ذخیره‌سازی ابری وارد کنید:

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

۴. کلید API هوش مصنوعی TypeSafe را در Secret Manager ذخیره کنید

مدیریت نقطه پایانی مدل (Model Endpoint Management) در AlloyDB به صورت بومی با Google Secret Manager ادغام می‌شود تا فراخوانی‌های API خارجی را بدون افشای اعتبارنامه‌های متنی ساده در کد پایگاه داده یا گزارش‌های پیکربندی، احراز هویت کند.

۱. راز را خلق کنید

در Cloud Shell، یک راز جدید با نام typesafe-jev-api-key ایجاد کنید:

gcloud secrets create typesafe-jev-api-key \
  --replication-policy="automatic"

کلید API هوش مصنوعی TypeSafe خود را به عنوان یک نسخه مخفی اضافه کنید:

echo -n "<YOUR_TYPESAFE_API_KEY>" | \
  gcloud secrets versions add typesafe-jev-api-key --data-file=-

۲. اعطای دسترسی به عامل سرویس 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 را دریافت کرده است.

۵. از طریق AlloyDB Studio به AlloyDB متصل شوید و افزونه‌های پایگاه داده را مقداردهی اولیه کنید

برای تعامل مستقیم با پایگاه داده AlloyDB خود از طریق مرورگر و بدون پیکربندی ابزارهای کلاینت محلی یا تونل‌های پروکسی، از AlloyDB Studio در کنسول Google Cloud استفاده کنید.

۱. استودیوی AlloyDB را باز کنید

  1. در کنسول گوگل کلود ، به مسیر AlloyDB for PostgreSQL > Clusters بروید.
  2. روی کلاستر خود ( my-alloydb-cluster ) کلیک کنید.
  3. در منوی ناوبری سمت چپ، روی AlloyDB Studio کلیک کنید.
  4. احراز هویت در پایگاه داده:
    • پایگاه داده : postgres
    • کاربر : postgres
    • رمز عبور : $PGPASSWORD تولید شده در طول ایجاد خوشه را وارد کنید (مثلاً برای مشاهده آن، echo $PGPASSWORD در Cloud Shell اجرا کنید).
  5. روی تأیید اعتبار کلیک کنید.

اکنون در ویرایشگر کوئری SQL تعاملی AlloyDB Studio هستید.

۲. فعال کردن افزونه‌ها و پرچم‌های پایگاه داده

در ویرایشگر کوئری 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';

برای اجرای کوئری ، روی Run کلیک کنید.

۳. رمز را در AlloyDB MEM ثبت کنید

به AlloyDB بگویید که کلید API 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'
);

۶. ایجاد توابع تبدیل SQL

رابط برنامه‌نویسی کاربردی سیستم یک (System One API) مربوط به TypeSafe AI، JSON ساختاریافته با اصول اولیه استدلال متمایز ( noul برای محدودیت‌های بولی، choice برای طبقه‌بندی چندکلاسی) را می‌پذیرد.

مدیریت نقطه پایانی مدل AlloyDB از چهار تابع تبدیل (ورودی اسکالر، خروجی اسکالر، ورودی دسته‌ای، خروجی دسته‌ای) برای اتصال امضاهای تابع استاندارد PostgreSQL ai.* به فرمت Jev REST API استفاده می‌کند.

۱. تبدیل ورودی اسکالر

تابع زیر را برای تبدیل فراخوانی‌های تک‌ردیفی 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;
$$;

۲. تبدیل خروجی اسکالر

تابعی را اضافه کنید که پاسخ 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;
$$;

۳. تبدیل ورودی دسته‌ای

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;
$$;

۴. تبدیل خروجی دسته‌ای

تابعی را اضافه کنید که پاسخ‌ها را با ترتیب صحیح اندیس آرایه 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;
$$;

۷. ثبت نقطه پایانی مدل سفارشی در AlloyDB

اکنون توابع تبدیل، اعتبارنامه مخفی و نقطه پایانی TypeSafe AI REST را در یک مدل ثبت شده به نام jev-model به هم متصل خواهید کرد.

۱. ثبت نام 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'
);

۲. تأیید ثبت‌نام

برای اطمینان از فعال و شناخته شدن 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)

۸. اجرای کوئری‌های آزمایشی علیه Jev

با ثبت jev-model ، اکنون می‌توانید عملیات معنایی را مستقیماً درون کوئری‌های استاندارد PostgreSQL اجرا کنید.

۱. تست فیلتر بولی اسکالر ( 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)

۲. آزمون تحلیل احساسات اسکالر ( 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)

۳. آزمایش فیلتر بولی آرایه‌ای-دسته‌ای

ارزیابی چندین مورد در یک پرس‌وجو با ارسال آرایه‌ای از اعلان‌ها:

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)

۴. تست پرس‌وجوهای جدول با دسته‌بندی آرایه

اکنون با استفاده از ai.if روی دسته‌ای از اقلام، جدول ecomm.products که قبلاً در طول آماده‌سازی خوشه‌ای بارگذاری شده است را جستجو کنید تا بررسی کنید کدام یک از محصولات موجود در کاتالوگ، تجهیزات هوای سرد هستند.

برای اجرای فیلترینگ معنایی با توان عملیاتی بالا روی داده‌های جدول (مثلاً ۵۰ ردیف در هر دسته)، از تابع پنجره‌ای row_number() در 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)

۵. نظرات مشتریان در مورد محصول را برای سنجش احساساتشان جویا شوید

اکنون با استفاده از ai.analyze_sentiment که توسط choice اولیه Jev پشتیبانی می‌شود، نظرات مشتریان را از جدول ecomm.product_reviews تجزیه و تحلیل کنید:

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)

۹. امتیاز ویژه: امتیازدهی مداوم به احساسات با امتیاز Jev

در حالی که توابع هوش مصنوعی AlloyDB مانند ai.analyze_sentiment مقادیر دسته‌بندی‌شده ( positive ، negative ، neutral ) را برمی‌گردانند، score اولیه TypeSafe AI تفاوت‌های جزئی را در یک روبریک مرتب ارزیابی می‌کند و یک رتبه‌بندی پیوسته و با وزن انتظاری از ۰ تا ۱۰۰ برمی‌گرداند.

از آنجا که score به جای برچسب طبقه‌بندی متن، فراداده عددی را برمی‌گرداند، می‌توانید یک نقطه پایانی مدل generic سفارشی ( jev-systemone ) ثبت کنید و آن را با استفاده از google_ml.predict_row فراخوانی کنید.

۱. ثبت نقطه پایانی عمومی

در 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'
);

۲. اجرای یک ارزیابی چندوظیفه‌ای (بولی + امتیاز پیوسته)

همزمان در یک فراخوانی HTTP، هم بررسی نقص بولی ( noul ) و هم شدت احساسات پیوسته ( score ) را ارزیابی کنید:

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 ارزیابی شده است، که به طور دقیق نشان می‌دهد مشتری با وجود اذعان به نرم بودن پارچه، تجربه عمدتاً منفی داشته است!

۱۰. تمیز کردن

برای جلوگیری از متحمل شدن هزینه‌های جاری برای منابع ایجاد شده در طول این آزمایش کد، اشیاء مخفی و پایگاه داده را پاک کنید و خوشه AlloyDB را حذف کنید.

۱. منابع مخفی مدیر را حذف کنید

در Cloud Shell، رمز ایجاد شده برای کلید TypeSafe AI API را حذف کنید:

gcloud secrets delete typesafe-jev-api-key --quiet

۲. نمونه و کلاستر اولیه AlloyDB را حذف کنید

ابتدا نمونه اصلی را حذف کنید:

gcloud alloydb instances delete $ADBINSTANCE \
  --cluster=$ADBCLUSTER \
  --region=$REGION \
  --quiet

پس از اتمام حذف نمونه، خوشه را حذف کنید:

gcloud alloydb clusters delete $ADBCLUSTER \
  --region=$REGION \
  --quiet

۱۱. تبریک

تبریک! شما با موفقیت یک کلاستر Google Cloud AlloyDB را آماده‌سازی و آن را با TypeSafe AI System One ( Jev ) ادغام کردید.

آنچه آموخته‌اید

  • نحوه ایجاد دسترسی به سرویس خصوصی (PSA) و تهیه AlloyDB برای کلاستر PostgreSQL و نمونه اولیه.
  • چگونه می‌توان --outbound-public-ip فعال کرد تا AlloyDB بتواند به APIهای SaaS خارجی HTTPS دسترسی پیدا کند.
  • چگونه اعتبارنامه‌های ارائه‌دهنده هوش مصنوعی شخص ثالث را به صورت ایمن در Google Secret Manager ذخیره کنیم و آنها را به AlloyDB متصل کنیم.
  • چگونه توابع تبدیل PL/pgSQL بنویسیم که توابع استاندارد هوش مصنوعی PostgreSQL ( ai.if و ai.analyze_sentiment ) را به APIهای خارجی REST متصل کنند.
  • نحوه ثبت نقاط پایانی LLM سفارشی در AlloyDB با استفاده از google_ml.create_model .
  • چگونه می‌توان کوئری‌های SQL معنایی دسته‌ای اسکالر و پربازده را مستقیماً در PostgreSQL اجرا کرد.
  • چگونه نظرات واقعی مشتریان در مورد محصولات را برای دسته‌بندی احساسات تجزیه و تحلیل کنیم؟
  • نحوه ثبت یک نقطه پایانی مدل عمومی و ارزیابی نمرات رضایت مشتری مداوم ( 0..100 ) از طریق google_ml.predict_row .

مراحل بعدی

اسناد مرجع