자연어를 사용하여 데이터베이스 쿼리

이 페이지에서는 AlloyDB Omni에서 제공되는 미리보기를 설명합니다. 이 미리보기에서는 자연어를 사용하여 데이터베이스를 쿼리하는 실험을 할 수 있습니다.

개요

AlloyDB Omni를 사용하여 데이터베이스 기반 애플리케이션이 '내 제품은 어디에 있나요?' 또는 '각 부서에서 가장 많은 수익을 올리는 사람은 누구인가요?'와 같은 애플리케이션 사용자의 자연어 쿼리를 더 안전하게 실행할 수 있는 일련의 실험용 기능을 미리 볼 수 있습니다. AlloyDB Omni은 자연어 입력을 데이터베이스별 SQL 쿼리로 변환하여 애플리케이션 사용자에게 표시할 수 있는 결과로만 결과를 제한합니다.

자연어 쿼리의 강점과 위험

Gemini Pro와 같은 대규모 언어 모델을 사용하면 애플리케이션이 애플리케이션의 최종 사용자가 만든 자연어 쿼리를 기반으로 데이터베이스 쿼리를 실행할 수 있습니다. 예를 들어 애플리케이션의 데이터베이스 스키마에 액세스할 수 있는 모델은 다음과 같은 최종 사용자 입력을 받을 수 있습니다.

What are the cheapest direct flights from Boston to Denver in July?

다음과 같이 SQL 쿼리로 변환합니다.

SELECT flight.id, flight.price, carrier.name, [...]
FROM [...]
WHERE [...]
ORDER BY flight.price ASC 
LIMIT 10

자연어 쿼리를 사용하면 애플리케이션에서 사용자에게 서비스를 제공하는 데 강력한 도구를 사용할 수 있습니다. 하지만 이 기술에는 최종 사용자가 데이터베이스 테이블에서 임의의 쿼리를 실행하도록 허용하기 전에 고려해야 하는 명확한 보안 위험도 있습니다. 제한된 액세스 권한을 가진 읽기 전용 데이터베이스 사용자로 데이터베이스에 연결하도록 애플리케이션을 구성했더라도 자연어 쿼리를 유도하는 애플리케이션은 다음에 취약할 수 있습니다.

  • 악의적인 사용자는 기본 모델을 조작하여 애플리케이션이 액세스할 수 있는 모든 데이터를 공개하려고 시도하는 프롬프트 삽입 공격을 제출할 수 있습니다.
  • 모델 자체가 적절하지 않은 범위의 SQL 쿼리를 생성하여 의도치 않은 사용자 쿼리에 대한 응답으로 민감한 정보를 노출할 수 있습니다.

매개변수화된 보안 뷰로 쿼리 정리

이전 섹션에 설명된 위험을 완화하기 위해 Google에서는 이 페이지에 설명된 기술을 사용하여 미리 볼 수 있는 실험용 기능인 매개변수화된 보안 뷰를 개발했습니다.

파라미터화된 보안 뷰를 사용하면 자연어 쿼리에서 데이터를 가져올 수 있는 테이블과 열을 명시적으로 정의하고 개별 애플리케이션 사용자가 사용할 수 있는 행 범위에 추가 제한사항을 추가할 수 있습니다. 이러한 제한을 사용하면 사용자가 자연어 쿼리를 어떻게 표현하든 애플리케이션 사용자가 자연어 쿼리를 통해 볼 수 있는 데이터를 엄격하게 제어할 수 있습니다.

이 미리보기를 사용 설정하면 Google에서 개발한 실험용 확장 프로그램인 alloydb_ai_nlparameterized_views에 액세스할 수 있습니다.

parameterized_views 확장 프로그램은 다음과 같은 기능을 제공합니다.

  • 매개변수화된 보안 뷰: 쿼리가 액세스할 수 있는 데이터 범위를 제한하기 위한 SQL 뷰의 변형입니다.
  • 매개변수가 있는 안전한 뷰를 쿼리할 수 있는 execute_parameterized_views() 함수

