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 đạt được kết quả tốt nhất bằng cách sử dụng QueryData API. Bạn sẽ khám phá cách tạo ra kết quả chính xác và có thể lặp lại khi đưa ra yêu cầu bằng ngôn ngữ tự nhiên cho cơ sở dữ liệu của mình. Để giúp bạn đạt được mục tiêu này, hướng dẫn sẽ giới thiệu cho bạn 6 công thức trong nhiều chương, khám phá các khía cạnh khác nhau của ngôn ngữ tự nhiên sang SQL (NL2SQL) và các ứng dụng thực tế của nó.
Điều kiện tiên quyết
- Hiểu biết cơ bản về Google Cloud và Google Cloud Console
- 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 một cụm và phiên bản chính AlloyDB
- Cách bật QueryData, các hàm AI và Chế độ xem an toàn có tham số
- Cách tạo bộ bối cảnh QueryData
- Cách sử dụng các mẫu và bối cảnh khác nhau trong QueryData API
- Cách làm cho mẫu QueryData linh hoạt hơn bằng các khía cạnh
- Cách giải quyết sự mơ hồ về dữ liệu bằng tính năng tìm kiếm giá trị và lập chỉ mục trigram
- Cách sử dụng các hàm AI để tìm kiếm ngữ nghĩa bằng mẫu
- Cách sử dụng Khung hiển thị an toàn có tham số với QueryData API
Bạn cần có
- Tài khoản Google Cloud và dự án trên đám mây của Google Cloud
- Một trình duyệt web (chẳng hạn như Chrome) hỗ trợ Google Cloud Console và Cloud Shell
2. Thiết lập và yêu cầu
Thiết lập dự án
- Đăng nhập vào Google Cloud Console. 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.
Sử dụng tài khoản cá nhân thay vì tài khoản do nơi làm việc hoặc trường học cấp.
- Tạo một dự án mới hoặc sử dụng lại một dự án hiện có. Để tạo một dự án mới trong Cloud Console của Google, trong tiêu đề, hãy nhấp vào nút Chọn dự án. Thao tác này sẽ mở một cửa sổ bật lên.

Trong cửa sổ Chọn một dự án, hãy nhấp vào Dự án mới. Thao tác này sẽ mở một hộp thoại cho dự án mới.

Trong hộp thoại, hãy nhập tên dự án và chọn vị trí.

- Tên dự án là tên hiển thị của những người tham gia dự án này. Tên dự án không được các API của Google sử dụng và bạn có thể thay đổi tên này bất cứ lúc nào.
- Mã dự án là mã duy nhất trên tất cả các dự án trên Google Cloud và không thể thay đổi (bạn không thể thay đổi mã này sau khi đã đặt). Google Cloud Console tự động tạo một mã nhận dạng riêng biệt, nhưng bạn có thể tuỳ chỉnh mã này. Nếu không thích mã nhận dạng được tạo, bạn có thể tạo một mã nhận dạng ngẫu nhiên khác hoặc cung cấp mã nhận dạng của riêng bạn để kiểm tra xem mã đó có còn trống hay không. 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 của mình. Mã này thường được xác định bằng phần giữ chỗ PROJECT_ID.
- Để bạn biết, có một giá trị thứ ba là Số dự án mà một số API sử dụng. Tìm hiểu thêm về cả 3 giá trị này trong tài liệu.
Bật thanh toán
Thiết lập tài khoản thanh toán cá nhân
Nếu thiết lập thông tin thanh toán bằng tín dụng Google Cloud, bạn có thể bỏ qua bước này.
Để thiết lập tài khoản thanh toán cá nhân, hãy truy cập vào đây để bật tính năng thanh toán trong Cloud Console.
Một số lưu ý:
- Việc hoàn thành bài tập thực hành này sẽ tốn ít hơn 5 USD cho các tài nguyên trên Cloud.
- Bạn có thể làm theo các bước ở cuối bài thực hành này để xoá tài nguyên nhằm tránh bị tính thêm phí.
- Người dùng mới đủ điều kiện dùng thử miễn phí trị giá 300 USD.
Khởi động Cloud Shell
Mặc dù có thể vận hành 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 Cloud.
Trên 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:

Hoặc bạn có thể nhấn phím G rồi nhấn phím S. Trình tự này sẽ kích hoạt Cloud Shell nếu bạn đang ở trong Google Cloud Console hoặc sử dụng đường liên kết này.
Quá trình này chỉ mất vài phút để cung cấp và kết nối với môi trường. Khi quá trình này kết thúc, bạn sẽ thấy như sau:

Máy ảo này được trang bị tất cả các công cụ phát triển mà bạn cần. Nền tảng này cung cấp một thư mục chính có dung lượng 5 GB và chạy trên Google Cloud, giúp tăng cường đáng kể hiệu suất mạng và hoạt động xác thực. Bạn có thể thực hiện mọi thao tác trong lớp học lập trình này trong trình duyệt. Bạn không cần cài đặt bất cứ thứ gì.
3. Trước khi bắt đầu
Bật API
Để sử dụng AlloyDB, Compute Engine, các dịch vụ mạng và Nền tảng Agent, hãy bật các API tương ứng trong dự án trên đám mây của bạn.
Trong thiết bị đầu cuối Cloud Shell, hãy đảm bảo rằng bạn đã thiết lập mã dự án:
gcloud config get-value project
Lệnh này sẽ trả về mã dự án trên Google Cloud của bạn.
Đặt biến môi trường PROJECT_ID:
PROJECT_ID=$(gcloud config get-value project)
Bật các API bắt buộc:
gcloud services enable alloydb.googleapis.com \
compute.googleapis.com \
cloudresourcemanager.googleapis.com \
servicenetworking.googleapis.com \
geminidataanalytics.googleapis.com \
cloudaicompanion.googleapis.com \
aiplatform.googleapis.com \
dataplex.googleapis.com
Kết quả đầu ra 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 alloydb.googleapis.com \
compute.googleapis.com \
cloudresourcemanager.googleapis.com \
servicenetworking.googleapis.com \
geminidataanalytics.googleapis.com \
cloudaicompanion.googleapis.com \
aiplatform.googleapis.com \
dataplex.googleapis.com
Operation "operations/acat.p2-4470404856-1f44ebd8-894e-4356-bea7-b84165a57442" finished successfully.
Bạn có thể đọc về từng API đã bật trong tài liệu.
4. Triển khai AlloyDB
Tạo cụm và phiên bản chính AlloyDB. Bạn có thể triển khai bằng cách sử dụng một tập lệnh đã chuẩn bị sẵn để triển khai tất cả các tài nguyên cần thiết hoặc bạn có thể tự thực hiện từng bước theo tài liệu của AlloyDB.
Triển khai AlloyDB bằng tập lệnh tự động
Phương pháp này sử dụng một tập lệnh tự động để triển khai cụm AlloyDB và cung cấp các thông tin cấu hình cần thiết để bắt đầu làm việc với các tài nguyên đã triển khai.
Trong thiết bị đầu cuối Cloud Shell, hãy chạy lệnh để sao chép tập lệnh triển khai từ kho lưu trữ:
REPO_NAME="codelabs"
REPO_URL="https://github.com/GoogleCloudPlatform/$REPO_NAME"
SOURCE_DIR="alloydb-ai-nla"
git clone --no-checkout --filter=blob:none --depth=1 $REPO_URL
cd $REPO_NAME
git sparse-checkout set $SOURCE_DIR
git checkout
cd $SOURCE_DIR
Chạy tập lệnh triển khai:
./deploy_alloydb.sh
Tập lệnh này mất từ 5 đến 7 phút để hoàn tất. Kết quả sẽ hiển thị thông tin chi tiết về việc triển khai cụm. Xin lưu ý rằng mật khẩu của bạn sẽ khác – hãy ghi lại mật khẩu để sử dụng sau này.
... <redacted> ... Creating primary instance: alloydb-aip-01-pr (8 vCPUs for TRIAL cluster) Operation ID: operation-1765988049916-646282264938a-bddce198-9f248715 Creating instance...done. ---------------------------------------- Deployment Process Completed Cluster: alloydb-aip-01 (TRIAL) Instance: alloydb-aip-01-pr Region: us-central1 Initial Password: JBBoDTgixzYwYpkF (if new cluster) ----------------------------------------
Xem cụm và phiên bản mới của bạn trên trang Cụm AlloyDB trong Google Cloud Console.

5. Chuẩn bị cơ sở dữ liệu
Tạo cơ sở dữ liệu, bật chế độ tích hợp Nền tảng Tác nhân Gemini Enterprise, tạo các đối tượng cơ sở dữ liệu và thêm dữ liệu mẫu.
Cấp các quyền cần thiết cho AlloyDB
Cấp các vai trò IAM cần thiết cho tác nhân dịch vụ AlloyDB:
Mở một thẻ Cloud Shell mới bằng cách nhấp vào biểu tượng Thêm (+).

