1. Introdução
Neste codelab, você vai conectar o modelo Jev da IA TypeSafe à IA do AlloyDB usando as funções nativas de IA do AlloyDB (ai.if, ai.analyze_sentiment e ml_predict_row). Isso permite executar inferências em lote eficientes usando o modelo Jev diretamente nos seus dados operacionais no AlloyDB, sem mover os dados ou escrever um código complexo do lado do aplicativo.
Atividades deste laboratório
- Provisionar o Acesso a serviços particulares (PSA) e um cluster e uma instância principal do AlloyDB para PostgreSQL
- Criar uma regra de firewall da VPC que permita o Cloud Shell e a conectividade interna
- Carregar um conjunto de dados de amostra de e-commerce usando
gcloud alloydb clusters import - Ativar o Google Secret Manager e a extensão
google_ml_integrationdo AlloyDB - Armazenar e conceder acesso à sua chave de API da IA TypeSafe no Secret Manager
- Criar funções de transformação de entrada e saída PL/pgSQL para as primitivas
noul(booleana) echoice(sentimento) do Jev - Registrar o endpoint do modelo
jev-modelpersonalizado no AlloyDB - Executar consultas semânticas escalares e em lote de matrizes (
ai.ifeai.analyze_sentiment) diretamente em SQL - Consultar avaliações do produto de clientes reais para classificação de sentimentos usando
ai.analyze_sentiment - (Bônus) Registre um endpoint genérico (
jev-systemone) e avalie a intensidade contínua da satisfação do cliente usando a primitivascorede Jev
O que é necessário
- Um navegador da web, como o Chrome
- Tenha um projeto do Google Cloud com o faturamento ativado.
- Uma chave de API da IA TypeSafe (da IA TypeSafe)
2. Antes de começar
Selecione seu projeto do Google Cloud.
No Console do Google Cloud, selecione ou crie o projeto na nuvem que você quer usar.
Iniciar o Cloud Shell
Clique em Ativar o Cloud Shell no canto superior direito do console do Google Cloud.
Verifique se a sessão do Cloud Shell está autenticada:
gcloud auth list
Defina o ID do projeto e as variáveis de ambiente:
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"
Ativar as APIs obrigatórias do Google Cloud
Execute este comando para ativar todas as APIs de serviço necessárias do Google Cloud:
gcloud services enable \
alloydb.googleapis.com \
servicenetworking.googleapis.com \
secretmanager.googleapis.com \
compute.googleapis.com
3. Provisionar o cluster do AlloyDB e a instância principal
Nesta etapa, você vai alocar um intervalo de endereços IP de acesso a serviços particulares na sua rede VPC, estabelecer peering particular e provisionar seu cluster e instância principal do AlloyDB com acesso à Internet de saída.
1. Criar um intervalo de IP de acesso a serviços particulares (PSA)
O AlloyDB exige uma alocação de intervalo de IP particular na sua rede de nuvem privada virtual (VPC). Supondo que você esteja usando a rede VPC default:
Crie a alocação de intervalo de IP privado:
gcloud compute addresses create psa-range \
--global \
--purpose=VPC_PEERING \
--prefix-length=24 \
--description="VPC private service access" \
--network=default
Estabeleça a conexão de peering de VPC particular:
gcloud services vpc-peerings connect \
--service=servicenetworking.googleapis.com \
--ranges=psa-range \
--network=default
2. Criar o cluster do AlloyDB
Gere uma senha segura para o usuário administrativo inicial postgres:
export PGPASSWORD="$(openssl rand -hex 8)@1aA"
echo "Your generated AlloyDB postgres password is: $PGPASSWORD"
Crie um cluster de teste sem custo financeiro do AlloyDB:
gcloud alloydb clusters create $ADBCLUSTER \
--password=$PGPASSWORD \
--network=default \
--region=$REGION
3. Criar a instância principal com flags de IA e conectividade de saída
O AlloyDB se conecta diretamente ao endpoint SaaS seguro da TypeSafe AI (https://api.typesafe.ai/v1/systemone) por HTTPS de saída. Portanto, é necessário especificar --outbound-public-ip. Além disso, configure as flags de banco de dados da IA do AlloyDB para o ambiente:
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. Carregar dados de e-commerce de amostra
Para testar consultas semânticas realistas, importe um exemplo de conjunto de dados de e-commerce com catálogos de produtos e avaliações de clientes diretamente do 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. Armazenar a chave de API da IA TypeSafe no Secret Manager
O gerenciamento de endpoints de modelo do AlloyDB se integra nativamente ao Google Secret Manager para autenticar chamadas de API externas sem expor credenciais de texto simples no código do banco de dados ou nos registros de configuração.
1. Criar o secret
No Cloud Shell, crie um novo secret chamado typesafe-jev-api-key:
gcloud secrets create typesafe-jev-api-key \
--replication-policy="automatic"
Adicione sua chave de API da IA do TypeSafe como uma versão secreta:
echo -n "<YOUR_TYPESAFE_API_KEY>" | \
gcloud secrets versions add typesafe-jev-api-key --data-file=-
2. Conceder acesso ao agente de serviço do AlloyDB
O AlloyDB usa o agente de serviço do projeto para recuperar chaves secretas durante a execução da consulta. Encontre o número do projeto e conceda a função de acessador de secrets:
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"
Você vai receber uma saída confirmando que o agente de serviço recebeu roles/secretmanager.secretAccessor.
5. Conectar-se ao AlloyDB pelo AlloyDB Studio e inicializar as extensões de banco de dados
Para interagir com seu banco de dados do AlloyDB diretamente do navegador sem configurar ferramentas de cliente local ou túneis de proxy, use o AlloyDB Studio no console do Google Cloud.
1. Abrir o AlloyDB Studio
- No console do Google Cloud, acesse AlloyDB para PostgreSQL > Clusters.
- Clique no cluster (
my-alloydb-cluster). - No menu de navegação à esquerda, clique em AlloyDB Studio.
- Autentique-se no banco de dados:
- Banco de dados:
postgres - Usuário:
postgres - Senha: digite a
$PGPASSWORDgerada durante a criação do cluster. Por exemplo, executeecho $PGPASSWORDno Cloud Shell para conferir.
- Banco de dados:
- Clique em Autenticar.
Agora você está no editor de consultas SQL interativo do AlloyDB Studio.
2. Ativar extensões e flags de banco de dados
No editor de consultas do AlloyDB Studio, cole e execute as instruções a seguir para ativar a extensão google_ml_integration e configurar as definições de execução:
-- 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';
Clique em Executar para realizar a consulta.
3. Registrar o Secret no AlloyDB MEM
Informe ao AlloyDB onde encontrar sua chave de API da IA TypeSafe:
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. Criar funções de transformação de SQL
A API System One da TypeSafe AI aceita JSON estruturado com primitivos de raciocínio distintos (noul para restrições booleanas e choice para classificação multiclasse).
O gerenciamento de endpoints de modelo do AlloyDB usa quatro funções de transformação (entrada escalar, saída escalar, entrada em lote e saída em lote) para conectar assinaturas de função ai.* padrão do PostgreSQL ao formato da API REST Jev.
1. Transformação de entrada escalar
Adicione a seguinte função para converter chamadas de ai.if e ai.analyze_sentiment de linha única em payloads de solicitação do 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. Transformação de saída escalar
Adicione a função para descompactar a resposta JSON de Jev de volta em um resultado TEXT do PostgreSQL:
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. Transformação de entrada em lote
O Jev pode avaliar dezenas de perguntas simultaneamente em uma única viagem de ida e volta HTTP sem degradação generativa.
Adicione a transformação de entrada em lote para converter matrizes prompts TEXT[] do PostgreSQL em perguntas paralelas q_1 .. q_N do 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. Transformação de saída em lote
Adicione a função para extrair respostas na ordem correta do índice da matriz 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. Registrar o endpoint do modelo personalizado no AlloyDB
Agora você vai vincular as funções de transformação, a credencial secreta e o endpoint REST da IA TypeSafe em um modelo registrado chamado jev-model.
1. Registrar jev-model
No editor de consultas do AlloyDB Studio, cole e execute:
-- 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. Verificar registro
Consulte a visualização do registro de modelo para garantir que jev-model esteja ativo e seja reconhecido:
SELECT model_id, model_type, model_provider, model_auth_type
FROM google_ml.model_info_view
WHERE model_id = 'jev-model';
Você verá uma saída como:
model_id | model_type | model_provider | model_auth_type ----------+------------+----------------+----------------- jev-model | llm | custom | secret_manager (1 row)
8. Executar consultas de teste no Jev
Com o jev-model registrado, agora é possível executar operações semânticas diretamente em consultas padrão do PostgreSQL.
1. Testar filtragem booleana escalar (ai.if)
Avalie uma única instrução de texto usando 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;
Você verá uma saída como:
is_suitable ------------- true (1 row)
2. Testar a análise de sentimento escalar (ai.analyze_sentiment)
Avalie o feedback do cliente com um rótulo categórico (positive, negative ou 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;
Você verá uma saída como:
sentiment ----------- negative (1 row)
3. Testar a filtragem booleana em lote de matrizes
Avalie vários itens em uma única consulta transmitindo uma matriz de comandos:
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;
Você verá uma saída como:
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. Testar consultas de tabelas com agrupamento em lote de matrizes
Agora, consulte a tabela ecomm.products carregada anteriormente durante o provisionamento do cluster usando ai.if em um lote de itens para verificar quais produtos do catálogo são roupas para clima frio.
Para executar filtragem semântica de alta capacidade em dados de tabela (por exemplo, 50 linhas por lote), use a função de janela row_number() do PostgreSQL para dividir as linhas em lotes:
-- 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;
Você verá uma saída como:
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. Consultar avaliações de produtos dos clientes para sentimento
Agora analise as avaliações dos clientes da tabela ecomm.product_reviews usando ai.analyze_sentiment com suporte da primitiva choice do 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;
Você verá uma saída como:
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. Bônus: pontuação de sentimento contínua com Jev score
Enquanto as funções de IA do AlloyDB, como ai.analyze_sentiment, retornam intervalos categóricos (positive, negative, neutral), a primitiva score da IA TypeSafe avalia nuances em uma rubrica ordenada e retorna uma classificação contínua ponderada por expectativa de 0 a 100.
Como score retorna metadados numéricos em vez de um rótulo de classificação de texto, é possível registrar um endpoint de modelo generic personalizado (jev-systemone) e invocá-lo usando google_ml.predict_row.
1. Registrar o endpoint genérico
No AlloyDB Studio, registre jev-systemone com 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. Executar uma avaliação multitarefa (booleana + pontuação contínua)
Avalie simultaneamente uma verificação booleana de defeito (noul) e a intensidade contínua do sentimento (score) em uma única chamada 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;
Você vai ver uma saída semelhante a esta (seus resultados podem variar):
{
"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
}
}
}
}
Observe que satisfaction_score foi avaliado como 11 / 100, capturando com precisão que o cliente teve uma experiência principalmente negativa, apesar de reconhecer que o tecido era macio.
10. Limpar
Para evitar cobranças contínuas pelos recursos criados durante este codelab, limpe o segredo e os objetos de banco de dados e exclua o cluster do AlloyDB.
1. Excluir recursos do Secret Manager
No Cloud Shell, exclua a chave secreta criada para a chave de API do TypeSafe AI:
gcloud secrets delete typesafe-jev-api-key --quiet
2. Excluir a instância principal e o cluster do AlloyDB
Exclua a instância principal primeiro:
gcloud alloydb instances delete $ADBINSTANCE \
--cluster=$ADBCLUSTER \
--region=$REGION \
--quiet
Quando a exclusão da instância for concluída, exclua o cluster:
gcloud alloydb clusters delete $ADBCLUSTER \
--region=$REGION \
--quiet
11. Parabéns
Parabéns! Você provisionou um cluster do AlloyDB no Google Cloud e o integrou ao TypeSafe AI System One (Jev).
O que você aprendeu
- Como estabelecer o acesso a serviços particulares (PSA, na sigla em inglês) e provisionar um cluster e uma instância principal do AlloyDB para PostgreSQL.
- Como ativar o
--outbound-public-ippara que o AlloyDB possa acessar APIs SaaS HTTPS externas. - Como armazenar credenciais de provedores de IA terceirizados com segurança no Google Secret Manager e vinculá-las ao AlloyDB.
- Como escrever funções de transformação PL/pgSQL que conectam funções de IA padrão do PostgreSQL (
ai.ifeai.analyze_sentiment) a APIs REST externas. - Como registrar endpoints de LLM personalizados no AlloyDB usando
google_ml.create_model. - Como executar consultas SQL semânticas escalares e em lote de alta capacidade diretamente no PostgreSQL.
- Como analisar avaliações de produtos de clientes reais para identificar sentimentos categóricos.
- Como registrar um endpoint de modelo genérico e avaliar as pontuações contínuas de satisfação do cliente (
0..100) usandogoogle_ml.predict_row.
Próximas etapas
- Saiba mais sobre os recursos das funções de IA do AlloyDB na documentação da IA do AlloyDB.
- Leia a Referência da API TypeSafe AI para saber mais sobre a lógica de restrição Noul e a pontuação de sentimento.