alloydb_ai_nl 확장 프로그램은 다음 기능을 제공합니다.

  • 자연어 쿼리를 현재 스키마의 테이블 및 뷰에 관한 SQL 쿼리로 변환하는 google_get_sql_current_schema() 함수

다음 섹션에서는 이러한 기능을 사용하는 방법을 설명하고 이러한 기능이 함께 작동하는 방식을 보여줍니다.

시작하기 전에

AI 모델 통합을 포함하여 AlloyDB Omni 버전 15.5.1 이상을 설치합니다. 자세한 내용은 PostgreSQL용 AlloyDB AI로 AlloyDB Omni 설치를 참고하세요.

매개변수가 있는 보안 뷰를 위해 데이터베이스 설정

  1. psql를 사용하여 AlloyDB Omni 클러스터에 연결합니다.

  2. shared_preload_libraries 지시문의 값에 alloydb_ai_nlparameterized_views가 포함되도록 /var/alloydb/config/postgresql.conf의 콘텐츠를 수정합니다. 수정된 지시어는 다음과 비슷하게 표시됩니다.

    shared_preload_libraries='g_stats,google_job_scheduler,google_insights,pg_stat_statements,google_db_advisor,google_columnar_engine,alloydb_ai_nl,parameterized_views'
    
  3. AlloyDB Omni를 중지합니다.

  4. AlloyDB Omni 시작

  5. alloydb_ai_nlparameterized_views 확장 프로그램을 사용 설정합니다.

    CREATE EXTENSION google_ml_integration;
    ALTER SYSTEM SET google_ml_integration.enable_model_support=on;
    ALTER SYSTEM SET alloydb_ai_nl.enabled=on;
    ALTER SYSTEM SET parameterized_views.enabled=on;
    SELECT pg_reload_conf();
    CREATE EXTENSION alloydb_ai_nl CASCADE;
    CREATE EXTENSION parameterized_views;
    
  6. 모델 엔드포인트 관리를 사용하여 Gemini Pro API를 기반으로 새 언어 모델을 등록합니다.

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

    다음을 바꿉니다.

  7. 새 데이터베이스 사용자를 만듭니다. 아직 권한이나 역할을 부여하지 마세요. 이 절차의 후속 단계에서는 사용자에게 필요한 권한을 부여합니다.

매개변수화된 보안 뷰

매개변수가 있는 보안 뷰는 기본적으로 저장된 SELECT 문인 일반 PostgreSQL 보안 뷰와 매우 유사하게 작동합니다. 매개변수가 있는 보안 뷰를 사용하면 쿼리할 때 뷰에 전달되는 하나 이상의 이름이 지정된 매개변수 값을 요구할 수 있습니다. 이는 일반 데이터베이스 쿼리의 바인드 변수와 유사합니다.

예를 들어 고객에게 상품 배송을 추적하는 데이터베이스가 있는 애플리케이션을 실행한다고 가정해 보겠습니다. 사용자가 쿼리 Where is my package?에서 12345 유형의 ID로 이 애플리케이션에 로그인했습니다. 매개변수가 있는 보안 뷰를 사용하면 PostgreSQL용 AlloyDB에서 이 쿼리를 실행하는 방식에 다음 요구사항이 적용되도록 할 수 있습니다.

  • 쿼리는 데이터베이스의 매개변수화된 보안 뷰에 명시적으로 나열된 데이터베이스 열만 읽을 수 있습니다. 이 경우 items, users, shipments 테이블의 특정 열일 수 있습니다.
  • 쿼리는 쿼리를 요청한 사용자와 연결된 데이터베이스 행만 읽을 수 있습니다. 이 경우 반환된 행이 id 열 값이 12345users 테이블 행과 데이터 관계를 가져야 할 수 있습니다.

매개변수가 있는 보안 뷰 만들기

매개변수가 있는 보안 뷰를 만들려면 다음 속성과 함께 PostgreSQL CREATE VIEW DDL 명령어를 사용하세요.

  • security_barrier 옵션으로 뷰를 만듭니다.
  • 애플리케이션 사용자가 볼 수 있는 행만 볼 수 있도록 제한하려면 WHERE 절에 $@PARAMETER_NAME 문법을 사용하여 필수 매개변수를 추가합니다. 일반적인 사례는 WHERE COLUMN = $@PARAMETER_NAME를 사용하여 열 값을 확인하는 것입니다.

