Générer du code SQL à l'aide du langage naturel d'AlloyDB AI


Ce tutoriel explique comment configurer et utiliser l'API en langage naturel AlloyDB/AI à l'aide de la console Google Cloud . Vous apprendrez à configurer l'API AlloyDB AI en langage naturel pour pouvoir poser des questions en langage naturel et recevoir des requêtes et des résultats SQL.

Objectifs

  • Créez et remplissez des tableaux, et utilisez la génération automatique pour créer du contexte.
  • Créez un index de valeurs pour les colonnes de la base de données.
  • Créez et configurez un objet de configuration en langage naturel (nl_config).
  • Créez des modèles pour un exemple de requête dans l'application.
  • Utilisez la fonction get_sql() pour générer une requête SQL qui répond à une question.
  • Utilisez la fonction execute_nl_query() pour répondre à une question en langage naturel à l'aide de la base de données.

Coûts

Dans ce document, vous utilisez les composants facturables suivants de Google Cloud :

Pour obtenir une estimation des coûts en fonction de votre utilisation prévue, utilisez le simulateur de coût.

Les nouveaux utilisateurs de Google Cloud peuvent bénéficier d'un essai gratuit.

Une fois que vous avez terminé les tâches décrites dans ce document, vous pouvez éviter de continuer à payer des frais en supprimant les ressources que vous avez créées. Pour en savoir plus, consultez la section Effectuer un nettoyage.

Avant de commencer

Demander l'accès

Avant de pouvoir utiliser le langage naturel AlloyDB AI pour générer du code SQL, vous devez demander l'accès au langage naturel AlloyDB AI et attendre de recevoir la confirmation d'activation avant de suivre les instructions de ce tutoriel.

Activer la facturation et les API requises

  1. Dans la console Google Cloud , sélectionnez un projet.

    Accéder au sélecteur de projet

  2. Assurez-vous que la facturation est activée pour votre projet Google Cloud .

  3. Activez les APIs Cloud nécessaires pour créer et vous connecter à AlloyDB pour PostgreSQL.

    Activer l'API

    1. À l'étape Confirmer le projet, cliquez sur Suivant pour confirmer le nom du projet que vous allez modifier.
    2. À l'étape Activer les API, cliquez sur Activer pour activer les éléments suivants :

      • API AlloyDB

Créer une base de données et s'y connecter

  1. Créez un cluster et son instance principale.
  2. Connectez-vous à votre instance et créez une base de données.
  3. Activez l'intégration à Vertex AI. Pour en savoir plus, consultez Intégrer à Vertex AI.

Installer l'extension requise

Pour installer l'extension alloydb_ai_nl, qui est l'API AlloyDB/AI pour la prise en charge du langage naturel, exécutez la requête suivante :

CREATE EXTENSION alloydb_ai_nl cascade;

Créer le schéma et les tables nla_demo

Dans les étapes suivantes, vous allez créer le schéma nla_demo et les tables du schéma. Vous remplissez les tables avec des données synthétiques. Le schéma et les données fournis sont conçus pour prendre en charge les opérations fondamentales d'une activité de vente au détail en ligne, avec des applications potentielles s'étendant à la gestion des clients, aux analyses, au marketing et aux aspects opérationnels.

