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

Cette page explique comment configurer et générer des instructions SQL à l'aide du langage naturel AlloyDB/AI. Le langage naturel vous permet de créer des applications d'IA générative destinées aux utilisateurs à l'aide du langage naturel pour interroger des bases de données.

Pour activer l'extension alloydb_ai_nl, qui est l'API AlloyDB pour PostgreSQL de prise en charge du langage naturel, vous devez suivre les étapes générales suivantes :

  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 les types de concepts et créez un index de valeurs.
  7. Générez des instructions SQL à l'aide d'une interface en langage naturel.

Avant de commencer

  • Découvrez comment vous connecter à la base de données AlloyDB et exécuter des commandes PostgreSQL. Pour en savoir plus, consultez la présentation des connexions.
  • Remplissez la base de données avec les données et le schéma auxquels l'utilisateur final souhaite accéder.

Activer l'extension requise

Avant de pouvoir installer et utiliser le langage naturel AlloyDB/AI, vous devez activer l'extension en ajoutant l'indicateur alloydb_ai_nl.enabled. Pour en savoir plus, consultez Configurer les options de base de données d'une instance.

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 et le schéma de l'application.
  2. Activer l'intégration à Vertex AI Pour en savoir plus, consultez Intégration de 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 Gérer les utilisateurs PostgreSQL avec l'authentification standard.

Préparer votre environnement

Pour préparer la génération de 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 :

CREATE EXTENSION alloydb_ai_nl cascade;

Mettre à niveau l'extension alloydb_ai_nl

Assurez-vous de disposer de la dernière version de l'extension alloydb_ai_nl. Si vous avez déjà installé l'extension, vérifiez si une nouvelle version est disponible et mettez-la à niveau si vous n'utilisez pas la dernière version. Pour en savoir plus sur l'extension alloydb_ai_nl, consultez la présentation du langage naturel AlloyDB/AI.

  1. Déterminez si vous devez mettre à niveau l'extension. Si la default_version est postérieure à la installed_version, mettez à niveau l'extension.

    SELECT * FROM pg_available_extensions where name = 'alloydb_ai_nl';
    
  2. Mettez à niveau l'extension.

    ALTER EXTENSION alloydb_ai_nl UPDATE;
    

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

Le langage naturel AlloyDB AI utilise nl_config pour associer des applications à certains schémas, modèles de requête et points de terminaison de modèle. nl_config est une configuration qui associe une application à des schémas, des modèles et d'autres contextes. Une grande application peut également utiliser différentes configurations pour différentes parties de l'application, à condition que vous spécifiiez la bonne configuration 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, comme 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écifique à 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'informations que vous pouvez utiliser pour répondre à une question d'utilisateur final, par exemple :

  • Structure et relations du schéma
  • Récapitulatifs et descriptions des colonnes
  • Valeurs de colonne et leur sémantique
  • Règles ou instructions de logique métier spécifiques à l'application ou au domaine

Ajouter un contexte général pour les règles spécifiques aux applications

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

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

  1. Pour ajouter un élément de contexte général à la configuration spécifiée, exécutez la requête suivante :

    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 le langage naturel AlloyDB/AI à fournir des réponses de meilleure qualité aux questions en langage naturel des utilisateurs.

  2. Pour afficher les contextes généraux de la configuration spécifiée, exécutez la requête 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 obtenir des résultats optimaux, 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 la requête 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 la vue 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 conçues avec des LLM, vous pouvez ajouter des modèles. Un modèle de requête est un ensemble organisé 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 du 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 incorporer dynamiquement des modèles SQL pertinents dans le processus de génération d'une instruction SQL permettant de répondre à la question de l'utilisateur final. La fonction template_store effectue les opérations suivantes :

  • Identifie les modèles dont l'intention est similaire à la question en langage naturel posée par l'utilisateur final.
  • Identifie l'instruction SQL paramétrée correspondante.
  • Synthétise une instruction SQL en instanciant des paramètres avec des valeurs issues de la question en langage naturel.

S'il n'existe pas de modèle ayant la même intention que la question posée par l'utilisateur final, alloydb_ai_nl utilise tous les modèles et contextes pertinents pour composer une instruction SQL.

Ajouter un modèle à la galerie de modèles

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

Pour ajouter un modèle au magasin de modèles, exécutez la requête suivante :

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

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