Trong thẻ mới, hãy chạy:
PROJECT_ID=$(gcloud config get-value project)
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:service-$(gcloud projects describe $PROJECT_ID --format="value(projectNumber)")@gcp-sa-alloydb.iam.gserviceaccount.com" \
--role="roles/aiplatform.user"
Kết quả đầu ra dự kiến trên bảng điều khiển:
student@cloudshell:~ (test-project-001-402417)$ PROJECT_ID=$(gcloud config get-value project) Your active configuration is: [cloudshell-11039] student@cloudshell:~ (test-project-001-402417)$ gcloud projects add-iam-policy-binding $PROJECT_ID \ --member="serviceAccount:service-$(gcloud projects describe $PROJECT_ID --format="value(projectNumber)")@gcp-sa-alloydb.iam.gserviceaccount.com" \ --role="roles/aiplatform.user" Updated IAM policy for project [test-project-001-402417]. bindings: - members: - serviceAccount:service-4470404856@gcp-sa-alloydb.iam.gserviceaccount.com role: roles/aiplatform.user - members: ... etag: BwYIEbe_Z3U= version: 1
Bật Data Access API
Bật Data Access API trên cụm AlloyDB.
Trong cùng thẻ dòng lệnh, hãy chạy lệnh sau:
PROJECT_ID=$(gcloud config get-value project)
REGION=us-central1
ADBCLUSTER=alloydb-aip-01
curl -X PATCH \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json" \
https://alloydb.googleapis.com/v1alpha/projects/$PROJECT_ID/locations/$REGION/clusters/$ADBCLUSTER/instances/$ADBCLUSTER-pr?updateMask=dataApiAccess \
-d '{
"dataApiAccess": "ENABLED",
}'
Cập nhật cờ cơ sở dữ liệu
Trước khi bật cờ ở cấp phiên bản, hãy đợi cho đến khi bước Data Access API (API truy cập dữ liệu) hoàn tất. Đảm bảo rằng trạng thái phiên bản của bạn có dấu đánh dấu màu xanh lục, như minh hoạ trong hình ảnh sau.

Để sử dụng các tiện ích AI và xác thực IAM cho các công cụ dựa trên tác nhân, bạn phải bật các cờ cơ sở dữ liệu cụ thể trên phiên bản và thêm chính mình làm người dùng cơ sở dữ liệu. Bật các cờ sau:
- alloydb.iam_authentication
- password.enforce_complexity
- google_ml_integration.enable_ai_query_engine
- parameterized_views
Trong cùng một thẻ dòng lệnh, hãy chạy các lệnh sau:
PROJECT_ID=$(gcloud config get-value project)
REGION=us-central1
ADBCLUSTER=alloydb-aip-01
gcloud beta alloydb instances update $ADBCLUSTER-pr \
--database-flags password.enforce_complexity=on,alloydb.iam_authentication=on,google_ml_integration.enable_ai_query_engine=on,parameterized_views.enabled=on \
--region=$REGION \
--cluster=$ADBCLUSTER \
--project=$PROJECT_ID \
--update-mode=FORCE_APPLY
Tạo người dùng IAM AlloyDB cho tài khoản của bạn:
REGION=us-central1
ADBCLUSTER=alloydb-aip-01
gcloud alloydb users create $(gcloud config get-value account) \
--cluster=$ADBCLUSTER \
--superuser=true \
--region=$REGION \
--type=IAM_BASED
Đóng thẻ bằng cách chạy lệnh thoát trong dòng lệnh:
exit
Kết nối với AlloyDB Studio
Trong các chương sau, bạn có thể chạy tất cả các lệnh SQL yêu cầu kết nối cơ sở dữ liệu trong AlloyDB Studio.
Để mở AlloyDB Studio, hãy thực hiện các bước sau:
- Trong Google Cloud Console, hãy chuyển đến trang Cụm cho AlloyDB cho PostgreSQL.
- Chọn phiên bản chính để mở giao diện web của phiên bản đó.

- Sau đó, nhấp vào AlloyDB Studio ở bên trái:

- Chọn cơ sở dữ liệu
postgres, chọn Xác thực IAM rồi nhấp vào Xác thực.

Thao tác này sẽ mở giao diện AlloyDB Studio.
- Chọn thẻ Untitled Query (Truy vấn chưa có tiêu đề) để mở trình chỉnh sửa SQL.

Thao tác này sẽ mở một trình chỉnh sửa nơi bạn có thể chạy các lệnh SQL, như trong hình sau:

Tạo cơ sở dữ liệu
Tạo cơ sở dữ liệu bắt đầu nhanh
Trong trình chỉnh sửa AlloyDB Studio, hãy chạy lệnh sau để tạo cơ sở dữ liệu:
CREATE DATABASE quickstart_db
Kết quả đầu ra dự kiến:
Statement executed successfully
Kết nối với quickstart_db
Nhấp vào Thay đổi cơ sở dữ liệu/người dùng trong AlloyDB Studio.

Chọn quickstart_db trong danh sách cơ sở dữ liệu, chọn Xác thực IAM rồi xác thực.