Les exemples de données montrent comment utiliser le langage naturel AlloyDB/AI à des fins de développement, de test et de démonstration, en particulier pour les fonctionnalités telles que les interfaces en langage naturel.

  1. Créez le schéma en exécutant la requête suivante :

    CREATE SCHEMA nla_demo;
    
  2. Créez des tables dans le schéma nla_demo. La table addresses stocke les informations d'adresse des clients et des commandes.

    CREATE TABLE nla_demo.addresses (
        address_id      SERIAL         PRIMARY KEY,
        street_address  VARCHAR(255)   NOT NULL,
        city            VARCHAR(255)   NOT NULL,
        country         VARCHAR(255)
    );
    
  3. Créez la table customers en exécutant la requête suivante. Ce tableau stocke les informations sur les clients, y compris leur ID, leur nom, leurs coordonnées, leur adresse, leur date de naissance et la date de création de leur fiche.

    CREATE TABLE nla_demo.customers (
        customer_id     SERIAL         PRIMARY KEY,
        first_name      VARCHAR(255)   NOT NULL,
        last_name       VARCHAR(255)   NOT NULL,
        email           VARCHAR(255)   UNIQUE NOT NULL,
        address_id      INTEGER        REFERENCES nla_demo.addresses(address_id),
        date_of_birth   DATE,
        created_at      TIMESTAMP      DEFAULT CURRENT_TIMESTAMP
    );
    
  4. Créez la table categories, qui stocke les catégories de produits.

    CREATE TABLE nla_demo.categories (
        category_id     INTEGER        PRIMARY KEY,
        category_name   VARCHAR(255)   UNIQUE NOT NULL
    );
    
  5. Créez la table brands, qui stocke les noms de marques.

    CREATE TABLE nla_demo.brands (
        brand_id      INTEGER        PRIMARY KEY,
        brand_name    VARCHAR(255)   NOT NULL
    );
    
  6. Créez la table products, qui stocke des informations sur les produits telles que l'ID du produit, son nom, sa description, sa marque, son association à une catégorie et l'heure de création de l'enregistrement.

    CREATE TABLE nla_demo.products (
        product_id    INTEGER        PRIMARY KEY,
        name          VARCHAR(255)   NOT NULL,
        description   TEXT           DEFAULT 'Not available',
        brand_id      INTEGER        REFERENCES nla_demo.brands(brand_id),
        category_id   INTEGER        REFERENCES nla_demo.categories(category_id),
        created_at    TIMESTAMP      DEFAULT CURRENT_TIMESTAMP
    );
    
  7. Créez la table orders. Ce tableau stocke des informations sur les commandes des clients, y compris le client, la date, le montant total, les adresses de livraison et de facturation, ainsi que l'état de la commande.

    CREATE TABLE nla_demo.orders (
        order_id            INTEGER        PRIMARY KEY,
        customer_id         INTEGER        REFERENCES nla_demo.customers(customer_id),
        order_date          TIMESTAMP      DEFAULT CURRENT_TIMESTAMP,
        total_amount        DECIMAL(10, 2) NOT NULL,
        shipping_address_id INTEGER        REFERENCES nla_demo.addresses(address_id),
        billing_address_id  INTEGER        REFERENCES nla_demo.addresses(address_id),
        order_status        VARCHAR(50)
    );
    
  8. Créez la table order_items. Ce tableau enregistre les articles individuels d'une commande, les liens vers la commande et la variante du produit, et spécifie la quantité et le prix.

    CREATE TABLE nla_demo.order_items (
        order_item_id   SERIAL         PRIMARY KEY,
        order_id        INTEGER        REFERENCES nla_demo.orders(order_id),
        product_id      INTEGER        REFERENCES nla_demo.products(product_id),
        quantity        INTEGER        NOT NULL,
        price           DECIMAL(10, 2) NOT NULL
    );
    

Remplir les tables du schéma nla_demo

  1. Remplissez la table addresses en exécutant la requête suivante :

    INSERT INTO nla_demo.addresses (street_address, city, country)
    VALUES
        ('1800 Amphibious Blvd', 'Mountain View', 'USA'),
        ('Avenida da Pastelaria, 1903', 'Lisbon', 'Portugal'),
        ('8 Rue du Nom Fictif 341', 'Paris', 'France');
    
  2. Remplissez la table customers.

    INSERT INTO nla_demo.customers (first_name, last_name, email, address_id, date_of_birth)
    VALUES
        ('Alex', 'B.', 'alex.b@example.com', 1, '2003-02-20'),
        ('Amal', 'M.', 'amal.m@example.com', 2, '1998-11-08'),
        ('Dani', 'G.', 'dani.g@example.com', 3, '2002-07-25');
    
  3. Remplissez la table categories.

    INSERT INTO nla_demo.categories (category_id, category_name)
    VALUES
        (1, 'Accessories'),
        (2, 'Apparel'),
        (3, 'Footwear'),
        (4, 'Swimwear');
    
  4. Remplissez la table brands.

    INSERT INTO nla_demo.brands (brand_id, brand_name)
    VALUES
        (1, 'CymbalPrime'),
        (2, 'CymbalPro'),
        (3, 'CymbalSports');
    
  5. Remplissez la table products.

    INSERT INTO nla_demo.products (product_id, brand_id, category_id, name)
    VALUES
        (1, 1, 2, 'Hoodie'),
        (2, 1, 3, 'Running Shoes'),
        (3, 2, 4, 'Swimsuit'),
        (4, 3, 1, 'Tote Bag'),
        (5, 3, 3, 'CymbalShoe');
    
  6. Remplissez la table orders.

    INSERT INTO nla_demo.orders (order_id, customer_id, total_amount, shipping_address_id, billing_address_id, order_status)
    VALUES
        (1, 1, 99.99, 1, 1, 'Shipped'),
        (2, 1, 69.99, 1, 1, 'Delivered'),
        (3, 2, 20.99, 2, 2, 'Processing'),
        (4, 3, 79.99, 3, 3, 'Shipped');
    
  7. Remplissez la table order_items.

    INSERT INTO nla_demo.order_items (order_id, product_id, quantity, price)
    VALUES
        (1, 1, 1, 79.99),
        (1, 3, 1, 20.00),
        (2, 4, 1, 69.99),
        (3, 3, 1, 20.00),
        (4, 2, 1, 79.99);
    

