2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

完走賞のQiitanぬいぐるみをお迎えするためにUnityでゲーム作ってみるAdvent Calendar 2023

Day 20

Azure OpenAI Service ワークショップに参加したので復習してみる(Cosmos DB×AI Search部分)

Last updated at Posted at 2023-12-20

はじめに

リソースがなんとか作成できたので、インデックスを作成するFunctionsの作成に入ります。

前回の記事

そもそもどういう構成か

アーキテクチャをそのまま引用していいかわからなかったので、すごく簡単に今回のワークショップで作成した構成をかきました。

image.png

まず、自身が持っているデータ(社内ナレッジとか)をCosmosDBに登録します。
登録したデータはAzure Open AIを使ってベクター化され、AI Searchにデータとともに登録されるイメージです。

そのデータを基におれおれChatGPTで社内ナレッジとかが検索できるようになる!というものでした。

今回実装してみるところ

この記事では、特に私が触ったことのなかった、Cosmos DBのChange Feedの機能を使ってAI Searchにインデックスを登録するところまでをピックアップしてまとめたいと思います。(上の図の赤枠で囲っているところ)

環境

  • windows11
  • Visual Studio Code
  • Python v3.10.11
  • Azure Core Tools v4.0.5455(x64)

リソース作成

以下のリソースを作成します。

  • CosmosDB
  • AI Search(プランはBasic)
  • Azure Functions(ローカルに作成)

Azure Functionsのリソースに関しては今回はローカル実行のみで発行はしてません。

AI Searchでインデックスを作成

インデックスを以下のような設定で作成します。

image.png

フィールド名 取得可能 フィルター可能 ソート可能 ファセット可能 検索可能 アナライザー
title Edm.String - - - 日本語 - Microsoft
category Edm.String - 日本語 - Microsoft
content Edm.String - - - 日本語 - Microsoft

image.png

各項目について( ..)φメモメモ

項目名 説明メモ
取得可能 チェックが入っていないとSELECTできない
フィルター可能 完全一致の検索
ソート可能 数字とか日付でソート
ファセット可能 ドリルダウンできる
検索可能 フルテキスト検索

おまけ
管理者キーはインデックスの更新とかができる
クエリキーはインデックスの読み込みだけができる

Funcionsを実装

Cosmos DB Triggerを使うことででリアルタイムに AI Search のインデックスを更新できます。

local.setting.json
{
  "IsEncrypted": false,
  "Values": {
    "AzureWebJobsStorage": "UseDevelopmentStorage=true",
    "FUNCTIONS_WORKER_RUNTIME": "python",
    "AzureWebJobsFeatureFlags": "EnableWorkerIndexing",
    "COSMOS_CONNECTION": "",
    "AI_SEARCH_ENDPOINT": "",
    "AI_SEARCH_ADMIN_KEY": ""
  }
}

COSMOS_CONNECTIONの値👇

image.png

AI_SEARCH_ENDPOINTの値👇

image.png

AI_SEARCH_ADMIN_KEYの値👇

image.png

indexer.py
import azure.functions as func
import logging
import os

from azure.core.credentials import AzureKeyCredential
from azure.search.documents import SearchClient

app = func.FunctionApp()

COSMOS_DATABASE_NAME = ""
COSMOS_CONTAINER_NAME = ""
AI_SEARCH_INDEX_NAME = ""

search_client = SearchClient(os.getenv("AI_SEARCH_ENDPOINT"),
                             AI_SEARCH_INDEX_NAME,
                             AzureKeyCredential(os.getenv("AI_SEARCH_ADMIN_KEY")))

@app.cosmos_db_trigger(arg_name="items",
                       connection="COSMOS_CONNECTION",
                       database_name=COSMOS_DATABASE_NAME, 
                       container_name=COSMOS_CONTAINER_NAME, 
                       create_lease_container_if_not_exists=False,
                       feed_poll_delay=5000,
                       lease_container_name="leases")
def indexer(items: func.DocumentList):
    documents_to_upsert = []

    for item in items:

        documents_to_upsert.append({
            "id": item["id"],
            "title": item["title"],
            "category": item["category"],
            "content": item["content"]})

    search_client.merge_or_upload_documents(documents_to_upsert)
    logging.info(f"{len(documents_to_upsert)} document(s) uploaded")

試してみる

CosmosDBにデータを登録してみてインデックスが登録されるかを見てみます。

以下のデータをデータエクスプローラーを使って登録してみます。

image.png

登録されたら、AI Searchから作成したインデックスを見てみます。
検索ボタンを押すと、先ほど登録したデータがこちらにも反映されていることが確認できました。

image.png

おわりに

今回初めてしっかり試したのですが、リアルタイムでデータを反映できるChange Feed機能は便利だなと思いました。
データが追加・更新されるたびに勝手にインデックスまで登録してくれるので、データの管理も楽ですね。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?