Bắt đầu sử dụng tính năng Nhúng vectơ trong Cloud SQL cho PostgreSQL

1. Giới thiệu

Trong lớp học lập trình này, bạn sẽ tìm hiểu cách sử dụng Cloud SQL để tích hợp AI với PostgreSQL bằng cách kết hợp tính năng tìm kiếm vectơ với các mục nhúng Vertex AI.

30b7c4dcdd8bb68f.png

Điều kiện tiên quyết

  • Có kiến thức cơ bản về Google Cloud, bảng điều khiển
  • Kỹ năng cơ bản về giao diện dòng lệnh và Cloud Shell

Kiến thức bạn sẽ học được

  • Cách triển khai phiên bản Cloud SQL cho PostgreSQL
  • Cách tạo cơ sở dữ liệu và bật tính năng tích hợp AI của Cloud SQL
  • Cách tải dữ liệu vào cơ sở dữ liệu
  • Cách sử dụng mô hình nhúng Vertex AI trong Cloud SQL
  • Cách làm phong phú kết quả bằng mô hình tạo sinh của Vertex AI
  • Cách cải thiện hiệu suất bằng chỉ mục vectơ

Bạn cần có

  • Tài khoản Google Cloud và dự án trên Google Cloud
  • Một trình duyệt web như Chrome hỗ trợ Google Cloud Console và Cloud Shell

2. Cách thiết lập và các yêu cầu

Thiết lập môi trường theo tốc độ của riêng bạn

  1. Đăng nhập vào Google Cloud Console rồi tạo một dự án mới hoặc sử dụng lại một dự án hiện có. Nếu chưa có tài khoản Gmail hoặc Google Workspace, bạn phải tạo một tài khoản.

fbef9caa1602edd0.png

a99b7ace416376c4.png

5e3ff691252acf41.png

  • Tên dự án là tên hiển thị cho người tham gia dự án này. Đây là một chuỗi ký tự không được API của Google sử dụng. Bạn luôn có thể cập nhật thông tin này.
  • Mã dự án là duy nhất trên tất cả các dự án Google Cloud và không thể thay đổi (không thể thay đổi sau khi đặt). Cloud Console sẽ tự động tạo một chuỗi duy nhất; thường thì bạn không cần quan tâm đến chuỗi này. Trong hầu hết các lớp học lập trình, bạn sẽ cần tham chiếu đến Mã dự án (thường được xác định là PROJECT_ID). Nếu không thích mã được tạo, bạn có thể tạo một mã ngẫu nhiên khác. Ngoài ra, bạn có thể thử dùng email của riêng mình để xem có thể sử dụng hay không. Bạn không thể thay đổi giá trị này sau bước này và giá trị này sẽ giữ nguyên trong suốt thời gian của dự án.
  • Xin lưu ý rằng có một giá trị thứ ba là Mã dự án mà một số API sử dụng. Tìm hiểu thêm về cả ba giá trị này trong tài liệu.
  1. Tiếp theo, bạn cần bật tính năng thanh toán trong Cloud Console để sử dụng các tài nguyên/API trên Cloud. Việc tham gia lớp học lập trình này sẽ không tốn kém nhiều chi phí, nếu có. Để tắt các tài nguyên nhằm tránh bị tính phí sau khi hoàn tất hướng dẫn này, bạn có thể xoá các tài nguyên đã tạo hoặc xoá dự án. Người dùng mới của Google Cloud đủ điều kiện tham gia chương trình Dùng thử miễn phí 300 USD.

Khởi động Cloud Shell

Mặc dù có thể điều khiển Google Cloud từ xa trên máy tính xách tay, nhưng trong lớp học lập trình này, bạn sẽ sử dụng Google Cloud Shell, một môi trường dòng lệnh chạy trên đám mây.

Trong Bảng điều khiển Google Cloud, hãy nhấp vào biểu tượng Cloud Shell trên thanh công cụ trên cùng bên phải:

55efc1aaa7a4d3ad.png

Quá trình cấp phép và kết nối với môi trường sẽ chỉ mất vài phút. Khi hoàn tất, bạn sẽ thấy như sau:

7ffe5cbb04455448.png

Máy ảo này được tải sẵn tất cả các công cụ phát triển mà bạn cần. Ứng dụng này cung cấp một thư mục gốc 5 GB ổn định và chạy trên Google Cloud, giúp nâng cao đáng kể hiệu suất mạng và xác thực. Bạn có thể thực hiện tất cả công việc trong lớp học lập trình này trong một trình duyệt. Bạn không cần cài đặt gì cả.

3. Trước khi bắt đầu

Bật API

Kết quả:

Trong Cloud Shell, hãy đảm bảo bạn đã thiết lập mã dự án:

gcloud config set project [YOUR-PROJECT-ID]

Đặt biến môi trường PROJECT_ID:

PROJECT_ID=$(gcloud config get-value project)

Bật tất cả các dịch vụ cần thiết:

