Esegui query sul database utilizzando il linguaggio naturale

Questa pagina descrive un'anteprima disponibile con AlloyDB Omni che ti consente di eseguire esperimenti con le query al database utilizzando il linguaggio naturale.

Panoramica

Puoi utilizzare AlloyDB Omni per visualizzare l'anteprima di un insieme di funzionalità sperimentali che consentono all'applicazione basata su database di eseguire in modo più sicuro query in linguaggio naturale da parte degli utenti dell'applicazione, ad esempio "Dove si trova il mio pacco?" o "Chi è il miglior guadagno in ogni reparto?" AlloyDB Omni traduce l'input in linguaggio naturale in una query SQL specifica per il tuo database, limitando i risultati solo a ciò che l'utente della tua applicazione è autorizzato a visualizzare.

Potenza e rischi delle query in linguaggio naturale

I modelli linguistici di grandi dimensioni, come Gemini Pro, possono consentire alla tua applicazione di eseguire query sul database in base a query in linguaggio naturale create dagli utenti finali della tua applicazione. Ad esempio, un modello con accesso allo schema del database della tua applicazione può accettare input da parte dell'utente finale come questo:

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

e tradurlo in una query SQL come questa:

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

Le query in linguaggio naturale possono fornire alla tua applicazione un potente strumento per servire gli utenti. Tuttavia, questa tecnologia comporta anche chiari rischi di sicurezza che devi prendere in considerazione prima di consentire agli utenti finali di eseguire query arbitrarie sulle tabelle del database. Anche se hai configurato l'applicazione in modo che si connetta al database come utente con accesso limitato e di sola lettura, un'applicazione che invita a eseguire query in linguaggio naturale può essere vulnerabile a quanto segue:

  • Gli utenti malintenzionati possono inviare attacchi di inserimento di prompt, cercando di manipolare il modello sottostante per rivelare tutti i dati a cui ha accesso l'applicazione.
  • Il modello stesso potrebbe generare query SQL di ambito più ampio del necessario, rivelando dati sensibili in risposta anche a query degli utenti ben intenzionate.

Eseguire la convalida delle query con viste sicure con parametri

Per contribuire a mitigare i rischi descritti nella sezione precedente, Google ha sviluppato le visualizzazioni sicure parametrizzate, una funzionalità sperimentale di cui puoi visualizzare l'anteprima utilizzando le tecniche descritte su questa pagina.

Le visualizzazioni sicure parametrizzate ti consentono di definire esplicitamente le tabelle e le colonne da cui le query in linguaggio naturale possono estrarre i dati e aggiungere ulteriori limitazioni all'intervallo di righe disponibili per un singolo utente dell'applicazione. Queste limitazioni ti consentono di controllare in modo rigoroso i dati che gli utenti della tua applicazione possono visualizzare tramite query in linguaggio naturale, indipendentemente dal modo in cui gli utenti formulano queste query.

Se attivi questa anteprima, hai accesso alle estensioni sperimentali sviluppate da Google chiamate alloydb_ai_nl e parameterized_views.

L'estensione parameterized_views fornisce le seguenti funzionalità:

  • Visualizzazioni sicure parametrizzate, una variante delle visualizzazioni SQL per limitare l'intervallo di dati a cui una query può accedere.
  • La funzione execute_parameterized_views(), che ti consente di eseguire query sulle visualizzazioni sicure parametrizzate.

L'estensione alloydb_ai_nl fornisce la seguente funzionalità:

  • La funzione google_get_sql_current_schema(), che converte le query in linguaggio naturale in query SQL di tabelle e viste nello schema corrente.

Le sezioni seguenti descrivono come utilizzare queste funzionalità e dimostrano come possono essere utilizzate insieme.

Prima di iniziare

Installa AlloyDB Omni versione 15.5.1 o successive, inclusa l'integrazione del modello di AI. Per saperne di più, consulta Installare AlloyDB Omni con AlloyDB per PostgreSQL AI.

