向量資料庫概念:
向量資料庫是一個特殊的資料庫類型,有別於一般表格式的資料庫,而是把資料變成高維向量也稱向量嵌入式,會專門處理儲存和檢索向量的資料庫,向量也是透過非結構化的資料(如文字或圖像)經過嵌入技術轉換而來的。
向量資料庫在 AI 系統扮演重要角色,在和大型語言模型(LLM)相結合,透過向量資料庫,AI 系統可以進行高效且準確的資料檢索,為使用者提供相關性高的回應。
今天我們會是用 ChromaDB 這個向量資料庫,可能還會有人有疑問,ChromaDB 在製作客製化 AI 聊天機器人時可以幫助我什麼,最主要可以達到:
接下來就實際操作如何把在臺北市資料大平台的景點資料,如何存進去 ChromaDB 裡,先把各景點資料放在 data 的資料夾
import os
import jieba as jb
import uuid
import chromadb
from chromadb.config import Settings
from openai_config import *
from openai import AzureOpenAI
# 設置目錄路徑
data_dir = "./data" # 儲存長文檔的目錄
cut_dir = "./data/cut" # 儲存切割後文檔的目錄
if not os.path.exists(cut_dir):
os.makedirs(cut_dir)
# 初始化 Azure OpenAI 客戶端
client = AzureOpenAI(
azure_endpoint=azure_endpoint,
api_key=api_key,
api_version=api_version
)
# 初始化 ChromaDB Persistent Client
chroma_client = chromadb.PersistentClient(path=cut_dir)
collection_name = "document_embeddings" # 設定 collection 名稱
collection = chroma_client.get_or_create_collection(name=collection_name)
# 定義函數以生成嵌入
def get_text_embedding(text):
response = client.embeddings.create(
input=text,
model="text-embedding-3-large" # 根據需求選擇適當的模型
)
embedding = response.data[0].embedding
return embedding
# 讀取目錄中的所有文件
file_names = [f for f in os.listdir(data_dir) if os.path.isfile(os.path.join(data_dir, f))]
# 處理每個文件
for file_name in file_names:
file_path = os.path.join(data_dir, file_name)
cut_file_path = os.path.join(cut_dir, f"cut_{file_name}")
with open(file_path, "r", encoding="utf-8") as file:
data = file.read()
# 將文檔按段落進行切割(這裡假設段落之間用兩個換行符分隔)
paragraphs = data.split("\n\n")
# 準備存儲的資料
texts = []
metadatas = []
# 逐段處理
with open(cut_file_path, "w", encoding="utf-8") as cut_file:
for paragraph in paragraphs:
if paragraph.strip(): # 避免處理空段落
# 使用 jieba 進行斷詞
word_list = list(jb.cut(paragraph))
cut_data = " ".join(word_list)
# 將切割後的段落寫入新文件
cut_file.write(cut_data + "\n")
# 收集嵌入的文本和對應的元數據
texts.append(cut_data)
metadatas.append({"source": file_path})
# 生成 ID 和嵌入
ids = [str(uuid.uuid1()) for _ in texts]
embeddings = [get_text_embedding(text) for text in texts]
# 將資料存儲到 ChromaDB
collection.add(
embeddings=embeddings,
documents=[text.replace(" ", "") for text in texts], # 去除斷詞後的空格
metadatas=metadatas,
ids=ids
)
切分後的資料會放在 cut 資料夾,詞彙也已經進行切分。
以上就是把資料嵌入後,再存進去自己 cut 的資料夾操作。