Créer une configuration en langage naturel

Pour utiliser le langage naturel AlloyDB/AI, assurez-vous que le point de terminaison Vertex AI est configuré. Vous devez ensuite créer une configuration et enregistrer un schéma. g_alloydb_ai_nl.g_create_configuration crée le modèle.

  1. Créez une configuration en langage naturel.

    SELECT alloydb_ai_nl.g_create_configuration( 'nla_demo_cfg' );
    
  2. Enregistrez les tables dans la configuration nla_demo_cfg.

    SELECT alloydb_ai_nl.g_manage_configuration(
        operation => 'register_table_view',
        configuration_id_in => 'nla_demo_cfg',
        table_views_in=>'{nla_demo.customers, nla_demo.addresses, nla_demo.brands, nla_demo.products, nla_demo.categories, nla_demo.orders, nla_demo.order_items}'
    );
    

Créer et appliquer un contexte pour les tableaux et les colonnes

Pour fournir des réponses précises à des questions en langage naturel, vous utilisez l'API en langage naturel AlloyDB/AI pour fournir le contexte des tables, des vues et des colonnes. Vous pouvez utiliser la fonctionnalité de génération de contexte automatisée de l'API AlloyDB/AI en langage naturel pour générer du contexte à partir de tables et de colonnes, et appliquer ce contexte en tant que COMMENTS aux tables, aux vues et aux colonnes.

  1. Pour générer des contextes de schéma pour les tables et leurs colonnes enregistrées dans la configuration nla_demo_cfg, exécutez la commande suivante :

    SELECT alloydb_ai_nl.generate_schema_context(
      'nla_demo_cfg',
      TRUE
    );
    

    La requête précédente remplit la vue alloydb_ai_nl.generated_schema_context_view avec du contexte. Le fait de transmettre TRUE écrase le contexte de cette vue à partir des exécutions précédentes.

  2. Pour vérifier le contexte généré pour la table nla_demo.products, exécutez la requête suivante :

    SELECT object_context
    FROM alloydb_ai_nl.generated_schema_context_view
    WHERE schema_object = 'nla_demo.products';
    

    Le contexte obtenu ressemble à ce qui suit :

    The products table stores information about products, including their name,
    a brief description, the brand they belong to (referenced by brand_id),
    and the category they fall under (referenced by category_id). Each product
    has a unique identifier (product_id) and a timestamp indicating its creation
    time (created_at).
    
  3. Pour vérifier le contexte généré pour une colonne, telle que nla_demo.products.name, exécutez la commande suivante :

    SELECT object_context
    FROM alloydb_ai_nl.generated_schema_context_view
    WHERE schema_object = 'nla_demo.products.name';
    

    Le résultat de la requête se présente comme suit :

    The name column in the nla_demo.products table contains the specific
    name or title of each product. This is a short, descriptive text string
    that clearly identifies the product, like "Hoodie," "Tote Bag,"
    "Running Shoes," or "Swimsuit." It helps distinguish individual products
    within the broader context of their brand and category. The name column
    specifies the exact product. This column is essential for users and
    systems to identify and refer to specific products within the database.
    
  4. Examinez le contexte généré dans la vue alloydb_ai_nl.generated_schema_context_view et mettez à jour le contexte qui doit être révisé.

    SELECT alloydb_ai_nl.update_generated_relation_context(
      'nla_demo.products',
      'The "nla_demo.products" table stores product details such as ID, name, description, brand, category linkage, and record creation time.'
    );
    
    SELECT alloydb_ai_nl.update_generated_column_context(
      'nla_demo.products.name',
      'The "name" column in the "nla_demo.products" table contains the specific name or title of each product.'
    );
    
  5. Appliquez le contexte généré qui sera associé aux objets correspondants :

    SELECT alloydb_ai_nl.apply_generated_relation_context(
      'nla_demo.products', true
    );
    
    SELECT alloydb_ai_nl.apply_generated_column_context(
      'nla_demo.products.name',
      true
    );
    

    Les entrées de contexte résultantes dans la vue alloydb_ai_nl.generated_schema_context_view sont appliquées aux objets de schéma correspondants, et les commentaires sont écrasés.