gcloud services enable sqladmin.googleapis.com \
                       compute.googleapis.com \
                       cloudresourcemanager.googleapis.com \
                       servicenetworking.googleapis.com \
                       aiplatform.googleapis.com

Kết quả dự kiến

student@cloudshell:~ (test-project-001-402417)$ gcloud config set project test-project-001-402417
Updated property [core/project].
student@cloudshell:~ (test-project-001-402417)$ PROJECT_ID=$(gcloud config get-value project)
Your active configuration is: [cloudshell-14650]
student@cloudshell:~ (test-project-001-402417)$ 
student@cloudshell:~ (test-project-001-402417)$ gcloud services enable sqladmin.googleapis.com \
                       compute.googleapis.com \
                       cloudresourcemanager.googleapis.com \
                       servicenetworking.googleapis.com \
                       aiplatform.googleapis.com
Operation "operations/acat.p2-4470404856-1f44ebd8-894e-4356-bea7-b84165a57442" finished successfully.

4. Tạo phiên bản Cloud SQL

Tạo phiên bản Cloud SQL có tích hợp cơ sở dữ liệu với Vertex AI.

Tạo mật khẩu cho cơ sở dữ liệu

Xác định mật khẩu cho người dùng cơ sở dữ liệu mặc định. Bạn có thể tự xác định mật khẩu hoặc sử dụng hàm ngẫu nhiên để tạo mật khẩu:

export CLOUDSQL_PASSWORD=`openssl rand -hex 12`

Lưu ý giá trị được tạo cho mật khẩu:

echo $CLOUDSQL_PASSWORD

Tạo phiên bản Cloud SQL cho PostgreSQL

Trong phiên Cloud Shell, hãy thực thi:

gcloud sql instances create my-cloudsql-instance \
--database-version=POSTGRES_16 \
--tier=db-custom-1-3840 \
--region=us-central1 \
--edition=ENTERPRISE \
--enable-google-ml-integration \
--database-flags cloudsql.enable_google_ml_integration=on

Sau khi tạo thực thể, chúng ta cần đặt mật khẩu cho người dùng mặc định trong thực thể và xác minh xem chúng ta có thể kết nối bằng mật khẩu đó hay không.

gcloud sql users set-password postgres \
    --instance=my-cloudsql-instance \
    --password=$CLOUDSQL_PASSWORD

Chạy lệnh và nhập mật khẩu của bạn vào lời nhắc khi đã sẵn sàng kết nối.

gcloud sql connect my-cloudsql-instance --user=postgres

Bật tính năng tích hợp Vertex AI

Cấp các đặc quyền cần thiết cho tài khoản dịch vụ cloud sql nội bộ để có thể sử dụng tính năng tích hợp Vertex AI.

Tìm email của tài khoản dịch vụ nội bộ Cloud SQL và xuất email đó dưới dạng biến.

SERVICE_ACCOUNT_EMAIL=$(gcloud sql instances describe my-cloudsql-instance --format="value(serviceAccountEmailAddress)")
echo $SERVICE_ACCOUNT_EMAIL

Cấp quyền truy cập vào Vertex AI cho tài khoản dịch vụ Cloud SQL:

gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member="serviceAccount:$SERVICE_ACCOUNT_EMAIL" \
  --role="roles/aiplatform.user"

Đọc thêm về cách tạo và định cấu hình thực thể trong tài liệu về Cloud SQL tại đây.

5. Chuẩn bị cơ sở dữ liệu

Bây giờ, chúng ta cần tạo một cơ sở dữ liệu và bật tính năng hỗ trợ vectơ.

Tạo cơ sở dữ liệu

Tạo một cơ sở dữ liệu có tên quickstart_db .Để làm như vậy, chúng ta có nhiều lựa chọn như ứng dụng cơ sở dữ liệu dòng lệnh như psql cho PostgreSQL, SDK hoặc Cloud SQL Studio. Chúng ta sẽ sử dụng SDK (gcloud) để tạo cơ sở dữ liệu và kết nối với thực thể.

Trong Cloud Shell, hãy thực thi lệnh để tạo cơ sở dữ liệu

gcloud sql databases create quickstart_db --instance=my-cloudsql-instance

Bật tiện ích

Để có thể làm việc với Vertex AI và vectơ, chúng ta cần bật hai tiện ích trong cơ sở dữ liệu đã tạo.

Trong Cloud Shell, hãy thực thi lệnh để kết nối với cơ sở dữ liệu đã tạo (bạn sẽ cần cung cấp mật khẩu)

gcloud sql connect my-cloudsql-instance --database quickstart_db --user=postgres

Sau đó, sau khi kết nối thành công, trong phiên sql, bạn cần chạy hai lệnh:

CREATE EXTENSION IF NOT EXISTS google_ml_integration CASCADE;
CREATE EXTENSION IF NOT EXISTS vector CASCADE;

Thoát khỏi phiên SQL:

exit;

6. Tải dữ liệu

