seekdb Vector 与 Firecrawl 集成
seekdb 提供了向量类型存储、向量索引、embedding 向量搜索的能力。可以将向量化后的数据存储在 seekdb,供下一步的搜索使用。
Firecrawl 使开发人员能够从任何网站抓取高质量数据,用于构建人工智能应用程序。该工具提供先进的网页抓取、爬虫和数据提取功能,可以高效地将网站内容转换为清洁的标记语言或结构化数据,以满足下游 AI 工作流的需求。
在本教程中,我们将向您展示如何使用 seekdb 和 Firecrawl 构建搜索-增强生成(RAG)管道。该管道集成了用于网络数据抓取的 Firecrawl、用于向量存储的 seekdb 和用于生成有洞察力的上下文感知响应的 Jina AI。
前提条件
-
您已经部署了 seekdb。
-
您的环境中已存在可以使用的数据库和账号,并已对数据库账号授读写权限。
-
安装 Python 3.11 及以上版本。
-
安装依赖。
python3 -m pip install cffi pyseekdb requests firecrawl-py
步骤一:获取数据库连接信息
联系 seekdb 部署人员或者管理员获取相应的数据库连接串,例如:
mysql -h$host -P$port -u$user_name -p$password -D$database_name
参数说明:
-
$host:提供 seekdb 连接 IP 地址。 -
$port:提供 seekdb 连接端口,默认是 2881。 -
$database_name:需要访问的数据库名称。提示连接的用户需要拥有该数据库的
CREATE、INSERT、DROP和SELECT权限。 -
$user_name:提供数据库连接账户。 -
$password:提供账户密码。
步骤二:构建您的 AI 助手
通过 Firecrawl 爬取网页信息并保存在 seekdb Vector 中,并进行搜索。
设置环境变量
获取 Firecrawl API 密钥,并同 seekdb 连接信息配置环境变量中
export SEEKDB_DATABASE_URL=YOUR_SEEKDB_DATABASE_URL
export SEEKDB_DATABASE_USER=YOUR_SEEKDB_DATABASE_USER
export SEEKDB_DATABASE_DB_NAME=YOUR_SEEKDB_DATABASE_DB_NAME
export SEEKDB_DATABASE_PASSWORD=YOUR_SEEKDB_DATABASE_PASSWORD
export FIRECRAWL_API_KEY=YOUR_FIRECRAWL_API_KEY
export JINAAI_API_KEY=YOUR_JINAAI_API_KEY
示例代码片段
import os ,requests
from firecrawl import FirecrawlApp
import pyseekdb
from pyseekdb import HNSWConfiguration
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://www.oceanbase.ai/docs/seekdb-overview",
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 为例,定义一个 generate_embeddings 辅助函数,用于调用 Jina AI 的 API:
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']
ids = []
embeddings = []
documents = []
for i, section in enumerate(tqdm(sections, desc="Processing sections")):
try:
# Generate the embedding for the section via API
embedding = generate_embeddings(section)
# Truncate content if too long
truncated_content = section[:4900] if len(section) > 4900 else section
# Append to lists
ids.append(f"{i+1}")
embeddings.append(embedding)
documents.append(truncated_content)
except Exception as e:
print(f"Error processing section {i}: {e}")
continue
print(f"Successfully processed {len(documents)} sections")
定义表并将数据存入 seekdb
创建一个名为 firecrawl_seekdb_demo_documents 的表:
SEEKDB_DATABASE_HOST = os.getenv('SEEKDB_DATABASE_HOST')
SEEKDB_DATABASE_PORT = int(os.getenv('SEEKDB_DATABASE_PORT', 2881))
SEEKDB_DATABASE_USER = os.getenv('SEEKDB_DATABASE_USER')
SEEKDB_DATABASE_DB_NAME = os.getenv('SEEKDB_DATABASE_DB_NAME')
SEEKDB_DATABASE_PASSWORD = os.getenv('SEEKDB_DATABASE_PASSWORD')
client = pyseekdb.Client(host=SEEKDB_DATABASE_HOST, port=SEEKDB_DATABASE_PORT, database=SEEKDB_DATABASE_DB_NAME, user=SEEKDB_DATABASE_USER, password=SEEKDB_DATABASE_PASSWORD)
table_name = "firecrawl_seekdb_demo_documents"
config = HNSWConfiguration(dimension=1024, distance='cosine')
collection = client.create_collection(
name=table_name,
configuration=config,
embedding_function=None
)
print('- Inserting Data to seekdb...')
collection.add(
ids=ids,
embeddings=embeddings,
documents=documents
)
语义搜索
通过 Jina AI 的 API 生成查询文本的向量,然后根据查询文本的向量与向量表中的每个向量的余弦距离,搜索最相关的文档:
query = 'What is seekdb'
# Generate the embedding for the query via Jina AI API.
query_embedding = generate_embeddings(query)
res = collection.query(
query_embeddings=query_embedding,
n_results=1
)
print('- The Most Relevant Document and Its Distance to the Query:')
for i, (doc_id, document, distance) in enumerate(zip(
res['ids'][0],
res['documents'][0],
res['distances'][0]
)):
print(f' - ID: {doc_id}')
print(f' content: {document}')
print(f' distance: {distance:.6f}')
预期结果
- ID: 1
content: Skip to main content
On this page
OceanBase seekdb (referred to as seekdb) is an AI-native search database. It unifies relational, vector, text, JSON and GIS in a single engine, enabling hybrid search and in-database AI workflows.
distance: 0.235985