Construire l'index de valeur

L'API en langage naturel AlloyDB AI produit des requêtes SQL précises en utilisant l'association de valeurs. L'association de valeurs permet d'associer des expressions de valeurs dans des instructions en langage naturel à des types de concepts et des noms de colonnes préenregistrés, ce qui peut enrichir la question en langage naturel.

Par exemple, la question "Quel est le prix d'un sweat à capuche ?" peut être traitée plus précisément si Hoodie est associé à un concept product_name, qui est associé à nla_demo.products.name. de la colonne.

  1. Pour définir le type de concept product_name et l'associer à la colonne nla_demo.products.name, exécutez les requêtes suivantes :

    SELECT alloydb_ai_nl.add_concept_type(
        concept_type_in => 'product_name',
        match_function_in => 'alloydb_ai_nl.get_concept_and_value_generic_entity_name',
        additional_info_in => '{
          "description": "Concept type for product name.",
          "examples": "SELECT alloydb_ai_nl.get_concept_and_value_generic_entity_name(''Camera'')" }'::jsonb
    );
    SELECT alloydb_ai_nl.associate_concept_type(
        'nla_demo.products.name',
        'product_name',
        'nla_demo_cfg'
    );
    
  2. Pour vérifier que le type de concept product_name a été ajouté à la liste des types de concepts, exécutez la requête suivante pour vous assurer que product_name est inclus dans le résultat de cette requête :

    SELECT alloydb_ai_nl.list_concept_types();
    
  3. Pour vérifier que la colonne nla_demo.products.name est associée au type de concept product_name, exécutez la requête suivante :

    SELECT *
    FROM alloydb_ai_nl.value_index_columns
    WHERE column_names = 'nla_demo.products.name';
    
  4. Pour définir le type de concept brand_name et l'associer à la colonne nla_demo.brands.brand_name, exécutez les requêtes suivantes :

    SELECT alloydb_ai_nl.add_concept_type(
        concept_type_in => 'brand_name',
        match_function_in => 'alloydb_ai_nl.get_concept_and_value_generic_entity_name',
        additional_info_in => '{
          "description": "Concept type for brand name.",
          "examples": "SELECT alloydb_ai_nl.get_concept_and_value_generic_entity_name(''CymbalPrime'')" }'::jsonb
    );
    SELECT alloydb_ai_nl.associate_concept_type(
        'nla_demo.brands.brand_name',
        'brand_name',
        'nla_demo_cfg'
    );
    
  5. Après avoir défini les types de concepts et associé des colonnes à ceux-ci, créez un index de valeurs.

    SELECT alloydb_ai_nl.create_value_index('nla_demo_cfg');
    SELECT alloydb_ai_nl.refresh_value_index('nla_demo_cfg');
    

Définir un modèle de requête