Le code SQL et l'intent sont paramétrés par alloydb_ai_nl. La vue alloydb_ai_nl.template_store_view expose les instructions SQL paramétrées et leurs intentions.

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

Cette instruction renvoie le résultat suivant :

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

Fournir une paramétrisation personnalisée

Pour fournir une paramétrisation personnalisée pour une instruction SQL à l'aide de l'interface manuelle de la fonction add_template, exécutez l'instruction de l'exemple suivant :

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

Dans la définition précédente, la paramétrisation de l'instruction SQL est fournie. Les paramètres sont respectivement $1 et $2 pour Slokolov et 1950. Un fichier manifeste est fourni sous la forme d'une version généralisée de l'intention, dans laquelle les valeurs des littéraux sont remplacées par des descriptions génériques des valeurs.

Dans cet exemple, la valeur de 1950 dans l'intention est remplacée par a given date, et la valeur de Slokolov est remplacée dans le fichier manifeste par a given city. Lorsqu'une valeur TRUE est fournie pour l'argument facultatif check_intent, une vérification de l'intention basée sur un LLM est effectuée pendant add_template. Lors de cette vérification, lorsque l'instruction SQL fournie ne reflète pas l'objectif de l'instruction d'intention fournie, add_template échoue et la raison est fournie en sortie.

Dans l'exemple suivant, l'objectif du modèle, tel qu'indiqué dans l'intention, est de récupérer l'ID de compte des comptes associés à la charge et situés dans une région. L'instruction SQL fournie renvoie le nombre de comptes, et non la liste des ID de compte, comme illustré dans l'exemple suivant.

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

Lorsque check_intent est défini sur TRUE, vous ne pouvez pas ajouter le modèle précédent à la galerie de modèles. Si vous exécutez l'instruction précédente, une erreur semblable à celle-ci est renvoyée :

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.

Gérer les modèles

Vous pouvez gérer les modèles dans le magasin de modèles à l'aide des API suivantes :

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

Lorsque vous créez un modèle, il est activé par défaut. Un modèle désactivé reste dans le magasin de modèles, mais n'est pas utilisé par alloydb_ai_nl pour la synthèse des requêtes. Vous pouvez activer un modèle désactivé à l'aide de alloydb_ai_nl.enable_template. L'exécution de alloydb_ai_nl.drop_template supprime définitivement le modèle du magasin de modèles.

Vous pouvez utiliser alloydb_ai_nl.template_store_view pour extraire le template_id d'un modèle, en fonction de son contenu. Par exemple, pour trouver l'identifiant des modèles ayant l'intention accounts that associated with loans, exécutez la requête suivante, qui renvoie un identifiant de modèle et indique si le modèle est activé à partir de alloydb_ai_nl.template_store_view :

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

Mettre à jour un modèle

Lorsque vous utilisez les modèles dans alloydb_ai_nl.template_store_view, assurez-vous que l'intention de chaque modèle est conforme aux points suivants :

  • Instruction SQL
  • Instruction SQL paramétrée
  • Intent paramétré
  • Fichier manifeste du modèle

alloydb_ai_nl peut récupérer les modèles pertinents si l'intégration conservée pour les modèles correspond au contenu des modèles.

Pour mettre à jour un modèle, procédez comme suit :

  1. Identifiez le template_id à l'aide de alloydb_ai_nl.template_store_view.
  2. Supprimez le modèle.
  3. Redéfinissez le nouveau modèle avec la modification requise à l'aide de la fonction alloydb_ai_nl.add_template.

Créer des fragments de requête

Vous pouvez spécialiser des modèles au moment de l'interrogation à l'aide de fragments, ce qui permet aux modèles de requête d'effectuer des recherches à facettes comme des questions en langage naturel. Un fragment est un ensemble organisé de conditions représentatives ou courantes en langage naturel avec les prédicats SQL correspondants. Les fragments sont censés être spécifiés par l'application.

Chaque fragment doit être associé à un nl_config_id et à un tableau de tables et de vues avec des alias auxquels s'applique le prédicat du fragment. Vous pouvez vérifier l'objectif d'un fragment lorsque l'argument check_intent est défini sur TRUE. L'extension alloydb_ai_nl peut utiliser un modèle avec une combinaison de fragments pour synthétiser la réponse à une requête en langage naturel.

