Usar a linguagem natural da IA do AlloyDB para gerar um SQL


Neste tutorial, descrevemos como configurar e usar a API Natural Language de IA do AlloyDB usando o Google Cloud console. Você vai aprender a configurar a API Natural Language da IA do AlloyDB para fazer perguntas em linguagem natural e receber resultados e consultas SQL.

Objetivos

  • Criar e preencher tabelas e usar a geração automática para criar um contexto.
  • Criar um índice de valor para as colunas no banco de dados.
  • Criar e configurar um objeto de configuração de linguagem natural (nl_config).
  • Criar modelos para uma amostra de consulta no aplicativo.
  • Usar a função get_sql() para gerar uma consulta SQL que responda a uma pergunta.
  • Usar a função execute_nl_query() para responder a uma pergunta em linguagem natural usando o banco de dados.

Custos

Neste documento, você vai usar os seguintes componentes faturáveis do Google Cloud:

Para gerar uma estimativa de custo baseada na sua projeção de uso, use a calculadora de preços.

Novos usuários do Google Cloud podem estar qualificados para um teste gratuito.

Ao concluir as tarefas descritas neste documento, é possível evitar o faturamento contínuo excluindo os recursos criados. Para mais informações, consulte Limpeza.

Antes de começar

Solicitar acesso

Antes de usar a linguagem natural da IA do AlloyDB para gerar um SQL, você precisa solicitar acesso à linguagem natural da IA do AlloyDB e aguardar até receber a confirmação de ativação antes de seguir as instruções deste tutorial.

Ativar o faturamento e as APIs necessárias

  1. No Google Cloud console, selecione um projeto.

    Acessar o seletor de projetos

  2. Verifique se o faturamento está ativado para seu projeto do Google Cloud .

  3. Ative as APIs do Cloud necessárias para criar e se conectar ao AlloyDB para PostgreSQL.

    Ativar a API

    1. Na etapa Confirmar projeto, clique em Avançar para confirmar o nome do projeto no qual você vai fazer alterações.
    2. Na etapa Ativar APIs, clique em Ativar para ativar o seguinte:

      • API AlloyDB

Criar e se conectar a um banco de dados

  1. Crie um cluster e a instância primária dele.
  2. Conecte-se à instância e crie um banco de dados.
  3. Ative a integração com a Vertex AI. Para mais informações, consulte Integração com a Vertex AI.

Instalar a extensão necessária

Para instalar a extensão alloydb_ai_nl, que é a API de suporte a linguagem natural da IA do AlloyDB, execute a seguinte consulta:

CREATE EXTENSION alloydb_ai_nl cascade;

Criar o esquema e as tabelas nla_demo

Nas etapas a seguir, você vai criar o esquema nla_demo e as tabelas nele. Você vai preencher as tabelas com dados sintéticos. O esquema e os dados fornecidos foram projetados para oferecer suporte às operações fundamentais de uma loja on-line, com possíveis aplicações que se estendem a gerenciamento de clientes, análise, marketing e aspectos operacionais.

Os dados de amostra apresentam como usar a linguagem natural da IA do AlloyDB para fins de desenvolvimento, testes e demonstrações, principalmente para recursos como interfaces de linguagem natural.

  1. Crie o esquema executando a seguinte consulta:

    CREATE SCHEMA nla_demo;
    
  2. Crie tabelas no esquema nla_demo. A tabela addresses armazena as informações de endereço de clientes e pedidos.

    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. Crie a tabela customers executando a consulta a seguir. Essa tabela armazena informações do cliente, incluindo ID de cliente, nome, detalhes de contato, referência de endereço, data de nascimento e hora de criação do registro.

    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. Crie a tabela categories, que armazena as categorias dos produtos.

    CREATE TABLE nla_demo.categories (
        category_id     INTEGER        PRIMARY KEY,
        category_name   VARCHAR(255)   UNIQUE NOT NULL
    );
    
  5. Crie a tabela brands, que armazena os nomes das marcas.

    CREATE TABLE nla_demo.brands (
        brand_id      INTEGER        PRIMARY KEY,
        brand_name    VARCHAR(255)   NOT NULL
    );
    
  6. Crie a tabela products, que armazena informações do produto, como ID do produto, nome, descrição, marca, vinculação de categoria e hora de criação do registro.

    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. Crie a tabela orders. Essa tabela armazena informações sobre pedidos de clientes, incluindo cliente, data, valor total, endereços de entrega e faturamento e status do pedido.

    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. Crie a tabela order_items. Essa tabela registra itens individuais em um pedido, links para o pedido e variante do produto, além de especificar quantidade e preço.

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