다음 예시에서는 매개변수가 지정된 보안 뷰를 사용하여 users이라는 테이블의 세 열에 액세스할 수 있으며 users.id이 필수 매개변수와 일치하는 행으로만 결과를 제한합니다.

CREATE VIEW user_psv WITH (security_barrier) AS 
SELECT 
  username,
  full_name,
  birthday
FROM 
  users
WHERE 
  users.id = $@user_id; 

매개변수가 있는 보안 뷰의 핵심인 SELECT 문은 일반 PostgreSQL 뷰에서 허용되는 문만큼 복잡할 수 있습니다.

뷰를 만든 후에는 이전에 만든 사용자에게 뷰에서 SELECT 쿼리를 실행할 권한을 부여해야 합니다.

GRANT SELECT ON VIEW_NAME TO NL_DB_USER;

다음을 바꿉니다.

  • VIEW_NAME: 이전 단계에서 만든 뷰의 이름입니다.
  • NL_DB_USER: 자연 언어 쿼리를 실행하도록 지정한 데이터베이스 사용자의 이름입니다.

매개변수화된 보안 뷰 쿼리

일반 PostgreSQL 뷰와 유사하지만 매개변수가 있는 보안 뷰는 직접 쿼리할 수 없습니다. 대신 parameterized_views 확장 프로그램에서 제공하는 execute_parameterized_query() 함수를 사용합니다. 이 함수의 문법은 다음과 같습니다.

SELECT * FROM
parameterized_views.execute_parameterized_query(
    query => SQL_QUERY
    param_names => ARRAY [PARAMETER_NAMES],
    param_values => ARRAY [PARAMETER_VALUES]
)

다음을 바꿉니다.

  • SQL_QUERY: FROM 절이 하나 이상의 매개변수화된 보안 뷰를 참조하는 SQL 쿼리입니다.
  • PARAMETER_NAMES: 전달할 매개변수 이름 목록(문자열)입니다.
  • PARAMETER_VALUES: 전달할 매개변수 값 목록입니다. 이 목록은 param_names 목록과 크기가 같아야 합니다. 값의 순서는 이름의 순서와 일치합니다.

이 함수는 JSON 객체 테이블을 반환합니다. 테이블의 각 행은 원래 쿼리 결과 행의 row_to_json() 값과 같습니다.

일반적으로 query 인수의 값은 자체 코드가 아니라 PostgreSQL용 AlloyDB 데이터베이스를 통합한 AI 모델에 의해 생성됩니다.

다음 예에서는 Python에서 매개변수화된 보안 뷰를 쿼리한 후 결과를 표시하는 방법을 보여줍니다. 이전 섹션의 user_psv 예시 뷰를 기반으로 합니다.

# Assume a get_user_id() function that returns the ID of the current
# application user.
app_user_id = get_user_id()

pool = await asyncpg.create_pool(
    host=INSTANCE_IP
    user=NL_DB_USER
    password=NL_DB_PASSWORD
    database=DB_NAME
)

table_name = "user_psv"

query = f"""
    SELECT 
      full_name,
      birthday
    FROM 
      {table_name} 
"""
params = {
    "user_id": app_user_id
}

param_query = f"""
SELECT * FROM parameterized_views.execute_parameterized_query(
  query => '{query}',
  param_names => $1,
  param_values => $2
);
"""

sql_results = await pool.execute(
    param_query, 
    params.keys(), 
    params.values()
)

for row in sql_results:
    print(json.loads(row))

자연어 쿼리 실행

매개변수화된 보안 뷰를 사용하여 자연어 쿼리를 실행하는 방법은 다음과 같은 두 단계로 이루어집니다.

  1. 적절한 매개변수화된 보안 뷰에 대한 SELECT 액세스 권한만 있는 데이터베이스 사용자는 대규모 언어 모델을 사용하여 자연어 쿼리를 SQL로 변환합니다.
  2. execute_parameterized_query() 함수를 사용하여 SQL을 처리하고 현재 사용자 세션에 적합한 매개변수 값에 바인딩합니다.

