跳到主要内容

OpenAI

OpenAI 是一家人工智能公司,已开发出多个大语言模型,这些模型在自然语言理解和生成方面表现出色,能够生成文本、回答问题、进行对话等,可以通过 API 对这些模型进行访问。

seekdb 提供了向量类型存储、向量索引、embedding 向量搜索的能力。可以利用 OpenAI 的 API 接口,将向量化后的数据存储在 seekdb,然后使用 seekdb 的向量搜索能力查询相关数据。

前提条件

  • 您已完成部署 seekdb。

  • 您的环境中已存在可以使用的 MySQL 数据库和账号,并已对数据库账号授予读写权限。

  • 安装 python 3.9 及以上版本 和相应 pip

  • 安装 poetryseekdb、OpenAI SDK。

    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:需要访问的数据库名称。

    提示

    连接的用户需要拥有该数据库的 CREATEINSERTDROPSELECT 权限。

  • $user_name:提供数据库连接账户。

  • $password:提供账户密码。

示例如下:

mysql -hxxx.xxx.xxx.xxx -P2881 -utest_user001 -p****** -Dtest

步骤二:注册 LLM 平台账号

获取 OpenAI API Key:

  1. 登录 OpenAI 平台。

  2. 在右上角点击 API Keys

  3. 点击 Create API Key

  4. 填写相关信息,点击 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

  1. 准备测试数据

    下载预先计算好向量化数据的 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)
  2. 运行下面的脚本,将测试数据插入 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 数据

  1. 保存以下 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)
  2. 输入问题,输出相关答案。

    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