Membuat kueri database menggunakan bahasa alami

Halaman ini menjelaskan pratinjau yang tersedia dengan AlloyDB Omni yang memungkinkan Anda bereksperimen dengan membuat kueri database menggunakan bahasa alami.

Ringkasan

Anda dapat menggunakan AlloyDB Omni untuk melihat pratinjau serangkaian fitur eksperimental yang memungkinkan aplikasi berbasis database Anda menjalankan kueri bahasa alami dari pengguna aplikasi Anda dengan lebih aman, seperti "Di mana paket saya?" atau "Siapa penghasil teratas di setiap departemen?" AlloyDB Omni menerjemahkan input bahasa natural menjadi kueri SQL khusus untuk database Anda, yang membatasi hasil hanya pada hal yang diizinkan untuk dilihat oleh pengguna aplikasi Anda.

Kekuatan dan risiko kueri bahasa alami

Model bahasa besar, seperti Gemini Pro, dapat memungkinkan aplikasi Anda menjalankan kueri database berdasarkan kueri bahasa alami yang dibuat oleh pengguna akhir aplikasi Anda. Misalnya, model dengan akses ke skema database aplikasi Anda dapat mengambil input pengguna akhir seperti ini:

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

Dan terjemahkan ke dalam kueri SQL seperti ini:

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

Kueri bahasa alami dapat memberikan alat yang efektif bagi aplikasi Anda untuk melayani pengguna. Namun, teknologi ini juga memiliki risiko keamanan yang jelas yang harus Anda pertimbangkan sebelum mengizinkan pengguna akhir menjalankan kueri arbitrer di tabel database Anda. Meskipun Anda telah mengonfigurasi aplikasi untuk terhubung ke database sebagai pengguna database hanya baca dengan akses terbatas, aplikasi yang mengundang kueri bahasa alami dapat rentan terhadap hal berikut:

  • Pengguna berbahaya dapat mengirimkan serangan injeksi perintah, yang mencoba memanipulasi model yang mendasarinya untuk mengungkapkan semua data yang dapat diakses oleh aplikasi.
  • Model itu sendiri mungkin menghasilkan kueri SQL yang cakupannya lebih luas daripada yang sesuai, sehingga mengungkapkan data sensitif sebagai respons terhadap kueri pengguna yang bermaksud baik.

Membersihkan kueri dengan tampilan aman berparameter

Untuk membantu mengurangi risiko yang dijelaskan di bagian sebelumnya, Google telah mengembangkan tampilan aman berparameter, fitur eksperimental yang dapat Anda lihat pratinjaunya menggunakan teknik yang dijelaskan di halaman ini.

Tampilan aman berparameter memungkinkan Anda menentukan tabel dan kolom secara eksplisit yang dapat diambil datanya oleh kueri bahasa alami, dan menambahkan batasan tambahan pada rentang baris yang tersedia untuk setiap pengguna aplikasi. Pembatasan ini memungkinkan Anda mengontrol dengan ketat data yang dapat dilihat oleh pengguna aplikasi melalui kueri bahasa alami, terlepas dari bagaimana pengguna Anda menyusun kueri ini.

Jika mengaktifkan Pratinjau ini, Anda akan mendapatkan akses ke ekstensi eksperimental yang dikembangkan oleh Google yang disebut alloydb_ai_nl dan parameterized_views.

Ekstensi parameterized_views menyediakan fitur berikut:

  • Tampilan aman berparameter, varian tampilan SQL untuk membatasi rentang data yang dapat diakses oleh kueri.
  • Fungsi execute_parameterized_views(), yang memungkinkan Anda membuat kueri tampilan aman berparameter.

Ekstensi alloydb_ai_nl menyediakan fitur berikut:

  • Fungsi google_get_sql_current_schema(), yang mengonversi kueri bahasa alam menjadi kueri SQL tabel dan tampilan dalam skema Anda saat ini.

Bagian berikut menjelaskan cara menggunakan fitur ini, dan menunjukkan cara fitur tersebut dapat bekerja sama.

Sebelum memulai

Instal AlloyDB Omni versi 15.5.1 atau yang lebih baru, termasuk integrasi model AI. Untuk informasi selengkapnya, lihat Menginstal AlloyDB Omni dengan AlloyDB untuk PostgreSQL AI.

