Fazer consultas SQL inteligentes usando funções de IA

As funções de IA do AlloyDB AI integram modelos de linguagem grandes (LLMs), como o Gemini, diretamente aos dados do AlloyDB para PostgreSQL para realizar operações inteligentes de dados. Esse recurso inclui funções integradas para o seguinte:

  • Filtros (ai.if)
  • Classificação semântica (ai.rank)
  • Geração de texto (ai.generate)

Essas funções de IA usam o mecanismo de consulta da IA do AlloyDB para ajudar seu aplicativo a processar dados usando modelos de inteligência artificial em várias escalas, desde respostas de linha única até operações de banco de dados em grande escala. É possível usar os operadores ai.if, ai.rank e ai.generate para combinar linguagem natural com consultas SQL. O AlloyDB AI reserva e cria o esquema ai.

Há três categorias de funções de IA que diferem com base em como elas processam dados de entrada e alocação de memória: funções escalares, baseadas em matrizes e de cursor. A escolha da função de IA certa depende da escala dos seus dados e dos requisitos de desempenho. Use a tabela a seguir para saber mais sobre essas funções e os casos de uso delas:

Categoria

Descrição

Caso de uso recomendado

Escalar

Projetado para processamento básico individual. Recebe uma única entrada e retorna uma única saída.

Use quando quiser uma função básica que ofereça desempenho aceitável para consultas que fazem um pequeno número (menos de 50) de chamadas de função escalar.

Baseada em matriz

Processa dados como uma matriz de linhas em uma única chamada de função. Recebe uma matriz como entrada e retorna uma matriz como saída.

Use para conjuntos de dados pequenos a médios em que toda a matriz de linhas qualificadas pode caber nos limites de memória. Isso oferece alta capacidade de transferência para operações baseadas em conjuntos.

Cursor

Usa um cursor como entrada e retorna um cursor como saída.

Use para processar um grande número de linhas, por exemplo,10.000 linhas.

Antes de começar

Integrar com a Vertex AI e instalar a extensão

  1. Configurar o acesso do usuário aos modelos da Vertex AI.
  2. Verifique se a versão mais recente do google_ml_integration está instalada.
    1. Para verificar a versão instalada, execute o seguinte comando:

              SELECT extversion FROM pg_extension WHERE extname = 'google_ml_integration';
              extversion 
              ------------
              1.5.2
              (1 row)
            
    2. Se a extensão não estiver instalada ou se a versão instalada for anterior à 1.5.2, atualize a extensão.

              CREATE EXTENSION IF NOT EXISTS google_ml_integration;
              ALTER EXTENSION google_ml_integration UPDATE;
            

      Se você tiver problemas ao executar os comandos anteriores ou se a extensão não for atualizada para a versão 1.5.2 depois de executar os comandos anteriores, entre em contato com o suporte doGoogle Cloud .

  3. Para usar a funcionalidade do mecanismo de consulta da IA do AlloyDB, defina a flag google_ml_integration.enable_ai_query_engine como on.

    SQL

    1. Ative o mecanismo de consulta de IA para a sessão atual.
                    SET google_ml_integration.enable_ai_query_engine = on;
                    
    2. Ativa recursos para um banco de dados específico em várias sessões.
                    ALTER DATABASE DATABASE_NAME SET google_ml_integration.enable_ai_query_engine = 'on';
                    
    3. Ative o mecanismo de consulta de IA para um usuário específico em sessões e bancos de dados.
                    ALTER ROLE postgres SET google_ml_integration.enable_ai_query_engine = 'on';
                  

    Console

    Para modificar o valor da flag google_ml_integration.enable_ai_query_engine, siga as etapas em Configurar flags de bancos de dados de uma instância.

    gcloud

    Para usar a gcloud CLI, você pode instalar e inicializar a CLI do Google Cloud ou usar o Cloud Shell.

    É possível modificar o valor da flag google_ml_integration.enable_ai_query_engine. Para mais informações, consulte Configurar flags de banco de dados de uma instância.

                 gcloud alloydb instances update INSTANCE_ID \
                   --database-flags google_ml_integration.enable_ai_query_engine=on \
                   --region=REGION_ID \
                   --cluster=CLUSTER_ID \
                   --project=PROJECT_ID
                