L'extension alloydb_ai_nl utilise fragment_store pour intégrer dynamiquement les conditions dans les fragments pertinents lors de la génération d'une instruction SQL permettant de répondre à la question de l'utilisateur final. Tout d'abord, template_store identifie les modèles dont l'intention est similaire à celle de la question en langage naturel posée par l'utilisateur final. Ensuite, les fragments pouvant spécialiser les modèles identifiés sont récupérés. Le remplacement des paramètres est appliqué aux modèles et aux fragments pour synthétiser une instruction SQL.

Les valeurs des paramètres sont extraites de la question en langage naturel et remplacées par le LLM à l'aide des modèles impliqués par les modèles et fragments pertinents. Toutefois, si la combinaison de modèles et de fragments n'a pas le même objectif que la question posée par l'utilisateur final, alloydb_ai_nl utilise tous les modèles et contextes pertinents pour composer une instruction SQL.

Ajouter un fragment

Pour ajouter un fragment, exécutez les exemples de requêtes suivants à l'aide de la fonction alloydb_ai_nl.add_fragment. Chaque fragment doit être associé à un identifiant nl_config_id de l'application.

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

Lorsque alloydb_ai_nl.add_fragment s'exécute, l'extension alloydb_ai_nl extrait un fichier manifeste de l'intention fournie, puis paramètre l'intention et la condition du fragment, si possible. Les fragments disponibles sont exposés par des vues telles que alloydb_ai_nl.fragment_store_view, comme illustré dans l'exemple suivant :

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

La requête renvoie un ensemble de résultats semblable à ce qui suit :

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

Un fichier manifeste dans un fragment est généré automatiquement à partir de l'intention et représente une version généralisée de l'intention. Par exemple, les nombres 6000 et 10000 dans l'intention sont chacun remplacés par a given number dans le fichier manifeste. Les nombres sont remplacés respectivement par $2 et $1 dans les colonnes pfragment et pintent. Les colonnes pfragment et pintent de alloydb_ai_nl.fragment_store_view sont respectivement la représentation paramétrée de fragment et intent.

Pour fournir une paramétrisation personnalisée d'un fragment, utilisez la version manuelle de alloydb_ai_nl.add_fragment, comme indiqué dans l'exemple suivant :

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

Gérer les fragments

Pour gérer les fragments, utilisez les API suivantes :

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

Vous pouvez utiliser la vue alloydb_ai_nl.fragment_store_view pour extraire le fragment_id d'un fragment, en fonction de son contenu. Par exemple, pour trouver l'identifiant d'un fragment dont l'intention est Average salary between 6000 and 10000, exécutez l'exemple de requête suivant :

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

Mettre à jour un fragment

Lorsque vous mettez à jour un fragment, assurez-vous que l'intention du fragment est cohérente avec les éléments suivants :

  • Manifeste et instruction SQL du fragment
  • Instruction SQL paramétrée
  • Intent paramétré

Pour assurer la cohérence lorsque vous mettez à jour un fragment, procédez comme suit :

  1. Supprimez le fragment que vous souhaitez modifier à l'aide de la fonction alloydb_ai_nl.drop_fragment.
  2. Insérez le fragment mis à jour à l'aide de la fonction alloydb_ai_nl.add_fragment.

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 correspondant aux questions courantes que vos utilisateurs finaux sont susceptibles de poser. Assurez-vous que les requêtes disposent de plans de requête complets et qu'elles fonctionnent bien.

Après l'exécution des requêtes, le langage naturel AlloyDB/AI 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
  • Exécutables : la requête peut être traitée par la commande EXPLAIN.
  • Aucun doublon : 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 dans le champ d'application de nl_config.

Pour générer, examiner et appliquer automatiquement des modèles, 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
    

    Le manifest dans le résultat renvoyé est un modèle général ou une description générale du type de question ou de l'opération qui peut être effectuée. pintent est une version paramétrée de intent. Elle généralise intent en remplaçant la valeur spécifique (1997) par un espace réservé ($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 à la bibliothèque de modèles et supprimés de la vue "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 AlloyDB/AI, consultez 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 des index de valeurs

Vous définissez des types de concepts et des index de valeurs 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, plutôt que leur forme littérale.

Par exemple, deux noms de pays peuvent être identiques même si l'un est en majuscules (USA) et l'autre en minuscules (usa). Dans ce cas, le nom du pays est le type de concept. Les noms de personnes, les noms de villes et les dates sont d'autres exemples de types de concepts.

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