Menyiapkan database untuk tampilan aman berparameter

  1. Hubungkan ke cluster AlloyDB Omni menggunakan psql.

  2. Edit konten /var/alloydb/config/postgresql.conf sehingga nilai perintah shared_preload_libraries menyertakan alloydb_ai_nl & parameterized_views. Perintah yang diedit akan terlihat seperti berikut:

    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. Hentikan AlloyDB Omni.

  4. Mulai AlloyDB Omni.

  5. Aktifkan ekstensi alloydb_ai_nl & parameterized_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. Daftarkan model bahasa baru berdasarkan Gemini Pro API dengan pengelolaan endpoint Model:

    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');
    

    Ganti kode berikut:

  7. Buat pengguna database baru. Jangan berikan izin atau peran apa pun. Langkah berikutnya dalam prosedur ini akan memberikan izin yang diperlukan kepada pengguna.

Tampilan aman berparameter

Tampilan aman berparameter berfungsi seperti tampilan aman PostgreSQL biasa: pada dasarnya, pernyataan SELECT yang disimpan. Tampilan aman berparameter juga memungkinkan Anda mewajibkan satu atau beberapa nilai parameter bernama yang diteruskan ke tampilan saat membuat kueri, agak mirip dengan variabel pengikatan dengan kueri database biasa.

Misalnya, bayangkan menjalankan aplikasi yang database-nya melacak pengiriman item ke pelanggan. Pengguna login ke aplikasi ini dengan ID jenis 12345 dalam kueri Where is my package?. Dengan menggunakan tampilan aman berparameter, Anda dapat memastikan bahwa persyaratan berikut berlaku untuk cara AlloyDB untuk PostgreSQL menjalankan kueri ini:

  • Kueri hanya dapat membaca kolom database yang telah Anda cantumkan secara eksplisit dalam tampilan aman berparameter database. Dalam hal ini, kolom tersebut mungkin adalah kolom tertentu dalam tabel items, users, dan shipments.
  • Kueri hanya dapat membaca baris database yang terkait dengan pengguna yang menanyakan kueri. Dalam hal ini, hal tersebut mungkin mengharuskan baris yang ditampilkan memiliki hubungan data dengan baris tabel users yang nilai kolom id-nya adalah 12345.

Membuat tampilan aman berparameter

Untuk membuat tampilan aman berparameter, gunakan perintah DDL CREATE VIEW PostgreSQL dengan atribut berikut:

  • Buat tampilan dengan opsi security_barrier.
  • Untuk membatasi pengguna aplikasi agar hanya melihat baris yang diizinkan untuk dilihat, tambahkan parameter yang diperlukan menggunakan sintaksis $@PARAMETER_NAME dalam klausa WHERE. Kasus umum adalah memeriksa nilai kolom menggunakan WHERE COLUMN = $@PARAMETER_NAME.

Contoh tampilan aman berparameter berikut memungkinkan akses ke tiga kolom dari tabel bernama users, dan membatasi hasil hanya ke baris tempat users.id cocok dengan parameter yang diperlukan:

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

Pernyataan SELECT di inti tampilan aman berparameter dapat sesulit pernyataan yang diizinkan oleh tampilan PostgreSQL biasa.

Setelah membuat tampilan, Anda harus memberikan izin kepada pengguna yang dibuat sebelumnya untuk menjalankan kueri SELECT pada tampilan:

GRANT SELECT ON VIEW_NAME TO NL_DB_USER;

Ganti kode berikut:

  • VIEW_NAME: Nama tampilan yang Anda buat di langkah sebelumnya.
  • NL_DB_USER: Nama pengguna database yang telah Anda tetapkan untuk menjalankan kueri bahasa alami.

Membuat kueri tampilan aman berparameter

Meskipun mirip dengan tampilan PostgreSQL biasa, Anda tidak dapat membuat kueri tampilan pengamanan berparameter secara langsung. Sebagai gantinya, Anda menggunakan fungsi execute_parameterized_query() yang disediakan oleh ekstensi parameterized_views. Fungsi ini memiliki sintaksis berikut:

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

Ganti kode berikut:

  • SQL_QUERY: Kueri SQL yang klausa FROM-nya merujuk ke satu atau beberapa tampilan aman berparameter.
  • PARAMETER_NAMES: Daftar nama parameter yang akan diteruskan, sebagai string.
  • PARAMETER_VALUES: Daftar nilai parameter yang akan diteruskan. Daftar ini harus berukuran sama dengan daftar param_names. Urutan nilai cocok dengan urutan nama.

