使用 AI 函式執行智慧型 SQL 查詢

AlloyDB AI AI 函式會將 Gemini 等大型語言模型 (LLM) 直接整合至 AlloyDB for PostgreSQL 資料,執行智慧資料作業。這項功能內建下列函式:

  • 篩選 (ai.if)
  • 語意排名 (ai.rank)
  • 生成文字 (ai.generate)

這些 AI 函式會使用 AlloyDB AI 查詢引擎,協助應用程式以各種規模的人工智慧模型處理資料,從單列回應到大規模資料庫作業皆可。您可以使用 ai.ifai.rankai.generate 運算子,將自然語言與 SQL 查詢合併。AlloyDB AI 會保留並建立 ai 結構定義。

AI 函式分為三類,差異在於處理輸入資料和記憶體配置的方式:純量、以陣列為基礎,以及游標函式。選擇合適的 AI 函式取決於資料規模和效能需求。請參閱下表,瞭解這些函式及其用途:

類別

說明

建議用途

純量

專為基本的一對一處理作業設計。接受單一輸入內容,並傳回單一輸出內容。

如果您需要基本函式,為純量函式呼叫次數較少 (少於 50 次) 的查詢提供可接受的效能,請使用這個函式。

以陣列為基礎

在單一函式呼叫中,以資料列陣列的形式處理資料。以陣列做為輸入,並傳回陣列做為輸出。

適用於中小型資料集,這類資料集的整個合格資料列陣列可納入記憶體限制。這可為以集合為基礎的作業提供高處理量。

Cursor

以游標做為輸入內容,並傳回游標做為輸出內容。

用於處理大量資料列,例如 10,000 列。

事前準備

整合 Vertex AI 並安裝擴充功能

  1. 設定 Vertex AI 模型的使用者存取權
  2. 確認已安裝最新版 google_ml_integration
    1. 如要檢查已安裝的版本,請執行下列指令:

              SELECT extversion FROM pg_extension WHERE extname = 'google_ml_integration';
              extversion 
              ------------
              1.5.2
              (1 row)
            
    2. 如果尚未安裝擴充功能,或安裝的版本低於 1.5.2,請更新擴充功能。

              CREATE EXTENSION IF NOT EXISTS google_ml_integration;
              ALTER EXTENSION google_ml_integration UPDATE;
            

      如果您在執行上述指令時遇到問題,或執行上述指令後,擴充功能未更新至 1.5.2 版,請與Google Cloud 支援團隊聯絡。

  3. 如要使用 AlloyDB AI 查詢引擎功能,請將 google_ml_integration.enable_ai_query_engine 旗標設為 on

    SQL

    1. 為目前的工作階段啟用 AI 查詢引擎。
                    SET google_ml_integration.enable_ai_query_engine = on;
                    
    2. 跨工作階段啟用特定資料庫的功能。
                    ALTER DATABASE DATABASE_NAME SET google_ml_integration.enable_ai_query_engine = 'on';
                    
    3. 為特定使用者啟用 AI 查詢引擎,適用於所有工作階段和資料庫。
                    ALTER ROLE postgres SET google_ml_integration.enable_ai_query_engine = 'on';
                  

    控制台

    如要修改 google_ml_integration.enable_ai_query_engine 旗標的值,請按照「設定執行個體的資料庫旗標」一文中的步驟操作。

    gcloud

    如要使用 gcloud CLI,可以安裝並初始化 Google Cloud CLI,也可以使用 Cloud Shell

    你可以修改 google_ml_integration.enable_ai_query_engine 旗標的值。 詳情請參閱「設定執行個體的資料庫旗標」。

                 gcloud alloydb instances update INSTANCE_ID \
                   --database-flags google_ml_integration.enable_ai_query_engine=on \
                   --region=REGION_ID \
                   --cluster=CLUSTER_ID \
                   --project=PROJECT_ID
                

使用所在區域支援的 Gemini 模型

如果 AlloyDB for PostgreSQL 叢集位於不支援 gemini-2.0-flash 的區域,您可以使用 model_id parameter,在該區域使用其他可用的 Gemini 模型。

或者,您也可以註冊 Gemini 模型端點,並將該模型 ID 提供給 AI 運算子。詳情請參閱「使用模型端點管理服務註冊及呼叫遠端 AI 模型」。

