자연어 질문을 사용하여 SQL 쿼리 생성

이 페이지에서는 AlloyDB AI 자연어를 사용하여 SQL 문을 설정, 구성, 생성하는 방법을 설명합니다. 자연어를 사용하면 자연어를 사용하여 데이터베이스를 쿼리하는 사용자 대상 생성형 AI 애플리케이션을 만들 수 있습니다.

PostgreSQL용 AlloyDB 자연어 지원 API인 alloydb_ai_nl 확장 프로그램을 사용 설정하려면 다음의 개략적인 단계를 실행하세요.

  1. alloydb_ai_nl 확장 프로그램을 설치합니다.
  2. 애플리케이션의 자연어 구성을 정의합니다.
  3. 스키마를 등록합니다.
  4. 맥락을 추가합니다.
  5. 쿼리 템플릿을 추가합니다.
  6. 개념 유형을 정의하고 값 색인을 만듭니다.
  7. 자연어 인터페이스를 사용하여 SQL 문을 생성합니다.

시작하기 전에

  • AlloyDB 데이터베이스에 연결하고 PostgreSQL 명령어를 실행하는 방법을 알아봅니다. 자세한 내용은 연결 개요를 참고하세요.
  • 최종 사용자가 액세스하려는 데이터와 스키마로 데이터베이스를 채웁니다.

필수 확장 프로그램 사용 설정

AlloyDB AI 자연어 기능을 설치하고 사용하려면 alloydb_ai_nl.enabled 플래그를 추가하여 확장 프로그램을 사용 설정해야 합니다. 자세한 내용은 인스턴스의 데이터베이스 플래그 구성을 참고하세요.

클러스터 생성 및 Vertex AI 통합 사용 설정

  1. AlloyDB 클러스터 및 인스턴스를 만듭니다. AlloyDB 인스턴스를 사용하여 애플리케이션 데이터베이스와 스키마를 만듭니다.
  2. Vertex AI 통합을 사용 설정합니다. 자세한 내용은 Vertex AI와 통합을 참고하세요.

필요한 역할

alloydb_ai_nl 확장 프로그램을 설치하고 다른 사용자에게 액세스 권한을 부여하려면 사용 중인 Google Cloud 프로젝트에 다음 ID 및 액세스 관리 (IAM) 역할이 있어야 합니다.

자세한 내용은 표준 인증으로 PostgreSQL 사용자 관리를 참고하세요.

개발 환경 준비

자연어 쿼리를 생성하려면 필수 확장 프로그램을 설치하고, 구성을 만들고, 스키마를 등록해야 합니다.

alloydb_ai_nl 확장 프로그램 설치

alloydb_ai_nl 확장 프로그램은 Vertex AI의 Gemini 모델을 비롯한 대규모 언어 모델 (LLM)과 상호작용하는 google_ml_integration 확장 프로그램을 사용합니다.

alloydb_ai_nl 확장 프로그램을 설치하려면 데이터베이스에 연결하고 다음 명령어를 실행합니다.

CREATE EXTENSION alloydb_ai_nl cascade;

alloydb_ai_nl 확장 프로그램 업그레이드

alloydb_ai_nl 확장 프로그램이 최신 버전인지 확인합니다. 확장 프로그램을 이미 설치한 경우 새 확장 프로그램 버전이 있는지 확인하고 최신 버전을 사용하지 않는 경우 확장 프로그램을 업그레이드합니다. alloydb_ai_nl 확장 프로그램에 관한 자세한 내용은 AlloyDB AI 자연어 개요를 참고하세요.

  1. 확장 프로그램을 업그레이드해야 하는지 확인합니다. default_versioninstalled_version보다 늦으면 확장 프로그램을 업그레이드합니다.

    SELECT * FROM pg_available_extensions where name = 'alloydb_ai_nl';
    
  2. 확장 프로그램을 업그레이드합니다.

    ALTER EXTENSION alloydb_ai_nl UPDATE;
    