Configurare il database per le viste sicure parametrizzate

  1. Connettiti al tuo cluster AlloyDB Omni utilizzando psql.

  2. Modifica i contenuti di /var/alloydb/config/postgresql.conf in modo che il valore della direttiva shared_preload_libraries includa alloydb_ai_nl e parameterized_views. La direttiva modificata dovrebbe avere il seguente aspetto:

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

  4. Avvia AlloyDB Omni.

  5. Attiva le estensioni alloydb_ai_nl e 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. Registra un nuovo modello linguistico basato sull'API Gemini Pro con la gestione dell'endpoint del modello:

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

    Sostituisci quanto segue:

  7. Crea un nuovo utente del database. Non concedere ancora autorizzazioni o ruoli. Un passaggio successivo di questa procedura concede all'utente le autorizzazioni necessarie.

esposizone incontrollata.

Visualizzazioni sicure con parametri

Una vista sicura parametrizzata funziona in modo molto simile a una normale vista sicura PostgreSQL: essenzialmente un'istruzione SELECT memorizzata. Le visualizzazioni sicure con parametri consentono inoltre di richiedere uno o più valori di parametro denominati passati alla visualizzazione quando viene eseguita una query, in modo simile alle variabili di associazione con le query del database ordinarie.

Ad esempio, immagina di eseguire un'applicazione il cui database monitora le spedizioni di articoli ai clienti. Un utente ha eseguito l'accesso a questa applicazione con l'ID dei tipi 12345 nella query Where is my package?. Utilizzando le viste sicure parametrizzate, puoi assicurarti che i seguenti requisiti vengano applicati alla modalità di esecuzione di questa query da parte di AlloyDB per PostgreSQL:

  • La query può leggere solo le colonne del database elencate esplicitamente nelle visualizzazioni sicure parametrizzate del database. In questo caso, potrebbe trattarsi di determinate colonne nelle tabelle items, users e shipments.
  • La query può leggere solo le righe del database associate all'utente che ha eseguito la query. In questo caso, potrebbe essere necessario che le righe restituite abbiano un rapporto di dati con la riga della tabella users il cui valore della colonna id è 12345.

Creare una visualizzazione sicura con parametri

Per creare una vista sicura parametrizzata, utilizza il comando DDL CREATE VIEW di PostgreSQL con i seguenti attributi:

  • Crea la vista con l'opzione security_barrier.
  • Per limitare gli utenti dell'applicazione a visualizzare solo le righe che possono vedere, aggiungi i parametri obbligatori utilizzando la sintassi $@PARAMETER_NAME nella clausola WHERE. Un caso comune è il controllo del valore di una colonna utilizzando WHERE COLUMN = $@PARAMETER_NAME.

L'esempio seguente di visualizzazione sicura parametrizzata consente l'accesso a tre colonne da una tabella denominata users e limita i risultati solo alle righe in cui users.id corrisponde a un parametro obbligatorio:

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

Le istruzioni SELECT al centro delle visualizzazioni sicure parametrizzate possono essere complesse quanto le istruzioni consentite dalle normali visualizzazioni PostgreSQL.

Dopo aver creato una vista, devi concedere all'utente che hai creato in precedenza l'autorizzazione per eseguire query SELECT sulla vista:

GRANT SELECT ON VIEW_NAME TO NL_DB_USER;

Sostituisci quanto segue:

  • VIEW_NAME: il nome della visualizzazione creata nel passaggio precedente.
  • NL_DB_USER: il nome dell'utente del database che hai designato per eseguire query in linguaggio naturale.

Esegui una query su una vista protetta con parametri

Nonostante la somiglianza con le normali viste PostgreSQL, non puoi eseguire query direttamente sulle viste protette parametrizzate. Utilizza invece la funzione execute_parameterized_query() fornita dall'estensione parameterized_views. La funzione ha la seguente sintassi:

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

Sostituisci quanto segue:

  • SQL_QUERY: una query SQL la cui clausola FROM fa riferimento a una o più viste sicure parametrizzate.
  • PARAMETER_NAMES: un elenco di nomi di parametri da passare come stringhe.
  • PARAMETER_VALUES: un elenco di valori di parametro da passare. Questo elenco deve avere le stesse dimensioni dell'elenco param_names. L'ordine degli indicatori corrisponde all'ordine dei nomi.