Bây giờ, chúng ta cần tạo các đối tượng trong cơ sở dữ liệu và tải dữ liệu. Chúng ta sẽ sử dụng dữ liệu của Cymbal Store (Cửa hàng cymbal) hư cấu. Dữ liệu có sẵn trên bộ chứa Google Storage công khai ở định dạng CSV.

Trước tiên, chúng ta cần tạo tất cả các đối tượng bắt buộc trong cơ sở dữ liệu. Để làm như vậy, chúng ta sẽ sử dụng các lệnh gcloud sql connect và gcloud storage quen thuộc để tải xuống và nhập các đối tượng giản đồ vào cơ sở dữ liệu của mình.

Trong màn hình shell trên đám mây, hãy thực thi và cung cấp mật khẩu đã ghi chú khi chúng ta tạo thực thể:

gcloud storage cat gs://cloud-training/gcc/gcc-tech-004/cymbal_demo_schema.sql |gcloud sql connect my-cloudsql-instance --database quickstart_db --user=postgres

Chúng ta đã làm gì chính xác trong lệnh trước? Chúng ta đã kết nối với cơ sở dữ liệu và thực thi mã SQL đã tải xuống để tạo các bảng, chỉ mục và trình tự.

Bước tiếp theo là tải dữ liệu và để làm như vậy, chúng ta cần tải tệp CSV xuống từ Google Cloud Storage.

gcloud storage cp gs://cloud-training/gcc/gcc-tech-004/cymbal_products.csv .
gcloud storage cp gs://cloud-training/gcc/gcc-tech-004/cymbal_inventory.csv .
gcloud storage cp gs://cloud-training/gcc/gcc-tech-004/cymbal_stores.csv .

Sau đó, chúng ta cần kết nối với cơ sở dữ liệu.

gcloud sql connect my-cloudsql-instance --database quickstart_db --user=postgres

Và nhập dữ liệu từ các tệp CSV của chúng tôi.

\copy cymbal_products from 'cymbal_products.csv' csv header
\copy cymbal_inventory from 'cymbal_inventory.csv' csv header
\copy cymbal_stores from 'cymbal_stores.csv' csv header

Thoát khỏi phiên SQL:

exit;

Nếu có dữ liệu riêng và tệp CSV tương thích với công cụ nhập Cloud SQL có trong bảng điều khiển Cloud, bạn có thể sử dụng công cụ này thay vì phương pháp dòng lệnh.

7. Tạo nội dung nhúng

Bước tiếp theo là tạo các phần nhúng cho nội dung mô tả sản phẩm bằng cách sử dụng mô hình textembedding-004 của Google Vertex AI và lưu trữ các phần nhúng đó dưới dạng dữ liệu vectơ.

Kết nối với cơ sở dữ liệu:

gcloud sql connect my-cloudsql-instance --database quickstart_db --user=postgres

Và tạo một cột ảo nhúng trong bảng cymbal_products bằng hàm nhúng.

ALTER TABLE cymbal_products ADD COLUMN embedding vector(768) GENERATED ALWAYS AS (embedding('text-embedding-004',product_description)) STORED;

Quá trình này có thể mất chút thời gian, nhưng đối với 900-1000 hàng, thời gian này không được vượt quá 5 phút và thường nhanh hơn nhiều.

8. Chạy tính năng Tìm kiếm nội dung tương tự

Bây giờ, chúng ta có thể chạy tìm kiếm bằng cách sử dụng tính năng tìm kiếm theo mức độ tương đồng dựa trên các giá trị vectơ được tính toán cho nội dung mô tả và giá trị vectơ mà chúng ta nhận được cho yêu cầu của mình.

Bạn có thể thực thi truy vấn SQL từ cùng một giao diện dòng lệnh bằng cách sử dụng lệnh gcloud sql connect hoặc thay vào đó là từ Cloud SQL Studio. Bạn nên quản lý mọi truy vấn phức tạp và nhiều hàng trong Cloud SQL Studio.

Khởi động Cloud SQL Studio

Trong bảng điều khiển, hãy nhấp vào phiên bản Cloud SQL mà chúng ta đã tạo trước đó.

b8d4844da1114a0b.png

Khi mở trên bảng điều khiển bên phải, chúng ta có thể thấy Cloud SQL Studio. Nhấp vào mục đó.

ce3f27dc21367f2e.png

Thao tác này sẽ mở ra một hộp thoại để bạn cung cấp tên cơ sở dữ liệu và thông tin xác thực của mình:

  • Cơ sở dữ liệu: quickstart_db
  • Người dùng: postgres
  • Password (Mật khẩu): mật khẩu bạn đã ghi chú cho người dùng cơ sở dữ liệu chính

Sau đó, nhấp vào nút "AUTHENTICATE" (XÁC THỰC).

2591c8bbc93e4e97.png

Thao tác này sẽ mở ra cửa sổ tiếp theo, trong đó bạn nhấp vào thẻ "Trình chỉnh sửa" ở bên phải để mở Trình chỉnh sửa SQL.