Thao tác này sẽ mở một kết nối mới để bạn có thể làm việc với các đối tượng trong cơ sở dữ liệu quickstart_db.
Bật tiện ích
Kiểm tra tất cả các tiện ích bắt buộc để xác minh rằng chúng được bật trong cơ sở dữ liệu của bạn và có phiên bản tối thiểu chính xác.
Xác minh rằng tất cả tiện ích bắt buộc đều có trong cơ sở dữ liệu của bạn:
SELECT extname, extversion FROM pg_extension WHERE extname IN ('vector', 'google_ml_integration', 'parameterized_views');
Kết quả đầu ra dự kiến:
extname | extversion -----------------------+---------------- google_ml_integration | 1.5.9 parameterized_views | 1.0 vector | 0.8.2.google-1
Nếu không trả về tất cả các hàng trên, tức là một số tiện ích chưa được bật.
Trước khi bật các tiện ích này, chúng ta cần đảm bảo rằng tất cả cờ cơ sở dữ liệu ,"google_ml_integration.enable_ai_query_engine" và "parameterized_views.enabled" đều được bật trên phiên bản.
Trong AlloyDB Studio, khi kết nối với quickstart_db, hãy thực thi:
show google_ml_integration.enable_ai_query_engine;
show parameterized_views.enabled;
Nếu bất kỳ mục nào trong số đó hiển thị "off" (tắt), hãy thử lặp lại bước "Cập nhật cờ cơ sở dữ liệu" và kiểm tra trạng thái bằng cách sử dụng lại các lệnh "show...".
Bật các tiện ích bắt buộc.
Trong AlloyDB Studio, khi kết nối với quickstart_db, hãy thực thi:
CREATE EXTENSION IF NOT EXISTS vector;
CREATE EXTENSION IF NOT EXISTS parameterized_views;
Kiểm tra các phiên bản tiện ích cho parameterized_views và google_ml.
Trong AlloyDB Studio, khi kết nối với quickstart_db, hãy thực thi:
SELECT extname, extversion FROM pg_extension WHERE extname IN ('vector', 'google_ml_integration', 'parameterized_views');
Kết quả đầu ra dự kiến:
extname | extversion -----------------------+---------------- google_ml_integration | 1.5.9 parameterized_views | 1.0 vector | 0.8.2.google-1
Nếu phiên bản thấp hơn phiên bản bắt buộc, hãy thử cập nhật tiện ích parameterized_views.
Đối với parameterized_views, hãy thử:
ALTER EXTENSION parameterized_views UPDATE;
Xác minh lại phiên bản.
Trong AlloyDB Studio, khi kết nối với quickstart_db, hãy thực thi:
SELECT extname, extversion FROM pg_extension WHERE extname IN ('vector', 'google_ml_integration', 'parameterized_views');
Kết quả đầu ra dự kiến:
extname | extversion -----------------------+---------------- google_ml_integration | 1.5.9 parameterized_views | 1.0 vector | 0.8.2.google-1
6. Dữ liệu mẫu
Bây giờ, bạn cần tạo các đối tượng trong cơ sở dữ liệu và tải dữ liệu. Bạn sẽ sử dụng một tập dữ liệu của công ty bất động sản hư cấu. Tệp này có dữ liệu giả định về việc bán tài sản và đại lý. Dữ liệu đã được cung cấp trong tập lệnh SQL real_estate_data.sql trong kho lưu trữ được sao chép.
Tạo bộ chứa Storage
Sử dụng Google SDK (gcloud) để nhập dữ liệu từ kho lưu trữ đã sao chép vào cơ sở dữ liệu AlloyDB. Bạn cần tạo một bộ chứa Cloud Storage cho việc đó và cấp quyền truy cập cho tài khoản dịch vụ AlloyDB. Ngoài ra, bạn luôn có thể thử thực hiện việc này bằng bảng điều khiển web, như mô tả trong tài liệu.
Trong cửa sổ dòng lệnh Google Cloud Shell, hãy thực thi:
PROJECT_ID=$(gcloud config get-value project)
REGION=us-central1
gcloud storage buckets create gs://$PROJECT_ID-import --project=$PROJECT_ID --location=$REGION
gcloud storage buckets add-iam-policy-binding gs://$PROJECT_ID-import --member="serviceAccount:service-$(gcloud projects describe $PROJECT_ID --format="value(projectNumber)")@gcp-sa-alloydb.iam.gserviceaccount.com" --role=roles/storage.objectViewer
Tải dữ liệu
Tệp kết xuất SQL của cơ sở dữ liệu nằm trong thư mục kho lưu trữ được sao chép. Lệnh sau đây giả định rằng bạn đã sử dụng thư mục chính làm điểm xuất phát khi sao chép kho lưu trữ ở bước trước trong khi tạo cụm AlloyDB.
Sao chép tệp kết xuất cơ sở dữ liệu vào nhóm Cloud Storage:
REPO_NAME="codelabs"
SOURCE_DIR="alloydb-ai-nla"
cd ~/$REPO_NAME/$SOURCE_DIR
gcloud storage cp ~/$REPO_NAME/$SOURCE_DIR/real_estate_data.sql gs://$PROJECT_ID-import
Nhập tập dữ liệu vào quickstart_db:
PROJECT_ID=$(gcloud config get-value project)
CLUSTER_NAME=alloydb-aip-01
REGION=us-central1
IAM_USER=$(gcloud config get-value account)
gcloud alloydb clusters import $CLUSTER_NAME --region=us-central1 --database=quickstart_db --gcs-uri=gs://$PROJECT_ID-import/real_estate_data.sql --project=$PROJECT_ID --sql --user=$IAM_USER
Lệnh này sẽ tải tập dữ liệu mẫu vào cơ sở dữ liệu quickstart_db.
Xác minh quá trình nhập bằng cách đếm các bản ghi trong bảng real_estate.agents bằng AlloyDB Studio:
SELECT COUNT(*) FROM real_estate.agents;
7. Chuẩn bị bản thể giản đồ
Thiết lập bộ bối cảnh QueryData, cung cấp siêu dữ liệu giản đồ và chạy tác nhân ADK.
Tạo siêu dữ liệu
Siêu dữ liệu bao gồm các chú thích SQL được áp dụng cho các bảng và cột trong cơ sở dữ liệu. Những nhận xét này hướng dẫn công cụ QueryData khi chọn các đối tượng cơ sở dữ liệu.
Nếu bạn đã nhập lược đồ dữ liệu bằng tệp trích xuất dữ liệu SQL được cung cấp, thì tất cả siêu dữ liệu đã được tạo trong lược đồ của bạn.
Sau đây là một đoạn mã ví dụ về siêu dữ liệu được áp dụng cho giản đồ real_estate:
COMMENT ON TABLE real_estate.agents IS 'Stores profile, contact, brokerage affiliation, and active status for individual real estate agents.'; COMMENT ON COLUMN real_estate.agents.agent_id IS 'Primary key uniquely identifying each real estate agent in the database.'; ...
Nếu đang làm việc với tập dữ liệu của riêng mình, bạn có thể làm theo hướng dẫn được ghi lại về cách thêm siêu dữ liệu cho giản đồ của bạn.
Tạo ngữ cảnh về bản thể học giản đồ
Tập hợp bối cảnh chứa các mẫu truy vấn, khía cạnh và cụm từ tìm kiếm giá trị giúp mô hình AI tạo truy vấn. Nếu không có bối cảnh, một tác nhân AI sẽ cố gắng tạo một truy vấn chỉ bằng cách sử dụng thông tin có sẵn từ giản đồ public, chủ yếu dựa trên tên bảng, cột và siêu dữ liệu để cố gắng suy ra các đối tượng phù hợp nhằm trả lời một yêu cầu truy vấn tự nhiên.
Tập hợp ngữ cảnh QueryData là một tệp JSON có các mẫu truy vấn, khía cạnh và lượt tìm kiếm giá trị. Bạn có thể xem các ví dụ khác nhau trong tài liệu.
Tải QueryData Context Set (Tập hợp ngữ cảnh QueryData) trong Web Console
Để tải một tập hợp bối cảnh, hãy mở AlloyDB Studio. Trong bảng điều khiển bên trái ở dưới cùng, bạn sẽ thấy biểu tượng Context sets và ba dấu chấm.

Nhấp vào biểu tượng ba dấu chấm đó rồi chọn Create context set.
Trong hộp thoại vừa mở, hãy nhập các giá trị sau:
- Tên:
sixrecipes - Thông tin mô tả:
Real Estate Query Data - Tải tệp ngữ cảnh lên: giữ trống
Khi bạn nhấn nút Create, có thể mất một chút thời gian để khởi tạo bộ nhớ bối cảnh nếu bạn thực hiện việc này lần đầu tiên.
Kiểm tra mã nhận dạng tập hợp bối cảnh QueryData bằng cách nhấp lại vào biểu tượng ba dấu chấm ở bên phải tên tập hợp bối cảnh rồi chọn Edit context set.

Mã nhận dạng tập hợp bối cảnh xuất hiện ở đầu thẻ đã mở ở bên phải