La funzione restituisce una tabella di oggetti JSON. Ogni riga della tabella è equivalente al valore row_to_json() della riga del risultato della query originale.

In un utilizzo tipico, il valore dell'argomento query non viene generato dal tuo codice, ma da un modello di AI con cui hai integrato il tuo database AlloyDB per PostgreSQL.

L'esempio seguente mostra come eseguire una query su una vista sicura parametroizzata in Python e poi visualizzarne i risultati. Si basa sulla visualizzazione di esempio user_psv della sezione precedente:

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

Esegui una query in linguaggio naturale

L'esecuzione di una query in linguaggio naturale utilizzando visualizzazioni sicure con parametri è un processo in due passaggi:

  1. In qualità di utente del database con accesso solo a SELECT visualizzazioni sicure parametrizzate appropriate, converti la query in linguaggio naturale in SQL utilizzando un modello linguistico di grandi dimensioni.
  2. Utilizza la funzione execute_parameterized_query() per elaborare il codice SQL, associandolo ai valori dei parametri appropriati alla sessione utente corrente.

Le sezioni seguenti descrivono questi passaggi in modo più dettagliato.

Converti il linguaggio naturale in SQL

Per tradurre l'input in linguaggio naturale in SQL, utilizza la funzione google_get_sql_current_schema() inclusa nell'anteprima della tecnologia delle visualizzazioni sicure parametrizzate:

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

Sostituisci quanto segue:

  • NL_TEXT: il testo in linguaggio naturale da trasformare in una query SQL.
  • MODEL_ID: l'ID del modello registrato nel catalogo dei modelli durante la configurazione del database per le visualizzazioni sicure parametrizzate.
  • HINT_TEXT: informazioni aggiuntive sullo schema del database, espresse in linguaggio naturale. In questo modo puoi fornire al modello ulteriori suggerimenti su aspetti importanti dello schema che potrebbero non essere estratti solo analizzando le strutture di tabelle, colonne e relazioni. Ad esempio: When joining flights and seats, be sure to join on flights.id = seats.flight_id.

L'output della funzione è una stringa contenente una query SQL.

Esegui il codice SQL convertito utilizzando i parametri

Dopo aver convertito la query in linguaggio naturale in SQL, puoi chiamare execute_parameterized_views() come descritto in precedenza in questa pagina, passando eventuali parametri di cui potrebbero avere bisogno le visualizzazioni sicure parametrizzate.

La funzione funziona se le passi più parametri di quelli necessari con una determinata query, quindi puoi chiamarla con tutti i parametri utilizzati da tutte le viste sicure parametrizzate per le quali la tua applicazione ha valori. La funzione genera un'eccezione se tenta di eseguire una query che richiede un parametro non definito.

Un esempio di esecuzione di una query in linguaggio naturale

Questa sezione mostra un flusso completo dall'input in linguaggio naturale al set di risultati SQL. Gli esempi di codice mostrano le query e le funzioni SQL sottostanti eseguite da un'applicazione.