Fungsi ini menampilkan tabel objek JSON. Setiap baris dalam tabel setara dengan nilai row_to_json() dari baris hasil kueri asli.

Dalam penggunaan biasa, nilai argumen query dihasilkan bukan oleh kode Anda sendiri, tetapi oleh model AI yang telah Anda integrasikan dengan database AlloyDB untuk PostgreSQL.

Contoh berikut menunjukkan cara membuat kueri tampilan aman berparameter di Python, lalu menampilkan hasilnya. Contoh ini dibuat berdasarkan tampilan contoh user_psv dari bagian sebelumnya:

# 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))

Menjalankan kueri bahasa alami

Menjalankan kueri bahasa alami menggunakan tampilan aman berparameter adalah proses dua langkah:

  1. Sebagai pengguna database yang hanya memiliki akses SELECT ke tampilan aman berparameter yang sesuai, konversikan kueri bahasa alami ke SQL menggunakan model bahasa besar.
  2. Gunakan fungsi execute_parameterized_query() untuk memproses SQL, dengan mengikat nilai parameter yang sesuai dengan sesi pengguna saat ini.

Bagian berikut menjelaskan langkah-langkah ini secara lebih mendetail.

Mengonversi bahasa alami ke SQL

Untuk menerjemahkan input bahasa alami ke dalam SQL, gunakan fungsi google_get_sql_current_schema() yang disertakan dengan pratinjau teknologi tampilan aman berparameter:

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

Ganti kode berikut:

  • NL_TEXT: Teks dalam bahasa alami yang akan diubah menjadi kueri SQL.
  • MODEL_ID: ID model yang Anda daftarkan dengan katalog model saat menyiapkan database untuk tampilan aman berparameter.
  • HINT_TEXT: Informasi tambahan tentang skema database, yang dinyatakan dalam bahasa alami. Hal ini memungkinkan Anda memberikan petunjuk tambahan kepada model tentang aspek penting skema yang mungkin tidak diekstrak hanya dengan menganalisis struktur tabel, kolom, dan hubungan. Sebagai contoh: When joining flights and seats, be sure to join on flights.id = seats.flight_id.

Output fungsi ini adalah string yang berisi kueri SQL.

Menjalankan SQL yang dikonversi menggunakan parameter

Setelah mengonversi kueri bahasa alami ke SQL, Anda dapat memanggil execute_parameterized_views() seperti yang dijelaskan sebelumnya di halaman ini, dengan meneruskan parameter apa pun yang mungkin diperlukan tampilan aman berparameter Anda.

Fungsi ini berfungsi jika Anda meneruskan lebih banyak parameter daripada yang diperlukan dengan kueri tertentu, sehingga Anda dapat memanggilnya dengan semua parameter yang digunakan oleh semua tampilan aman berparameter yang memiliki nilai untuk aplikasi Anda. Fungsi ini akan menampilkan pengecualian jika mencoba menjalankan kueri yang memerlukan parameter yang tidak ditentukan.

Contoh menjalankan kueri natural language

Bagian ini menunjukkan alur lengkap dari input bahasa alami ke set hasil SQL. Contoh kode menunjukkan kueri dan fungsi SQL yang mendasarinya yang dijalankan aplikasi.