Preencher tabelas no esquema nla_demo

  1. Preencha a tabela addresses executando a seguinte consulta:

    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. Preencha a tabela 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. Preencha a tabela categories.

    INSERT INTO nla_demo.categories (category_id, category_name)
    VALUES
        (1, 'Accessories'),
        (2, 'Apparel'),
        (3, 'Footwear'),
        (4, 'Swimwear');
    
  4. Preencha a tabela brands.

    INSERT INTO nla_demo.brands (brand_id, brand_name)
    VALUES
        (1, 'CymbalPrime'),
        (2, 'CymbalPro'),
        (3, 'CymbalSports');
    
  5. Preencha a tabela 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. Preencha a tabela 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. Preencha a tabela 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);
    

Criar uma configuração de linguagem natural

Para usar a linguagem natural da IA do AlloyDB, verifique se o endpoint da Vertex AI está configurado. Em seguida, você vai criar uma configuração e registrar um esquema. g_alloydb_ai_nl.g_create_configuration cria o modelo.

  1. Crie uma configuração de linguagem natural.

    SELECT alloydb_ai_nl.g_create_configuration( 'nla_demo_cfg' );
    
  2. Registre as tabelas na configuração 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}'
    );
    

Criar e aplicar um contexto às tabelas e colunas

Para fornecer respostas precisas a perguntas em linguagem natural, use a API Natural Language da IA do AlloyDB para disponibilizar o contexto sobre tabelas, visualizações e colunas. Você pode usar o recurso de geração de contexto automatizada da API Natural Language da IA do AlloyDB para gerar o contexto com base em tabelas e colunas e aplicá-lo como COMMENTS anexados a tabelas, visualizações e colunas.

  1. Para gerar contextos de esquema para as tabelas e as colunas delas ques estão registradas na configuração nla_demo_cfg, execute o seguinte:

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

    A consulta anterior preenche a visualização alloydb_ai_nl.generated_schema_context_view com o contexto. A transmissão de TRUE substitui o contexto nessa visualização de execuções anteriores.

  2. Para verificar o contexto gerado para a tabela nla_demo.products, execute a seguinte consulta:

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

    O contexto resultante é parecido com este:

    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. Para verificar o contexto produzido para uma coluna, como nla_demo.products.name, execute o seguinte:

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

    A resposta da consulta será parecida com esta:

    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. Revise o contexto gerado na visualização alloydb_ai_nl.generated_schema_context_view e atualize o contexto que precisa de revisão.

    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. Aplique o contexto gerado que será anexado aos objetos correspondentes:

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

    As entradas de contexto resultantes na visualização alloydb_ai_nl.generated_schema_context_view são aplicadas aos objetos de esquema correspondentes, e os comentários são substituídos.

Construir o índice de valor

A API Natural Language da IA do AlloyDB gera consultas SQL precisas usando a vinculação de valores. A vinculação de valores associa frases de valor em instruções de linguagem natural a tipos de conceitos e nomes de colunas pré-registrados, o que pode enriquecer a pergunta em linguagem natural.

Por exemplo, a pergunta "Qual o preço de um moletom com capuz?" poderá ser respondida com mais precisão se Hoodie estiver associado a um conceito product_name, que está associado à coluna nla_demo.products.name.

  1. Para definir o tipo de conceito product_name e associá-lo à coluna nla_demo.products.name, execute as seguintes consultas:

    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. Para verificar se o tipo de conceito product_name foi adicionado à lista de tipos de conceito, execute a seguinte consulta para garantir que product_name esteja incluído no resultado dela:

    SELECT alloydb_ai_nl.list_concept_types();
    
  3. Para verificar se a coluna nla_demo.products.name está associada ao tipo de conceito product_name, execute a seguinte consulta:

    SELECT *
    FROM alloydb_ai_nl.value_index_columns
    WHERE column_names = 'nla_demo.products.name';
    
  4. Para definir o tipo de conceito brand_name e associá-lo à coluna nla_demo.brands.brand_name, execute as seguintes consultas:

    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. Depois de definir os tipos de conceito e associar colunas a eles, crie um índice de valor.

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