Usar um modelo do Gemini disponível na sua região

Se o cluster do AlloyDB para PostgreSQL estiver em uma região em que gemini-2.0-flash não é compatível, use um dos outros modelos do Gemini disponíveis na sua região usando o model_id parameter.

Como alternativa, é possível registrar um endpoint de modelo do Gemini e fornecer esse ID de modelo aos operadores de IA. Para mais informações, consulte Registrar e chamar modelos de IA remotos usando o gerenciamento de endpoints de modelo.

O exemplo a seguir mostra como registrar outro endpoint do Gemini. Neste exemplo, o segundo endpoint do Gemini é o endpoint global para gemini-2.0-flash. É possível usar esse modelo registrado com operadores de IA transmitindo model_id =>gemini-2.5-flash-global` como um argumento adicional.

CALL
  google_ml.create_model(
    model_id => 'gemini-2.5-flash-global',
    model_type => 'llm',
    model_provider => 'google',
    model_qualified_name => 'gemini-2.5-flash',
    model_request_url =>  'https://aiplatform.googleapis.com/v1/projects/PROJECT_ID/locations/global/publishers/google/models/gemini-2.5-flash:generateContent',
    model_auth_type => 'alloydb_service_agent_iam'
);

Usar modelos do Gemini 3.0

Alguns modelos do Gemini, como o gemini-3.0-pro-preview, estão disponíveis apenas no endpoint global. Você precisa registrar esses modelos da seguinte forma:

CALL
  google_ml.create_model(
    model_id => 'gemini-3-preview-model',
    model_request_url => 'https://aiplatform.googleapis.com/v1/projects/PROJECT_ID/locations/global/publishers/google/models/gemini-3-pro-preview:generateContent',
    model_qualified_name => 'gemini-3-pro-preview',
    model_provider => 'google',
    model_type => 'llm',
    model_auth_type => 'alloydb_service_agent_iam'
);

Substitua PROJECT_ID pelo ID do projeto em que o modelo da Vertex AI está disponível. A conta de serviço do AlloyDB precisa ter o papel de usuário da Vertex AI nesse projeto.

Depois de registrar o modelo, você pode usá-lo em funções de IA da seguinte maneira:

SELECT ai.generate(prompt => 'What is AlloyDB?', model_id => 'gemini-3-preview-model');

Usar filtros nas consultas

A IA do AlloyDB oferece funções SQL com tecnologia de IA que permitem usar o processamento de linguagem natural e LLMs diretamente nas consultas de banco de dados, incluindo os operadores ai.if e ai.rank.

Fazer filtragem usando funções escalares

Para avaliar se uma condição expressa em linguagem natural é atendida, use o operador ai.if/google_ml.if. A função retorna o valor booleano verdadeiro ou falso e false se a saída não for claramente detectada.

- Function signature
FUNCTION ai.if(prompt TEXT, model_id VARCHAR(100) DEFAULT NULL) RETURNS bool

O exemplo a seguir mostra o uso do operador ai.if como um filtro para encontrar restaurantes com mais de 500 avaliações positivas localizados em cidades com uma população maior que 100.000. O exemplo usa restaurant_reviews e contém dados como avaliações e localização da cidade. O operador ai.if ajuda você a entender o sentimento das avaliações e combinar os locais do banco de dados com o conhecimento geral do Gemini sobre a população dessas regiões.

SELECT r.name, r.location_city
FROM restaurant_reviews r
WHERE
  AI.IF(r.location_city || ' has a population OF more than 100,000 AND the following is a positive review; Review: ' || r.review)
GROUP BY r.name, r.location_city
HAVING COUNT(*) > 500;

A seguir, mostramos o mesmo exemplo usando o modelo registrado em Usar um modelo do Gemini disponível na sua região.

SELECT r.name, r.location_city
FROM restaurant_reviews r
WHERE
  AI.IF(r.location_city || ' has a population of more than 100,000 AND the following is a positive review; Review: ' || r.review, model_id => 'gemini-2.5-flash')
GROUP BY r.name, r.location_city
HAVING COUNT(*) > 500;

Fazer uma junção em uma consulta que usa o operador "if"

Para realizar uma operação de junção, use o operador ai.if/google_ml.if com a junção. A consulta de exemplo a seguir encontra o número de avaliações que mencionam cada item do cardápio do restaurante.

    SELECT item_name, COUNT(*)
    FROM menu_items JOIN user_reviews
      ON ai.if(
        prompt => 'Does the following user review talk about the menu item mentioned ? review: ' || user_reviews.review_text || ' menu item: ' || item_name)
    GROUP BY item_name;

Fazer filtragem usando funções baseadas em matrizes

O exemplo a seguir identifica restaurantes com mais de 10 avaliações positivas usando um modelo de IA (gemini-2.0-flash) para analisar o sentimento das avaliações e filtrar os resultados. O ARRAY_AGG é usado para transformar linhas individuais de dados em matrizes estruturadas para que possam ser processadas pelo modelo de IA em massa, em vez de uma linha por vez.

WITH initial_arrays AS (WITH initial_arrays AS (
  SELECT
    ARRAY_AGG(r.id ORDER BY r.id) AS review_ids,
    -- Assuming ai.if takes an array of prompts and returns a boolean array
    ai.if(
      prompts => ARRAY_AGG('Is the review positive: ' || r.review ORDER BY r.id)
      model_id => 'gemini-2.5-flash',
      batch_size => 20
    ) AS truth_values
  FROM restaurant_reviews r
),
reviews AS (
SELECT
  initial_arrays.review_ids[i] AS review_id,
  initial_arrays.truth_values[i] AS truth_value
FROM
  initial_arrays,
  generate_series(1, array_length(initial_arrays.review_ids, 1)) AS i
)
SELECT rest_review.city, rest_review.name
FROM restaurant_reviews rest_review JOIN reviews review ON rest_review.id=review.review_id
WHERE review.truth_value = 't'
GROUP BY rest_review.city, rest_review.name
HAVING COUNT(*) > 10;

Fazer filtragem usando cursores

O exemplo a seguir mostra como filtrar um grande conjunto de avaliações de restaurantes transmitindo-as por um cursor.

CREATE TABLE filtered_results(input text, result bool);

DO $$
DECLARE
    prompt_cursor REFCURSOR;
    result_cursor REFCURSOR;
    rec RECORD;
BEGIN
    -- 1. Open a cursor for the input data
    OPEN prompt_cursor FOR
        SELECT r.location_city || ' has a population of > 100,000 and is a positive review; Review: ' || r.review
        FROM restaurant_reviews r;

    -- 2. Call the array-based function using the input cursor
    result_cursor := ai.if(
        'Is the given statement true? ',
        prompt_cursor,
        model_id => 'gemini-2.5-flash'
    );

    -- 3. Fetch results from the output cursor and store them
    LOOP
        FETCH result_cursor INTO rec;
        EXIT WHEN NOT FOUND;
        INSERT INTO filtered_results VALUES(rec.input, rec.output);
    END LOOP;

    CLOSE result_cursor;
END $$;

Resumo e geração de textos

A IA do AlloyDB oferece operadores de geração de texto, como ai.generate escalar e ai.generate baseado em matriz e cursor.

Realizar a geração de texto usando funções escalares

A função ai.generate gera texto combinando os dados fornecidos com o comando do usuário.

-- Function Signature
FUNCTION ai.generate(prompt TEXT, model_id VARCHAR(100) DEFAULT NULL) RETURNS TEXT

Por exemplo, é possível usar a consulta a seguir para gerar um resumo conciso de cada avaliação do usuário.

SELECT
  ai.generate(
    prompt => 'Summarize the review in 20 words or less. Review: ' || review) AS review_summary
FROM user_reviews;

Realizar geração de texto usando funções baseadas em matrizes

A consulta a seguir usa UNNEST e ai.generate para resumir várias avaliações de forma eficiente.

SELECT
  UNNEST(
    ai.generate(
      prompts => ARRAY_AGG('Summarize the review in 20 words or less. Review: ' || review),
      model_id => 'gemini-2.5-flash',
    )
  ) AS review_summary
FROM user_reviews;

Realizar geração de texto usando cursores

Para gerar resumos ou traduções de milhões de linhas sem atingir gargalos de memória, use a geração em lote com cursores.

CREATE TABLE summary_results(summary text);

DO $$
DECLARE
    prompt_cursor REFCURSOR;
    summary_cursor REFCURSOR;
    rec RECORD;
BEGIN
    OPEN prompt_cursor FOR SELECT review_text FROM user_reviews ORDER BY id;

    summary_cursor := ai.generate(
        'Summarize the review in 20 words or less. Review:',
        prompt_cursor,
    );

    LOOP
        FETCH summary_cursor INTO rec;
        EXIT WHEN NOT FOUND;
        INSERT INTO summary_results VALUES(rec.output);
    END LOOP;

    CLOSE summary_cursor;
END $$;

Pontuar os resultados da consulta

Se você precisar classificar os resultados da consulta usando instruções personalizadas de linguagem natural, use o operador ai.rank.

Realizar pontuações usando funções escalares

A função a seguir permite fornecer um comando que descreve os critérios de classificação e retorna uma pontuação para cada item.

-- Function signature
FUNCTION ai.rank(prompt TEXT, model_id VARCHAR(100) DEFAULT NULL) RETURNS real

Por exemplo, a consulta a seguir recebe as 20 avaliações de restaurantes mais positivas, usando pontuações de um LLM.

SELECT review AS top20
FROM user_reviews
ORDER BY ai.rank(
  'Score the following review according to these rules:
  (1) Score OF 8 to 10 IF the review says the food IS excellent.
  (2) 4 to 7 IF the review says the food is ok.
  (3) 1 to 3 IF the review says the food is not good. Here is the review:' || review) DESC
LIMIT 20;

Realizar pontuações usando funções baseadas em matrizes

Com essa função ai.rank, é possível pontuar e classificar os resultados da consulta com base em instruções personalizadas de linguagem natural.

FUNCTION ai.rank(prompts TEXT[], model_id VARCHAR(100) DEFAULT NULL) RETURNS real[]

A consulta a seguir usa UNNEST e ai.rank para pontuar várias avaliações de forma eficiente.

SELECT
  UNNEST(
    ai.rank(
      ARRAY_AGG('Score the following review according to these rules:
  (1) Score OF 8 to 10 IF the review says the food IS excellent.
  (2) 4 to 7 IF the review says the food is ok.
  (3) 1 to 3 IF the review says the food is not good. Here is the review:' || review),
    )
  ) as review_scores
FROM user_reviews;

Realizar pontuação usando cursores

Essa função é usada para pontuar grandes conjuntos de dados sem atingir os limites de memória.

FUNCTION ai.rank(context TEXT, input_cursor REFCURSOR, model_id VARCHAR(100) DEFAULT NULL) RETURNS REFCURSOR

O exemplo a seguir mostra como pontuar grandes volumes de texto de acordo com critérios específicos de linguagem natural.

CREATE TABLE scored_results(input text, score real);

DO $$
DECLARE
    prompt_cursor REFCURSOR;
    score_cursor REFCURSOR;
    rec RECORD;
BEGIN
    OPEN prompt_cursor FOR SELECT review FROM user_reviews ORDER BY id;

    score_cursor := ai.rank(
        'Score the following review: (1) 8-10 if excellent, (2) 4-7 if ok, (3) 1-3 if not good. Review:',
        prompt_cursor,
    );

    LOOP
        FETCH score_cursor INTO rec;
        EXIT WHEN NOT FOUND;
        INSERT INTO scored_results VALUES(rec.input, rec.output);
    END LOOP;

    CLOSE score_cursor;
END $$;

A seguir