Untuk alur contoh ini, asumsikan hal berikut tentang aplikasi Anda:

  • Aplikasi berbasis database Anda melacak pengiriman produk kepada pelanggan.
  • Anda telah mendaftarkan model berbasis Gemini Pro bernama my-gemini-model di Katalog Model.
  • Anda telah menentukan tampilan aman berparameter dalam database bernama shipment_view.
    • Tampilan ini memilih data dari beberapa tabel yang relevan dengan pengiriman ke pelanggan.
    • Tampilan memerlukan parameter user_id, yang nilainya adalah ID pengguna akhir aplikasi.
  1. Pengguna akhir yang ID pengguna aplikasinya adalah 12345 mengetik "Where is my package?" ke dalam aplikasi web Anda.
  2. Aplikasi Anda memanggil google_get_sql_current_schema() untuk menerjemahkan input ke dalam SQL:

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

    Panggilan ini menampilkan string yang berisi satu kueri SELECT SQL. Kueri hanya terbatas pada tampilan aman berparameter yang dapat dilihat oleh pengguna database yang Anda buat untuk menggunakan tampilan aman berparameter.

    SQL yang dihasilkan dari Where is my package? mungkin terlihat seperti berikut:

    SELECT current_location, ship_date, ship_eta FROM shipment_view;
    

    Karena shipment_view adalah tampilan aman berparameter, bukan tampilan PostgreSQL biasa, aplikasi Anda harus menggunakan execute_parameterized_views() untuk menjalankan kueri dengan parameter user_id yang diperlukan dengan aman, seperti yang ditunjukkan pada langkah berikutnya.

  3. Aplikasi Anda meneruskan SQL ke execute_parameterized_views(), bersama dengan parameter yang membatasi output. Dalam contoh kami, ini adalah ID pengguna akhir aplikasi yang memberikan input:

    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']
    );
    
    

    Output-nya adalah set hasil SQL, yang dinyatakan sebagai data JSON.

  4. Aplikasi Anda menangani data JSON sesuai kebutuhan.

Desain database untuk penanganan bahasa alami

Fungsi google_get_sql_current_schema() yang disediakan dengan pratinjau teknologi ini berfungsi terutama untuk menunjukkan fungsi tampilan aman berparameter, sehingga memberi Anda kesempatan awal untuk bereksperimen dengan teknologi yang sedang berkembang ini. Seperti Pratinjau lainnya, Anda tidak boleh menerapkan fungsi ini ke aplikasi dalam produksi.

Dengan mempertimbangkan hal tersebut, Anda dapat menerapkan saran di bagian ini untuk meningkatkan kualitas output google_get_sql_current_schema() selama bereksperimen dengannya.

Mendesain skema untuk dipahami manusia

Secara umum, beri nama dan komentar struktur database Anda yang cukup jelas agar developer manusia biasa dapat menyimpulkan tujuan tabel, kolom, dan hubungannya. Kejelasan ini dapat membantu model bahasa besar menghasilkan kueri SQL yang lebih akurat berdasarkan skema Anda.

Menggunakan nama deskriptif

Pilih nama deskriptif untuk tabel, kolom, dan hubungan. Hindari singkatan atau akronim. Misalnya, model berfungsi lebih baik dengan tabel bernama users daripada dengan tabel bernama u.

Jika tidak memungkinkan untuk mengganti nama struktur data yang ada, berikan petunjuk ke model menggunakan argumen prompt_text saat memanggil google_get_sql_current_schema().

Menggunakan jenis data tertentu

Model dapat membuat inferensi yang lebih baik tentang data Anda jika Anda menggunakan jenis data yang lebih spesifik dengan kolom. Misalnya, jika Anda menggunakan kolom secara eksklusif untuk menyimpan nilai benar atau salah, gunakan jenis data boolean dengan true dan false, bukan integer dengan 1 dan 0.

Lakukan roll back dengan hati-hati setelah mengaktifkan pratinjau

Jika Anda telah mengaktifkan pratinjau teknologi tampilan aman berparameter di database, tetapi kemudian memutuskan untuk melakukan rollback AlloyDB Omni ke versi sebelum 15.5.0, Anda harus melakukan beberapa langkah pembersihan manual sebelum melakukan downgrade.

Jika Anda tidak melakukan langkah-langkah ini, setiap upaya untuk membuat kueri, mengubah, atau menghapus tampilan aman berparameter akan menghasilkan error SQL. Hal ini mencakup kueri pada katalog tampilan database Anda yang akan menyertakan tampilan aman berparameter dalam hasilnya, seperti SELECT * FROM pg_views.

Untuk menghapus pratinjau teknologi ini sepenuhnya dari database Anda sebelum rollback AlloyDB Omni, ikuti langkah-langkah berikut:

  1. Di psql, gunakan perintah DROP VIEW untuk menghapus setiap tampilan aman berparameter di database Anda.

  2. Di psql, gunakan perintah DROP EXTENSION untuk menonaktifkan ekstensi alloydb_ai_nl & parameterized_views di database Anda.

  3. Dalam file postgresql.conf, hapus referensi ke alloydb_ai_nl dan parameterized_views dari perintah shared_preload_libraries.

Untuk informasi selengkapnya tentang cara melakukan rollback penginstalan AlloyDB Omni, lihat Melakukan rollback upgrade.