74307cb101a3ba9d.png

Bây giờ, chúng ta đã sẵn sàng chạy truy vấn.

Chạy truy vấn

Chạy truy vấn để nhận danh sách các sản phẩm hiện có liên quan nhất đến yêu cầu của khách hàng. Yêu cầu mà chúng ta sẽ chuyển đến Vertex AI để lấy giá trị vectơ có dạng như "Loại cây ăn quả nào phát triển tốt ở đây?"

Dưới đây là truy vấn mà bạn có thể chạy để chọn 10 mục đầu tiên phù hợp nhất với yêu cầu của chúng ta:

SELECT
        cp.product_name,
        left(cp.product_description,80) as description,
        cp.sale_price,
        cs.zip_code,
        (cp.embedding <=> embedding('text-embedding-004','What kind of fruit trees grow well here?')::vector) as distance
FROM
        cymbal_products cp
JOIN cymbal_inventory ci on
        ci.uniq_id=cp.uniq_id
JOIN cymbal_stores cs on
        cs.store_id=ci.store_id
        AND ci.inventory>0
        AND cs.store_id = 1583
ORDER BY
        distance ASC
LIMIT 10;

Sao chép và dán truy vấn vào trình chỉnh sửa Cloud SQL Studio, sau đó nhấn nút "RUN" (CHẠY) hoặc dán truy vấn vào phiên dòng lệnh kết nối với cơ sở dữ liệu quickstart_db.

cd07549522fd04c9.png

Dưới đây là danh sách các sản phẩm được chọn trùng khớp với cụm từ tìm kiếm.

product_name       |                                   description                                    | sale_price | zip_code |      distance       
-------------------------+----------------------------------------------------------------------------------+------------+----------+---------------------
 Cherry Tree             | This is a beautiful cherry tree that will produce delicious cherries. It is an d |      75.00 |    93230 | 0.43922018972266397
 Meyer Lemon Tree        | Meyer Lemon trees are California's favorite lemon tree! Grow your own lemons by  |         34 |    93230 |  0.4685112926118228
 Toyon                   | This is a beautiful toyon tree that can grow to be over 20 feet tall. It is an e |      10.00 |    93230 |  0.4835677149651668
 California Lilac        | This is a beautiful lilac tree that can grow to be over 10 feet tall. It is an d |       5.00 |    93230 |  0.4947204525907498
 California Peppertree   | This is a beautiful peppertree that can grow to be over 30 feet tall. It is an e |      25.00 |    93230 |  0.5054166905547247
 California Black Walnut | This is a beautiful walnut tree that can grow to be over 80 feet tall. It is a d |     100.00 |    93230 |  0.5084219510932597
 California Sycamore     | This is a beautiful sycamore tree that can grow to be over 100 feet tall. It is  |     300.00 |    93230 |  0.5140519790508755
 Coast Live Oak          | This is a beautiful oak tree that can grow to be over 100 feet tall. It is an ev |     500.00 |    93230 |  0.5143126438081371
 Fremont Cottonwood      | This is a beautiful cottonwood tree that can grow to be over 100 feet tall. It i |     200.00 |    93230 |  0.5174774727252058
 Madrone                 | This is a beautiful madrona tree that can grow to be over 80 feet tall. It is an |      50.00 |    93230 |  0.5227400803389093
(10 rows)

9. Cải thiện phản hồi LLM bằng dữ liệu đã truy xuất

Chúng ta có thể cải thiện phản hồi LLM AI Gen cho ứng dụng khách bằng cách sử dụng kết quả của truy vấn đã thực thi và chuẩn bị đầu ra có ý nghĩa bằng cách sử dụng kết quả truy vấn được cung cấp như một phần của lời nhắc cho mô hình ngôn ngữ nền tảng tạo sinh Vertex AI.

Để đạt được điều đó, chúng ta cần tạo một tệp JSON chứa kết quả tìm kiếm vectơ, sau đó sử dụng tệp JSON đã tạo đó để bổ sung cho lời nhắc cho mô hình LLM trong Vertex AI nhằm tạo ra kết quả có ý nghĩa. Trong bước đầu tiên, chúng ta tạo JSON, sau đó kiểm thử JSON đó trong Vertex AI Studio và ở bước cuối cùng, chúng ta kết hợp JSON đó vào một câu lệnh SQL có thể được sử dụng trong một ứng dụng.

Tạo đầu ra ở định dạng JSON

Sửa đổi truy vấn để tạo đầu ra ở định dạng JSON và chỉ trả về một hàng để chuyển đến Vertex AI

Cloud SQL cho PostgreSQL

Sau đây là ví dụ về truy vấn:

WITH trees as (
SELECT
        cp.product_name,
        left(cp.product_description,80) as description,
        cp.sale_price,
        cs.zip_code,
        cp.uniq_id as product_id
FROM
        cymbal_products cp
JOIN cymbal_inventory ci on
        ci.uniq_id=cp.uniq_id
JOIN cymbal_stores cs on
        cs.store_id=ci.store_id
        AND ci.inventory>0
        AND cs.store_id = 1583
ORDER BY
        (cp.embedding <=> embedding('text-embedding-004','What kind of fruit trees grow well here?')::vector) ASC
LIMIT 1)
SELECT json_agg(trees) FROM trees;