자연어 구성 만들기 및 스키마 등록

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) 생성에 대한 선언적 근거를 제공하는 설명으로 구성된 선별된 집합입니다. 템플릿은 주로 애플리케이션에서 지정하도록 되어 있지만 자주 사용되는 SQL 쿼리를 기반으로 alloydb_ai_nl 확장 프로그램에서 템플릿을 자동으로 생성할 수도 있습니다. 각 템플릿은 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_id => '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_intentTRUE인 경우 alloydb_ai_nl는 제공된 인텐트가 전달된 SQL 문과 일치하는지 확인하기 위해 시맨틱 검사를 실행합니다. 인텐트가 SQL 문과 일치하지 않으면 템플릿이 추가되지 않습니다.

SQL과 인텐트는 alloydb_ai_nl에 의해 매개변수화됩니다. alloydb_ai_nl.template_store_view 뷰는 매개변수화된 SQL 문과 그 의도를 노출합니다.

SELECT psql
FROM alloydb_ai_nl.template_store_view
WHERE intent = 'How many accounts associated with loans are located in the Prague region?';

이 문은 다음을 반환합니다.

SELECT COUNT(T1.account_id)
FROM account AS T1 INNER JOIN loan AS T2
  ON T1.account_id = T2.account_id
INNER JOIN district AS T3
  ON T1.district_id = T3.district_id WHERE T3."A3" = $1

맞춤 매개변수화 제공

add_template 함수의 수동 인터페이스를 사용하여 SQL 문에 맞춤 매개변수화를 제공하려면 다음 예시의 문을 실행합니다.

SELECT
  alloydb_ai_nl.add_template(
     nl_config_id => 'my_app_config',
     intent => 'Among the accounts opened, how many customers born before 1950 resided in Slokolov at the time of account opening?',
     sql => $$SELECT COUNT(DISTINCT T2.client_id)
              FROM district AS T1 INNER JOIN client AS T2
                ON T1.district_id = T2.district_id
             INNER JOIN account AS T3 ON T2.client_id IN (
                   SELECT client_id FROM disp WHERE account_id = T3.account_id)
             WHERE to_char(T2.birth_date::timestamp, 'YYYY') < '1950'
               AND T1."A2" = 'Slokolov'$$,
  parameterized_sql => $$SELECT COUNT(DISTINCT T2.client_id)
                         FROM district AS T1 INNER JOIN client AS T2
                           ON T1.district_id = T2.district_id
                   INNER JOIN account AS T3 ON T2.client_id IN (
                         SELECT client_id FROM disp WHERE account_id = T3.account_id)
                   WHERE to_char(T2.birth_date::timestamp, 'YYYY') < $2
                     AND T1."A2" = $1$$,
  parameterized_intent => $$Among the accounts opened, how many customers born before $2 resided in $1 at the time of account opening?$$,
  manifest => $$Among the accounts opened, how many customers born before a given date resided in a given city at the time of account opening?$$,
  check_intent => TRUE);

위의 정의에서는 SQL 문의 매개변수화가 제공됩니다. 매개변수는 각각 Slokolov1950$1$2입니다. 매니페스트는 의도의 일반화된 버전으로 제공되며, 여기서 리터럴 값은 값의 일반 설명으로 대체됩니다.

이 예시에서 인텐트의 1950 값은 a given date로 대체되고 매니페스트의 Slokolov 값은 a given city로 대체됩니다. 선택적 인수 check_intentTRUE 값이 제공되면 add_template 중에 LLM 기반 인텐트 확인이 실행됩니다. 이 검사 중에 제공된 SQL 문이 제공된 인텐트 문의 목적과 목표를 포착하지 못하면 add_template이 실패하고 이유가 출력으로 제공됩니다.