以下範例說明如何註冊另一個 Gemini 端點。在本例中,第二個 Gemini 端點是 gemini-2.0-flash 的全域端點。您可以傳遞 model_id =>gemini-2.5-flash-global` 做為額外引數,搭配 AI 運算子使用這個已註冊的模型。

CALL
  google_ml.create_model(
    model_id => 'gemini-2.5-flash-global',
    model_type => 'llm',
    model_provider => 'google',
    model_qualified_name => 'gemini-2.5-flash',
    model_request_url =>  'https://aiplatform.googleapis.com/v1/projects/PROJECT_ID/locations/global/publishers/google/models/gemini-2.5-flash:generateContent',
    model_auth_type => 'alloydb_service_agent_iam'
);

使用 Gemini 3.0 模型

部分 Gemini 模型 (例如 gemini-3.0-pro-preview) 僅透過全球端點提供。您必須按照下列方式註冊這類模型:

CALL
  google_ml.create_model(
    model_id => 'gemini-3-preview-model',
    model_request_url => 'https://aiplatform.googleapis.com/v1/projects/PROJECT_ID/locations/global/publishers/google/models/gemini-3-pro-preview:generateContent',
    model_qualified_name => 'gemini-3-pro-preview',
    model_provider => 'google',
    model_type => 'llm',
    model_auth_type => 'alloydb_service_agent_iam'
);

PROJECT_ID 替換為 Vertex AI 模型所在的專案 ID。請注意,AlloyDB 服務帳戶必須在該專案中具備 Vertex AI 使用者角色

註冊模型後,您可以在 AI 函式中使用模型,如下所示:

SELECT ai.generate(prompt => 'What is AlloyDB?', model_id => 'gemini-3-preview-model');

在查詢中使用篩選器

AlloyDB AI 提供 AI 輔助的 SQL 函式,可讓您直接在資料庫查詢中使用自然語言處理和大型語言模型,包括 ai.ifai.rank 運算子。

使用純量函式執行篩選作業

如要評估是否符合以自然語言陳述的條件,請使用 ai.if/google_ml.if 運算子。函式會傳回布林值 true 或 false,如果無法清楚偵測輸出內容,則會傳回 false

- Function signature
FUNCTION ai.if(prompt TEXT, model_id VARCHAR(100) DEFAULT NULL) RETURNS bool

以下範例說明如何使用 ai.if 運算子做為篩選器,找出位於人口超過 10 萬的城市,且有超過 500 則正面評論的餐廳。這個範例使用 restaurant_reviews,並包含評論和城市位置等資料。ai.if 運算子可協助你瞭解評論情緒,並將資料庫中的地點與 Gemini 對這些地點人口的一般知識結合。

SELECT r.name, r.location_city
FROM restaurant_reviews r
WHERE
  AI.IF(r.location_city || ' has a population OF more than 100,000 AND the following is a positive review; Review: ' || r.review)
GROUP BY r.name, r.location_city
HAVING COUNT(*) > 500;

以下範例與使用您所在區域支援的 Gemini 模型中的範例相同,但使用的是您註冊的模型。

SELECT r.name, r.location_city
FROM restaurant_reviews r
WHERE
  AI.IF(r.location_city || ' has a population of more than 100,000 AND the following is a positive review; Review: ' || r.review, model_id => 'gemini-2.5-flash')
GROUP BY r.name, r.location_city
HAVING COUNT(*) > 500;

對使用 if 運算子的查詢執行聯結

如要執行聯結作業,請搭配使用 ai.if/google_ml.if 運算子和聯結。 下列查詢範例會找出提及餐廳菜單中各個菜單項目的評論數量。

    SELECT item_name, COUNT(*)
    FROM menu_items JOIN user_reviews
      ON ai.if(
        prompt => 'Does the following user review talk about the menu item mentioned ? review: ' || user_reviews.review_text || ' menu item: ' || item_name)
    GROUP BY item_name;

使用陣列函式執行篩選作業

以下範例使用 AI 模型 (gemini-2.0-flash) 分析評論情緒並篩選結果,找出有超過 10 則正面評論的餐廳。ARRAY_AGG 可將個別資料列轉換為結構化陣列,以便 AI 模型一次處理大量資料,而非一次處理一列。

WITH initial_arrays AS (WITH initial_arrays AS (
  SELECT
    ARRAY_AGG(r.id ORDER BY r.id) AS review_ids,
    -- Assuming ai.if takes an array of prompts and returns a boolean array
    ai.if(
      prompts => ARRAY_AGG('Is the review positive: ' || r.review ORDER BY r.id)
      model_id => 'gemini-2.5-flash',
      batch_size => 20
    ) AS truth_values
  FROM restaurant_reviews r
),
reviews AS (
SELECT
  initial_arrays.review_ids[i] AS review_id,
  initial_arrays.truth_values[i] AS truth_value
FROM
  initial_arrays,
  generate_series(1, array_length(initial_arrays.review_ids, 1)) AS i
)
SELECT rest_review.city, rest_review.name
FROM restaurant_reviews rest_review JOIN reviews review ON rest_review.id=review.review_id
WHERE review.truth_value = 't'
GROUP BY rest_review.city, rest_review.name
HAVING COUNT(*) > 10;

使用游標執行篩選

以下範例說明如何透過游標串流處理大量餐廳評論,並加以篩選。

CREATE TABLE filtered_results(input text, result bool);

DO $$
DECLARE
    prompt_cursor REFCURSOR;
    result_cursor REFCURSOR;
    rec RECORD;
BEGIN
    -- 1. Open a cursor for the input data
    OPEN prompt_cursor FOR
        SELECT r.location_city || ' has a population of > 100,000 and is a positive review; Review: ' || r.review
        FROM restaurant_reviews r;

    -- 2. Call the array-based function using the input cursor
    result_cursor := ai.if(
        'Is the given statement true? ',
        prompt_cursor,
        model_id => 'gemini-2.5-flash'
    );

    -- 3. Fetch results from the output cursor and store them
    LOOP
        FETCH result_cursor INTO rec;
        EXIT WHEN NOT FOUND;
        INSERT INTO filtered_results VALUES(rec.input, rec.output);
    END LOOP;

    CLOSE result_cursor;
END $$;

生成文字和摘要

AlloyDB AI 提供純量 ai.generate、陣列和游標型 ai.generate 等文字生成運算子。

使用純量函式生成文字

ai.generate 函式會結合提供的資料和使用者提示,生成文字。

-- Function Signature
FUNCTION ai.generate(prompt TEXT, model_id VARCHAR(100) DEFAULT NULL) RETURNS TEXT

舉例來說,您可以使用下列查詢,為每則使用者評論產生簡要摘要。

SELECT
  ai.generate(
    prompt => 'Summarize the review in 20 words or less. Review: ' || review) AS review_summary
FROM user_reviews;

使用陣列型函式生成文字

下列查詢使用 UNNESTai.generate,有效率地彙整多則評論。

SELECT
  UNNEST(
    ai.generate(
      prompts => ARRAY_AGG('Summarize the review in 20 words or less. Review: ' || review),
      model_id => 'gemini-2.5-flash',
    )
  ) AS review_summary
FROM user_reviews;

使用游標執行文字生成作業

如要為數百萬列資料產生摘要或翻譯,且不希望遇到記憶體瓶頸,請使用游標進行批次生成。

CREATE TABLE summary_results(summary text);

DO $$
DECLARE
    prompt_cursor REFCURSOR;
    summary_cursor REFCURSOR;
    rec RECORD;
BEGIN
    OPEN prompt_cursor FOR SELECT review_text FROM user_reviews ORDER BY id;

    summary_cursor := ai.generate(
        'Summarize the review in 20 words or less. Review:',
        prompt_cursor,
    );

    LOOP
        FETCH summary_cursor INTO rec;
        EXIT WHEN NOT FOUND;
        INSERT INTO summary_results VALUES(rec.output);
    END LOOP;

    CLOSE summary_cursor;
END $$;

為查詢結果評分

如需使用自訂自然語言指令排序查詢結果,請使用 ai.rank 運算子。

使用純量函式執行評分作業

您可以使用下列函式提供提示,說明排名條件,並為每個項目傳回分數。

-- Function signature
FUNCTION ai.rank(prompt TEXT, model_id VARCHAR(100) DEFAULT NULL) RETURNS real

舉例來說,下列查詢會使用 LLM 的評分,取得前 20 則最正面的餐廳評論。

SELECT review AS top20
FROM user_reviews
ORDER BY ai.rank(
  'Score the following review according to these rules:
  (1) Score OF 8 to 10 IF the review says the food IS excellent.
  (2) 4 to 7 IF the review says the food is ok.
  (3) 1 to 3 IF the review says the food is not good. Here is the review:' || review) DESC
LIMIT 20;

使用陣列型函式進行評分

這項 ai.rank 函式可根據自訂自然語言指令,為查詢結果評分和排序。

FUNCTION ai.rank(prompts TEXT[], model_id VARCHAR(100) DEFAULT NULL) RETURNS real[]

下列查詢使用 UNNESTai.rank,有效率地為多則評論評分。

SELECT
  UNNEST(
    ai.rank(
      ARRAY_AGG('Score the following review according to these rules:
  (1) Score OF 8 to 10 IF the review says the food IS excellent.
  (2) 4 to 7 IF the review says the food is ok.
  (3) 1 to 3 IF the review says the food is not good. Here is the review:' || review),
    )
  ) as review_scores
FROM user_reviews;

使用指標執行評分

這項函式用於對大型資料集評分,不會達到記憶體限制。

FUNCTION ai.rank(context TEXT, input_cursor REFCURSOR, model_id VARCHAR(100) DEFAULT NULL) RETURNS REFCURSOR

以下範例說明如何根據特定自然語言條件,為大量文字評分。

CREATE TABLE scored_results(input text, score real);

DO $$
DECLARE
    prompt_cursor REFCURSOR;
    score_cursor REFCURSOR;
    rec RECORD;
BEGIN
    OPEN prompt_cursor FOR SELECT review FROM user_reviews ORDER BY id;

    score_cursor := ai.rank(
        'Score the following review: (1) 8-10 if excellent, (2) 4-7 if ok, (3) 1-3 if not good. Review:',
        prompt_cursor,
    );

    LOOP
        FETCH score_cursor INTO rec;
        EXIT WHEN NOT FOUND;
        INSERT INTO scored_results VALUES(rec.input, rec.output);
    END LOOP;

    CLOSE score_cursor;
END $$;

後續步驟