Lưu mã nhận dạng này để dùng cho các bước sau.
Bắt đầu sử dụng Tác nhân AI
Để tương tác với phụ trợ QueryData nhằm tạo và thực thi truy vấn, bạn có thể sử dụng giao diện AlloyDB Studio như mô tả trong tài liệu. Nhưng trong phòng thí nghiệm này, bạn sẽ sử dụng một tác nhân AI làm công cụ giao tiếp chính với cơ sở dữ liệu. Các tác nhân AI là một kịch bản thực tế hơn cho các khối lượng công việc trong tương lai và khung ADK của Google cung cấp một giao diện web tuyệt vời, nơi bạn có thể xem tất cả các bước và lượt tương tác giữa các mô hình, API và ứng dụng.
Xem lại cấu hình nguồn của tác nhân trong Cloud Shell:
REPO_NAME="codelabs"
SOURCE_DIR="alloydb-ai-nla"
cd ~/$REPO_NAME/$SOURCE_DIR/data_agent
edit agent.py
Trong tệp này, bạn có thể thấy nơi chúng ta xác định danh sách các bảng trong giản đồ. Chúng ta sẽ quay lại vấn đề đó ở một trong các bước sau này.
# List of database tables included in QueryData API requests
TABLE_IDS = [
"real_estate.municipalities",
"real_estate.cities",
"real_estate.agents",
"real_estate.properties",
"real_estate.schools",
"real_estate.school_to_property",
"real_estate.property_transactions",
"real_estate.secure_offers",
]
Ngoài ra, còn có một quy trình call_querydata_api để làm việc với QueryData API cùng với một bộ công cụ để làm việc với các kỹ năng QueryData API.
def call_querydata_api(
prompt: str,
target_project_id: str = project_id,
target_location: str = location,
target_cluster_id: str = cluster_name,
target_instance_id: str = instance_name,
target_database_id: str = database_name,
target_context_set_id: str = context_set_id,
target_table_ids: list[str] = TABLE_IDS,
) -> dict:
"""Calls the Gemini Data Analytics QueryData API to translate natural ...
<Redacted>
...
# ADK File-Based Skill
database_query_skill = load_skill_from_dir(
pathlib.Path(__file__).parent / "skills" / "database-query-skill"
)
skill_toolset = SkillToolset(
skills=[database_query_skill]
)
Đây là chính tác nhân gốc với một câu lệnh và các công cụ có sẵn.
# Agent configuration
root_agent = Agent(
model=MODEL_ID,
name='root_agent',
description='A helpful assistant for analyst requests.',
instruction=f"""
Answer user questions to the best of your knowledge using provided tools.
Do not try to generate non-existent data but use the grounded data from the database.
When you answer questions about database contents, real estate properties, or sales activity:
1. Refer to database-query-skill for instructions on querying data using QueryData API.
2. Use `call_querydata_api` to submit the natural language prompt to the QueryData API.
CRITICAL: Call `call_querydata_api` EXACTLY ONCE per user request. Do NOT make retries, follow-up calls, or rephrased calls to `call_querydata_api`, even if the result contains zero rows or empty data.
3. Immediately parse the JSON response from that first `call_querydata_api` call.
4. Format your final response to the user containing:
- The generated SQL query (formatted in a Markdown SQL code block).
- The query results formatted as a Markdown table (constructed from `queryResult.columns` and `queryResult.rows`).
- The natural language answer (`naturalLanguageAnswer`).
""",
tools=[call_querydata_api, skill_toolset],
)
Xem lại data_agent/SKILL.md để hiểu chỉ dẫn hệ thống của tác nhân:
REPO_NAME="codelabs"
SOURCE_DIR="alloydb-ai-nla"
cd ~/$REPO_NAME/$SOURCE_DIR/data_agent
edit SKILL.md
Trước khi bắt đầu tác nhân, bạn cần chuẩn bị một tệp .env có các tham số cho yêu cầu API Agent và QueryData.
Xuất mã nhận dạng tập hợp bối cảnh sang một biến môi trường:
export QUERYDATA_CONTEXTSET=<context set id from the Create Context Set chapter>
Tạo tệp cấu hình môi trường thời gian chạy (.env) trong thư mục data_agent:
PROJECT_ID=$(gcloud config get-value project)
REGION=us-central1
REPO_NAME="codelabs"
SOURCE_DIR="alloydb-ai-nla"
cd ~/$REPO_NAME/$SOURCE_DIR/data_agent
echo "GOOGLE_GENAI_USE_ENTERPRISE=true" > .env
echo "GOOGLE_CLOUD_PROJECT=$(gcloud config get-value project -q)" >> .env
echo "GOOGLE_CLOUD_LOCATION=global" >> .env
echo "QUERYDATA_CONTEXTSET=$QUERYDATA_CONTEXTSET" >> .env
echo "ALLOYDB_CLUSTER=alloydb-aip-01" >> .env
echo "ALLOYDB_INSTANCE=alloydb-aip-01-pr" >> .env
echo "ALLOYDB_DATABASE=quickstart_db" >> .env
echo "ALLOYDB_LOCATION=$REGION" >> .env
Cài đặt các phần phụ thuộc và khởi động dịch vụ web của tác nhân:
cd ~/$REPO_NAME/$SOURCE_DIR/
uv sync
Khởi động tác nhân:
uv run adk web --allow_origins 'regex:https://.*\.cloudshell\.dev'
Bạn sẽ thấy kết quả đầu ra như sau với điểm cuối http://127.0.0.1:8000 .
INFO: Started server process [83608] INFO: Waiting for application startup. +-----------------------------------------------------------------------------+ | ADK Web Server started | | | | For local testing, access at http://127.0.0.1:8000. | +-----------------------------------------------------------------------------+ INFO: Application startup complete. INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)

Nhấp vào URL máy chủ web đã tạo (ví dụ: http://127.0.0.1:8000) trong Cloud Shell để chạy giao diện tác nhân. Nếu cách này không hiệu quả, trong Cloud Shell, hãy nhấp vào Web Preview (Xem trước trên web) -> Preview on port 8000 (Xem trước trên cổng 8000) để mở giao diện của tác nhân.
Kiểm tra để đảm bảo bạn đã chọn data_agent trong trình đơn thả xuống ở trên cùng bên trái.

Tạo và chạy truy vấn
Hãy chạy truy vấn Q1
Chạy câu lệnh bằng ngôn ngữ tự nhiên này trong giao diện trò chuyện của tác nhân để đánh giá hiệu suất QueryData cơ bản mà không cần các mẫu hoặc khía cạnh tuỳ chỉnh:
How many properties are currently for sale in San Diego?
Sau đó nhấn vào nút mũi tên.

Thao tác này sẽ bắt đầu quy trình làm việc của tác nhân khi tác nhân chọn kỹ năng phù hợp và sử dụng kỹ năng đó cùng hàm để gửi yêu cầu đến điểm cuối API, đồng thời nhận lại truy vấn và kết quả đã tạo.

Và nếu di con trỏ chuột lên các bước, bạn có thể thấy chính xác những gì các bước đó đã làm. Bạn cũng có thể thấy điều đó và nhiều thông tin khác trong bảng điều khiển bên trái khi chọn một bước nào đó. Bạn có thể tìm hiểu cách các tác nhân hoạt động với kỹ năng và API.

Gửi câu hỏi tiếp theo (Q2):
List agents who sold a property for over $1000000.
Bạn sẽ nhận thấy rằng tác nhân chuyển thẳng đến kỹ năng QueryData API vì tác nhân đã ghi các kỹ năng có sẵn vào bộ nhớ và không cần trải qua giai đoạn khám phá nữa.
SQL được tạo sẽ có dạng như câu lệnh sau:
SELECT DISTINCT "a"."agent_id", "a"."firstname", "a"."lastname", "a"."email", "a"."brokerage" FROM "real_estate"."agents" AS "a" INNER JOIN "real_estate"."property_transactions" AS "t" ON "a"."agent_id" = "t"."seller_agent_id" WHERE "t"."sale_price" > 1000000 AND "a"."agent_id" IS NOT NULL ORDER BY "a"."lastname" ASC NULLS LAST;
Thử một cụm từ tìm kiếm khác (Q3):
What is the average price of a single-family home with a garage in San Diego?
QueryData tạo các truy vấn tiêu chuẩn với một tập hợp ngữ cảnh trống, nhưng các tác vụ kinh doanh thường yêu cầu logic nghiệp vụ cụ thể và hành vi xác định.
8. Đạt được độ chính xác cao và mức độ phù hợp với doanh nghiệp bằng cách chèn nội dung diễn giải
Việc chèn nội dung diễn giải vào câu lệnh đảm bảo rằng các cụm từ tìm kiếm được tạo khớp với logic nghiệp vụ cụ thể.
Bạn sẽ thử một ví dụ như vậy với một khách hàng yêu cầu tìm nhà một tầng ở Del Mar. Câu hỏi này có 2 chỉ số quan trọng và thể hiện một mẫu hình thường gặp để lựa chọn.
Hãy thử câu lệnh bằng ngôn ngữ tự nhiên sau đây (Q4) trong tác nhân.
Single level Del Mar houses
Công cụ này trả về một truy vấn chung, nhưng có thể bao gồm một số điều kiện bổ sung như is_single_family = TRUE:
SELECT p."property_id", p."address_street", p."price", p."bedrooms", p."bathrooms", p."listing_status", p."is_single_family", p."num_stories", c."city_name" FROM "real_estate"."properties" AS p JOIN "real_estate"."cities" AS c ON p."city_id" = c."city_id" WHERE c."city_name" ILIKE 'Del Mar' AND p."num_stories" = 1 AND p."is_single_family" = TRUE ORDER BY p."property_id" ASC NULLS LAST;
Chúng ta sẽ nhận được một hàng được trả về làm kết quả:
Natural Language Answer The database contains one single-level, single-family house in Del Mar: Address: 999 Main Ave (Postal Code: 90024) Price: $3,800,000.00 Bedrooms: 4 Bathrooms: 3.5 Listing Status: Active Features: Single-family home (1 story), has a garage, and no condo fees.
Thử một câu lệnh khác (Q5):
Del Mar houses close to good schools
Công cụ này đủ thông minh để sử dụng các cột proximity_miles và school_ranking để sắp xếp các thuộc tính nhưng không đánh giá trọng số và tầm quan trọng của từng chỉ số.
SELECT "p"."property_id", "p"."address_street", "p"."price", "p"."bedrooms", "p"."bathrooms", "s"."school_name", "s"."school_ranking", "sp"."proximity_miles" FROM "real_estate"."properties" AS "p" INNER JOIN "real_estate"."cities" AS "c" ON "p"."city_id" = "c"."city_id" INNER JOIN "real_estate"."school_to_property" AS "sp" ON "p"."property_id" = "sp"."property_id" INNER JOIN "real_estate"."schools" AS "s" ON "sp"."school_id" = "s"."school_id" WHERE "c"."city_name" = 'Del Mar' AND "sp"."proximity_miles" IS NOT NULL AND "s"."school_ranking" IS NOT NULL ORDER BY "sp"."proximity_miles" ASC NULLS LAST, "s"."school_ranking" ASC NULLS LAST;
Tổng quát hoá truy vấn mẫu thành một mẫu
Logic nghiệp vụ yêu cầu:
- Trong phạm vi 2 dặm
- Xếp hạng trường học từ 5 trở xuống
- Sắp xếp có trọng số: 80% thứ hạng trường học + 20% khoảng cách (Điểm = 0,8 * thứ hạng_trường_học + 0,2 * khoảng_cách_tính_bằng_dặm)
Sau đây là công thức xếp hạng có trọng số:
Score = 0.8 * school_ranking + 0.2 * proximity_miles
Tải tệp ngữ cảnh sixrecipe_context1_1.json xuống từ Cloud Shell bằng giao diện dòng lệnh trong Cloud Shell:
cloudshell download ~/codelabs/alloydb-ai-nla/sixrecipe_context1_1.json
Hoặc bằng cách sử dụng mục Download trong trình đơn Cloud Shell:

Tải sixrecipe_context1_1.json lên tập hợp ngữ cảnh sixrecipe bằng AlloyDB Studio để xác định cấu trúc tiêu chuẩn này. Nhấp vào biểu tượng ba dấu chấm ở bên phải ngữ cảnh sixrecipes rồi dùng "Chỉnh sửa bộ ngữ cảnh" để tải tệp mới lên. Thao tác này sẽ thay thế ngữ cảnh trống cũ bằng ngữ cảnh mới một cách hiệu quả.
Mẫu này xác định các quy tắc mẫu SQL rõ ràng cho các quy tắc lân cận trường học phù hợp:
{
"facets": [],
"templates": [
{
"nl_query": "Riverside houses close to good schools.",
"sql": "SELECT \"p\".\"address_street\", \"p\".\"address_postal_code\", \"s\".\"school_name\", \"stp\".\"proximity_miles\" FROM \"real_estate\".\"properties\" AS \"p\" JOIN \"real_estate\".\"cities\" AS \"c\" ON \"p\".\"city_id\" = \"c\".\"city_id\" JOIN \"real_estate\".\"school_to_property\" AS \"stp\" ON \"p\".\"property_id\" = \"stp\".\"property_id\" JOIN \"real_estate\".\"schools\" AS \"s\" ON \"stp\".\"school_id\" = \"s\".\"school_id\" WHERE \"c\".\"city_name\" = 'Riverside' AND \"s\".\"school_ranking\" <= 5 AND \"stp\".\"proximity_miles\" <= 2 ORDER BY 0.8 * \"s\".\"school_ranking\" + 0.2 * \"stp\".\"proximity_miles\"",
"intent": "Houses in Riverside close to good schools (within 2 miles of schools with a rank of at least 5).",
"manifest": "A given city houses close to good schools.",
"parameterized": {
"parameterized_intent": "Houses in $1 close to good schools (within 2 miles of schools with a rank of at least 5).",
"parameterized_sql": "SELECT \"p\".\"address_street\", \"p\".\"address_postal_code\", \"s\".\"school_name\", \"stp\".\"proximity_miles\" FROM \"real_estate\".\"properties\" AS \"p\" JOIN \"real_estate\".\"cities\" AS \"c\" ON \"p\".\"city_id\" = \"c\".\"city_id\" JOIN \"real_estate\".\"school_to_property\" AS \"stp\" ON \"p\".\"property_id\" = \"stp\".\"property_id\" JOIN \"real_estate\".\"schools\" AS \"s\" ON \"stp\".\"school_id\" = \"s\".\"school_id\" WHERE \"c\".\"city_name\" = $1 AND \"s\".\"school_ranking\" <= 5 AND \"stp\".\"proximity_miles\" <= 2 ORDER BY 0.8 * \"s\".\"school_ranking\" + 0.2 * \"stp\".\"proximity_miles\""
}
}
]
}
Chạy lại câu lệnh:
Del Mar houses close to good schools
Giờ đây, truy vấn kết quả sẽ khớp với logic nghiệp vụ được xác định trong mẫu:
SELECT "p"."address_street", "p"."address_postal_code", "s"."school_name", "stp"."proximity_miles" FROM "real_estate"."properties" AS "p" JOIN "real_estate"."cities" AS "c" ON "p"."city_id" = "c"."city_id" JOIN "real_estate"."school_to_property" AS "stp" ON "p"."property_id" = "stp"."property_id" JOIN "real_estate"."schools" AS "s" ON "stp"."school_id" = "s"."school_id" WHERE "c"."city_name" = 'Del Mar' AND "s"."school_ranking" <= 5 AND "stp"."proximity_miles" <= 2 ORDER BY 0.8 * "s"."school_ranking" + 0.2 * "stp"."proximity_miles"
Cùng với câu lệnh SQL được tạo, ý định sau đây cũng được tạo:
intentExplanation: "Houses in Del Mar close to good schools (within 2 miles of schools with a rank of at least 5)."
Bạn có thể thấy ý định trên ngăn bên trái của giao diện web ADK như minh hoạ ở đây:

Kết quả cho thấy 2 tài sản được sắp xếp theo Điểm số của chúng tôi:
Query Results address_street address_postal_code school_name proximity_miles 200 Coast Blvd 92014 Del Mar Heights Elementary 0.50 100 Del Mar Heights Rd 92014 Del Mar Heights Elementary 1.00 Answer Based on the data, here are the properties in Del Mar located within 2 miles of a top-rated school (ranking of 5 or better): 200 Coast Blvd (92014) School: Del Mar Heights Elementary Proximity: 0.50 miles 100 Del Mar Heights Rd (92014) School: Del Mar Heights Elementary Proximity: 1.00 miles
Trong chương tiếp theo, bạn sẽ mở rộng phạm vi cho mẫu.
Chèn nội dung diễn giải bằng cách ghi lại và diễn giải nhiều câu hỏi
Bạn có thể mở rộng phạm vi sử dụng mẫu của chúng tôi không chỉ cho "gần các trường học tốt" mà còn thêm các điều kiện khác vào tệp kê khai để sử dụng cho ví dụ như "nhà dành cho gia đình có trẻ em".
Tải tệp ngữ cảnh đã cập nhật xuống:
cloudshell download ~/codelabs/alloydb-ai-nla/sixrecipe_context1_2.json
Tải tệp sixrecipe_context1_2.json đã cập nhật lên tập hợp bối cảnh của bạn.
Trong tệp tập hợp bối cảnh mới, chúng ta sẽ thay thế tệp kê khai từ: "manifest": "A given city houses close to good schools." sang tệp kê khai: "manifest": "A given city houses close to good schools, or are great for families with kids.". Điều này giúp mở rộng phạm vi ứng dụng của mẫu này, không chỉ dùng cho một trường hợp.
Gửi truy vấn này (Q6):
Houses in Waterloo great for families with kids.
Tác nhân sử dụng tệp kê khai mẫu đã cập nhật để áp dụng logic truy vấn được chuẩn hoá, trả về cùng một truy vấn như trên, với ý định:
intentExplanation : "Houses in Waterloo close to good schools (within 2 miles of schools with a rank of at least 5)."
9. Sử dụng Mẫu phân loại để đạt được độ chính xác cao mà vẫn linh hoạt
Khía cạnh là các điều kiện SQL theo mô-đun được kết hợp linh hoạt với các mẫu để xử lý các tiêu chí phân loại (ví dụ: "dành cho gia đình mới", "nhìn ra biển") mà không cần tạo các mẫu riêng cho từng hoán vị.
Thay vì tạo một mẫu cho mỗi truy vấn hoặc điều kiện, chúng ta có thể chuẩn bị các đoạn mã có thể áp dụng cho các mẫu hiện có, thêm nhiều phương diện hơn vào truy vấn.
Xác định một khía cạnh cho các thuộc tính có những thuộc tính sau:
- Nhà dành cho một hộ gia đình
- Trạng thái trang thông tin đang hoạt động
- Từ 3 đến 4 phòng ngủ và ít nhất 2 phòng tắm
- Địa điểm nằm trong một đô thị có tỷ lệ tội phạm dưới 500 trên 100.000 cư dân
Tải tệp ngữ cảnh có nhiều khía cạnh xuống:
cloudshell download ~/codelabs/alloydb-ai-nla/sixrecipe_context2_1.json
Tải sixrecipe_context2_1.json lên tập hợp ngữ cảnh sixrecipes trong AlloyDB Studio để định cấu hình các khía cạnh.
"facets": [
{
"sql_snippet": "real_estate.properties.is_single_family = TRUE AND real_estate.properties.listing_status = 'Active' AND real_estate.properties.bedrooms BETWEEN 3 AND 4 AND real_estate.properties.bathrooms >= 2.0 AND 500 > (SELECT m.crime_rate_per_100k FROM real_estate.cities c JOIN real_estate.municipalities m ON c.municipality_id = m.municipality_id AND c.city_id = real_estate.properties.city_id)",
"intent": "for a starter family (active single-family home listings with 3 to 4 bedrooms, 2+ bathrooms, and a crime rate under 500 per 100,000 residents)",
"manifest": "for a starter family",
"parameterized": {
"parameterized_intent": "for a starter family (active single-family home listings with 3 to 4 bedrooms, 2+ bathrooms, and a crime rate under 500 per 100,000 residents)",
"parameterized_sql_snippet": "real_estate.properties.is_single_family = TRUE AND real_estate.properties.listing_status = 'Active' AND real_estate.properties.bedrooms BETWEEN 3 AND 4 AND real_estate.properties.bathrooms >= 2.0 AND 500 > (SELECT m.crime_rate_per_100k FROM real_estate.cities c JOIN real_estate.municipalities m ON c.municipality_id = m.municipality_id AND c.city_id = real_estate.properties.city_id)"
}
}
]
Truy vấn bằng tính năng tìm kiếm theo khía cạnh
Chạy truy vấn bằng ngôn ngữ tự nhiên này (Q7):
Del Mar houses close to good schools for a starter family.
Công cụ này sẽ thêm trực tiếp các điều kiện về khía cạnh vào truy vấn cơ sở:
SELECT "p"."address_street", "p"."address_postal_code", "s"."school_name", "stp"."proximity_miles"
FROM "real_estate"."properties" AS "p"
JOIN "real_estate"."cities" AS "c" ON "p"."city_id" = "c"."city_id"
JOIN "real_estate"."school_to_property" AS "stp" ON "p"."property_id" = "stp"."property_id"
JOIN "real_estate"."schools" AS "s" ON "stp"."school_id" = "s"."school_id"
WHERE "c"."city_name" = 'Del Mar'
AND "s"."school_ranking" <= 5
AND "stp"."proximity_miles" <= 2
AND "p"."is_single_family" = TRUE
AND "p"."listing_status" = 'Active'
AND "p"."bedrooms" BETWEEN 3 AND 4
AND "p"."bathrooms" >= 2.0
AND 500 > (
SELECT m.crime_rate_per_100k
FROM real_estate.cities c
JOIN real_estate.municipalities m ON c.municipality_id = m.municipality_id
AND c.city_id = p.city_id
)
ORDER BY 0.8 * "s"."school_ranking" + 0.2 * "stp"."proximity_miles"
Sau đây là kết quả:
Query Results address_street address_postal_code school_name proximity_miles 200 Coast Blvd 92014 Del Mar Heights Elementary 0.50 Natural Language Answer Based on your criteria, there is an active listing for a single-family house in Del Mar that fits your needs: Address: 200 Coast Blvd, Del Mar, 92014 Nearby School: Del Mar Heights Elementary (ranked within the top 5) Proximity to School: 0.50 miles
Thêm các khía cạnh khác
Nếu chúng ta muốn thêm một phương diện khác dựa trên mẫu mới nổi – chẳng hạn như khung hiển thị cửa sổ cho thuộc tính thì sao?
Thêm tính năng so khớp ngữ nghĩa chế độ xem đại dương vào định nghĩa khía cạnh.
{
"sql_snippet": "((real_estate.properties.description_embedding <=> google_ml.embedding('gemini-embedding-001', 'unobstructed, panoramic, ocean vista, vast Pacific, breathtaking, commanding view, deep blue horizon, massive, sweeping view')::vector) < 0.4)",
"intent": "with ocean view",
"manifest": "with ocean view",
"parameterized": {
"parameterized_intent": "with ocean view",
"parameterized_sql_snippet": "((real_estate.properties.description_embedding <=> google_ml.embedding('gemini-embedding-001', 'unobstructed, panoramic, ocean vista, vast Pacific, breathtaking, commanding view, deep blue horizon, massive, sweeping view')::vector) < 0.4)"
}
Giá trị 0,4 trong định nghĩa về khía cạnh ở trên là một ngưỡng được hiệu chỉnh theo thực nghiệm. Tải tệp ngữ cảnh đa khía cạnh xuống:
cloudshell download ~/codelabs/alloydb-ai-nla/sixrecipe_context2_2.json
Tải sixrecipe_context2_2.json lên tập hợp bối cảnh của bạn và chạy câu lệnh này (Q8):
Ocean view Del Mar homes near good schools.
Kết quả chứa các điều kiện tiêu chuẩn kết hợp với tính năng so khớp độ tương tự của vectơ thông qua google_ml.embedding:
SELECT "p"."address_street", "p"."address_postal_code", "s"."school_name", "stp"."proximity_miles"
FROM "real_estate"."properties" AS "p"
JOIN "real_estate"."cities" AS "c" ON "p"."city_id" = "c"."city_id"
JOIN "real_estate"."school_to_property" AS "stp" ON "p"."property_id" = "stp"."property_id"
JOIN "real_estate"."schools" AS "s" ON "stp"."school_id" = "s"."school_id"
WHERE "c"."city_name" = 'Del Mar' AND "s"."school_ranking" <= 5 AND "stp"."proximity_miles" <= 2
AND (((p.description_embedding <=> google_ml.embedding('gemini-embedding-001', 'unobstructed, panoramic, ocean vista, vast Pacific, breathtaking, commanding view, deep blue horizon, massive, sweeping view')::vector) <= 0.4))
ORDER BY 0.8 * "s"."school_ranking" + 0.2 * "stp"."proximity_miles";
Truy vấn này trả về một thuộc tính:
Query Results address_street address_postal_code school_name proximity_miles 100 Del Mar Heights Rd 92014 Del Mar Heights Elementary 1.00 Answer The ocean-view home in Del Mar near a top-ranked school is located at 100 Del Mar Heights Rd (92014). It is situated just 1.00 mile away from Del Mar Heights Elementary, which is one of the area's highly-ranked schools (ranking of 5 or better).
Xác minh kết quả bằng cách kiểm tra nội dung mô tả của thuộc tính trong AlloyDB Studio và chạy truy vấn sau:
select description from real_estate.properties where address_postal_code='92014' and description is not null;
Nội dung mô tả sẽ có đoạn "cảnh tượng biển cả hùng vĩ".
Well-located 2-bedroom condo with excellent proximity to coastal shopping and dining. The balcony provides a magnificent marine spectacle against an azure backdrop. Under contract, high monthly HOA fee.
10. Phân biệt dữ liệu riêng tư của bạn bằng cách sử dụng tính năng Tìm kiếm giá trị
Các yêu cầu không rõ ràng có thể khớp với nhiều thực thể, chẳng hạn như nhầm lẫn tên vị trí với tên doanh nghiệp. Các cụm từ tìm kiếm giá trị ánh xạ các thuật ngữ sang các khái niệm trong cơ sở dữ liệu để giúp giải quyết những thông tin tham chiếu này.
Tính năng tìm kiếm giá trị cung cấp mối liên kết giữa tên cột cộng với các giá trị trong cột và một loại khái niệm, chẳng hạn như thành phố, quốc gia hoặc tên. Vì đã lập chỉ mục không chỉ siêu dữ liệu mà còn cả các mẫu dữ liệu đại diện trong một cột, nên tính năng này có thể liên kết một giá trị được dùng trong yêu cầu bằng ngôn ngữ tự nhiên với một loại khái niệm tiềm năng, cũng như bảng và cột có thể được dùng trong SQL kết quả.
Tính mơ hồ trong một truy vấn
Trong thực tế, việc này có thể còn khó khăn hơn do lỗi chính tả của các tên và vị trí khác nhau. Chạy câu lệnh này (Q9) có chứa lỗi chính tả và thuật ngữ mơ hồ:
Westwod's sold properties in the last 1 month.
Có hai vấn đề ở đây: tên bị sai chính tả và không rõ liệu chúng ta đang nói về các tài sản được bán ở vị trí có tên tương tự hay về một công ty bất động sản. Khi chúng ta chạy truy vấn, truy vấn sẽ trả về một truy vấn như sau.
SELECT "p"."property_id", "p"."address_street", "p"."address_postal_code", "p"."price" AS "listing_price", "p"."bedrooms", "p"."bathrooms", "p"."listing_status", "pt"."sale_date", "pt"."sale_price", "c"."city_name" FROM "real_estate"."properties" AS "p" INNER JOIN "real_estate"."property_transactions" AS "pt" ON "p"."property_id" = "pt"."property_id" INNER JOIN "real_estate"."cities" AS "c" ON "p"."city_id" = "c"."city_id" WHERE ("c"."city_name" ILIKE '%Westwood%' OR "c"."city_name" ILIKE '%Westwod%') AND "pt"."sale_date" >= '2025-09-01'::date AND "pt"."sale_date" <= '2025-09-30'::date ORDER BY "pt"."sale_date" DESC NULLS LAST, "pt"."sale_price" DESC NULLS LAST
AI đã sửa tên và giả định rằng câu hỏi là về vị trí của cơ sở lưu trú, cố gắng so khớp các cơ sở lưu trú ở thành phố Westwood.
Bật tiện ích pg_trgm trong AlloyDB Studio để hỗ trợ so sánh chuỗi tương tự:
CREATE EXTENSION IF NOT EXISTS pg_trgm;
Sau đó, chúng ta có thể sử dụng tiện ích này để thêm các tìm kiếm giá trị vào tập hợp ngữ cảnh QueryData.
Sau đây là danh sách các cụm từ tìm kiếm giá trị mà chúng tôi muốn sử dụng:
"value_searches": [
{
"conceptType": "Municipality name",
"query": "/* Requires extension: pg_trgm */ WITH TrigramMetrics AS (SELECT T.municipality_name AS original_value, (T.municipality_name % $value::text) AS normalized_dist FROM real_estate.municipalities T WHERE T.municipality_name % $value::text) SELECT original_value AS value, 'real_estate.municipalities.municipality_name' AS columns, 'Name of the municipality' AS concept_type, normalized_dist AS distance, ''::text AS context FROM TrigramMetrics",
"description": "Trigram match for municipality name"
},
{
"conceptType": "City name",
"query": "/* Requires extension: pg_trgm */ WITH TrigramMetrics AS (SELECT T.city_name AS original_value, (T.city_name % $value::text) AS normalized_dist FROM real_estate.cities T WHERE T.city_name % $value::text) SELECT original_value AS value, 'real_estate.cities.city_name' AS columns, 'Name of the city' AS concept_type, normalized_dist AS distance, ''::text AS context FROM TrigramMetrics",
"description": "Trigram match for city name"
},
{
"conceptType": "Brokerage name",
"query": "/* Requires extension: pg_trgm */ WITH TrigramMetrics AS (SELECT T.brokerage AS original_value, (T.brokerage % $value::text) AS normalized_dist FROM real_estate.agents T WHERE T.brokerage % $value::text) SELECT original_value AS value, 'real_estate.agents.brokerage' AS columns, 'Name of the brokerage' AS concept_type, normalized_dist AS distance, ''::text AS context FROM TrigramMetrics",
"description": "Trigram match for brokerage name"
}
]
Tải tệp ngữ cảnh tìm kiếm giá trị xuống:
cloudshell download ~/codelabs/alloydb-ai-nla/sixrecipe_context3_1.json
Tải sixrecipe_context3_1.json lên bộ ngữ cảnh QueryData sixrecipes rồi lưu lại.
Chạy lại câu lệnh (Q9):
Westwod's sold properties in the last 1 month.
Công cụ này đã trả về một câu trả lời làm rõ vì trong quá trình tìm kiếm giá trị, công cụ này tìm thấy 3 thực thể khác nhau có giá trị tương tự:
The database requires some clarification to provide the exact information you need: The search term 'Westwod' (Westwood) is ambiguous because it can refer to: A municipality name (e.g., the municipality of Westwood) A city name (e.g., the city of Westwood) A brokerage name (e.g., properties sold by agents affiliated with the Westwood brokerage) Could you please clarify which of these you are referring to?
Dấu vết này cho chúng ta biết lý do tại sao nó chọn đường dẫn cụ thể đó

Sau đây là toàn văn:
"[NOT_ENOUGH_INFO] The search term 'Westwod' is ambiguous because it can refer to a municipality name, a city name, or a brokerage name. Could you please clarify if you are referring to properties sold within the municipality of Westwood, the city of Westwood, or properties sold by agents affiliated with the Westwood brokerage?"
Xoá sự mơ hồ khỏi cụm từ tìm kiếm
Tinh chỉnh câu lệnh đầu vào (Q10):
Westwood city location properties sold in September 2025.
Và bây giờ, chúng ta có truy vấn và kết quả:
Generated SQL SELECT "p"."property_id", "p"."address_street", "p"."address_postal_code", "p"."price", "pt"."sale_date", "pt"."sale_price" FROM "real_estate"."properties" AS "p" INNER JOIN "real_estate"."cities" AS "c" ON "p"."city_id" = "c"."city_id" INNER JOIN "real_estate"."property_transactions" AS "pt" ON "p"."property_id" = "pt"."property_id" WHERE "c"."city_name" = 'Westwood' AND "pt"."sale_date" >= '2025-09-01'::date AND "pt"."sale_date" <= '2025-09-30'::date ORDER BY "pt"."sale_date" ASC NULLS LAST Query Results property_id address_street address_postal_code price sale_date sale_price 32 999 Main St 99999 3800000.00 2025-09-12 1000000.00
11. Tìm kiếm ngữ nghĩa và các hàm AI
Các hàm AI của AlloyDB cho phép lọc ngữ nghĩa trên dữ liệu không có cấu trúc. Sử dụng các hàm như ai.if và google_ml.embedding ngay trong các truy vấn SQL cùng với các toán tử cơ sở dữ liệu tiêu chuẩn.
Mẫu có toán tử ILIKE
Bước đầu tiên là tải tệp ngữ cảnh mới lên bằng toán tử ILIKE.
Tải tệp ngữ cảnh mẫu ILIKE xuống:
cloudshell download ~/codelabs/alloydb-ai-nla/sixrecipe_context4_1.json
Tải sixrecipe_context4_1.json lên tập hợp ngữ cảnh của bạn để đánh giá tính năng so khớp mẫu ILIKE tiêu chuẩn cho nhà "dọn vào ở ngay".
{
"nl_query": "Move-in ready houses",
"sql": "SELECT \"p\".\"address_street\", \"p\".\"address_postal_code\" FROM \"real_estate\".\"properties\" AS \"p\" WHERE \"p\".listing_status = 'Active' AND \"p\".\"description\" IS NOT NULL AND (\"p\".description ILIKE '%turnkey%' OR \"p\".description ILIKE '%move-in%')",
"intent": "Move-in ready houses",
"manifest": "Move-in ready houses",
"parameterized": {
"parameterized_intent": "Move-in ready houses",
"parameterized_sql": "SELECT \"p\".\"address_street\", \"p\".\"address_postal_code\" FROM \"real_estate\".\"properties\" AS \"p\" WHERE \"p\".listing_status = 'Active' AND \"p\".\"description\" IS NOT NULL AND (\"p\".description ILIKE '%turnkey%' OR \"p\".description ILIKE '%move-in%')"
}
}
Gửi truy vấn này (Q11):
List move-in ready houses.
Truy vấn thu được:
SELECT "p"."address_street", "p"."address_postal_code"
FROM "real_estate"."properties" AS "p"
WHERE "p".listing_status = 'Active'
AND "p"."description" IS NOT NULL
AND ("p".description ILIKE '%turnkey%' OR "p".description ILIKE '%move-in%')
Hàm này trả về một bản ghi khớp.
Query Results address_street address_postal_code 40 Main St, Unit 8 N2H 2G8
Mẫu có hàm AI.IF
Tải tệp ngữ cảnh mẫu AI.IF xuống:
cloudshell download ~/codelabs/alloydb-ai-nla/sixrecipe_context4_2.json
Tải sixrecipe_context4_2.json lên tập hợp ngữ cảnh của bạn để đánh giá hàm lọc ngữ nghĩa ai.if.
{
"nl_query": "List Move-in ready houses",
"sql": "SELECT \"p\".\"address_street\", \"p\".\"address_postal_code\" FROM \"real_estate\".\"properties\" AS \"p\" WHERE \"p\".listing_status = 'Active' AND \"p\".\"description\" IS NOT NULL AND ai.if('Does this description represent a move-in ready house? Description: ' || \"p\".\"description\")",
"intent": "List Move-in ready houses",
"manifest": "List Move-in ready houses",
"parameterized": {
"parameterized_intent": "List Move-in ready houses",
"parameterized_sql": "SELECT \"p\".\"address_street\", \"p\".\"address_postal_code\" FROM \"real_estate\".\"properties\" AS \"p\" WHERE \"p\".listing_status = 'Active' AND \"p\".\"description\" IS NOT NULL AND ai.if('Does this description represent a move-in ready house? Description: ' || \"p\".\"description\")"
}
}
Lặp lại lời nhắc (Q12):
List move-in ready houses.
SQL được tạo:
SELECT "p"."address_street", "p"."address_postal_code"
FROM "real_estate"."properties" AS "p"
WHERE "p".listing_status = 'Active'
AND "p"."description" IS NOT NULL
AND ai.if('Does this description represent a move-in ready house? Description: ' || "p"."description")
Điều này mang lại cho chúng ta cùng một thuộc tính trong kết quả:
Query Results Address Street Address Postal Code 40 Main St, Unit 8 N2H 2G8 Natural Language Answer The move-in ready home currently available is located at: Address: 40 Main St, Unit 8 Postal Code: N2H 2G8
Phân loại bằng tính năng tìm kiếm vectơ
Tải tệp ngữ cảnh tìm kiếm nhúng xuống:
cloudshell download ~/codelabs/alloydb-ai-nla/sixrecipe_context4_3.json
Tải sixrecipe_context4_3.json lên tập hợp ngữ cảnh của bạn để đánh giá tính năng tìm kiếm bằng vectơ ngữ nghĩa bằng google_ml.embedding và tìm kiếm nhà có thiết bị nhà bếp mới.
Cập nhật tập hợp bối cảnh bằng tệp sixrecipe_context4_3.json có một khía cạnh bổ sung bằng tính năng tìm kiếm vectơ AlloyDB.
{
"sql_snippet": "((real_estate.properties.description_embedding <=> google_ml.embedding('gemini-embedding-001', 'Upgraded kitchen appliances')::vector) < 0.4)",
"intent": "with upgraded kitchen appliances",
"manifest": "with upgraded kitchen appliances",
"parameterized": {
"parameterized_intent": "with upgraded kitchen appliances",
"parameterized_sql_snippet": "((real_estate.properties.description_embedding <=> google_ml.embedding('gemini-embedding-001', 'Upgraded kitchen appliances')::vector) < 0.4)"
}
}
Giá trị 0,4 trong định nghĩa về khía cạnh ở trên là một ngưỡng được hiệu chỉnh theo thực nghiệm.
Chạy truy vấn này (Q13):
List move-in ready houses with upgraded kitchen appliances.
SQL được tạo:
SELECT "p"."address_street", "p"."address_postal_code" FROM "real_estate"."properties" AS "p" WHERE "p"."listing_status" = 'Active' AND "p"."description" IS NOT NULL AND ai.if('Does this description represent a Move-in ready house? Description: ' || "p"."description") AND ((("p"."description_embedding" <=> google_ml.embedding('gemini-embedding-001', 'Upgraded kitchen appliances')::vector) < 0.4))
Sau đây là kết quả truy vấn và đề xuất bằng ngôn ngữ tự nhiên:
Query Results Address Postal Code 40 Main St, Unit 8 N2H 2G8 Natural Language Answer The move-in ready house with upgraded kitchen appliances is located at: Address: 40 Main St, Unit 8 Postal Code: N2H 2G8
12. Bảo mật và quyền riêng tư
Bất cứ khi nào QueryData API tạo truy vấn, sẽ có nguy cơ về quyền riêng tư là các truy vấn được tạo có thể tiết lộ dữ liệu thuộc về những người dùng khác. Khung hiển thị an toàn được tham số hoá (PSV) thực thi các ranh giới bảo mật ở cấp hàng trong quá trình tạo NL2SQL.
Tạo chế độ xem an toàn có tham số
Chúng tôi có bảng real_estate.offers chứa thông tin về các ưu đãi cho tất cả giao dịch bất động sản. Chúng tôi muốn nhân viên chỉ xem được các giao dịch của riêng họ chứ không xem được giao dịch của nhân viên khác. Chúng tôi tạo một PSV có khả năng lọc các hàng dựa trên agent_id.
Tạo một Chế độ xem an toàn có tham số cho bảng ưu đãi trong AlloyDB Studio:
CREATE VIEW real_estate.secure_offers
WITH (security_barrier) AS
SELECT offer_id, property_id, buyer_agent_id,
seller_agent_id, offer_amount, offer_date,
offer_status, offer_expiration_date,
contingencies
FROM real_estate.offers
WHERE buyer_agent_id = $@agent_id;
Xác minh định nghĩa khung hiển thị bảo mật có tham số:
SELECT definition
FROM parameterized_views.all_parameterized_views
WHERE schemaname = 'real_estate' AND viewname = 'secure_offers';
Còn bảng real_estate.offers thì sao?
Hạn chế quyền truy cập dữ liệu QueryData bằng các khung hiển thị an toàn được tham số hóa của AlloyDB
Trong agent.py, khung hiển thị bảo mật được tham số hoá real_estate.secure_offers được đăng ký trong TABLE_IDS thay vì real_estate.offers:
Mã nguồn agent.py:
List of database tables included in QueryData API requests
TABLE_IDS = [
"real_estate.municipalities",
"real_estate.cities",
"real_estate.agents",
"real_estate.properties",
"real_estate.schools",
"real_estate.school_to_property",
"real_estate.property_transactions",
"real_estate.secure_offers",
]
Và truyền ngữ cảnh thời gian chạy của phiên cho một tác nhân có agent_id=1:
"parameterized_secure_view_parameters": {
"parameters": {
"key": "agent_id",
"value": "1"
}
}
},
Do đó, mọi yêu cầu API QueryData sẽ truyền tham số đó và khi chế độ xem an toàn được đưa vào yêu cầu, chế độ này sẽ áp dụng tính năng lọc chỉ trả về kết quả cho tác nhân cụ thể đó.
Chạy truy vấn này (Q14):
List the offer id and listing price in 2025 where the offer was within 5% of the final selling price.
SQL được tạo:
SELECT "o"."offer_id", "p"."price" AS "listing_price"
FROM "real_estate"."secure_offers" AS "o"
INNER JOIN "real_estate"."properties" AS "p" ON "o"."property_id" = "p"."property_id"
INNER JOIN "real_estate"."property_transactions" AS "t" ON "o"."property_id" = "t"."property_id"
WHERE "o"."offer_date" >= '2025-01-01'
AND "o"."offer_date" <= '2025-12-31'
AND "o"."offer_amount" IS NOT NULL
AND "t"."sale_price" IS NOT NULL
AND "p"."price" IS NOT NULL
AND ABS("o"."offer_amount" - "t"."sale_price") <= (0.05 * "t"."sale_price")
ORDER BY "o"."offer_id" ASC NULLS LAST
Việc truy vấn chế độ xem sẽ lọc kết quả theo tham số phiên của tác nhân đang hoạt động, bảo vệ dữ liệu bản ghi trái phép và chỉ trả về 2 bản ghi.
Query Results Offer ID Listing Price 7 $750,000.00 8 $510,000.00 Natural Language Answer Here are the offers from 2025 where the offer amount was within 5% of the final selling price: Offer ID 7: Listing Price of $750,000.00 Offer ID 8: Listing Price of $510,000.00
Nếu bạn chạy truy vấn sau đây dựa trên bảng real_estate.offers cơ sở trong AlloyDB Studio:
SELECT "o"."offer_id", "p"."price" AS "listing_price"
FROM "real_estate"."offers" AS "o"
INNER JOIN "real_estate"."properties" AS "p" ON "o"."property_id" = "p"."property_id"
INNER JOIN "real_estate"."property_transactions" AS "t" ON "o"."property_id" = "t"."property_id"
WHERE "o"."offer_date" >= '2025-01-01'
AND "o"."offer_date" <= '2025-12-31'
AND "o"."offer_amount" IS NOT NULL
AND "t"."sale_price" IS NOT NULL
AND "p"."price" IS NOT NULL
AND ABS("o"."offer_amount" - "t"."sale_price") <= (0.05 * "t"."sale_price")
ORDER BY "o"."offer_id" ASC NULLS LAST
Thao tác này trả về nhiều hơn 2 bản ghi, cho thấy dữ liệu của tất cả các nhân viên.
Đến đây là hết phần thực hành! Bạn đã tìm hiểu cách sử dụng QueryData API, các hàm AI và Chế độ xem an toàn được tham số hoá AlloyDB.
13. Dọn dẹp môi trường
Huỷ các thực thể và cụm AlloyDB khi bạn hoàn thành bài thực hành.
Xoá cụm AlloyDB và tất cả các phiên bản
Cụm bị huỷ bằng lựa chọn force. Lựa chọn này cũng sẽ xoá tất cả các phiên bản thuộc cụm.
Nếu thiết bị đầu cuối của bạn bị ngắt kết nối, hãy kết nối lại và xác định dự án cũng như các biến môi trường trong Cloud Shell:
gcloud config set project <YOUR_PROJECT_ID>
export REGION=us-central1
export ADBCLUSTER=alloydb-aip-01
export PROJECT_ID=$(gcloud config get-value project)
Xoá cụm:
gcloud alloydb clusters delete $ADBCLUSTER --region=$REGION --force
Kết quả đầu ra dự kiến trên bảng điều khiển:
student@cloudshell:~ (test-project-001-402417)$ gcloud alloydb clusters delete $ADBCLUSTER --region=$REGION --force All of the cluster data will be lost when the cluster is deleted. Do you want to continue (Y/n)? Y Operation ID: operation-1697820178429-6082890a0b570-4a72f7e4-4c5df36f Deleting cluster...done.
Xoá bản sao lưu AlloyDB
Xoá tất cả các bản sao lưu AlloyDB cho cụm:
for i in $(gcloud alloydb backups list \
--filter="CLUSTER_NAME: projects/$PROJECT_ID/locations/$REGION/clusters/$ADBCLUSTER" \
--format="value(name)" \
--sort-by=~createTime) ; do \
gcloud alloydb backups delete $(basename $i) --region $REGION --quiet; done
Kết quả đầu ra dự kiến trên bảng điều khiển:
student@cloudshell:~ (test-project-001-402417)$ for i in $(gcloud alloydb backups list --filter="CLUSTER_NAME: projects/$PROJECT_ID/locations/$REGION/clusters/$ADBCLUSTER" --format="value(name)" --sort-by=~createTime) ; do gcloud alloydb backups delete $(basename $i) --region $REGION --quiet; done Operation ID: operation-1697826266108-60829fb7b5258-7f99dc0b-99f3c35f Deleting backup...done.
Xoá bộ chứa Cloud Storage
Xoá bộ chứa nhập trong Cloud Storage để tránh bị tính phí lưu trữ liên tục:
gcloud storage rm -r gs://${PROJECT_ID}-import
14. 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 một cụm và phiên bản chính AlloyDB
- Cách bật QueryData, các hàm AI và Chế độ xem an toàn có tham số cho AlloyDB
- Cách tạo bộ bối cảnh QueryData
- Cách sử dụng các mẫu và bối cảnh khác nhau trong QueryData API
- Cách làm cho mẫu QueryData linh hoạt hơn bằng các khía cạnh
- Cách giải quyết sự mơ hồ về dữ liệu bằng tính năng tìm kiếm giá trị và lập chỉ mục trigram
- Cách sử dụng các hàm AI để tìm kiếm ngữ nghĩa bằng mẫu
- Cách sử dụng Chế độ xem bảo mật được tham số hoá bằng QueryData API
Khảo sát
Kết quả: