Générer des requêtes SQL à l'aide de questions en langage naturel

Cette page explique comment configurer, configurer et générer des instructions SQL à l'aide de l'IA AlloyDB en langage naturel. Le langage naturel vous permet de créer des applications d'IA générative destinées aux utilisateurs à l'aide de requêtes de base de données en langage naturel.

Pour activer l'extension alloydb_ai_nl, qui est l'API de prise en charge du langage naturel AlloyDB pour PostgreSQL, procédez comme suit:

  1. Installez l'extension alloydb_ai_nl.
  2. Définissez une configuration en langage naturel pour votre application.
  3. Enregistrez un schéma.
  4. Ajoutez du contexte.
  5. Ajoutez des modèles de requête.
  6. Définissez des types de concepts et créez un indice de valeur.
  7. Générez des instructions SQL à l'aide d'une interface en langage naturel.

Avant de commencer

  • Demandez l'accès au langage naturel AlloyDB AI et attendez de recevoir la confirmation d'activation avant de suivre les instructions de cette page.
  • Découvrez comment vous connecter à la base de données AlloyDB et exécuter des commandes PostgreSQL. Pour en savoir plus, consultez la section Présentation de la connexion.
  • Renseignez la base de données avec les données et le schéma auxquels l'utilisateur final souhaite accéder.

Créer un cluster et activer l'intégration à Vertex AI

  1. Créez un cluster et une instance AlloyDB. Vous utilisez l'instance AlloyDB pour créer la base de données de l'application et le schéma.
  2. Activez l'intégration à Vertex AI. Pour en savoir plus, consultez la section Intégration à Vertex AI.

Rôles requis

Pour installer l'extension alloydb_ai_nl et accorder l'accès à d'autres utilisateurs, vous devez disposer du rôle IAM (Identity and Access Management) suivant dans le projet Google Cloud que vous utilisez:

Pour en savoir plus, consultez la page Gérer les utilisateurs PostgreSQL avec l'authentification standard.

Préparer votre environnement

Pour vous préparer à générer des requêtes en langage naturel, vous devez installer l'extension requise, créer une configuration et enregistrer un schéma.

Installer l'extension alloydb_nl_ai

L'extension alloydb_ai_nl utilise l'extension google_ml_integration, qui interagit avec les grands modèles de langage (LLM), y compris les modèles Gemini sur Vertex AI.

Pour installer l'extension alloydb_ai_nl, connectez-vous à la base de données et exécutez la commande suivante, qui active les extensions google_ml_integration et alloydb_ai_nl.

CREATE EXTENSION google_ml_integration;
CREATE EXTENSION alloydb_ai_nl cascade;

Créer une configuration en langage naturel et enregistrer un schéma

L'IA AlloyDB en langage naturel utilise nl_config pour associer des applications à certains schémas, modèles de requêtes et points de terminaison de modèle. nl_config est une configuration qui associe une application à un schéma, des modèles et d'autres contextes. Une application volumineuse peut également utiliser différentes configurations pour différentes parties de l'application, à condition que vous spécifiiez la configuration appropriée lorsqu'une question est envoyée à partir de cette partie de l'application. Vous pouvez enregistrer un schéma entier ou des objets de schéma spécifiques, tels que des tables, des vues et des colonnes.

  1. Pour créer une configuration en langage naturel, utilisez l'exemple suivant:

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

    "gemini-2.0-flash:generateContent" est le point de terminaison du modèle.

  2. Enregistrez un schéma pour une configuration spécifiée à l'aide de l'exemple suivant:

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

Ajouter le contexte

Le contexte inclut tout type d'information que vous pouvez utiliser pour répondre à une question d'utilisateur final. Le contexte comprend la structure et les relations du schéma, les résumés et les descriptions des colonnes, les valeurs des colonnes et leur sémantique, ainsi que les règles ou les instructions de logique métier spécifiques à l'application ou au domaine.