Definir um modelo de consulta

Você pode definir modelos para melhorar a qualidade das respostas geradas pela API Natural Language da IA do AlloyDB.

  1. Para oferecer exemplos de modelos para perguntas críticas para os negócios e perguntas previstas para as quais se espera alta precisão, execute a seguinte consulta para adicionar um modelo:

    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. Para conferir a lista de modelos adicionados, consulte o alloydb_ai_nl.template_store_view:

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

    Você verá a seguinte resposta:

    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.
    

    Nesse modelo, o valor correspondente ao atributo psql é a consulta SQL parametrizada, e o valor da coluna pintent é a instrução de intent parametrizada. O id de um modelo adicionado recentemente pode ser diferente, dependendo dos modelos adicionados antes. Os modelos são usados para oferecer respostas altamente precisas às perguntas.

Gerar resultados SQL com base em perguntas em linguagem natural

  1. Para usar a API Natural Language da IA do AlloyDB para gerar consultas SQL e conjuntos de resultados, execute a seguinte consulta:

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

    Você verá a seguinte resposta:

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

    A resposta JSON é uma consulta SQL que usa o modelo adicionado em Definir um modelo de consulta.

  2. Para usar a API Natural Language da IA do AlloyDB e gerar consultas SQL, execute a seguinte consulta:

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

    Você verá a seguinte resposta:

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

    A API Natural Language da IA do AlloyDB reconhece que CymbalShoe é o nome do produto usando o índice de valor. Substitua CymbalShoe por um nome de marca (CymbalPrime) na seguinte consulta:

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

    gera a seguinte resposta:

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

    A IA do AlloyDB usa o índice de valor criado em Construir o índice de valor para resolver CymbalPrime no tipo de conceito brand_name e usa a coluna nla_demo.brands.brand_name associada a brand_name.

  3. Para usar a API Natural Language da IA do AlloyDB e gerar o resultado de uma pergunta, execute a seguinte consulta:

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

    Você verá a seguinte resposta:

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

Limpeza

Para evitar cobranças na sua conta do Google Cloud pelos recursos usados neste tutorial, exclua o projeto que os contém ou mantenha o projeto e exclua os recursos individuais.

As seções a seguir descrevem como excluir esses recursos e objetos.

Excluir o cluster

Quando você exclui o cluster criado em Antes de começar, todos os objetos criados também são excluídos.

  1. No Google Cloud console, acesse a página Clusters.

    Acessar Clusters

  2. Clique no nome do cluster, my-cluster, na coluna Nome do recurso.

  3. Clique em Excluir cluster.

  4. Em Excluir cluster my-cluster, insira my-cluster para confirmar que você quer excluir o cluster.

  5. Clique em Excluir.

  6. Se você criou uma conexão particular ao criar um cluster, acesse a página Redes VPC do Google Cloud console e clique em Excluir rede VPC.

Excluir os objetos

Você pode manter os recursos configurados em Antes de começar e excluir apenas os objetos criados no projeto do Google Cloud .

  1. Para remover o modelo definido em Definir um modelo de consulta, execute a seguinte consulta:

    SELECT alloydb_ai_nl.drop_template(id)
    FROM alloydb_ai_nl.template_store_view
    WHERE config = 'nla_demo_cfg';
    
  2. Para remover o tipo de conceito product_name que você definiu em Construir o índice de valor, execute a seguinte consulta:

    SELECT alloydb_ai_nl.drop_concept_type('product_name');
    
  3. Para atualizar o índice de valor depois de remover o tipo de conceito product_name, execute a seguinte consulta:

    SELECT alloydb_ai_nl.refresh_value_index();
    
  4. Para remover a configuração de nla_demo_cfg criada em Criar uma configuração de linguagem natural, execute a seguinte consulta:

    SELECT
    alloydb_ai_nl.g_manage_configuration(
        'drop_configuration',
        'nla_demo_cfg'
    );
    
  5. Para remover o esquema nla_demo e as tabelas que você criou e preencheu em Criar o esquema e as tabelas nla_demo e Preencher tabelas no esquema nla_demo, execute a seguinte consulta:

    DROP SCHEMA nla_demo CASCADE;
    

A seguir