OceanBaseデータベースは、ベクトル型データの格納、ベクトルインデックス、そしてembeddingベクトル検索機能を提供しています。これにより、ベクトル化されたデータをOceanBaseデータベースに保存し、その後の検索処理で利用することが可能になります。
Firecrawlは、開発者が任意のウェブサイトから高品質なデータを取得し、人工知能アプリケーションの構築に活用できるようにします。このツールは、高度なWebクローリング、スパイダー、データ抽出機能を備えており、ウェブコンテンツを効率的にクリーンなマークアップ言語や構造化データに変換し、下流のAIワークフローのニーズを満たすことができます。
このチュートリアルでは、OceanBaseとFirecrawlを使用して検索強化型生成(RAG)パイプラインを構築する方法をご紹介します。このパイプラインは、Webデータの取得にFirecrawl、ベクトルストレージにOceanBase、そして洞察に富んだ文脈認識型の応答生成にJina AIを統合したものです。
前提条件
OceanBaseデータベースV4.4.0以降をデプロイし、MySQLモードのテナントを作成していること。テナントの作成後、以下の手順に従って操作します。
環境に使用可能なMySQLテナント、MySQLデータベース、およびアカウントが存在し、データベースアカウントに読み取り書き込み権限が付与されていること。
Python 3.11以降のバージョンがインストール済みであること。
依存関係のパッケージがインストール済みであること。
python3 -m pip install firecrawl-py pyobvector requests tqdmテナント内で
ob_vector_memory_limit_percentage構成パラメータを設定し、ベクトル検索機能を有効にしていることを確認してください。V4.3.5 BP3以前のバージョンでは、値として30を設定することを推奨します。V4.3.5 BP3以降のバージョンでは、デフォルト値の0のままにすることを推奨します。この構成パラメータをより正確に設定する必要がある場合は、ob_vector_memory_limit_percentage参照してこの値を計算してください。
ステップ1:データベース接続情報を取得する
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テナントへの接続を参照してください。
ステップ2:AIアシスタントを構築する
Firecrawlを使用してウェブページの情報を取得し、OceanBase Vectorに保存して検索を実行します。
環境変数の設定
Firecrawl 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 FIRECRAWL_API_KEY=YOUR_FIRECRAWL_API_KEY
export JINAAI_API_KEY=YOUR_JINAAI_API_KEY
サンプルコードスニペット
Firecrawlクロール OceanBase公式サイトの概要
import os ,requests
from firecrawl import FirecrawlApp
from sqlalchemy import Column, Integer, String
from pyobvector import ObVecClient, VECTOR, IndexParam, cosine_distance
from tqdm import tqdm
def split_markdown_content(content):
return [section.strip() for section in content.split("# ") if section.strip()]
app = FirecrawlApp(api_key=os.environ["FIRECRAWL_API_KEY"])
# Scrape a website:
scrape_status = app.scrape(
url="https://en.oceanbase.com/docs/common-oceanbase-database-10000000001970957",
formats=["markdown"]
)
markdown_content = scrape_status.markdown
# Process the scraped markdown content
sections = split_markdown_content(markdown_content)
Jina AIのベクトルを取得する
Jina AIは複数のモデルを提供しており、ユーザーは自身のニーズに応じて対応するモデルの使用を選択できます。 ここでは、jina-embeddings-v3を例に、Jina AIのAPIを呼び出すためのgenerate_embeddingsヘルパー関数を定義します。
JINAAI_API_KEY = os.getenv('JINAAI_API_KEY')
def generate_embeddings(text: str):
JINAAI_API_URL = 'https://api.jina.ai/v1/embeddings'
JINAAI_HEADERS = {
'Content-Type': 'application/json',
'Authorization': f'Bearer {JINAAI_API_KEY}'
}
JINAAI_REQUEST_DATA = {
'input': [text],
'model': 'jina-embeddings-v3' # with dimension 1024.
}
response = requests.post(JINAAI_API_URL, headers=JINAAI_HEADERS, json=JINAAI_REQUEST_DATA)
return response.json()['data'][0]['embedding']
data = []
for i, section in enumerate(tqdm(sections, desc="Processing sections")):
try:
embedding = generate_embeddings(section)
truncated_content = section[:4900] if len(section) > 4900 else section
data.append({"content": truncated_content, "content_vec": embedding})
except Exception as e:
print(f"Error processing section {i}: {e}")
continue
ベクトルテーブル構造の定義とベクトルのOceanBaseへの保存
テキストを格納する content 列、ベクトルを格納する content_vec 列、およびベクトルインデックス情報を含む firecrawl_oceanbase_demo_documents という名前のテーブルを作成します。
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 = "firecrawl_oceanbase_demo_documents"
client.drop_table_if_exist(table_name)
cols = [
Column("id", Integer, primary_key=True, autoincrement=True),
Column("content", String(5000), nullable=False),
Column("content_vec", VECTOR(1024))
]
# Create vector index
vector_index_params = IndexParam(
index_name="idx_content_vec",
field_name="content_vec",
index_type="HNSW",
distance_metric="cosine"
)
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)
セマンティック検索
Jina AIのAPIを使用してクエリテキストのベクトルを生成し、その後、クエリテキストのベクトルとベクトルテーブル内の各ベクトルとのコサイン距離に基づいて、最も関連性の高いドキュメントを検索します。
query = 'what is OceanBase High compatibility'
# Generate the embedding for the query via Jina AI API.
query_embedding = generate_embeddings(query)
res = client.ann_search(
table_name,
vec_data=query_embedding,
vec_column_name="content_vec",
distance_func=cosine_distance, # Use the cosine distance function.
with_dist=True,
topk=1,
output_column_names=["id", "content"],
)
print('- The Most Relevant Document and Its Distance to the Query:')
for row in res.fetchall():
print(f'- ID: {row[0]}\n'
f' content: {row[1]}\n'
f' distance: {row[2]}')
期待される結果
- ID: 5
content: High compatibility
OceanBase Database is highly compatible with most general features of Oracle and MySQL, and supports advanced features such as procedural language and triggers. OceanBase Migration Service (OMS), an automatic migration tool, is provided to support migration assessment and reverse synchronization to ensure data migration security when a core system is migrated to OceanBase Database in key industries such as finance, public governance, and communication service.
##
distance: 0.2341035693195166