使用自然語言問題生成 SQL 查詢

本頁面說明如何使用 AlloyDB AI 自然語言設定、設定及產生 SQL 陳述式。自然語言可讓您使用自然語言查詢資料庫,建立面向使用者的生成式 AI 應用程式。

如要啟用 alloydb_ai_nl 擴充功能 (即 AlloyDB for PostgreSQL 自然語言支援 API),請執行下列高階步驟:

  1. 安裝 alloydb_ai_nl 擴充功能。
  2. 為應用程式定義自然語言設定。
  3. 註冊結構定義。
  4. 新增背景資訊。
  5. 新增查詢範本。
  6. 定義概念類型並建立值索引。
  7. 使用自然語言介面生成 SQL 陳述式。

事前準備

  • 要求存取 AlloyDB AI 自然語言,並等待收到啟用確認訊息,再按照本頁的指示操作。
  • 瞭解如何連線至 AlloyDB 資料庫並執行 PostgreSQL 指令。詳情請參閱連線總覽
  • 在資料庫中填入使用者想存取的資料和結構定義。

建立叢集並啟用 Vertex AI 整合功能

  1. 建立 AlloyDB 叢集和執行個體。 您會使用 AlloyDB 執行個體建立應用程式資料庫和結構定義。
  2. 啟用 Vertex AI 整合功能。詳情請參閱「與 Vertex AI 整合」。

必要的角色

如要安裝 alloydb_ai_nl 擴充功能並授予其他使用者存取權,您必須在使用的 Google Cloud 專案中具備下列 Identity and Access Management (IAM) 角色:

詳情請參閱使用標準驗證管理 PostgreSQL 使用者

準備環境

如要準備生成自然語言查詢,您必須安裝必要擴充功能、建立設定,以及註冊結構定義。

安裝 alloydb_nl_ai 擴充功能

alloydb_ai_nl 擴充功能會使用 google_ml_integration 擴充功能,與大型語言模型 (LLM) 互動,包括 Vertex AI 上的 Gemini 模型。

如要安裝 alloydb_ai_nl 擴充功能,請連線至資料庫並執行下列指令:

CREATE EXTENSION alloydb_ai_nl cascade;

建立自然語言設定並註冊結構定義

AlloyDB AI 自然語言會使用 nl_config 將應用程式與特定結構定義、查詢範本和模型端點建立關聯。nl_config 是一種設定,可將應用程式與結構定義、範本和其他環境建立關聯。大型應用程式也可以為應用程式的不同部分使用不同的設定,只要在從應用程式的該部分傳送問題時指定正確的設定即可。您可以註冊整個結構定義,也可以註冊特定結構定義物件,例如資料表、檢視區塊和資料欄。

  1. 如要建立自然語言設定,請使用下列範例:

    SELECT
      alloydb_ai_nl.g_create_configuration(
        'my_app_config'        -- configuration_id
      );
    

    「gemini-2.0-flash:generateContent」是模型端點。

  2. 使用下列範例,為指定設定註冊結構定義:

    SELECT
      alloydb_ai_nl.g_manage_configuration(
        operation => 'register_schema',
        configuration_id_in => 'my_app_config',
        schema_names_in => '{my_schema}'
      );
    

新增情境

背景資訊:可用於回答使用者問題的任何資訊。內容包括結構和關係的結構定義、資料欄的摘要和說明、資料欄值及其語意,以及應用程式或網域專屬的商業邏輯規則或陳述。

為應用程式專屬規則新增一般情境

一般內容項目包括應用程式專屬規則、商業邏輯陳述式,或任何未連結至特定結構定義物件的應用程式和網域專屬術語。

如要為應用程式專屬規則和應用程式/網域專屬術語新增一般背景資訊,請按照下列步驟操作:

  1. 如要為指定設定新增一般內容項目,請使用下列範例:

    SELECT
      alloydb_ai_nl.g_manage_configuration(
        'add_general_context',
        'my_app_config',
        general_context_in => '{"If the user asks for a good seat, assume that means a window or aisle seat."}'
      );
    

    上述陳述有助於 AlloyDB AI 自然語言為使用者的自然語言問題提供更高品質的回覆。

  2. 如要查看指定設定的一般內容,請執行下列陳述式:

    SELECT alloydb_ai_nl.list_general_context(nl_config TEXT);
    

生成並檢查結構定義內容