Dưới đây là JSON dự kiến trong kết quả:

[{"product_name":"Cherry Tree","description":"This is a beautiful cherry tree that will produce delicious cherries. It is an d","sale_price":75.00,"zip_code":93230,"product_id":"d536e9e823296a2eba198e52dd23e712"}]

Chạy câu lệnh trong Vertex AI Studio

Chúng ta có thể sử dụng JSON đã tạo để cung cấp JSON đó dưới dạng một phần của câu lệnh cho mô hình văn bản AI tạo sinh trong Vertex AI Studio

Mở tính năng Trò chuyện trong Vertex AI Studio trong bảng điều khiển trên đám mây.

449b5959fa0e93bd.png

Bạn có thể được yêu cầu bật các API bổ sung nhưng bạn có thể bỏ qua yêu cầu này. Chúng ta không cần thêm API nào khác để hoàn tất lớp học lập trình này.

Dưới đây là câu lệnh mà chúng ta sẽ sử dụng:

You are a friendly advisor helping to find a product based on the customer's needs.
Based on the client request we have loaded a list of products closely related to search.
The list in JSON format with list of values like {"product_name":"name","description":"some description","sale_price":10,"zip_code": 10234, "produt_id": "02056727942aeb714dc9a2313654e1b0"}
Here is the list of products:
[place your JSON here]
The customer asked "What tree is growing the best here?"
You should give information about the product, price and some supplemental information.
Do not ask any additional questions and assume location based on the zip code provided in the list of products.

Và đây là giao diện khi chúng ta thay thế phần giữ chỗ JSON bằng phản hồi từ truy vấn:

You are a friendly advisor helping to find a product based on the customer's needs.
Based on the client request we have loaded a list of products closely related to search.
The list in JSON format with list of values like {"product_name":"name","description":"some description","sale_price":10,"zip_code": 10234, "produt_id": "02056727942aeb714dc9a2313654e1b0"}
Here is the list of products:
[{"product_name":"Cherry Tree","description":"This is a beautiful cherry tree that will produce delicious cherries. It is an d","sale_price":75.00,"zip_code":93230,"product_id":"d536e9e823296a2eba198e52dd23e712"}]
The customer asked "What tree is growing the best here?"
You should give information about the product, price and some supplemental information.
Do not ask any additional questions and assume location based on the zip code provided in the list of products.

Và đây là kết quả khi chúng ta chạy lời nhắc bằng các giá trị JSON và sử dụng mô hình gemini-2.0-flash:

2c5145ebc04daae1.png

Sau đây là câu trả lời mà chúng ta nhận được từ mô hình trong ví dụ này. Xin lưu ý rằng câu trả lời của bạn có thể khác do mô hình và các tham số thay đổi theo thời gian:

"Được rồi, dựa trên danh sách sản phẩm hiện có, cây tốt nhất mà chúng tôi có và có thể phát triển tốt ở khu vực của bạn là cây Anh đào.

Giá của sản phẩm là 75 USD.

Mặc dù tôi không có thông tin chi tiết cụ thể về điều kiện trồng cây theo mã bưu chính chính xác của bạn (93230), nhưng cây anh đào thường phát triển mạnh ở những khu vực có khí hậu ôn hòa và đất thoát nước tốt. Thường thì các cây này cần một khoảng thời gian nhất định trong mùa đông để ra quả, vì vậy, bạn cần lưu ý điều này. Tuy nhiên, chúng có thể là một điểm nhấn tuyệt vời cho khu vườn, mang đến vẻ đẹp và những quả anh đào ngon khi điều kiện thích hợp."

Chạy lời nhắc trong PSQL

Chúng ta cũng có thể sử dụng tính năng tích hợp AI Cloud SQL với Vertex AI để nhận được phản hồi tương tự từ một mô hình tạo sinh bằng cách sử dụng SQL ngay trong cơ sở dữ liệu. Tuy nhiên, để sử dụng mô hình gemini-2.0-flash-exp, trước tiên, chúng ta cần đăng ký mô hình đó.

Chạy trong Cloud SQL cho PostgreSQL

Nâng cấp tiện ích lên phiên bản 1.4.2 trở lên (nếu phiên bản hiện tại thấp hơn). Kết nối với cơ sở dữ liệu quickstart_db từ gcloud sql connect như đã hiển thị trước đó (hoặc sử dụng Cloud SQL Studio) và thực thi:

SELECT extversion from pg_extension where extname='google_ml_integration';

Nếu giá trị được trả về nhỏ hơn 1.4.2, hãy thực thi:

ALTER EXTENSION google_ml_integration UPDATE TO '1.4.2';

Sau đó, chúng ta cần đặt cờ cơ sở dữ liệu google_ml_integration.enable_model_support thành "bật". Để thực hiện việc đó, bạn có thể sử dụng giao diện bảng điều khiển web hoặc chạy lệnh gcloud sau.

gcloud sql instances patch my-cloudsql-instance \
--database-flags google_ml_integration.enable_model_support=on,cloudsql.enable_google_ml_integration=on

Lệnh này sẽ mất khoảng 1 đến 3 phút để thực thi trong nền. Sau đó, bạn có thể xác minh cờ mới trong phiên psql hoặc sử dụng Cloud SQL Studio để kết nối với cơ sở dữ liệu quickstart_db.

show google_ml_integration.enable_model_support;

Kết quả dự kiến từ phiên psql là "bật":

quickstart_db => show google_ml_integration.enable_model_support;
 google_ml_integration.enable_model_support 
--------------------------------------------
 on
(1 row)

Sau đó, chúng ta cần đăng ký hai mô hình. Mô hình đầu tiên là mô hình text-embedding-004 đã được sử dụng. Bạn cần đăng ký mô hình này vì chúng tôi đã bật các tính năng đăng ký mô hình.

Để đăng ký mô hình chạy trong psql hoặc Cloud SQL Studio, hãy sử dụng mã sau:

CALL
  google_ml.create_model(
    model_id => 'text-embedding-004',
    model_provider => 'google',
    model_qualified_name => 'text-embedding-004',
    model_type => 'text_embedding',
    model_auth_type => 'cloudsql_service_agent_iam',
    model_in_transform_fn => 'google_ml.vertexai_text_embedding_input_transform',
    model_out_transform_fn => 'google_ml.vertexai_text_embedding_output_transform');

Mô hình tiếp theo mà chúng ta cần đăng ký là gemini-2.0-flash-001. Mô hình này sẽ được dùng để tạo kết quả thân thiện với người dùng.

CALL
  google_ml.create_model(
    model_id => 'gemini-2.0-flash-001',
    model_request_url => 'https://us-central1-aiplatform.googleapis.com/v1/projects/$PROJECT_ID/locations/us-central1/publishers/google/models/gemini-2.0-flash-001:streamGenerateContent',
    model_provider => 'google',
    model_auth_type => 'cloudsql_service_agent_iam');

Bạn luôn có thể xác minh danh sách các mô hình đã đăng ký bằng cách chọn thông tin từ google_ml.model_info_view.

select model_id,model_type from google_ml.model_info_view;

Dưới đây là kết quả mẫu

quickstart_db=> select model_id,model_type from google_ml.model_info_view;
               model_id               |   model_type   
--------------------------------------+----------------
 textembedding-gecko                  | text_embedding
 textembedding-gecko@001              | text_embedding
 gemini-1.5-pro:streamGenerateContent | generic
 gemini-1.5-pro:generateContent       | generic
 gemini-1.0-pro:generateContent       | generic
 text-embedding-004                   | text_embedding
 gemini-2.0-flash-001                 | generic

Bây giờ, chúng ta có thể sử dụng dữ liệu được tạo trong truy vấn phụ JSON để cung cấp dữ liệu đó dưới dạng một phần của câu lệnh cho mô hình văn bản AI tạo sinh bằng SQL.

Trong phiên psql hoặc Cloud SQL Studio với cơ sở dữ liệu, hãy chạy truy vấn

WITH trees AS (
SELECT
        cp.product_name,
        cp.product_description AS description,
        cp.sale_price,
        cs.zip_code,
        cp.uniq_id AS product_id
FROM
        cymbal_products cp
JOIN cymbal_inventory ci ON
        ci.uniq_id = cp.uniq_id
JOIN cymbal_stores cs ON
        cs.store_id = ci.store_id
        AND ci.inventory>0
        AND cs.store_id = 1583
ORDER BY
        (cp.embedding <=> google_ml.embedding('text-embedding-004',
        'What kind of fruit trees grow well here?')::vector) ASC
LIMIT 1),
prompt AS (
SELECT
        'You are a friendly advisor helping to find a product based on the customer''s needs.
Based on the client request we have loaded a list of products closely related to search.
The list in JSON format with list of values like {"product_name":"name","product_description":"some description","sale_price":10}
Here is the list of products:' || json_agg(trees) || 'The customer asked "What kind of fruit trees grow well here?"
You should give information about the product, price and some supplemental information' AS prompt_text
FROM
        trees),
response AS (
SELECT
        json_array_elements(google_ml.predict_row( model_id =>'gemini-2.0-flash-001',
        request_body => json_build_object('contents',
        json_build_object('role',
        'user',
        'parts',
        json_build_object('text',
        prompt_text)))))->'candidates'->0->'content'->'parts'->0->'text' AS resp
FROM
        prompt)
SELECT
        string_agg(resp::text,
        ' ')
FROM
        response;

Và đây là kết quả dự kiến. Kết quả của bạn có thể khác nhau tuỳ thuộc vào phiên bản mô hình và các thông số.:

"That" "'s a great question! Based on your location (assuming you're" " in zip code 93230), I have a suggestion for a" " fruit tree that should thrive.\n\nWe have the **Cherry Tree** available.\n\n**Product Name:** Cherry Tree\n\n**Description:** This is a beautiful cherry" " tree that will produce delicious cherries. It's a deciduous tree (meaning it loses its leaves in the fall) growing to about 15 feet tall." " The leaves are dark green in summer, turning a beautiful red in the fall. Cherry trees are known for their beauty, shade, and privacy.\n\n**Sale Price:** $75.00\n\n**Important Considerations for Growing" " Cherry Trees:**\n\n* **Climate:** Cherry trees prefer a cool, moist climate, and 93230 falls within a suitable range (USDA zones 4-9). However, it's always a good idea to" " check the specific microclimate of your property (sun exposure, drainage etc.).\n* **Soil:** They do best in sandy soil. If your soil is different, you may need to amend it to improve drainage.\n* **Pollination:** Many cherry varieties require a second, compatible cherry tree for proper pollination" ". Check the specific pollination needs of this variety before purchase if you want a significant cherry yield.\n\nThis cherry tree is a beautiful addition to any yard and will provide you with delicious cherries if you can meet its needs. Would you like to know more about its pollination requirements, or perhaps see if we have any other" " fruit trees suitable for your area?\n" ""

10. Tạo chỉ mục kề cận

Tập dữ liệu của chúng tôi khá nhỏ và thời gian phản hồi chủ yếu phụ thuộc vào các lượt tương tác với mô hình AI. Tuy nhiên, khi bạn có hàng triệu vectơ, quá trình tìm kiếm vectơ có thể chiếm một phần đáng kể thời gian phản hồi và gây ra tải cao cho hệ thống. Để cải thiện điều đó, chúng ta có thể tạo một chỉ mục trên các vectơ của mình.

Tạo chỉ mục HNSW

Chúng ta sẽ thử loại chỉ mục HNSW cho kiểm thử. HNSW là viết tắt của Hierarchical Navigable Small World (Thế giới nhỏ có thể điều hướng theo phân cấp) và đại diện cho một chỉ mục biểu đồ nhiều lớp.

Để tạo chỉ mục cho cột nhúng, chúng ta cần xác định cột nhúng, hàm khoảng cách và các tham số không bắt buộc như m hoặc ef_constructions. Bạn có thể đọc chi tiết về các tham số này trong tài liệu.

CREATE INDEX cymbal_products_embeddings_hnsw ON cymbal_products
  USING hnsw (embedding vector_cosine_ops)
  WITH (m = 16, ef_construction = 64);

Kết quả đầu ra dự kiến:

quickstart_db=> CREATE INDEX cymbal_products_embeddings_hnsw ON cymbal_products
  USING hnsw (embedding vector_cosine_ops)
  WITH (m = 16, ef_construction = 64);
CREATE INDEX
quickstart_db=>

So sánh phản hồi

Bây giờ, chúng ta có thể chạy truy vấn tìm kiếm vectơ ở chế độ EXPLAIN (GIẢI THÍCH) và xác minh xem chỉ mục đã được sử dụng hay chưa.

EXPLAIN (analyze) 
WITH trees as (
SELECT
        cp.product_name,
        left(cp.product_description,80) as description,
        cp.sale_price,
        cs.zip_code,
        cp.uniq_id as product_id
FROM
        cymbal_products cp
JOIN cymbal_inventory ci on
        ci.uniq_id=cp.uniq_id
JOIN cymbal_stores cs on
        cs.store_id=ci.store_id
        AND ci.inventory>0
        AND cs.store_id = 1583
ORDER BY
        (cp.embedding <=> embedding('text-embedding-004','What kind of fruit trees grow well here?')::vector) ASC
LIMIT 1)
SELECT json_agg(trees) FROM trees;

Kết quả đầu ra dự kiến:

 Aggregate  (cost=779.12..779.13 rows=1 width=32) (actual time=1.066..1.069 rows=1 loops=1)
   ->  Subquery Scan on trees  (cost=769.05..779.12 rows=1 width=142) (actual time=1.038..1.041 rows=1 loops=1)
         ->  Limit  (cost=769.05..779.11 rows=1 width=158) (actual time=1.022..1.024 rows=1 loops=1)
               ->  Nested Loop  (cost=769.05..9339.69 rows=852 width=158) (actual time=1.020..1.021 rows=1 loops=1)
                     ->  Nested Loop  (cost=768.77..9316.48 rows=852 width=945) (actual time=0.858..0.859 rows=1 loops=1)
                           ->  Index Scan using cymbal_products_embeddings_hnsw on cymbal_products cp  (cost=768.34..2572.47 rows=941 width=941) (actual time=0.532..0.539 rows=3 loops=1)
                                 Order By: (embedding <=> '[0.008864171,0.03693164,-0.024245683,...
<redacted>
...,0.017593635,-0.040275685,-0.03914233,-0.018452475,0.00826032,-0.07372604
]'::vector)
                           ->  Index Scan using product_inventory_pkey on cymbal_inventory ci  (cost=0.42..7.17 rows=1 width=37) (actual time=0.104..0.104 rows=0 loops=3)
                                 Index Cond: ((store_id = 1583) AND (uniq_id = (cp.uniq_id)::text))
                                 Filter: (inventory > 0)
                                 Rows Removed by Filter: 1
                     ->  Materialize  (cost=0.28..8.31 rows=1 width=8) (actual time=0.133..0.134 rows=1 loops=1)
                           ->  Index Scan using product_stores_pkey on cymbal_stores cs  (cost=0.28..8.30 rows=1 width=8) (actual time=0.129..0.129 rows=1 loops=1)
                                 Index Cond: (store_id = 1583)
 Planning Time: 112.398 ms
 Execution Time: 1.221 ms