Ajouter un contexte général pour les règles spécifiques à une application

Les éléments de contexte généraux incluent des règles spécifiques à l'application, des instructions de logique métier ou toute terminologie spécifique à l'application et au domaine qui n'est pas associée à un objet de schéma spécifique.

Pour ajouter un contexte général aux règles spécifiques à l'application et à la terminologie spécifique à l'application ou au domaine, procédez comme suit:

  1. Pour ajouter un élément de contexte général pour la configuration spécifiée, utilisez l'exemple suivant:

    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."}'
      );
    

    L'instruction précédente aide l'IA AlloyDB à fournir des réponses de meilleure qualité aux questions des utilisateurs en langage naturel.

  2. Pour afficher les contextes généraux de la configuration spécifiée, exécutez l'instruction suivante:

    SELECT alloydb_ai_nl.list_general_context(nl_config TEXT);
    

Générer et examiner le contexte du schéma

Le contexte de schéma décrit les objets de schéma, y compris les tables, les vues, les vues matérialisées et les colonnes. Ce contexte est stocké en tant que COMMENT de chaque objet de schéma.

  1. Pour générer des contextes pour les objets de schéma, appelez les API suivantes. Pour de meilleurs résultats, assurez-vous que les tables de la base de données contiennent des données représentatives.

    -- 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. Examinez les contextes de schéma générés en exécutant l'instruction suivante.

    SELECT schema_object, object_context
    FROM alloydb_ai_nl.generated_schema_context_view;
    

    Les contextes de schéma générés sont stockés dans la vue précédente.

  3. Facultatif: mettez à jour les contextes de schéma générés.

    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. Appliquez le contexte. Lorsque vous appliquez le contexte, il prend effet immédiatement et est supprimé de 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. Facultatif: Vérifiez le contexte généré. L'API suivante vous permet de vérifier les contextes de schéma, qui sont utilisés lorsque vous générez des instructions 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. Facultatif: Définissez manuellement le contexte du schéma.

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

Créer des modèles de requêtes

Pour améliorer la qualité des applications d'IA générative créées avec des LLM, vous pouvez ajouter des modèles. Un modèle de requête est un ensemble sélectionné de questions représentatives ou courantes en langage naturel, avec les requêtes SQL correspondantes, ainsi que des explications pour fournir une justification déclarative de la génération de langage naturel vers SQL (NL2SQL). Les modèles sont principalement destinés à être spécifiés par l'application, mais ils peuvent également être générés automatiquement par l'extension alloydb_ai_nl en fonction des requêtes SQL fréquemment utilisées. Chaque modèle doit être associé à un nl_config.

L'extension alloydb_ai_nl utilise un template_store pour intégrer dynamiquement des modèles SQL pertinents lors de la génération d'une instruction SQL pour répondre à la question de l'utilisateur. template_store identifie les modèles dont les intentions sont similaires à la question posée en langage naturel, identifie l'instruction SQL paramétrée correspondante et synthétise une instruction SQL en instanciant des paramètres avec les valeurs de la question en langage naturel. Toutefois, si aucun modèle n'a la même intention que la question posée par l'utilisateur, alloydb_ai_nl utilise tous les modèles et contextes pertinents pour composer une instruction SQL.

Pour ajouter des modèles, spécifiez la question (à l'aide d'un paramètre nommé intent) et la requête SQL.

Pour ajouter un modèle au dépôt de modèles, exécutez l'instruction suivante:

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

Lorsque check_intent est TRUE, alloydb_ai_nl effectue une vérification sémantique pour confirmer que l'intent fourni correspond à l'instruction SQL transmise. Si l'intent ne correspond pas à l'instruction SQL, le modèle n'est pas ajouté.

Générer automatiquement des modèles