Vous pouvez définir des modèles pour améliorer la qualité des réponses générées par l'API en langage naturel AlloyDB/AI.

  1. Pour fournir des exemples de modèles pour les questions critiques pour l'entreprise et pour fournir des questions attendues pour lesquelles une grande précision est attendue, exécutez la requête suivante pour ajouter un modèle :

    SELECT alloydb_ai_nl.add_template(
        nl_config_id => 'nla_demo_cfg',
        intent => 'List the first names and the last names of all customers who ordered Swimsuit.',
        sql => 'SELECT c.first_name, c.last_name FROM nla_demo.Customers c JOIN nla_demo.orders o ON c.customer_id = o.customer_id JOIN nla_demo.order_items oi ON o.order_id = oi.order_id JOIN nla_demo.products p ON oi.product_id = p.product_id  AND p.name = ''Swimsuit''',
        sql_explanation => 'To answer this question, JOIN `nla_demo.Customers` with `nla_demo.orders` on having the same `customer_id`, and JOIN the result with nla_demo.order_items on having the same `order_id`. Then JOIN the result with `nla_demo.products` on having the same `product_id`, and filter rwos that with p.name = ''Swimsuit''. Return the `first_name` and the `last_name` of the customers with matching records.',
        check_intent => TRUE
    );
    
  2. Pour afficher la liste des modèles ajoutés, interrogez alloydb_ai_nl.template_store_view :

    SELECT nl, sql, intent, psql, pintent
    FROM alloydb_ai_nl.template_store_view
    WHERE config = 'nla_demo_cfg';
    

    Le résultat suivant s'affiche :

    nl      | List the first names and the last names of all customers who ordered Swimsuit.
    sql     | SELECT c.first_name, c.last_name
            | FROM nla_demo.Customers c
            | JOIN nla_demo.orders o ON c.customer_id = o.customer_id
            | JOIN nla_demo.order_items oi ON o.order_id = oi.order_id
            | JOIN nla_demo.products p ON oi.product_id = p.product_id
            | AND p.name = 'Swimsuit'
    intent  | List the first names and the last names of all customers who ordered
            | Swimsuit.
    psql    | SELECT c.first_name, c.last_name
            | FROM nla_demo.Customers c JOIN nla_demo.orders o
            | ON c.customer_id = o.customer_id 
            | JOIN nla_demo.order_items oi ON o.order_id = oi.order_id
            | JOIN nla_demo.products p ON oi.product_id = p.product_id
            | AND p.name = $1
    pintent | List the first names and the last names of all customers who ordered
            | $1.
    

    Dans ce modèle, la valeur correspondant à l'attribut psql est la requête SQL paramétrée, et la valeur de la colonne pintent est l'instruction d'intent paramétrée. Le id d'un modèle récemment ajouté peut être différent, en fonction des modèles ajoutés précédemment. Les modèles sont utilisés pour fournir des réponses très précises aux questions.

