你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

使用 Azure Database for PostgreSQL 灵活服务器和 Azure OpenAI 的建议系统

适用于: Azure Database for PostgreSQL 灵活服务器

本动手教程介绍如何使用 Azure Database for PostgreSQL 灵活服务器和 Azure OpenAI 服务生成推荐器应用程序。 建议可用于不同领域 - 服务提供商通常会根据从客户和环境收集的先前历史记录和上下文信息提供有关产品和服务的建议。

可通过不同方法对建议系统进行建模。 本文探讨最简单的形式 - 基于对应于(例如)先前购买的产品的建议。 本教程使用了《语义搜索》一文中使用的食谱数据集,对食谱的建议则基于客户喜欢或之前搜索过的食谱。

先决条件

  1. 创建 OpenAI 帐户并请求访问 Azure OpenAI 服务
  2. 在所需订阅中授予对 Azure OpenAI 的访问权限。
  3. 授予创建 Azure OpenAI 资源和部署模型的访问权限。

创建和部署 Azure OpenAI 服务资源和模型、部署嵌入模型 text-embedding-ada-002。 复制部署名称,因为这是创建嵌入内容所必需的。

启用 azure_ai 和 pgvector 扩展

在 Azure Database for PostgreSQL 灵活服务器实例上启用 azure_aipgvector 之前,需要按照如何使用 PostgreSQL 扩展所述将其添加到允许列表中,并通过运行 SHOW azure.extensions; 检查是否正确添加。

然后,可通过连接到目标数据库并运行 CREATE EXTENSION 命令来安装扩展。 需要对希望扩展可用的每个数据库分别重复该命令。

CREATE EXTENSION azure_ai;
CREATE EXTENSION vector;

配置 OpenAI 终结点和密钥

在 Azure AI 服务中的“资源管理”>“密钥和终结点”下,可以找到 Azure AI 资源的终结点和密钥。 使用终结点和密钥之一启用 azure_ai 扩展来调用模型部署。

select azure_ai.set_setting('azure_openai.endpoint','https://<endpoint>.openai.azure.com');
select azure_ai.set_setting('azure_openai.subscription_key', '<API Key>');

下载和导入数据

  1. Kaggle 下载数据。
  2. 连接到服务器并创建一个 test 数据库,然后在其中创建一个用于导入数据的表。
  3. 导入数据。
  4. 向表添加嵌入列。
  5. 生成嵌入。
  6. 搜索。

创建表

CREATE TABLE public.recipes(
    rid integer NOT NULL,
    recipe_name text,
    prep_time text,
    cook_time text,
    total_time text,
    servings integer,
    yield text,
    ingredients text,
    directions text,
    rating real,
    url text,
    cuisine_path text,
    nutrition text,
    timing text,
    img_src text,
    PRIMARY KEY (rid)
);

导入数据

在客户端窗口中设置以下环境变量,以将编码设置为 utf-8。 此步骤是必需的,因为此特定数据集使用 WIN1252 编码。

Rem on Windows
Set PGCLIENTENCODING=utf-8;
# on Unix based operating systems
export PGCLIENTENCODING=utf-8

将数据导入到创建的表中;请注意,此数据集包含标题行:

psql -d <database> -h <host> -U <user> -c "\copy recipes FROM <local recipe data file> DELIMITER ',' CSV HEADER"

添加一个列来存储嵌入

ALTER TABLE recipes ADD COLUMN embedding vector(1536);

生成嵌入

使用 azure_ai 扩展为数据生成嵌入。 在以下部分中,我们对一些不同的字段进行矢量化处理,并将其连接:

WITH ro AS (
    SELECT ro.rid
    FROM
        recipes ro
    WHERE
        ro.embedding is null
        LIMIT 500
)
UPDATE
    recipes r
SET
    embedding = azure_openai.create_embeddings('text-embedding-ada-002', r.recipe_name||' '||r.cuisine_path||' '||r.ingredients||' '||r.nutrition||' '||r.directions)
FROM
    ro
WHERE
    r.rid = ro.rid;

重复该命令,直到不存在要处理的行为止。

提示

尝试 LIMIT。 如果使用的值较高,该语句可能因 Azure OpenAI 施加的限制而中途失败。 如果该语句失败,请等待至少一分钟,然后再次执行命令。

为方便起见,请在数据库中创建搜索函数:

create function
    recommend_recipe(sampleRecipeId int, numResults int)
returns table(
            out_recipeName text,
            out_nutrition text,
            out_similarityScore real)
as $$
declare
    queryEmbedding vector(1536);
    sampleRecipeText text;
begin
    sampleRecipeText := (select
                            recipe_name||' '||cuisine_path||' '||ingredients||' '||nutrition||' '||directions
                        from
                            recipes where rid = sampleRecipeId);

    queryEmbedding := (azure_openai.create_embeddings('text-embedding-ada-002',sampleRecipeText));

    return query
    select
        distinct r.recipe_name,
        r.nutrition,
        (r.embedding <=> queryEmbedding)::real as score
    from
        recipes r
    order by score asc limit numResults; -- cosine distance
end $$
language plpgsql;

现在只需调用函数来搜索建议:

select out_recipename, out_similarityscore from recommend_recipe(1, 20); -- search for 20 recipe recommendations that closest to recipeId 1

浏览结果:

            out_recipename             | out_similarityscore
---------------------------------------+---------------------
 Apple Pie by Grandma Ople             |                   0
 Easy Apple Pie                        |          0.05137232
 Grandma's Iron Skillet Apple Pie      |         0.054287136
 Old Fashioned Apple Pie               |         0.058492836
 Apple Hand Pies                       |          0.06449003
 Apple Crumb Pie                       |          0.07290977
 Old-Fashioned Apple Dumplings         |         0.078374185
 Fried Apple Pies                      |          0.07918481
 Apple Pie Filling                     |         0.084320426
 Apple Turnovers                       |          0.08576391
 Dutch Apple Pie with Oatmeal Streusel |          0.08779895
 Apple Crisp - Perfect and Easy        |          0.09170883
 Delicious Cinnamon Baked Apples       |          0.09384012
 Easy Apple Crisp with Pie Filling     |          0.09477234
 Jump Rope Pie                         |          0.09503954
 Easy Apple Strudel                    |         0.095167875
 Apricot Pie                           |          0.09634114
 Easy Apple Crisp with Oat Topping     |          0.09708358
 Baked Apples                          |          0.09826993
 Pear Pie                              |         0.099974394
(20 rows)