다음 예에서 템플릿의 목적은 인텐트에 표시된 대로 로드와 연결되고 특정 지역에 있는 계정의 계정 ID를 가져오는 것입니다. 제공된 SQL 문은 다음 예와 같이 계정 ID 목록이 아닌 계정 수를 반환합니다.

SELECT
  alloydb_ai_nl.add_template(
    nl_config_id => 'my_app_config',
    intent => 'List the account id for all accounts that associated with loans and are located in the Prague region.',
    sql => 'SELECT COUNT(T1.account_id)
            FROM account AS T1 INNER JOIN loan AS T2
              ON T1.account_id = T2.account_id
            INNER JOIN district AS T3
              ON T1.district_id = T3.district_id
            WHERE T3."A3" = ''Prague''',
    check_intent => TRUE
  );

check_intentTRUE로 설정된 경우 앞의 템플릿을 템플릿 스토어에 추가할 수 없습니다. 위 문을 실행하면 다음과 비슷한 오류가 반환됩니다.

ERROR:  Checking intent failed, for nl_question:List the account id for all accounts that associated with loans and are located in the Prague region...reason:The SQL query only counts the number of account IDs, but the question asks for a list of the account IDs.

템플릿 관리

다음 API를 사용하여 템플릿 저장소에서 템플릿을 관리할 수 있습니다.

-- To disable a template:
SELECT alloydb_ai_nl.disable_template(INPUT template_id);

-- To enable a template which has been disabled:
SELECT alloydb_ai_nl.enable_template(INPUT template_id);

-- To permanently remove a template:
SELECT alloydb_ai_nl.drop_template(INPUT template_id);

템플릿을 만들면 기본적으로 사용 설정됩니다. 사용 중지된 템플릿은 템플릿 저장소에 남아 있지만 alloydb_ai_nl에서 쿼리 합성에는 사용되지 않습니다. alloydb_ai_nl.enable_template를 사용하여 사용 중지된 템플릿을 사용 설정할 수 있습니다. alloydb_ai_nl.drop_template을 실행하면 템플릿이 템플릿 스토어에서 영구적으로 삭제됩니다.

콘텐츠가 주어지면 alloydb_ai_nl.template_store_view를 사용하여 템플릿의 template_id을 추출할 수 있습니다. 예를 들어 의도가 accounts that associated with loans인 템플릿의 식별자를 찾으려면 다음 쿼리를 실행하세요. 그러면 템플릿 식별자가 반환되고 템플릿이 alloydb_ai_nl.template_store_view에서 사용 설정되었는지 여부가 식별됩니다.

SELECT id, enabled
FROM alloydb_ai_nl.template_store_view
WHERE intent ILIKE '%accounts that associated with loans%';

템플릿 업데이트

alloydb_ai_nl.template_store_view에서 템플릿을 사용할 때는 모든 템플릿의 의도가 다음 사항과 일치하는지 확인하세요.

  • SQL 문
  • 매개변수화된 SQL 문
  • 매개변수화된 인텐트
  • 템플릿의 매니페스트

템플릿에 유지된 삽입이 템플릿 콘텐츠와 일치하는 경우 alloydb_ai_nl가 관련 템플릿을 가져올 수 있습니다.

템플릿을 업데이트하려면 다음 단계를 따르세요.

  1. alloydb_ai_nl.template_store_view을 사용하여 template_id를 식별합니다.
  2. 템플릿을 삭제합니다.
  3. alloydb_ai_nl.add_template 함수를 사용하여 필요한 수정사항이 포함된 새 템플릿을 재정의합니다.

쿼리 프래그먼트 만들기

프래그먼트를 사용하여 쿼리 시간에 템플릿을 전문화할 수 있습니다. 이렇게 하면 쿼리 템플릿이 자연어 질문과 같은 패싯 검색을 실행하는 데 도움이 됩니다. 프래그먼트는 해당 SQL 술어가 포함된 대표적이거나 일반적인 자연어 조건의 선별된 집합입니다. 프래그먼트는 애플리케이션에서 지정해야 합니다.

각 프래그먼트는 nl_config_id 및 프래그먼트 술어가 적용되는 테이블과 뷰의 배열(별칭 포함)과 연결되어야 합니다. check_intent 인수가 TRUE로 설정된 경우 프래그먼트의 용도를 확인할 수 있습니다. alloydb_ai_nl 확장 프로그램은 프래그먼트 조합이 포함된 템플릿을 사용하여 자연어 질문에 대한 답변을 합성할 수 있습니다.

alloydb_ai_nl 확장 프로그램은 fragment_store을 사용하여 최종 사용자의 질문에 답변하기 위한 SQL 문을 생성하는 과정에서 관련 프래그먼트의 조건을 동적으로 통합합니다. 먼저 template_store는 최종 사용자가 질문한 자연어 질문과 의도가 유사한 템플릿을 식별합니다. 다음으로 식별된 템플릿에 전문성을 제공할 수 있는 프래그먼트가 검색됩니다. 매개변수 대체는 템플릿과 프래그먼트에 모두 적용되어 SQL 문을 합성합니다.

매개변수 값은 자연어 질문에서 추출되며 관련 템플릿과 프레그먼트에서 암시된 패턴을 사용하여 LLM에 의해 대체됩니다. 하지만 템플릿과 프래그먼트의 조합이 최종 사용자가 질문한 내용과 동일한 목적을 갖지 않는 경우 alloydb_ai_nl는 모든 관련 템플릿과 컨텍스트를 사용하여 SQL 문을 구성합니다.

프래그먼트 추가

프래그먼트를 추가하려면 alloydb_ai_nl.add_fragment 함수를 사용하여 다음 예시 쿼리를 실행하세요. 각 프래그먼트는 애플리케이션의 nl_config_id 식별자와 연결되어야 합니다.

-- A fragment that cannot be parameterized.
SELECT alloydb_ai_nl.add_fragment(
  nl_config_id => 'my_app_config',
  table_aliases => ARRAY['account AS T'],
  intent => 'Accounts with issuance after transaction',
  fragment => 'T.frequency = ''POPLATEK PO OBRATU''',
  check_intent => True);