Từ kết quả, chúng ta có thể thấy rõ rằng truy vấn đang sử dụng "Index Scan using cymbal_products_embeddings_hnsw" (Quét chỉ mục bằng cymbal_products_embeddings_hnsw).

Và nếu chúng ta chạy truy vấn mà không có explain:

WITH trees as (
SELECT
        cp.product_name,
        left(cp.product_description,80) as description,
        cp.sale_price,
        cs.zip_code,
        cp.uniq_id as product_id
FROM
        cymbal_products cp
JOIN cymbal_inventory ci on
        ci.uniq_id=cp.uniq_id
JOIN cymbal_stores cs on
        cs.store_id=ci.store_id
        AND ci.inventory>0
        AND cs.store_id = 1583
ORDER BY
        (cp.embedding <=> embedding('text-embedding-004','What kind of fruit trees grow well here?')::vector) ASC
LIMIT 1)
SELECT json_agg(trees) FROM trees;

Kết quả đầu ra dự kiến:

[{"product_name":"Cherry Tree","description":"This is a beautiful cherry tree that will produce delicious cherries. It is an d","sale_price":75.00,"zip_code":93230,"product_id":"d536e9e823296a2eba198e52dd23e712"}]

Chúng ta có thể thấy kết quả vẫn giống nhau và trả về cùng một cây anh đào đứng đầu trong kết quả tìm kiếm mà không cần lập chỉ mục. Tuỳ thuộc vào các thông số và loại chỉ mục, kết quả có thể hơi khác. Trong quá trình kiểm thử, truy vấn được lập chỉ mục trả về kết quả trong 131.301 mili giây so với 167.631 mili giây mà không có chỉ mục nào, nhưng chúng tôi đang xử lý một tập dữ liệu rất nhỏ và sự khác biệt sẽ đáng kể hơn trên dữ liệu lớn hơn.

Bạn có thể thử nhiều chỉ mục có sẵn cho các vectơ cũng như các phòng thí nghiệm và ví dụ khác có tích hợp chuỗi ngôn ngữ trong tài liệu.

11. Dọn dẹp môi trường

Xoá phiên bản Cloud SQL

Huỷ phiên bản Cloud SQL khi bạn hoàn tất lớp học lập trình

Trong màn hình shell trên đám mây, hãy xác định biến môi trường và dự án nếu bạn đã bị ngắt kết nối và tất cả các chế độ cài đặt trước đó đều bị mất:

export INSTANCE_NAME=my-cloudsql-instance
export PROJECT_ID=$(gcloud config get-value project)

Xoá thực thể:

gcloud sql instances delete $INSTANCE_NAME --project=$PROJECT_ID

Kết quả đầu ra dự kiến trên bảng điều khiển:

student@cloudshell:~$ gcloud sql instances delete $INSTANCE_NAME --project=$PROJECT_ID
All of the instance data will be lost when the instance is deleted.

Do you want to continue (Y/n)?  y

Deleting Cloud SQL instance...done.                                                                                                                
Deleted [https://sandbox.googleapis.com/v1beta4/projects/test-project-001-402417/instances/my-cloudsql-instance].

12. Xin chúc mừng

Chúc mừng bạn đã hoàn thành lớp học lập trình này.

Nội dung đã đề cập

  • Cách triển khai phiên bản Cloud SQL cho PostgreSQL
  • Cách tạo cơ sở dữ liệu và bật tính năng tích hợp AI của Cloud SQL
  • Cách tải dữ liệu vào cơ sở dữ liệu
  • Cách sử dụng mô hình nhúng Vertex AI trong Cloud SQL
  • Cách làm phong phú kết quả bằng mô hình tạo sinh của Vertex AI
  • Cách cải thiện hiệu suất bằng chỉ mục vectơ

Thử lớp học lập trình tương tự cho AlloyDB với chỉ mục ScaNN thay vì HNSW

13. Khảo sát

Kết quả:

Bạn sẽ sử dụng hướng dẫn này như thế nào?

Chỉ đọc qua Đọc và hoàn thành bài tập