OceanBaseはV4.3.3以降、ベクトル型データの格納、ベクトルインデックス、および埋め込みベクトル検索をサポートしています。ベクトル化したデータをOceanBaseに保存し、その後の検索に利用できます。
Google Gemini AIは、Googleが開発したマルチモーダル大規模言語モデル(LLM)群です。テキスト、コード、画像、音声、動画など、さまざまな種類のデータを理解して処理できるよう設計されています。
このチュートリアルでは、OceanBase Cloudのベクトル検索機能とGoogle Geminiを使用して、チャットアプリケーションを作成する方法を説明します。
前提条件
- ご利用の環境でOceanBase Cloudのトランザクション処理用インスタンスを利用できること。
インスタンスの作成方法については、トランザクション処理用インスタンスの作成をご参照ください。
インスタンスにMySQL互換テナントを作成済みであること。作成方法については、MySQL互換テナントの作成をご参照ください。
テナント内に使用可能なMySQLデータベースとアカウントを作成済みであり、データベースアカウントに読み取りおよび書き込み権限を付与済みであること。詳細については、アカウントの作成およびデータベースの作成(MySQLのみ)をご参照ください。
プロジェクト管理者またはインスタンス管理者であり、インスタンスのデータを読み書きするために必要な権限を持っていること。権限がない場合は、組織管理者に連絡して必要な権限を付与してもらってください。
Python 3.11以降をインストールしていること。
依存関係をインストールしていること。
python3 -m pip install pyobvector requests google-genai tqdm
ステップ1:データベース接続情報を取得する
OceanBase Cloudコンソールにログインします。
インスタンス一覧ページで、対象インスタンスの情報を展開します。
対象テナントで、接続 > 接続文字列を取得 を選択します。
ポップアップウィンドウで、接続方式として パブリック接続 を選択します。
ポップアップウィンドウの案内に従って、パブリックエンドポイントと接続文字列を取得します。
ステップ2:AIアシスタントを構築する
環境変数の設定
Google GeminiのAPIキーとOceanBase接続情報を取得し、環境変数に設定します。
export OCEANBASE_DATABASE_URL=YOUR_OCEANBASE_DATABASE_URL
export OCEANBASE_DATABASE_USER=YOUR_OCEANBASE_DATABASE_USER
export OCEANBASE_DATABASE_DB_NAME=YOUR_OCEANBASE_DATABASE_DB_NAME
export OCEANBASE_DATABASE_PASSWORD=YOUR_OCEANBASE_DATABASE_PASSWORD
export GEMINI_API_KEY=YOUR_GEMINI_API_KEY
サンプルコード
データの読み込み
ここでは、text-embedding-004を例に、Google Gemini AIの埋め込みAPIを使用してベクトルデータを生成します。
from google import genai
from glob import glob
from tqdm import tqdm
import os
from google.genai import types
from sqlalchemy import Column, Integer, String
from pyobvector import ObVecClient, VECTOR, IndexParam, l2_distance
documents = [
"Artificial intelligence was founded as an academic discipline in 1956.",
"Alan Turing was the first person to conduct substantial research in AI.",
"Born in Maida Vale, London, Turing was raised in southern England.",
]
genai_client=genai.Client(api_key=os.environ["GEMINI_API_KEY"])
def embed_documents_in_batches(documents, batch_size=100):
all_embeddings = []
for i in range(0, len(documents), batch_size):
batch = documents[i:i + batch_size]
response = genai_client.models.embed_content(
model="text-embedding-004",
contents=batch,
config=types.EmbedContentConfig(output_dimensionality=768)
)
all_embeddings.extend(response.embeddings)
return all_embeddings
embeddings = embed_documents_in_batches(documents)
data = []
for i, line in enumerate(tqdm(documents, desc="Creating embeddings")):
data.append({"text": line ,"embedding": embeddings[i].values})
ベクトルテーブルの定義とベクトルデータのOceanBaseへの格納
テキストを格納する text 列、埋め込みベクトルを格納する embedding 列、およびベクトルインデックスを含む、gemini_oceanbase_demo_documents という名前のテーブルを作成し、ベクトルデータをOceanBaseに格納します。
OCEANBASE_DATABASE_URL = os.getenv('OCEANBASE_DATABASE_URL')
OCEANBASE_DATABASE_USER = os.getenv('OCEANBASE_DATABASE_USER')
OCEANBASE_DATABASE_DB_NAME = os.getenv('OCEANBASE_DATABASE_DB_NAME')
OCEANBASE_DATABASE_PASSWORD = os.getenv('OCEANBASE_DATABASE_PASSWORD')
client = ObVecClient(uri=OCEANBASE_DATABASE_URL, user=OCEANBASE_DATABASE_USER,password=OCEANBASE_DATABASE_PASSWORD,db_name=OCEANBASE_DATABASE_DB_NAME)
table_name = "gemini_oceanbase_demo_documents"
client.drop_table_if_exist(table_name)
cols = [
Column("id", Integer, primary_key=True, autoincrement=True),
Column("text", String(10000), nullable=False),
Column("embedding", VECTOR(768))
]
# Create vector index
vector_index_params = IndexParam(
index_name="idx_question_embedding",
field_name="embedding",
index_type="HNSW",
distance_metric="l2"
)
client.create_table_with_index_params(
table_name=table_name,
columns=cols,
vidxs=[vector_index_params]
)
print('- Inserting Data to OceanBase...')
client.insert(table_name, data=data)
セマンティック検索
text-embedding-004を使用してクエリテキストの埋め込みベクトルを生成し、クエリテキストの埋め込みベクトルとベクトルテーブル内の各埋め込みベクトルとのL2距離に基づいて、最も関連性の高いドキュメントを検索します。
question = "When was artificial intelligence founded?"
quest_embed = genai_client.models.embed_content(model="text-embedding-004", contents=question)
search_res = client.ann_search(
table_name,
vec_data=quest_embed.embeddings[0].values,
vec_column_name="embedding",
distance_func=l2_distance,
with_dist=True,
topk=1,
output_column_names=["id","text"],
)
print('- The Most Relevant Document and Its Distance to the Query:')
for row in search_res.fetchall():
print(f' - ID: {row[0]}\n'
f' content: {row[1]}\n'
f' distance: {row[2]}')
期待される結果
- ID: 1
content: Artificial intelligence was founded as an academic discipline in 1956.
distance: 0.6019276093082409