Per questo flusso di esempio, ipotizza quanto segue in merito alla tua applicazione:

  • L'applicazione basata su database monitora le spedizioni dei prodotti ai clienti.
  • Hai registrato un modello basato su Gemini Pro denominato my-gemini-model nel Catalogo modelli.
  • Hai definito una vista sicura parametrizzata nel tuo database denominata shipment_view.
    • La vista seleziona i dati di diverse tabelle pertinenti alle spedizioni ai clienti.
    • La visualizzazione richiede un parametro user_id, il cui valore è l'ID di un utente finale dell'applicazione.
  1. Un utente finale il cui ID utente dell'applicazione è 12345 digita "Dove si trova il mio pacco?" nella tua applicazione web.
  2. L'applicazione chiama google_get_sql_current_schema() per tradurre l'input in SQL:

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

    Questa chiamata restituisce una stringa contenente una singola query SELECT SQL. La query è limitata solo alle visualizzazioni sicure con parametri visibili all'utente del database che hai creato per lavorare con le visualizzazioni sicure con parametri.

    Il codice SQL generato da Where is my package? potrebbe essere simile al seguente:

    SELECT current_location, ship_date, ship_eta FROM shipment_view;
    

    Poiché shipment_view è una vista sicura con parametri e non una normale vista PostgreSQL, l'applicazione deve utilizzare execute_parameterized_views() per eseguire in sicurezza la query con il parametro user_id richiesto, come mostrato nel passaggio successivo.

  3. L'applicazione passa il codice SQL a execute_parameterized_views(), insieme ai parametri che vincolano l'output. Nel nostro esempio, si tratta dell'ID dell'utente finale dell'applicazione che ha fornito l'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']
    );
    
    

    L'output è un insieme di risultati SQL, espresso come dati JSON.

  4. L'applicazione gestisce i dati JSON in base alle esigenze.

Progettazione del database per la gestione del linguaggio naturale

La funzione google_get_sql_current_schema() fornita con questa anteprima della tecnologia serve principalmente a dimostrare la funzionalità delle visualizzazioni sicure parametrizzate, offrendoti un'opportunità in anteprima per sperimentare questa tecnologia in fase di sviluppo. Come per qualsiasi anteprima, non devi applicare questa funzione a un'applicazione in produzione.

Tenendo presente questo, puoi applicare i consigli riportati in questa sezione per migliorare la qualità dell'output di google_get_sql_current_schema() durante le sperimentazioni.

Progetta lo schema per la comprensione umana

In generale, assegna alle strutture del database nomi e commenti sufficientemente chiari da consentire a un tipico sviluppatore di dedurre lo scopo delle tabelle, delle colonne e delle relazioni. Questa chiarezza può aiutare un modello linguistico di grandi dimensioni a generare query SQL più accurate in base allo schema.

Utilizza nomi descrittivi

Preferisci nomi descrittivi per tabelle, colonne e relazioni. Evita abbreviature o acronimi. Ad esempio, il modello funziona meglio con una tabella denominata users rispetto a una denominata u.

Se non è possibile rinominare le strutture di dati esistenti, fornisci suggerimenti al modello utilizzando l'argomento prompt_text quando chiami google_get_sql_current_schema().

Utilizzare tipi di dati specifici

Il modello può fare deduzioni migliori sui tuoi dati se utilizzi tipi di dati più specifici con le colonne. Ad esempio, se utilizzi una colonna esclusivamente per memorizzare valori di tipo vero o falso, utilizza un tipo di dati boolean con true e false anziché un integer con 1 e 0.

Esegui il rollback con cautela dopo aver attivato l'anteprima

Se hai attivato l'anteprima della tecnologia delle visualizzazioni sicure parametrizzate nel tuo database, ma poi decidi di eseguire il rollback di AlloyDB Omni a una versione precedente alla 15.5.0, devi eseguire alcuni passaggi di pulizia manuale prima di eseguire il downgrade.

Se non segui questi passaggi, qualsiasi tentativo di eseguire query, modificare o eliminare una vista sicura parametrizzata genera un errore SQL. Sono incluse le query sul catalogo delle visualizzazioni del database che altrimenti includerebbero visualizzazioni sicure parametrizzate nei risultati, come SELECT * FROM pg_views.

Per rimuovere completamente questa anteprima della tecnologia dal database prima di un rollback di AlloyDB Omni:

  1. In psql, utilizza il comando DROP VIEW per eliminare tutte le visualizzazioni sicure parametrizzate nel database.

  2. In psql, utilizza il comando DROP EXTENSION per disattivare le estensioni alloydb_ai_nl e parameterized_views nel database.

  3. Nel file postgresql.conf, rimuovi il riferimento a alloydb_ai_nl e parameterized_views dalla direttiva shared_preload_libraries.

Per ulteriori informazioni sul rollback dell'installazione di AlloyDB Omni, consulta Eseguire il rollback di un upgrade.