1. 簡介
在本程式碼研究室中,您將使用 AlloyDB 的原生 AI 函式 (ai.if、ai.analyze_sentiment 和 ml_predict_row),將 TypeSafe AI 的 Jev 模型連結至 AlloyDB AI。這樣一來,您就能直接在 AlloyDB 的營運資料上,使用 Jev 模型執行有效率的批次推論,不必移動資料或編寫複雜的應用程式端程式碼。
學習內容
- 佈建 Private Service Access (PSA) 和 AlloyDB for PostgreSQL 叢集與主要執行個體
- 建立虛擬私有雲防火牆規則,允許 Cloud Shell 和內部連線
- 使用
gcloud alloydb clusters import載入電子商務資料集範例 - 啟用 Google Secret Manager 和 AlloyDB 的
google_ml_integration擴充功能 - 在 Secret Manager 中儲存並授予 TypeSafe AI API 金鑰的存取權
- 為 Jev 的
noul(布林值) 和choice(情緒) 基本型別建立 PL/pgSQL 輸入和輸出轉換函式 - 在 AlloyDB 中註冊自訂
jev-model模型端點 - 直接在 SQL 中執行純量和陣列批次語意查詢 (
ai.if和ai.analyze_sentiment) - 使用
ai.analyze_sentiment查詢真實顧客的產品評論,進行情緒分類 - (獎勵) 註冊一般端點 (
jev-systemone),並使用 Jev 的score基本型別評估持續的顧客滿意度強度
軟硬體需求
- 網路瀏覽器,例如 Chrome
- 已啟用計費功能的 Google Cloud 雲端專案
- TypeSafe AI API 金鑰 (來自 TypeSafe AI)
2. 事前準備
選取 Google Cloud 專案
在 Google Cloud 控制台中,選取或建立要使用的 Google Cloud 雲端專案。
啟動 Cloud Shell
點選 Google Cloud 控制台右上方的「啟用 Cloud Shell」。
確認 Cloud Shell 工作階段已通過驗證:
gcloud auth list
設定專案 ID 和環境變數:
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 API
執行下列指令,啟用所有必要的 Google Cloud 服務 API:
gcloud services enable \
alloydb.googleapis.com \
servicenetworking.googleapis.com \
secretmanager.googleapis.com \
compute.googleapis.com
3. 佈建 AlloyDB 叢集和主要執行個體
在這個步驟中,您會在虛擬私有雲網路中分配私人服務存取 IP 範圍、建立私人對等互連,並佈建 AlloyDB 叢集和主要執行個體,以取得網際網路輸出存取權。
1. 建立私人服務連線 (PSA) IP 範圍
AlloyDB 需要在虛擬私有雲 (VPC) 網路中分配私人 IP 範圍。假設您使用 default 虛擬私有雲網路:
建立私人 IP 範圍分配:
gcloud compute addresses create psa-range \
--global \
--purpose=VPC_PEERING \
--prefix-length=24 \
--description="VPC private service access" \
--network=default
建立私人虛擬私有雲對等互連連線:
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 免費試用叢集:
gcloud alloydb clusters create $ADBCLUSTER \
--password=$PGPASSWORD \
--network=default \
--region=$REGION
3. 使用 AI 旗標和傳出連線建立主要執行個體
AlloyDB 會透過外送 HTTPS,直接連線至 TypeSafe AI 的安全 SaaS 端點 (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
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 原生整合,可驗證外部 API 呼叫,不必在資料庫程式碼或設定記錄中公開純文字憑證。
1. 建立 Secret
在 Cloud Shell 中,建立名為 typesafe-jev-api-key 的新密鑰:
gcloud secrets create typesafe-jev-api-key \
--replication-policy="automatic"
將 TypeSafe AI API 金鑰新增為密鑰版本:
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 Studio 連線至 AlloyDB,並初始化資料庫擴充功能
如要直接透過瀏覽器與 AlloyDB 資料庫互動,不必設定本機用戶端工具或 Proxy 通道,請使用 Google Cloud 控制台中的 AlloyDB Studio。
1. 開啟 AlloyDB Studio
- 前往 Google Cloud 控制台,依序點選「AlloyDB for PostgreSQL」 >「叢集」。
- 按一下叢集 (
my-alloydb-cluster)。 - 在左側導覽選單中,按一下「AlloyDB Studio」。
- 向資料庫進行驗證:
- 資料庫:
postgres - 使用者:
postgres - 密碼:輸入叢集建立期間產生的
$PGPASSWORD(例如在 Cloud Shell 中執行echo $PGPASSWORD即可查看)。
- 資料庫:
- 按一下「Authenticate」(驗證)。
您現在位於 AlloyDB Studio 互動式 SQL 查詢編輯器。
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';
按一下 [Run] (執行) 開始執行查詢。
3. 在 AlloyDB MEM 中註冊密碼
告知 AlloyDB 在何處尋找 TypeSafe AI API 金鑰:
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 轉換函式
TypeSafe AI 的 System One API 接受結構化 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. 純量輸出轉換
新增函式,將 Jev 的 JSON 回應解壓縮回 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 往返中同時評估數十個問題,不會造成生成內容品質下降。
新增批次輸入轉換,將 PostgreSQL prompts TEXT[] 陣列轉換為平行 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. 使用陣列批次處理測試資料表查詢
現在,請使用 ai.if 查詢先前在叢集佈建期間載入的 ecomm.products 表格,針對一批項目檢查目錄中的哪些產品是寒冷天氣裝備。
如要對資料表資料執行高處理量的語意篩選 (例如每批 50 列),請使用 PostgreSQL 的 row_number() window 函式將資料列分批:
-- 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. 查詢顧客產品評論的情緒
現在,請使用以 Jev 的 choice 基本型別為基礎的 ai.analyze_sentiment,分析 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)
9. 加分功能:使用 Jev score 持續評估情緒
AlloyDB 的 AI 函式 (例如 ai.analyze_sentiment) 會傳回類別值 (positive、negative、neutral),而 TypeSafe AI 的 score 基本型別會根據排序的評分標準評估細微差異,並傳回 0 到 100 的連續期望加權評分。
由於 score 會傳回數值中繼資料,而非文字分類標籤,因此您可以註冊自訂 generic 模型端點 (jev-systemone),並使用 google_ml.predict_row 叫用該端點。
1. 註冊通用端點
在 AlloyDB Studio 中,使用 model_type => 'generic' 註冊 jev-systemone:
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. 執行多工作評估 (布林值 + 連續分數)
在單一 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,準確反映出顧客的體驗大多為負面,即使他們承認布料柔軟!
10. 清理
為避免系統持續收取本程式碼研究室建立資源的費用,請清理密鑰和資料庫物件,並刪除 AlloyDB 叢集。
1. 刪除 Secret Manager 資源
在 Cloud Shell 中,刪除為 TypeSafe AI API 金鑰建立的密鑰:
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) 整合。
目前所學內容
- 如何建立私人服務連線 (PSA),並佈建 AlloyDB for PostgreSQL 叢集和主要執行個體。
- 如何啟用
--outbound-public-ip,讓 AlloyDB 可以連線至外部 HTTPS SaaS API。 - 瞭解如何在 Google Secret Manager 中安全地儲存第三方 AI 供應商憑證,並將憑證繫結至 AlloyDB。
- 如何編寫 PL/pgSQL 轉換函式,將標準 PostgreSQL AI 函式 (
ai.if和ai.analyze_sentiment) 橋接至外部 REST API。 - 如何使用
google_ml.create_model在 AlloyDB 中註冊自訂大型語言模型端點。 - 如何直接在 PostgreSQL 中執行純量和高輸送量批次語意 SQL 查詢。
- 如何分析真實顧客的產品評論,瞭解各類別的情緒。
- 如何註冊一般模型端點,並透過
google_ml.predict_row評估持續的顧客滿意度分數 (0..100)。
後續步驟
- 如要進一步瞭解 AlloyDB AI 函式的功能,請參閱 AlloyDB AI 說明文件。
- 如要進一步瞭解 Noul 限制邏輯和情緒評分,請參閱 TypeSafe AI API 參考資料。