다음 섹션에서는 이러한 단계를 자세히 설명합니다.

자연어를 SQL로 변환

자연 언어 입력을 SQL로 변환하려면 매개변수가 있는 보안 뷰 기술 미리보기에 포함된 google_get_sql_current_schema() 함수를 사용하세요.

SELECT alloydb_ai_nl.google_get_sql_current_schema(
  sql_text => 'NL_TEXT',
  model_id => 'MODEL_ID',
  prompt_text => 'HINT_TEXT'
);

다음을 바꿉니다.

  • NL_TEXT: SQL 쿼리로 변환할 자연어 텍스트입니다.
  • MODEL_ID: 매개변수화된 보안 뷰용 데이터베이스를 설정할 때 모델 카탈로그에 등록한 모델의 ID입니다.
  • HINT_TEXT: 자연 언어로 표현된 데이터베이스 스키마에 관한 추가 정보입니다. 이렇게 하면 테이블, 열, 관계 구조를 분석하는 것만으로는 추출하지 못할 수 있는 스키마의 중요한 측면에 관한 추가 힌트를 모델에 제공할 수 있습니다. 예를 들면 다음과 같습니다. When joining flights and seats, be sure to join on flights.id = seats.flight_id.

함수의 출력은 SQL 쿼리가 포함된 문자열입니다.

매개변수를 사용하여 변환된 SQL 실행

자연어 쿼리를 SQL로 변환한 후 이 페이지 앞부분에 설명된 대로 execute_parameterized_views()를 호출하여 매개변수화된 보안 뷰에 필요한 매개변수를 전달할 수 있습니다.

이 함수는 지정된 쿼리와 함께 필요한 것보다 더 많은 매개변수를 전달하면 작동하므로 애플리케이션에 값이 있는 모든 매개변수화된 보안 뷰에서 사용하는 모든 매개변수를 사용하여 호출할 수 있습니다. 정의되지 않은 매개변수가 필요한 쿼리를 실행하려고 하면 함수에서 예외가 발생합니다.

자연어 쿼리 실행의 예

이 섹션에서는 자연어 입력에서 SQL 결과 집합으로의 전체 흐름을 보여줍니다. 코드 샘플은 애플리케이션이 실행하는 기본 SQL 쿼리 및 함수를 보여줍니다.

이 흐름 예에서는 애플리케이션에 대해 다음을 가정합니다.

  • 데이터베이스 기반 애플리케이션이 고객에게 제품 배송을 추적합니다.
  • 모델 카탈로그에 my-gemini-model라는 Gemini Pro 기반 모델을 등록했습니다.
  • 데이터베이스에 shipment_view라는 매개변수가 있는 보안 뷰를 정의했습니다.
    • 이 뷰는 고객 배송과 관련된 여러 테이블에서 데이터를 선택합니다.
    • 뷰에는 user_id 매개변수가 필요하며, 이 매개변수의 값은 애플리케이션 최종 사용자의 ID입니다.
  1. 애플리케이션 사용자 ID가 12345인 최종 사용자가 웹 애플리케이션에 '내 패키지는 어디에 있나요?'라고 입력합니다.
  2. 애플리케이션은 google_get_sql_current_schema()를 호출하여 입력을 SQL로 변환합니다.

    SELECT alloydb_ai_nl.google_get_sql_current_schema(
      sql_text => 'Where is my package?'
      model_id => 'my-gemini-model'
    );
    

    이 호출은 단일 SQL SELECT 쿼리가 포함된 문자열을 반환합니다. 쿼리는 매개변수화된 보안 뷰를 사용하기 위해 만든 데이터베이스 사용자에게 표시되는 매개변수화된 보안 뷰로만 제한됩니다.

    Where is my package?에서 생성된 SQL은 다음과 유사할 수 있습니다.

    SELECT current_location, ship_date, ship_eta FROM shipment_view;
    

    shipment_view는 일반 PostgreSQL 뷰가 아닌 매개변수가 지정된 보안 뷰이므로 애플리케이션은 다음 단계와 같이 execute_parameterized_views()를 사용하여 필요한 user_id 매개변수와 함께 쿼리를 안전하게 실행해야 합니다.

  3. 애플리케이션은 출력을 제한하는 매개변수와 함께 SQL을 execute_parameterized_views()에 전달합니다. 이 예에서는 입력을 제공한 애플리케이션 최종 사용자의 ID입니다.

    SELECT * FROM
    parameterized_views.execute_parameterized_views(
        query => 'SELECT current_location, ship_date, ship_eta FROM shipment_view',
        param_names => ['user_id'],
        param_values => ['12345']
    );
    
    

    출력은 JSON 데이터로 표현된 SQL 결과 집합입니다.

  4. 애플리케이션은 필요에 따라 JSON 데이터를 처리합니다.