-- A fragment that can be parameterized.
SELECT alloydb_ai_nl.add_fragment(
  nl_config_id => 'my_app_config',
  table_aliases => ARRAY['district AS T'],
  intent => 'Average salary between 6000 and 10000',
  fragment => 'T."A11" BETWEEN 6000 AND 10000',
  check_intent => True);

alloydb_ai_nl.add_fragment가 실행되면 alloydb_ai_nl 확장 프로그램이 제공된 인텐트에서 매니페스트를 추출하고 확장 프로그램이 가능한 경우 프래그먼트의 인텐트와 조건을 매개변수화합니다. 사용 가능한 프래그먼트는 다음 예와 같이 alloydb_ai_nl.fragment_store_view와 같은 뷰에 의해 노출됩니다.

SELECT manifest, scope, fragment, intent, pfragment, pintent
FROM alloydb_ai_nl.fragment_store_view
WHERE intent = 'Average salary between 6000 and 10000';

이 쿼리는 다음과 유사한 결과 집합을 반환합니다.

manifest  | Average salary between a given number and a given number
scope     | district AS T
fragment  | T."A11" BETWEEN 6000 AND 10000
intent    | Average salary between 6000 and 10000
pfragment | T."A11" BETWEEN $2 AND $1
pintent   | Average salary between $2 and $1

프래그먼트의 매니페스트는 인텐트에서 자동으로 생성되며 인텐트의 일반화된 버전을 나타냅니다. 예를 들어 인텐트의 숫자 600010000은 각각 매니페스트의 a given number로 대체됩니다. 이 숫자는 pfragmentpintent 열에서 각각 $2$1로 바뀝니다. alloydb_ai_nl.fragment_store_viewpfragmentpintent 열은 각각 fragmentintent의 매개변수화된 표현입니다.

