OpenAIは人工知能企業であり、これまでに複数の大規模言語モデルを開発しています。これらのモデルは自然言語の理解や生成において優れた性能を発揮し、テキストの生成、質問への回答、対話などを行うことができます。これらのモデルはAPIを通じてアクセスすることが可能です。
OceanBaseデータベースは、ベクトル型データの格納、ベクトルインデックス、そしてembeddingベクトル検索機能を提供しています。OpenAIのAPIを利用して、ベクトル化したデータをOceanBaseデータベースに保存し、その後OceanBaseのベクトル検索機能を用いて関連するデータを検索することができます。
前提条件
OceanBaseデータベースV4.4.0以降をデプロイし、MySQLモードのテナントを作成していること。テナントの作成後、以下の手順を参照して操作してください。
環境に使用可能なMySQLテナント、MySQLデータベース、およびデータベースアカウントが存在し、データベースアカウントに読み書き権限が付与されていること。
Python 3.9以降のバージョンと対応するpipをインストールしていること。
poetry、pyobvector、OpenAI SDKをインストールしていること。
python3 pip install poetry python3 pip install pyobvector python3 pip install openaiOpenAI APIキーを準備していること。
ベクトル検索機能を有効にするために、テナントで
ob_vector_memory_limit_percentageパラメータを設定していることを確認してください。V4.4.1以前のバージョンでは値を30に設定することを推奨しますが、V4.4.1以降のバージョンではデフォルト値の0のままにすることを推奨します。このパラメータをより正確に設定する必要がある場合は、ob_vector_memory_limit_percentageを参照してこの値を計算してください。
ステップ1:OceanBaseデータベースの接続文字列を取得する
OceanBaseデータベースのデプロイ担当者または管理者から、該当するデータベース接続文字列を取得します。例:
obclient -h$host -P$port -u$user_name -p$password -D$database_name
パラメータ説明:
$host:OceanBaseデータベースへの接続IPアドレス。OceanBaseデータベースプロキシ(OceanBase Database Proxy、ODP)接続方式ではODPアドレスを使用し、直接接続方式ではOBServerノードのIPアドレスを使用します。$port:OceanBaseデータベースへの接続ポート。ODP接続方式のデフォルトポートは2883で、ODPデプロイ時にカスタマイズ可能です。直接接続方式のデフォルトポートは2881で、OceanBaseデータベースのデプロイ時にカスタマイズ可能です。$database_name:アクセス対象のデータベース名。注意
テナントに接続するユーザーは、データベースに対する
CREATE、INSERT、DROP、およびSELECT権限が付与されていなければなりません。ユーザー権限の詳細については、MySQLモードの権限分類を参照してください。$user_name:テナントの接続アカウント。ODP接続の一般的な形式:ユーザー名@テナント名#クラスタ名またはクラスタ名:テナント名:ユーザー名。直接接続方式の形式:ユーザー名@テナント名。$password:アカウントのパスワードを指定します。
接続文字列の詳細については、OBClientを使用したOceanBaseテナントへの接続を参照してください。
例:
```shell
obclient -hxxx.xxx.xxx.xxx -P2881 -utest_user001@mysql001 -p****** -Dtest
```
ステップ2:LLMプラットフォームアカウントの登録
OpenAI APIキーを取得する:
OpenAI プラットフォームにログインします。
右上の API Keys をクリックします。
Create API Key をクリックします。
関連情報を入力し、Create API Key をクリックします。
OpenAI APIキーを環境変数に設定する:
Unixベースのシステム(UbuntuやMacOSなど)の場合は、ターミナルで以下のコマンドを実行します:
export OPENAI_API_KEY='your-api-key'Windowsシステムの場合は、コマンドプロンプトで以下のコマンドを実行します:
set OPENAI_API_KEY=your-api-key
your-api-key は実際のOpenAI APIキーに置き換えてください。
ステップ3:OceanBaseデータベースにベクトルデータを格納する
OceanBaseデータベースにベクトルデータを格納する
- テストデータの準備
事前にベクトル化されたデータを含むCSVファイルをダウンロードします。このCSVファイルには1000件のグルメレビューデータセットが含まれており、最終列はベクトル化後の値であるため、再度ベクトルを計算する必要はありません。以下のコードを使用して、embedding列(つまりベクトル列)を再計算し、新しいCSVファイルを生成することもできます。
```shell
from openai import OpenAI
import pandas as pd
input_datapath = "./fine_food_reviews.csv"
client = OpenAI()
# ここではtext-embedding-ada-002埋め込みモデルを使用しています。必要に応じて調整可能です。
def embedding_text(text, model="text-embedding-ada-002"):
# embeddingベクトルの作成方法については、次のURLを参照してください:https://community.openai.com/t/embeddings-api-documentation-needs-to-updated/475663
res = client.embeddings.create(input=text, model=model)
return res.data[0].embedding
df = pd.read_csv(input_datapath, index_col=0)
# 実際の生成には数分かかります。OpenAI Embedding APIを1行ずつ呼び出します。
df["embedding"] = df.combined.apply(embedding_text)
output_datapath = './fine_food_reviews_self_embeddings.csv'
df.to_csv(output_datapath)
```
以下のスクリプトを実行して、テストデータをOceanBaseデータベースに挿入します。スクリプトがあるディレクトリは、テストデータがあるディレクトリと同じである必要があります。
import os import sys import csv import json from pyobvector import * from sqlalchemy import Column, Integer, String # pyobvectorを使用してOBに接続する場合、ユーザー名やパスワードに@記号が含まれる場合は、%40に置き換えてください。 client = ObVecClient(uri="host:port", user="username",password="****",db_name="test") # 事前に準備されたテストデータセットは既にベクトル化されています。デフォルトではPythonスクリプトと同じディレクトリに配置されています。自分で再度ベクトル化した場合は、対応するファイルに置き換えてください。 file_name = "fine_food_reviews.csv" file_path = os.path.join("./", file_name) # 列を定義します。ベクトル化された列は最後のフィールドに配置されています。 cols = [ Column('id', Integer, primary_key=True, autoincrement=False), Column('product_id', String(256), nullable=True), Column('user_id', String(256), nullable=True), Column('score', Integer, nullable=True), Column('summary', String(2048), nullable=True), Column('text', String(8192), nullable=True), Column('combined', String(8192), nullable=True), Column('n_tokens', Integer, nullable=True), Column('embedding', VECTOR(1536)) ] # テーブル名 table_name = 'fine_food_reviews' # テーブルが存在しない場合は作成します。 if not client.check_table_exists(table_name): client.create_table(table_name,columns=cols) # ベクトル列のインデックスを作成します。 client.create_index( table_name=table_name, is_vec_index=True, index_name='vidx', column_names=['embedding'], vidx_params='distance=l2, type=hnsw, lib=vsag', ) # CSVファイルを開いて読み込みます。 with open(file_name, mode='r', newline='', encoding='utf-8') as csvfile: csvreader = csv.reader(csvfile) # ヘッダー行を読み取ります。 headers = next(csvreader) print("Headers:", headers) batch = [] # データを格納し、10行ごとにデータベースに挿入します。 for i, row in enumerate(csvreader): # CSVファイルには9つのフィールドがあります: id,product_id,user_id,score,summary,text,combined,n_tokens,embedding if not row: break food_review_line= {'id':row[0],'product_id':row[1],'user_id':row[2],'score':row[3],'summary':row[4],'text':row[5],\ combined':row[6],'n_tokens':row[7],'embedding':json.loads(row[8])} batch.append(food_review_line) # 10行ごとに挿入します。 if (i + 1) % 10 == 0: client.insert(table_name,batch) batch = [] # バッファをクリア # 残りの行(ある場合)を挿入します。 if batch: client.insert(table_name,batch) # テーブル内のデータを確認し、すべてのデータが挿入されていることを保証します。 count_sql = f"select count(*) from {table_name};" cursor = client.perform_raw_text_sql(count_sql) result = cursor.fetchone() print(f"インポートデータ総件数:{result[0]}")
OceanBaseデータベースのデータをクエリする
以下のPythonスクリプトを
openAIQuery.pyという名前で保存します。import os import sys import csv import json from pyobvector import * from sqlalchemy import func from openai import OpenAI # コマンドライン引数を取得する if len(sys.argv) != 2: print("検索キーワードを入力してください。") sys.exit() queryStatement = sys.argv[1] # pyobvectorを使用してOBに接続する際、ユーザー名やパスワードに@が含まれる場合は、%40に置き換えてください。 client = ObVecClient(uri="host:port", user="usename",password="****",db_name="test") openAIclient = OpenAI() # テキストのベクトル表現を生成する関数を定義する def generate_embeddings(text, model="text-embedding-ada-002"): # ベクトル埋め込みの方法については、次のURLを参照してください:https://community.openai.com/t/embeddings-api-documentation-needs-to-updated/475663 res = openAIclient.embeddings.create(input=text, model=model) return res.data[0].embedding def query_ob(query, tableName, vector_name="embedding", top_k=1): embedding = generate_embeddings(query) # 近似最近傍探索を実行する res = client.ann_search( table_name=tableName, vec_data=embedding, vec_column_name=vector_name, distance_func=func.l2_distance, topk=top_k, output_column_names=['combined'] ) for row in res: print(str(row[0]).replace("Title: ", "").replace("; Content: ", ": ")) # テーブル名 table_name = 'fine_food_reviews' query_ob(queryStatement,table_name,'embedding',1)質問を入力し、関連する回答を出力します。
python3 openAIQuery.py 'pet food'
期待される結果は次のとおりです:
Crack for dogs.: These thing are like crack for dogs. I am not sure of the make-up but the doggies sure love them.