使用 AI 函数执行智能 SQL 查询

选择文档版本:

本页面介绍了如何使用 AlloyDB Omni AI 查询引擎,以及如何使用 AI 函数执行智能 SQL 查询。

AlloyDB AI 函数可将 Gemini 等大语言模型 (LLM) 直接与 AlloyDB Omni 数据集成,以执行智能数据操作。此功能包括以下方面的内置函数:

  • 过滤 (ai.if)
  • 语义排名 (ai.rank)
  • 文本生成 (ai.generate)

这些 AI 函数使用 AlloyDB AI 查询引擎来帮助您的应用使用各种规模的人工智能模型处理数据,从单行响应到大规模数据库操作。您可以使用 ai.ifai.rankai.generate 运算符将自然语言与 SQL 查询相结合。AlloyDB AI 会预留并创建 ai 架构。

AI 函数分为三类,它们在处理输入数据和内存分配方面有所不同:标量函数、基于数组的函数和光标函数。选择合适的 AI 函数取决于您的数据规模和性能要求。您可以使用下表了解这些函数及其使用场景:

类别

说明

推荐的使用场景

标量

专为基本的一对一处理而设计。接受单个输入并返回单个输出。

如果您需要一个基本函数,该函数可为标量函数调用次数较少(少于 50 次)的查询提供可接受的性能,则可以使用此函数。

基于数组

在单个函数调用中将数据作为行数组进行处理。接受数组作为输入,并返回数组作为输出。

适用于小型到中型数据集,其中符合条件的所有行的整个数组都可以放入内存限制范围内。这可为基于集合的操作提供高吞吐量。

光标

接受游标作为输入,并返回游标作为输出。

用于处理大量行(例如 10,000 行)。

准备工作

  1. 配置用户对 Vertex AI 模型的访问权限
  2. 验证是否已安装最新版本的 google_ml_integration

    1. 如需检查已安装的版本,请运行以下命令:

      SELECT extversion FROM pg_extension WHERE extname = 'google_ml_integration';
      extversion 
      ------------
      1.5.2
      (1 row)
    2. 如果未安装该扩展程序,或者安装的版本低于 1.5.2,请更新该扩展程序。

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

      如果您在运行上述命令时遇到问题,或者在运行上述命令后扩展程序未更新到 1.5.2 版,请与Google Cloud 支持团队联系。

  3. 如需使用 AlloyDB AI 查询引擎功能,请将 google_ml_integration.enable_ai_query_engine 标志设置为 on

    SQL

    1. 为当前会话启用 AI 查询引擎。

      SET google_ml_integration.enable_ai_query_engine = on;
    2. 为特定数据库在不同会话中启用功能。

      ALTER DATABASE DATABASE_NAME SET google_ml_integration.enable_ai_query_engine = 'on';
    3. 为特定用户在不同会话和数据库中启用 AI 查询引擎。

      ALTER ROLE postgres SET google_ml_integration.enable_ai_query_engine = 'on';

使用您所在区域支持的 Gemini 模型

如果您的 AlloyDB Omni 集群位于不支持 gemini-2.5-flash-lite 的区域,您可以使用 model_id parameter 在您所在的区域中使用其他可用的 Gemini 模型。

或者,您可以注册 Gemini 模型端点,并将该模型 ID 提供给 AI 运算符。如需了解详情,请参阅使用模型端点管理注册和调用远程 AI 模型

以下示例展示了如何注册另一个 Gemini 端点。在此示例中,第二个 Gemini 端点是 gemini-2.5-flash-lite 的全球端点。您可以通过传递 model_id => 'gemini-2.5-flash-lite-global' 作为附加参数,将此已注册的模型与 AI 运算符搭配使用。

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

使用 Gemini 3.0 模型

部分 Gemini 模型(例如 gemini-3.0-pro-preview)只能通过全球端点使用。您必须按如下方式注册此类模型:

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

PROJECT_ID 替换为 Vertex AI 模型所在项目的 ID。请注意,AlloyDB Omni 服务账号必须在该项目中具有 Vertex AI User 角色

注册模型后,您可以在 AI 函数中使用该模型,如下所示:

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

在查询中使用过滤条件

AlloyDB AI 提供 AI 赋能的 SQL 函数,让您可以在数据库查询中直接使用自然语言处理和 LLM,包括 ai.ifai.rank 运算符。

使用标量函数执行过滤

如需评估是否满足以自然语言陈述的条件,请使用 ai.if/google_ml.if 运算符。该函数会返回布尔值 true 或 false,如果未明确检测到输出,则返回 false

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

以下示例展示了如何使用 ai.if 运算符作为过滤条件,查找正面评价数量超过 500 且位于人口超过 100,000 的城市中的餐厅。该示例使用 restaurant_reviews,并且包含评价和城市位置等数据。ai.if 运算符可帮助您了解评价情绪,并将数据库中的位置与 Gemini 关于这些位置的人口的一般知识相结合。

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;

以下示例展示了如何使用在使用您所在区域支持的 Gemini 模型中注册的模型。

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-lite')
GROUP BY r.name, r.location_city
HAVING COUNT(*) > 500;

对查询执行使用 if 运算符的联接

如需执行联接操作,请将 ai.if/google_ml.if 运算符与联接搭配使用。以下示例查询会查找提及餐厅菜单中的每个菜单项的评价数量。

    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;

使用基于数组的函数执行过滤

以下示例使用 AI 模型 (gemini-2.5-flash-lite) 分析评价情感并过滤结果,以找出获得 10 条以上正面评价的餐厅。ARRAY_AGG 用于将单个数据行转换为结构化数组,以便 AI 模型可以批量处理这些数据,而不是一次处理一行。

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

使用游标执行过滤

以下示例展示了如何通过光标以流式传输方式过滤大量餐厅评价。

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

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

文本生成和总结

AlloyDB AI 提供文本生成运算符,例如标量 ai.generate 以及基于数组和基于游标的 ai.generate

使用标量函数执行文本生成

ai.generate 函数通过将提供的数据与用户的提示相结合来生成文本。

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

例如,您可以使用以下查询为每条用户评价生成简明摘要。

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

使用基于数组的函数执行文本生成

以下查询使用 UNNESTai.generate 来高效地总结多条评价。

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

使用光标执行文本生成

如需为数百万行生成摘要或翻译,同时避免内存瓶颈,请使用带光标的批量生成。

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

为查询结果评分

如果您需要使用自定义的自然语言指令对查询结果进行排序,请使用 ai.rank 运算符。

使用标量函数执行评分

以下函数可让您提供描述排名条件的提示,并返回每项的得分。

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

例如,以下查询使用来自 LLM 的评分获取前 20 条最正面的餐厅评价。

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;

使用基于数组的函数执行评分

借助此 ai.rank 函数,您可以根据自定义的自然语言指令对查询结果进行评分和排名。

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

以下查询使用 UNNESTai.rank 高效地对多条评价进行评分。

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;

使用光标执行评分

此函数用于对大型数据集进行评分,而不会超出内存限制。

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

以下示例展示了如何根据特定的自然语言标准对大量文本进行评分。

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

后续步骤