上一篇我們已經把文件檔案進行切割。長文檔切割(Chunk)就是把較長的文本資料分割成較小的部份,以便於進行處理或分析。這個在自然語言處理(NLP)很重要,因為許多 NLP 模型對於輸入文本輸入長度都有一定限制,若把幾百頁的知識一次性放入 prompt , 那 token 數量一定很可觀,導致模型無法處理。所以才需要 chunk 長文檔切割,解決 token 限制問題,還可以提高檢索效率,讓我們有更精的匹配搜尋。
接下來就是進行文件的檢索:
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 = 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
# 查詢 ChromaDB 的函數
def chromadb_query(query_text):
# 生成查詢文本的嵌入
embeddings = get_text_embedding(query_text)
# 使用嵌入來查詢相似的結果
results = collection.query(
query_embeddings=[embeddings], # 使用這個嵌入來查詢
n_results=5 # 返回最相似的 5 個結果
)
# 列印查詢結果
for doc, meta in zip(results['documents'], results['metadatas']):
print(f"Document: {doc}, Metadata: {meta}")
# 主程序,進行查詢循環
while True:
user_input = input("You: ")
if user_input.lower() == "exit":
break
# 執行查詢並列印結果
chromadb_query(user_input)
embeddings
: 嵌入向量,用於進行相似度檢索。documents
: 對應於嵌入的原始文本資料,檢索結果會返回這些文檔。metadatas
: 與每個文檔相關的附加元數據,提供文檔的上下文或其他有助於理解結果的資訊。這兩天的學習重點在將長篇知識進行切割,使用 jieba 進行斷詞處理,並生成向量嵌入,存入 ChromaDB。當使用者提問時,問題會首先轉換為向量嵌入,接著進入 ChromaDB 進行檢索,最後檢索到的結果將會以相似度的方式返回,提供給前端顯示給使用者。
如果想知道 ChromaDB 如何安裝可以看之前的介紹:https://ithelp.ithome.com.tw/articles/10355097