結構定義內容說明結構定義物件,包括資料表、檢視區塊、具體化檢視區塊和資料欄。這個內容會儲存為每個結構定義物件的 COMMENT

  1. 如要產生結構定義物件的背景資訊,請呼叫下列 API。為獲得最佳結果,請確保資料庫表格包含代表性資料。

    -- For all schema objects (tables, views, materialized views and columns)
    -- within the scope of a provided nl_config.
    SELECT
      alloydb_ai_nl.generate_schema_context(
        'my_app_config' -- nl_config
      );
    
  2. 執行下列陳述式,查看產生的結構定義內容。

    SELECT schema_object, object_context
    FROM alloydb_ai_nl.generated_schema_context_view;
    

    產生的結構定義情境會儲存在前一個檢視畫面中。

  3. 選用步驟:更新產生的結構定義脈絡。

    SELECT
      alloydb_ai_nl.update_generated_relation_context(
        'my_schema.my_table',
        'This table contains archival records, if you need latest records use records_new table.'
      );
    
    SELECT
      alloydb_ai_nl.update_generated_column_context(
        'my_schema.my_table.column1',
        'The seat_class column takes single letters like "E" for economy, "P" for premium economy, "B" for business and "F" for First.'
      );
    
  4. 套用背景資訊。套用後,背景資訊會立即生效,並從 generated_schema_context_view 中刪除。

    -- For all schema objects (tables, views, materialized views and columns)
    -- within the scope of nl_config.
    SELECT
      alloydb_ai_nl.apply_generated_schema_context(
        'my_app_config' --nl_config
      );
    
  5. 選用:驗證產生的背景資訊。您可以使用下列 API 檢查結構定義內容,這些內容會在生成 SQL 陳述式時使用。

    -- For table, view or materialized view.
    SELECT
      alloydb_ai_nl.get_relation_context(
        'my_schema.my_table'
      );
    
    -- For column.
    SELECT
      alloydb_ai_nl.get_column_context(
        'my_schema.my_table.column1'
      );
    
  6. 選用:手動設定結構定義內容。

    -- For table, view or materialized view.
    SELECT
      alloydb_ai_nl.set_relation_context(
        'my_schema.my_table',
        'One-to-many mapping from product to categories'
      );
    
    -- For column.
    SELECT
      alloydb_ai_nl.set_column_context(
        'my_schema.my_table.column1',
        'This column provides additional tagged info for the product in  Json format, e.g., additional color or size information of the product - tags: { "color": "red", "size": "XL"}'
      );
    

建立查詢範本

如要提升以 LLM 建構的生成式 AI 應用程式品質,可以加入範本。查詢範本是一組精選的代表性或常見自然語言問題,以及對應的 SQL 查詢和說明,可為自然語言轉 SQL (NL2SQL) 生成功能提供聲明式基本原理。範本主要由應用程式指定,但 alloydb_ai_nl 擴充功能也會根據常用的 SQL 查詢自動產生範本。每個範本都必須與 nl_config 建立關聯。

alloydb_ai_nl 擴充功能會使用 template_store,在生成 SQL 陳述式來回答使用者問題的過程中,動態納入相關的 SQL 範本。template_store 會找出與自然語言問題意圖相似的範本,識別對應的參數化 SQL 陳述式,並透過自然語言問題中的值例項化參數,合成 SQL 陳述式。不過,如果沒有與使用者問題意圖相同的範本,alloydb_ai_nl 會使用所有相關範本和情境來撰寫 SQL 陳述式。

如要新增範本,請指定問題 (使用名為 intent 的參數) 和 SQL 查詢。

如要將範本新增至範本商店,請執行下列陳述式:

SELECT
  alloydb_ai_nl.add_template(
    nl_config => 'my_app_config',
    intent => 'How many accounts associated with loans are located in the Prague region?',
    sql => 'SELECT COUNT(T1.account_id)
            FROM bird_dev_financial.account AS T1
            INNER JOIN bird_dev_financial.loan AS T2
              ON T1.account_id = T2.account_id
            INNER JOIN bird_dev_financial.district AS T3
              ON T1.district_id = T3.district_id
            WHERE T3."A3" = ''Prague''',
    check_intent => TRUE
  );

如果 check_intentTRUEalloydb_ai_nl 會執行語意檢查,確認提供的意圖與傳入的 SQL 陳述式相符。如果意圖與 SQL 陳述式不符,系統就不會新增範本。

自動產生範本

資料表中有代表性資料集後,建議您執行與常見問題相應的 SQL 查詢,這些問題很可能是使用者會提出的。請務必確保查詢有良好的查詢計畫,且執行效能良好。

執行查詢後,AlloyDB AI 自然語言可根據查詢記錄自動產生範本。您可以呼叫下列 API 來產生範本。您必須先檢查並套用產生的範本,範本才會生效。

系統會根據查詢記錄中最常使用的查詢自動生成範本 google_db_advisor_workload_statements。系統會根據下列條件篩選查詢:

  • SELECT 個陳述式
  • 可執行檔:查詢可由 EXPLAIN 指令順利處理。
  • 沒有重複:查詢先前未用於產生範本。
  • 所有參照的資料表和檢視區塊都在 nl_config 的範圍內。

如要自動產生、查看及套用範本,請按照下列步驟操作:

  1. 要求 AlloyDB 根據查詢記錄生成範本:

    SELECT
      alloydb_ai_nl.generate_templates(
        'my_app_config',
    );
    

    使用提供的檢視畫面 alloydb_ai_nl.generated_templates_view 檢查 generated_templates

    以下輸出內容顯示產生的範本數量:

    -[ RECORD 1 ]------+--
    generate_templates | 1
    
  2. 使用 generated_templates_view 檢視產生的範本。

    SELECT *
    FROM alloydb_ai_nl.generated_templates_view;
    

    以下是傳回的輸出內容範例:

    -[ RECORD 1 ]----------------------------------------------------------------
    id          | 1
    config      | my_app_config
    type        | Template
    manifest    | How many clients have a birth year of a given number?
    nl          | How many clients have a birth year of 1997?
    sql         | select count(*) from public.client as T where
                 to_char(T.birth_date::timestamp, 'YYYY') = '1997';
    intent      | How many clients have a birth year of 1997?
    psql        | select count(*) from public.client as T where
                 to_char(T.birth_date::timestamp, 'YYYY') = $1;
    pintent     | How many clients have a birth year of $1?
    comment     |
    explanation |
    weight      | 1
    

    回傳輸出內容中的 manifest 是指一般範本,或是問題類型或可執行的作業的廣泛說明。pintentintent 的參數化版本,會將特定值 (1997) 替換為預留位置 ($1),藉此將 intent 一般化。

  3. 如要更新產生的範本,請執行下列範例陳述式:

    SELECT alloydb_ai_nl.update_generated_template(
      id => 1,
      manifest => 'How many clients are born in a given year?',
      nl => 'How many clients are born in 1997?',
      intent => 'How many clients are born in 1997?',
      pintent => 'How many clients are born in $1?'
    
    );
    
  4. 套用範本。套用的範本會立即新增至範本商店,並從審查檢視畫面中刪除。

    -- For all templates generated under the nl config.
    SELECT
      alloydb_ai_nl.apply_generated_templates('my_app_config');
    

設定自然語言的安全性

如要設定 AlloyDB AI 自然語言的安全性,請參閱「使用參數化安全檢視畫面管理資料應用程式安全性」。

定義概念類型和值索引

您可以定義概念類型和值索引,進一步瞭解所提出的問題。概念類型是實體的類別或類別,可識別字詞的語意,而不只是字詞的字面形式。

舉例來說,即使一個國家/地區名稱為大寫 (例如 USA),另一個國家/地區名稱為小寫 (例如 usa),這兩個名稱仍可能相同。在本例中,國家/地區名稱是概念類型。其他概念類型範例包括人名、城市名稱和日期。

值索引是自然語言設定 nl_config 中資料欄值的索引,以與每個資料欄相關聯的概念類型為準。值索引可有效比對所問問題的值詞組和資料庫中的值。

如要定義概念類型和值索引,請按照下列步驟操作,並使用提供的範例。這些範例會將資料欄與概念類型建立關聯、建立及重新整理值索引,並使用同義字集執行值搜尋。

  1. 如要將資料欄與概念類型建立關聯,請執行下列查詢:

    SELECT
      alloydb_ai_nl.associate_concept_type(
        column_names_in => 'my_schema.country.country_name',
        concept_type_in => 'country_name',
        nl_config_id_in => 'my_app_config'
      );
    
  2. 如要根據自然語言設定中屬於概念類型的所有資料欄建立值索引,請執行下列陳述式:

    SELECT
      alloydb_ai_nl.create_value_index(
        nl_config_id_in => 'my_app_config'
      );
    
  3. 將概念類型與新資料欄建立關聯後,請重新整理值索引,以反映變更。

    SELECT
      alloydb_ai_nl.refresh_value_index(
        nl_config_id_in => 'my_app_config'
      );
    
  4. 如要啟用 AlloyDB AI 自然語言,以比對值的同義字,請執行下列範例陳述式:

    SELECT
      alloydb_ai_nl.insert_synonym_set(
        ARRAY [
          'USA',
          'US',
          'United States',
          'United States of America'
        ]
      );
    

    雖然資料表中的資料可能使用特定值 (例如,如果 United States 用於識別國家/地區),但您可以定義包含 United States 所有同義字的同義字集。如果自然語言問題中出現任何同義字,AlloyDB AI 自然語言會將同義字與資料表中的值相符。

  5. 執行值搜尋,找出正確的資料庫值 (如果提供值詞組陣列)。

    SELECT
      alloydb_ai_nl.get_concept_and_value(
        value_phrases_in => ARRAY['United States'],
        nl_config_id_in  => 'my_app_config'
      );
    

    舉例來說,如果使用者提出「美國的人口數是多少?」這類問題,並使用下列 get_sql 查詢,AlloyDB AI 自然語言會使用 get_concept_and_value 函式搭配值片語 United States,對值索引執行模糊搜尋模糊搜尋是一種搜尋技術,即使搜尋查詢與對應資料不完全相符,也能找出相符項目。

    自然語言會找出與搜尋查詢相近的結果 (即 USA 值),並使用該結果生成 SQL 查詢。

    SELECT
      alloydb_ai_nl.get_sql(
        nl_config_id    => 'my_app_config',
        nl_question     => 'What is the population of the United States?',
        additional_info => json_build_object('enrich_nl_question', TRUE)
      ) ->> 'sql';
    

    下表列出 AlloyDB AI 自然語言定義的內建概念類型。

    概念名稱 說明
    generic_entity_name 單一字串類型資料欄可用於一般實體名稱。例如:
      SELECT alloydb_ai_nl.associate_concept_type('public.item.item_name', 'generic_entity_name')
      
    country_namecity_nameregion_name 國家/地區、城市和區域的名稱。使用方式與 generic_entity_name 概念類型完全相同。
    full_person_name 使用者姓名,包括姓氏、名字和中間名。最多可使用三個字串類型欄位,代表完整的個人姓名。將名稱資料欄與 full_person_name 建立關聯時,可以略過任何資料欄。例如:
      SELECT alloydb_ai_nl.associate_concept_type('public.person.last_name,public.person.first_name,public.person.middle_name','full_person_name')
      
    ssn 包含身分證字號的單一字串資料欄。例如:
      SELECT alloydb_ai_nl.associate_concept_type('public.person.ssn','ssn')
     
    date 日期或時間戳記。例如:
     SELECT alloydb_ai_nl.associate_concept_type('public.person.date_col','date')
     

根據自然語言輸入內容生成 SQL 陳述式

您可以使用 AlloyDB AI 自然語言,從自然語言輸入內容生成 SQL 陳述式。執行生成的 SQL 陳述式時,系統會提供資料庫中的資料,協助您回答自然語言問題。

  1. 如要使用自然語言,透過 alloydb_ai_nl.get_sql 函式從資料庫取得結果,請參閱下列範例:

    SELECT
      alloydb_ai_nl.get_sql(
        'my_app_config', -- nl_config
        'What is the sum that client number 4''s account has following transaction 851?' -- nl question
      );
    

    系統會傳回下列 JSON 輸出內容:

    {
      "sql": "SELECT T3.balance FROM public.client AS T1 INNER JOIN public.account AS T2 ON T1.district_id = T2.district_id INNER JOIN public.trans AS T3 ON T2.account_id = T3.account_id WHERE T1.client_id = 4 AND T3.trans_id = 851",
      "prompt": "",
      "retries": 0,
      "error_msg": "",
      "nl_question": "What is the sum that client number 4's account has following transaction 851?"
    }
    
  2. 選用:如要將產生的 SQL 查詢擷取為文字字串,請新增 ->>'sql'

    SELECT
      alloydb_ai_nl.get_sql(
        'my_app_config', -- nl_config
        'What is the sum that client number 4''s account has following transaction 851?' -- nl question
      ) ->> 'sql';
    

    ->> 運算子用於以文字形式擷取 JSON 值。alloydb_ai_nl.get_sql 函式會傳回 JSON 物件,也就是陳述式的一部分,用於擷取與鍵 sql 相關聯的值。這個值是生成的 SQL 查詢。

測試及修正

如要取得更優質的自動生成查詢,請修改或新增更完善的脈絡查詢範本值索引,然後反覆操作,直到獲得滿意的結果為止。

後續步驟