Générer des résultats SQL à partir de questions en langage naturel

  1. Pour utiliser l'API en langage naturel AlloyDB AI afin de générer des requêtes SQL et des ensembles de résultats, exécutez la requête suivante :

    SELECT
        alloydb_ai_nl.get_sql(
            'nla_demo_cfg',
            'Find the customers who purchased Tote Bag.'
        ) ->> 'sql';
    

    Le résultat suivant s'affiche :

    SELECT DISTINCT "c"."first_name", "c"."last_name"
    FROM "nla_demo"."customers" AS "c"
    JOIN "nla_demo"."orders" AS "o" ON "c"."customer_id" = "o"."customer_id"
    JOIN "nla_demo"."order_items" AS "oi" ON "o"."order_id" = "oi"."order_id"
    JOIN "nla_demo"."products" AS "p" ON "oi"."product_id" = "p"."product_id"
    WHERE "p"."name" = 'Tote Bag';
    

    La sortie JSON est une requête SQL utilisant le modèle que vous avez ajouté dans Définir un modèle de requête.

  2. Pour utiliser l'API en langage naturel AlloyDB AI afin de générer des requêtes SQL, exécutez la requête suivante :

    SELECT
        alloydb_ai_nl.get_sql(
            'nla_demo_cfg',
            'List the maximum price of any CymbalShoe.'
        ) ->> 'sql';
    

    Le résultat suivant s'affiche :

    SELECT max("price")
    FROM "nla_demo"."order_items" AS t1
    JOIN "nla_demo"."products" AS t2 ON t1."product_id" = t2."product_id"
    WHERE t2."name" = 'CymbalShoe';
    

    L'API en langage naturel AlloyDB/AI reconnaît que CymbalShoe est le nom du produit en utilisant l'index de valeur. Remplacer CymbalShoe par une marque (CymbalPrime) dans la requête suivante :

    SELECT
        alloydb_ai_nl.get_sql(
            'nla_demo_cfg',
            'List the maximum price of any CymbalPrime.'
        ) ->> 'sql';
    

    produit la sortie suivante :

    SELECT max("price")
    FROM "nla_demo"."order_items" AS "oi"
    JOIN "nla_demo"."products" AS "p" ON "oi"."product_id" = "p"."product_id"
    JOIN "nla_demo"."brands" AS "b" ON "p"."brand_id" = "b"."brand_id"
    WHERE "b"."brand_name" = 'CymbalPrime';
    

    AlloyDB/AI utilise l'index de valeurs créé dans Construire l'index de valeurs pour résoudre CymbalPrime dans le type de concept brand_name et utilise la colonne nla_demo.brands.brand_name associée à brand_name.

  3. Pour utiliser l'API en langage naturel AlloyDB/AI afin de générer la réponse à une question, exécutez la requête suivante :

    SELECT
    alloydb_ai_nl.execute_nl_query(
        'Find the last name of the customers who live in Lisbon.',
        'nla_demo_cfg'
    );
    

    Le résultat suivant s'affiche :

    execute_nl_query     
    --------------------------
    {"last_name":"M."}
    

Effectuer un nettoyage

Pour éviter que les ressources utilisées lors de ce tutoriel soient facturées sur votre compte Google Cloud, supprimez le projet contenant les ressources, ou conservez le projet et supprimez les ressources individuelles.

Dans les sections suivantes, nous allons voir comment supprimer ces ressources et ces objets.

Supprimer le cluster

Lorsque vous supprimez le cluster que vous avez créé dans Avant de commencer, tous les objets que vous avez créés sont également supprimés.

  1. Dans la console Google Cloud , accédez à la page Clusters.

    accéder aux clusters

  2. Dans la colonne Nom de ressource, cliquez sur le nom de votre cluster, my-cluster.

  3. Cliquez sur Supprimer le cluster.

  4. Dans Delete cluster my-cluster, saisissez my-cluster pour confirmer que vous souhaitez supprimer votre cluster.

  5. Cliquez sur Supprimer.

  6. Si vous avez créé une connexion privée lorsque vous avez créé un cluster, accédez à la page Réseaux VPC de la console Google Cloud , puis cliquez sur Supprimer le réseau VPC.

Supprimer les objets

Vous pouvez choisir de conserver les ressources que vous avez configurées dans Avant de commencer et de supprimer uniquement les objets que vous avez créés dans le projet Google Cloud .

  1. Pour supprimer le modèle que vous avez défini dans Définir un modèle de requête, exécutez la requête suivante :

    SELECT alloydb_ai_nl.drop_template(id)
    FROM alloydb_ai_nl.template_store_view
    WHERE config = 'nla_demo_cfg';
    
  2. Pour supprimer le type de concept product_name que vous avez défini dans Construire l'index des valeurs, exécutez la requête suivante :

    SELECT alloydb_ai_nl.drop_concept_type('product_name');
    
  3. Pour actualiser l'index des valeurs après avoir supprimé le type de concept product_name, exécutez la requête suivante :

    SELECT alloydb_ai_nl.refresh_value_index();
    
  4. Pour supprimer la configuration nla_demo_cfg que vous avez créée dans Créer une configuration en langage naturel, exécutez la requête suivante :

    SELECT
    alloydb_ai_nl.g_manage_configuration(
        'drop_configuration',
        'nla_demo_cfg'
    );
    
  5. Pour supprimer le schéma et les tables nla_demo que vous avez créés et remplis dans Créer le schéma et les tables nla_demo et Remplir les tables du schéma nla_demo, exécutez la requête suivante :

    DROP SCHEMA nla_demo CASCADE;
    

Étapes suivantes