프래그먼트의 맞춤 매개변수화를 제공하려면 다음 예와 같이 alloydb_ai_nl.add_fragment의 수동 버전을 사용하세요.

SELECT alloydb_ai_nl.add_fragment(
  nl_config_id => 'my_app_config',
  table_aliases => ARRAY['bird_dev_financial.district AS T'],
  intent => $$districts in 'Prague'$$,
  parameterized_intent => $$districts in $1$$,
  fragment => $$T."A3" = 'Prague'$$,
  parameterized_fragment => $$T."A3" = $1$$,
  manifest => $$districts in a given city$$,
  check_intent => TRUE);

프래그먼트 관리

프래그먼트를 관리하려면 다음 API를 사용하세요.

-- To disable a fragment:
SELECT alloydb_ai_nl.disable_fragment(INPUT fragment_id);

-- To enable a fragment which has been disabled:
SELECT alloydb_ai_nl.enable_fragment(INPUT fragment_id);

-- To permanently remove a fragment:
SELECT alloydb_ai_nl.drop_fragment(INPUT fragment_id);

콘텐츠가 지정된 프래그먼트의 fragment_id을 추출하려면 alloydb_ai_nl.fragment_store_view 뷰를 사용하면 됩니다. 예를 들어 인텐트가 Average salary between 6000 and 10000인 프래그먼트의 식별자를 찾으려면 다음 예시 쿼리를 실행합니다.

SELECT id
FROM alloydb_ai_nl.fragment_store_view
WHERE intent = "Average salary between 6000 and 10000";

프래그먼트 업데이트

프래그먼트를 업데이트할 때는 프래그먼트 인텐트가 다음 항목과 일치해야 합니다.

  • 프래그먼트의 매니페스트 및 SQL 문
  • 매개변수화된 SQL 문
  • 매개변수화된 인텐트

프래그먼트를 업데이트할 때 일관성을 유지하려면 다음 단계를 따르세요.

  1. alloydb_ai_nl.drop_fragment 함수를 사용하여 수정하려는 프래그먼트를 삭제합니다.
  2. alloydb_ai_nl.add_fragment 함수를 사용하여 업데이트된 프래그먼트를 삽입합니다.

템플릿 자동 생성

