次の方法で共有


Azure Database for PostgreSQL - フレキシブル サーバーと Azure OpenAI を使用したセマンティック検索

適用対象: Azure Database for PostgreSQL - フレキシブル サーバー

このハンズオン チュートリアルでは、Azure Database for PostgreSQL フレキシブル サーバーと Azure OpenAI Service を使用してセマンティック検索アプリケーションを構築する方法について説明します。 セマンティック検索では、セマンティクスに基づいて検索を行います。一方、標準の字句検索では、クエリで指定されたキーワードに基づいて検索を行います。 たとえば、レシピ データセットに、グルテンフリー、ビーガン、乳製品フリー、フルーツフリー、デザートなどのラベルが含まれていないとしても、これらの特性は成分から推測できます。 基本となるのは、このようなセマンティック クエリを発行し、関連する検索結果を取得するという考え方です。

GenAI とフレキシブル サーバーを使用してデータに対するセマンティック検索機能を構築するには、次の手順を実行します。

  • 検索シナリオを特定します。 検索に関係するデータ フィールドを特定します。
  • 検索に関係するすべてのデータ フィールドに対し、そのデータ フィールドに保存されている値の埋め込みを保存するための、対応するベクター フィールドを作成します。
  • 選択したデータ フィールド内のデータの埋め込みを生成し、その埋め込みを対応するベクター フィールドに保存します。
  • 特定の入力検索クエリの埋め込みを生成します。
  • ベクトル データ フィールドを検索し、ニアレストネイバーを一覧表示します。
  • 適切な関連性、ランク付け、パーソナル化モデルを使用して結果を実行し、最終的なランク付けを生成します。 このようなモデルがない場合は、結果をドット積の降順でランク付けします。
  • モデル、結果の品質、CTR (セレクトスルー率) や滞在時間などのビジネス メトリックを監視します。 フィードバック メカニズムを組み込んで、データ品質、データ鮮度、パーソナル化からユーザー エクスペリエンスまで、検索スタックをデバッグおよび改善します。

前提条件

  1. OpenAI アカウントを作成して、Azure OpenAI Service へのアクセスを要求します。
  2. 目的のサブスクリプションでの権利を Azure OpenAI に与えます。
  3. Azure OpenAI リソースを作成し、モデルをデプロイするためのアクセス許可を付与します。

Azure OpenAI Service リソースとモデルを作成およびデプロイし、埋め込みモデル 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 が強制したスロットリングが原因で、ステートメントが途中で失敗することがあります。 失敗した場合は、少なくとも 1 分間待ってから、コマンドをもう一度実行します。

利便性のため、データベースに検索機能を作成します。

create function
    recipe_search(searchQuery text, numResults int)
returns table(
            recipeId int,
            recipe_name text,
            nutrition text,
            score real)
as $$
declare
    query_embedding vector(1536);
begin
    query_embedding := (azure_openai.create_embeddings('text-embedding-ada-002', searchQuery));
    return query
    select
        r.rid,
        r.recipe_name,
        r.nutrition,
        (r.embedding <=> query_embedding)::real as score
    from
        recipes r
    order by score asc limit numResults; -- cosine distance
end $$
language plpgsql;

次に、その関数を呼び出して検索します。

select recipeid, recipe_name, score from recipe_search('vegan recipes', 10);

結果を調べます。

 recipeid |                         recipe_name                          |   score
----------+--------------------------------------------------------------+------------
      829 | Avocado Toast (Vegan)                                        | 0.15672222
      836 | Vegetarian Tortilla Soup                                     | 0.17583494
      922 | Vegan Overnight Oats with Chia Seeds and Fruit               | 0.17668104
      600 | Spinach and Banana Power Smoothie                            |  0.1773768
      519 | Smokey Butternut Squash Soup                                 | 0.18031077
      604 | Vegan Banana Muffins                                         | 0.18287598
      832 | Kale, Quinoa, and Avocado Salad with Lemon Dijon Vinaigrette | 0.18368931
      617 | Hearty Breakfast Muffins                                     | 0.18737361
      946 | Chia Coconut Pudding with Coconut Milk                       |  0.1884186
      468 | Spicy Oven-Roasted Plums                                     | 0.18994217
(10 rows)