Une fois que vous disposez d'un ensemble de données représentatif dans vos tables, nous vous recommandons d'exécuter des requêtes SQL qui correspondent aux questions courantes que vos utilisateurs finaux sont susceptibles de poser. Vous devez vous assurer que les requêtes disposent de bons plans de requêtes et qu'elles fonctionnent bien.

Une fois les requêtes exécutées, AlloyDB AI Natural Language peut générer automatiquement des modèles en fonction de l'historique des requêtes. Vous pouvez appeler les API suivantes pour générer des modèles. Vous devez examiner et appliquer les modèles générés avant qu'ils ne prennent effet.

La génération automatique de modèles est basée sur les requêtes les plus fréquemment utilisées dans le journal des requêtes, google_db_advisor_workload_statements. Les requêtes sont filtrées en fonction des critères suivants:

  • Instructions SELECT
  • Fichiers exécutables: la requête peut être traitée avec succès par la commande EXPLAIN.
  • Aucune duplication: la requête n'a pas déjà été utilisée pour générer des modèles.
  • Toutes les tables et vues référencées sont incluses dans le champ d'application de nl_config.

Pour générer automatiquement des modèles, les examiner et les appliquer, procédez comme suit:

  1. Demandez à AlloyDB de générer des modèles en fonction de votre historique de requêtes:

    SELECT 
      alloydb_ai_nl.generate_templates(
        'my_app_config', 
    );
    

    Utilisez la vue fournie, alloydb_ai_nl.generated_templates_view, pour examiner le generated_templates.

    Le résultat suivant indique le nombre de modèles générés:

    -[ RECORD 1 ]------+--
    generate_templates | 1
    
  2. Examinez les modèles générés à l'aide de la vue generated_templates_view.

    SELECT * 
    FROM alloydb_ai_nl.generated_templates_view;
    

    Voici un exemple de résultat renvoyé:

    -[ 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
    
  3. Pour mettre à jour un modèle généré, exécutez l'exemple d'instruction suivant:

    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. Appliquez les modèles. Les modèles que vous appliquez sont immédiatement ajoutés au dépôt de modèles et supprimés de la vue d'examen.

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

Configurer la sécurité pour le langage naturel

Pour configurer la sécurité du langage naturel de l'IA AlloyDB, consultez la section Gérer la sécurité des applications de données à l'aide de vues sécurisées paramétrées.

Définir des types de concepts et un indice de valeur

Vous définissez des types de concepts et des indices de valeur pour mieux comprendre les questions posées. Un type de concept est une catégorie ou une classe d'entités qui identifie la signification sémantique des mots et des expressions, et non seulement leur forme littérale.

Par exemple, deux noms de pays peuvent être identiques, même si l'un est en majuscules (USA, par exemple) et l'autre en minuscules (usa, par exemple). Dans ce cas, le nom du pays est le type de concept. D'autres exemples de types de concepts sont le nom d'une personne, le nom d'une ville et la date.

Un indice de valeur est un indice au-dessus des valeurs des colonnes qui font partie de la configuration de langage naturel nl_config, en fonction des types de concepts associés à chaque colonne. Un indice de valeurs permet de faire correspondre efficacement les expressions de valeur pour la question posée et les valeurs de la base de données.

Pour définir des types de concepts et un indice de valeur, procédez comme suit en vous appuyant sur les exemples fournis. Les exemples associent une colonne à un type de concept, créent et actualisent un indice de valeurs, et utilisent un ensemble de synonymes pour effectuer une recherche de valeur.

  1. Pour associer une colonne à un type de concept, exécutez la requête suivante:

    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. Pour créer un indice de valeurs basé sur toutes les colonnes qui font partie d'une configuration de langage naturel et qui sont associées à un type de concept, exécutez l'instruction suivante:

    SELECT
      alloydb_ai_nl.create_value_index(
        nl_config_id_in => 'my_app_config'
      );
    
  3. Lorsque vous associez des types de concepts à de nouvelles colonnes, actualisez l'index des valeurs pour refléter les modifications.

    SELECT
      alloydb_ai_nl.refresh_value_index(
        nl_config_id_in => 'my_app_config'
      );
    
  4. Pour permettre à l'IA AlloyDB de trouver des synonymes d'une valeur en langage naturel, exécutez l'exemple d'instruction suivant:

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

    Bien que les données de vos tables puissent utiliser une valeur spécifique (par exemple, si United States est utilisé pour identifier un pays), vous pouvez définir un ensemble de synonymes contenant tous les synonymes de United States. Si l'un des synonymes apparaît dans la question en langage naturel, l'IA AlloyDB en langage naturel fait correspondre les synonymes aux valeurs de vos tables.

  5. Effectuez une recherche de valeurs pour trouver les valeurs de base de données appropriées, en fonction d'un tableau d'expressions de valeur.

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

    Par exemple, si un utilisateur pose une question comme "Quelle est la population des États-Unis ?" qui utilise la requête get_sql suivante, l'IA AlloyDB en langage naturel utilise la fonction get_concept_and_value avec la phrase de valeur United States pour effectuer une recherche floue sur les index de valeur. La recherche approximative est une technique de recherche qui trouve des correspondances même lorsque la requête de recherche ne correspond pas exactement aux données correspondantes.

    Le langage naturel trouve un résultat (la valeur USA) proche de la requête de recherche et utilise ce résultat pour générer la requête 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';
    

    Les types de concepts intégrés définis par le langage naturel AlloyDB AI sont répertoriés dans le tableau suivant.

    Nom du concept Description
    generic_entity_name Une seule colonne de type chaîne peut être utilisée pour un nom d'entité générique. Exemple :
      SELECT alloydb_ai_nl.associate_concept_type('public.item.item_name', 'generic_entity_name')
      
    country_name, city_name, region_name Noms de pays, de villes et de régions. L'utilisation est exactement la même que celle du type de concept generic_entity_name.
    full_person_name Nom de la personne, composé du prénom, du nom et du deuxième prénom. Vous pouvez utiliser jusqu'à trois colonnes de type chaîne pour un nom complet. Vous pouvez ignorer n'importe quelle colonne lorsque vous associez des colonnes de nom à full_person_name. Par exemple :
      SELECT alloydb_ai_nl.associate_concept_type('public.person.last_name,public.person.first_name,public.person.middle_name','full_person_name')
      
    ssn Colonne de chaîne unique contenant un numéro de sécurité sociale. Exemple :
      SELECT alloydb_ai_nl.associate_concept_type('public.person.ssn','ssn')
     
    date Une date ou un code temporel Exemple :
     SELECT alloydb_ai_nl.associate_concept_type('public.person.date_col','date')
     

Générer des instructions SQL à partir d'entrées en langage naturel

Vous pouvez utiliser le langage naturel d'AlloyDB AI pour générer des instructions SQL à partir d'entrées en langage naturel. Lorsque vous exécutez l'instruction SQL générée, elle fournit les données de la base de données dont vous avez besoin pour répondre à la question en langage naturel.

  1. Pour utiliser le langage naturel pour obtenir des résultats à partir de votre base de données à l'aide de la fonction alloydb_ai_nl.get_sql, utilisez l'exemple suivant:

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

    Le résultat JSON suivant est renvoyé:

    {
      "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. Facultatif: Pour extraire la requête SQL générée en tant que chaîne de texte, ajoutez ->>'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';
    

    L'opérateur ->> permet d'extraire une valeur JSON au format texte. La fonction alloydb_ai_nl.get_sql renvoie un objet JSON, qui est la partie de l'instruction qui récupère la valeur associée à la clé sql. Cette valeur correspond à la requête SQL générée.

Tester et affiner

Pour obtenir des requêtes générées automatiquement plus efficaces, ajoutez un meilleur contexte, des modèles de requête et des index de valeur, puis itérez jusqu'à obtenir les résultats souhaités.

Étape suivante