OpenAI
OpenAI 是一家人工智能公司,已开发出多个大语言模型,这些模型在自然语言理解和生成方面表现出色,能够生成文本、回答问题、进行对话等,可以通过 API 对这些模型进行访问。
seekdb 提供了向量类型存储、向量 索引、embedding 向量搜索的能力。可以利用 OpenAI 的 API 接口,将向量化后的数据存储在 seekdb,然后使用 seekdb 的向量搜索能力查询相关数据。
前提条件
-
您已完成部署 seekdb。
-
您的环境中已存在可以使用的 MySQL 数据库和账号,并已对数据库账号授予读写权限。
-
安装 python 3.9 及以上版本 和相应 pip。
-
python3 -m pip install pyseekdb openai pandas cffi -
准备 OpenAI API 密钥。
步骤一:获取 seekdb 连接串
联系 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:提供账户密码。
示例如下:
mysql -hxxx.xxx.xxx.xxx -P2881 -utest_user001 -p****** -Dtest
步骤二:注册 LLM 平台账号
获取 OpenAI API Key:
-
登录 OpenAI 平台。
-
在右上角点击 API Keys。
-
点击 Create API Key。
-
填写相关信息,点击 Create API Key。
配置 OpenAI API Key 和 seekdb 连接信息到环境变量:
-
对于基于 Unix 的系统(如 Ubuntu 或 MacOS),你可以在终端中运行以下命令:
export OPENAI_API_KEY='your-api-key'
export SEEKDB_DATABASE_HOST=SEEKDB_DATABASE_HOST
export SEEKDB_DATABASE_PORT=SEEKDB_DATABASE_PORT
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 -
对于 Windows 系统,你可以在命令提示符中运行以下命令:
set OPENAI_API_KEY=your-api-key
set SEEKDB_DATABASE_HOST=SEEKDB_DATABASE_HOST
set SEEKDB_DATABASE_PORT=SEEKDB_DATABASE_PORT
set SEEKDB_DATABASE_USER=YOUR_SEEKDB_DATABASE_USER
set SEEKDB_DATABASE_DB_NAME=YOUR_SEEKDB_DATABASE_DB_NAME
set SEEKDB_DATABASE_PASSWORD=YOUR_SEEKDB_DATABASE_PASSWORD
请确保将 your-api-key 替换为你的实际 OpenAI API 密钥。
步骤三:存储向量数据到 seekdb
存储向量数据到 seekdb
-
准备测试数据
下载预先计算好向量化数据的 CSV 文件,这个 CSV 文件中包含 1000 条美食评论数据集,最后一列是向量化之后的值,所以不需要再计算向量。 也可以使用下面的代码对 embedding 列(即向量列)重新计算,生成新的 CSV 文件。
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"):
# For more information about how to create embedding vectors, see 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
df["embedding"] = df.combined.apply(embedding_text)
output_datapath = './fine_food_reviews_self_embeddings.csv'
df.to_csv(output_datapath) -
运行下面的脚本,将测试数据插入 seekdb,脚本所在的目录需要和测试数据所在的目录相同。
import os,csv,json
import pyseekdb
from pyseekdb import HNSWConfiguration
ids = []
embeddings = []
documents = []
metadatas = []
file_name = "fine_food_reviews_self_embeddings.csv"
file_path = os.path.join("./", file_name)
# Open and read the CSV file.
with open(file_name, mode='r', newline='', encoding='utf-8') as csvfile:
csvreader = csv.reader(csvfile)
headers = next(csvreader)
print("Headers:", headers)
for i, row in enumerate(csvreader):
if not row or len(row) < 9:
continue
ids.append(row[0])
embeddings.append(json.loads(row[8]))
documents.append(row[6])
metadata = {
"product_id": str(row[1]),
"user_id": str(row[2]),
"score": str(row[3]),
"summary": str(row[4]),
"n_tokens": str(row[7])
}
metadatas.append(metadata)
# Connect to seekdb by using pyseekdb
client = pyseekdb.Client(
host=os.getenv('SEEKDB_DATABASE_HOST'),
port=int(os.getenv('SEEKDB_DATABASE_PORT', 2881)),
database=os.getenv('SEEKDB_DATABASE_DB_NAME'),
user=os.getenv('SEEKDB_DATABASE_USER'),
password=os.getenv('SEEKDB_DATABASE_PASSWORD')
)
table_name = 'fine_food_reviews'
config = HNSWConfiguration(dimension=1536, distance='cosine')
collection = client.create_collection(
name=table_name,
configuration=config,
embedding_function=None
)
# Insert 10 rows each time.
batch_size = 100
total_records = len(ids)
for i in range(0, total_records, batch_size):
end_idx = min(i + batch_size, total_records)
batch_ids = ids[i:end_idx]
batch_embeddings = embeddings[i:end_idx]
batch_documents = documents[i:end_idx]
batch_metadatas = metadatas[i:end_idx]
try:
collection.add(
ids=batch_ids,
embeddings=batch_embeddings,
documents=batch_documents,
metadatas=batch_metadatas
)
print(f"Batch {i//batch_size + 1} inserted successfully!")
except Exception as e:
print(f"Batch {i//batch_size + 1} insertion failed: {e}")
break
print("All data insertion completed!")
查询 seekdb 数据
-
保存以下 python 脚本,命名为
openAIQuery.py。import os,csv,json,sys
import pyseekdb
from pyseekdb import HNSWConfiguration
from openai import OpenAI
# Obtain command-line options.
if len(sys.argv) != 2:
print("Enter a query statement." )
sys.exit()
queryStatement = sys.argv[1]
# Connect to seekdb by using pyseekdb
client = pyseekdb.Client(
host=os.getenv('SEEKDB_DATABASE_HOST'),
port=int(os.getenv('SEEKDB_DATABASE_PORT', 2881)),
database=os.getenv('SEEKDB_DATABASE_DB_NAME'),
user=os.getenv('SEEKDB_DATABASE_USER'),
password=os.getenv('SEEKDB_DATABASE_PASSWORD')
)
openAIclient = OpenAI()
# Define the function for generating text vectors.
def generate_embeddings(text, model="text-embedding-ada-002"):
# For more information about how to create embedding vectors, see 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, top_k=1):
query_embedding = generate_embeddings(query)
collection = client.get_collection(name=tableName)
res = collection.query(
query_embeddings=query_embedding,
n_results=top_k
)
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}')
# Specify the table name.
table_name = 'fine_food_reviews'
query_ob(queryStatement,table_name,1) -
输入问题,输出相关答案。
python3 openAIQuery.py 'pet food'预期结果如下:
- The Most Relevant Document and Its Distance to the Query:
- ID: 818
content: Title: Good food; Content: The only dry food my queen cat will eat. Helps prevent hair balls. Good packaging. Arrives promptly. Recommended by a friend who sells pet food.
distance: 0.159281