테이블에 대표적인 데이터 세트가 있으면 최종 사용자가 자주 묻는 질문에 해당하는 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 자연어는 값 색인에 대해 United States 값 문구와 함께 get_concept_and_value 함수를 사용하여 퍼지 검색을 실행합니다. 퍼지 검색은 검색어와 해당 데이터가 정확히 일치하지 않더라도 일치 항목을 찾는 검색 기법입니다.

    자연어는 검색어와 유사한 결과(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_name, city_name, region_name 국가, 도시, 지역 이름 사용법은 generic_entity_name 개념 유형과 정확히 동일합니다.
    full_person_name 이름, 성, 중간 이름으로 구성된 사람 이름입니다. 최대 3개의 문자열 유형 열을 전체 이름에 사용할 수 있습니다. 이름 열을 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')
     

개념 유형 연결 자동 생성

열을 개념 유형과 자동으로 연결하려면 AlloyDB AI 자연어 API의 자동 개념 유형 연결 기능을 사용하세요. 개념 유형 연결은 개념 유형과 하나 이상의 데이터베이스 열 간의 관계를 정의하며, 이는 값 색인을 만드는 데 필요한 전제 조건입니다.

콘셉트 유형 연결을 자동 생성하려면 다음 단계를 따르세요.

  1. 연결을 생성하려면 다음 API를 호출하세요.

    -- To cover all relations within the scope of a provided nl_config.
    SELECT alloydb_ai_nl.generate_concept_type_associations(
      nl_config => 'my_app_config'
    );
    
    -- To cover a specific relation.
    SELECT alloydb_ai_nl.generate_concept_type_associations(
      nl_config => 'my_app_config',
      relation_name => 'my_app_table'
    );
    
  2. 다음 쿼리를 실행하여 생성된 연결을 검토합니다.

    SELECT * FROM alloydb_ai_nl.generated_value_index_columns_view;
    
  3. 선택사항: 생성된 연결을 업데이트합니다.

    -- NULL means keeping the original value.
    SELECT alloydb_ai_nl.update_generated_concept_type_associations(
      id => 1,
      column_names => NULL,
      concept_type => 'generic_entity_name',
      additional_info => NULL
    );
    
  4. 선택사항: 생성된 연결을 삭제합니다.

    SELECT alloydb_ai_nl.drop_generated_concept_type_association(id => 1);
    
  5. 생성된 연결을 적용합니다.

    -- To apply all associations under a nl config.
    SELECT alloydb_ai_nl.apply_generated_concept_type_associations(
      nl_config => 'my_app_config'
    );
    
    -- To apply a specific association by id.
    SELECT alloydb_ai_nl.apply_generated_concept_type_association(
      id => 1
    );
    
  6. 변경사항을 반영하도록 값 색인을 새로고침합니다.

    SELECT alloydb_ai_nl.refresh_value_index(
      nl_config_id_in => 'my_app_config'
    );
    

자연어 입력에서 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 쿼리입니다.

자연어 입력에서 결과 요약 생성

AlloyDB AI 자연어를 사용하여 자연어 입력에서 결과 요약을 생성할 수 있습니다. alloydb_ai_nl.get_sql_summary 함수는 기본 테이블에서 자연어 질문을 안전하게 실행하고, 결과 집합의 샘플을 요약하고, 요약을 자연어로 반환합니다.

데이터베이스의 자연어 질문에 대한 결과 요약을 생성하려면 다음 예와 같이 alloydb_ai_nl.get_sql_summary 함수를 사용합니다.

SELECT
  alloydb_ai_nl.get_sql_summary(
    nl_config_id => 'my_app_config',
    nl_question => 'Give me the total number of accounts and the earliest opening date and other information for accounts who choose issuance after transaction are staying in east Bohemia region?');

위의 명령문을 호출하면 다음 JSON 객체가 생성됩니다.

{
  "answer": "The result set indicates that there are 13 accounts that chose issuance after a transaction and are located in the East Bohemia region. The earliest opening date among these accounts is August 21, 1993. Other information about these accounts is not provided in the result set."
}

하나 이상의 파라미터화된 보안 뷰를 사용하여 alloydb_ai_nl.get_sql_summary에서 쿼리가 액세스하는 테이블과 뷰를 보호할 수 있습니다. 매개변수 이름과 값은 애플리케이션에서 사용할 수 있으며 alloydb_ai_nl.get_sql_summary에서 필요합니다.

예를 들어 애플리케이션은 사용자 ID가 123인 인증된 사용자에 대해 user_id 매개변수를 제공할 수 있습니다. 다음 예와 같이 param_namesparam_values 입력을 제공하여 이를 달성합니다.

SELECT
  alloydb_ai_nl.get_sql_summary(
    nl_config_id => 'my_app_config',
    nl_question => 'Give me the total number of accounts and the earliest opening date and other information for accounts who choose issuance after transaction are staying in east Bohemia region?',
    param_names => ARRAY ['user_id'],
    param_values => ARRAY ['123']
);

param_namesparam_values 인수를 제공하면 nl_question에 매개변수화된 보안 뷰로 시행되는 SQL 문으로 답변할 수 있는 경우 결과 집합이 생성되고 요약이 생성될 때 지정된 보안 필터가 적용됩니다.

테스트 및 개선

자동 생성된 쿼리를 개선하려면 더 나은 컨텍스트, 쿼리 템플릿, 값 색인을 수정하거나 추가한 다음 원하는 결과가 나올 때까지 반복합니다.

다음 단계