Pour définir des types de concepts et un index de valeurs, suivez les étapes ci-dessous en utilisant les exemples fournis. Les exemples associent une colonne à un type de concept, créent et actualisent un index de valeurs, et utilisent un ensemble de synonymes pour effectuer une recherche de valeurs.

  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 index de valeurs basé sur toutes les colonnes qui font partie d'une configuration en 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 à AlloyDB/AI en langage naturel de faire correspondre les synonymes d'une valeur, 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 tableaux 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, AlloyDB AI fait correspondre les synonymes aux valeurs de vos tables.

  5. Effectuez une recherche de valeurs pour trouver les valeurs de base de données correctes à partir d'un tableau d'expressions de valeurs.

    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, le langage naturel AlloyDB/AI utilise la fonction get_concept_and_value avec la phrase de valeur United States pour effectuer une recherche approximative par rapport aux index de valeurs. 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 l'utilise 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 listé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 pour le type de concept generic_entity_name.
    full_person_name Nom de la personne, composé du prénom, du nom de famille et du deuxième prénom. Vous pouvez utiliser jusqu'à trois colonnes de type chaîne pour le nom complet d'une personne. 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 automatiquement des associations de types de concepts

Pour associer automatiquement des colonnes à des types de concepts, utilisez la fonctionnalité d'association automatisée des types de concepts de l'API en langage naturel AlloyDB/AI. Une association de type de concept définit la relation entre un type de concept et une ou plusieurs colonnes de base de données. Il s'agit d'une condition préalable à la création d'index de valeurs.

Pour générer automatiquement des associations de types de concepts, procédez comme suit :

  1. Pour générer des associations, appelez les API suivantes.

    -- 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. Examinez les associations générées en exécutant la requête suivante.

    SELECT * FROM alloydb_ai_nl.generated_value_index_columns_view;
    
  3. Facultatif : mettez à jour les associations générées.

    -- 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. Facultatif : Supprimez une association générée.

    SELECT alloydb_ai_nl.drop_generated_concept_type_association(id => 1);
    
  5. Appliquez les associations générées.

    -- 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. Actualisez l'index des valeurs pour refléter les modifications.

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

Générer des instructions SQL à partir de saisies en langage naturel

Vous pouvez utiliser le langage naturel 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 afin d'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 s'affiche :

    {
      "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 sous forme de 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 sous forme de 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.

Générer des résumés de résultats à partir de saisies en langage naturel

Vous pouvez utiliser le langage naturel AlloyDB AI pour générer des résumés de résultats à partir d'entrées en langage naturel. La fonction alloydb_ai_nl.get_sql_summary exécute de manière sécurisée la question en langage naturel sur la table sous-jacente, résume un échantillon de l'ensemble de résultats et renvoie le résumé en langage naturel.

Pour générer un récapitulatif des résultats d'une question en langage naturel dans votre base de données, utilisez la fonction alloydb_ai_nl.get_sql_summary, comme illustré dans l'exemple suivant :

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

L'appel de l'instruction précédente produit l'exemple d'objet JSON suivant :

{
  "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."
}

Vous pouvez sécuriser les tables et les vues auxquelles une requête accède dans alloydb_ai_nl.get_sql_summary à l'aide d'une ou de plusieurs vues sécurisées paramétrées. Les noms et les valeurs des paramètres sont disponibles pour une application et sont requis par alloydb_ai_nl.get_sql_summary.

Par exemple, l'application peut vouloir fournir le paramètre user_id pour un utilisateur authentifié avec un ID utilisateur de 123. Pour ce faire, fournissez les entrées param_names et param_values, comme illustré dans l'exemple suivant :

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

En fournissant les arguments param_names et param_values, vous vous assurez que, lorsque la nl_question peut être résolue par une instruction SQL appliquée par des vues sécurisées paramétrées, les filtres de sécurité désignés sont appliqués lorsque l'ensemble de résultats est produit et que le récapitulatif est généré.

Tester et affiner

Pour obtenir des requêtes autogénérées améliorées, modifiez ou ajoutez un meilleur contexte, des modèles de requêtes et des index de valeurs, puis itérez jusqu'à obtenir les résultats souhaités.

Étapes suivantes