자연어 처리를 위한 데이터베이스 설계

이 기술 미리보기와 함께 제공되는 google_get_sql_current_schema() 함수는 주로 매개변수가 지정된 보안 뷰의 기능을 보여주는 역할을 하며, 이를 통해 개발 중인 이 기술을 조기에 실험할 수 있습니다. 다른 미리보기와 마찬가지로 프로덕션의 애플리케이션에는 이 함수를 적용하면 안 됩니다.

이를 염두에 두고 이 섹션의 조언을 적용하여 google_get_sql_current_schema() 실험 중에 google_get_sql_current_schema() 출력의 품질을 개선할 수 있습니다.

인간의 이해를 위한 스키마 설계

일반적으로 데이터베이스 구조에 이름과 주석을 명확하게 지정하여 일반적인 개발자가 테이블, 열, 관계의 목적을 추론할 수 있도록 합니다. 이렇게 하면 대규모 언어 모델이 스키마를 기반으로 더 정확한 SQL 쿼리를 생성하는 데 도움이 됩니다.

설명이 포함된 이름 사용

테이블, 열, 관계의 이름은 설명적인 이름을 사용하는 것이 좋습니다. 약어 또는 축약어는 피하세요. 예를 들어 u라는 테이블보다 users라는 테이블에서 모델이 더 잘 작동합니다.

기존 데이터 구조의 이름을 바꿀 수 없는 경우 google_get_sql_current_schema()를 호출할 때 prompt_text 인수를 사용하여 모델에 힌트를 제공합니다.

특정 데이터 유형 사용

열에 더 구체적인 데이터 유형을 사용하면 모델이 데이터에 관해 더 정확하게 추론할 수 있습니다. 예를 들어 열을 참 또는 거짓 값을 저장하는 데만 사용하는 경우 10가 있는 integer 대신 truefalse가 있는 boolean 데이터 유형을 사용하세요.

미리보기를 사용 설정한 후 주의해서 롤백

데이터베이스에서 매개변수가 지정된 보안 보기 기술 미리보기를 사용 설정했지만 AlloyDB Omni를 15.5.0 이전 버전으로 롤백하기로 결정한 경우 다운그레이드하기 전에 몇 가지 수동 정리 단계를 수행해야 합니다.

이 단계를 수행하지 않으면 매개변수가 있는 보안 뷰를 쿼리, 수정 또는 삭제하려고 하면 SQL 오류가 발생합니다. 여기에는 SELECT * FROM pg_views와 같이 결과에 매개변수가 있는 보안 뷰가 포함되는 데이터베이스의 뷰 카탈로그에 대한 쿼리가 포함됩니다.

AlloyDB Omni 롤백 전에 데이터베이스에서 이 기술 미리보기를 완전히 삭제하려면 다음 단계를 따르세요.

  1. psql에서 DROP VIEW 명령어를 사용하여 데이터베이스의 모든 매개변수화된 보안 뷰를 삭제합니다.

  2. psql에서 DROP EXTENSION 명령어를 사용하여 데이터베이스에서 alloydb_ai_nlparameterized_views 확장 프로그램을 사용 중지합니다.

  3. postgresql.conf 파일에서 shared_preload_libraries 지시문에서 alloydb_ai_nlparameterized_views 참조를 삭제합니다.

AlloyDB Omni 설치 롤백에 관한 자세한 내용은 업그레이드 롤백을 참고하세요.