dbs物件 在akasha中,chromadb建立完之後,會被儲存成dbs物件,會儲存chromadb中的文件內容、metadata、向量資料、unique id,並被使用於後續的vector similarity search。
該物件可以添加多個chromadb資料,也可與其他dbs物件互相結合,也可根據filter抽取出需要的向量資料。
建立向量資料 processMultiDB processMultiDB可對多個文件集(list of directory)建立chromadb,並回傳dbs物件與建立不成功的檔案list,若文件內容、使用嵌入模型、chunk size相等的chromadb已存在,則不會重新創建而直接讀取。
文件內容改變也會建立新的chromadb,設定參數ignore_check=True則不進行文件內容更改與否的確認,可更快的進行chromadb的讀取。
1 2 3 4 5 6 7 8 9 10 11 import akashadoc_paths = ["docs/pns_query" , "docs/mic" ] emb_name = "openai:text-embedding-ada-002" emb_obj = akasha.handle_embeddings(emb_name) db, ignore_files = akasha.processMultiDB(doc_path_list=doc_paths, verbose=False , embeddings=emb_obj, chunk_size=1000 , ignore_check=False )
createDB_file & createDB_directory 使用多個文字檔案創建chromadb可使用 createDB_file ,使用資料夾創建chromadb則使用 createDB_directory 創建完的dbs物件(db_files, db_directory)可以直接輸入進 get_response 中,減少重複讀取。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 import akasha db_files = akasha.createDB_file(file_path = ["f1.txt","f2.docs"], embeddings="openai:text-embedding-ada-002",chunk_size=500, ignore_check=True) db_directory = akasha.createDB_directory(doc_path= "./docs/mic/", embeddings="openai:text-embedding-ada-002", ignore_check=True) qa = akasha.Doc_QA( verbose=True, search_type="svm", model="openai:gpt-3.5-turbo", ) qa.get_response( doc_path=db_directory, prompt="五軸是甚麼?", system_prompt="請用中文回答", )
根據關鍵字建立向量資料 在建立向量資料時,若您不想根據整個文件片段進行embedding,可以使用 akasha.db.create_keyword_chromadb ,可自訂義函式來輸出想進行embedding的關鍵字,如以下範例 我們定義了一個函式 generate_llm_keyword 請語言模型根據文件段落產生3~5個關鍵字並回傳。
當我們使用 akasha.db.create_keyword_chromadb ,建立向量資料(chromadb),每個文件片段便會根據自訂義函式 generate_llm_keyword 的輸出來進行embedding
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 import akashamd_obj = akasha.handle_model("openai:gpt-4o" , temperature=1 ) emb_obj = akasha.handle_embeddings("openai:text-embedding-ada-002" ) def generate_llm_keyword (text, keyword_num ): prompt = f"Generate 3~{keyword_num} keywords for the following text: \n\n" + text + "\n\n use \, to separate each keyword" res = akasha.call_model(md_obj, prompt) return [res] db, _ = akasha.db.create_keyword_chromadb( "docs/mic" , emb_obj, 1000 , keyword_function=generate_llm_keyword)
注意 若不使用自訂義函式,預設的函式 akasha.generate_keyword 需安裝keybert套件
使用dbs物件 init 您可以直接宣告akasha.dbs()建立空的dbs物件,也可以利用已建立的chromadb建立dbs物件。
dbs物件包含ids(每個文字段落的unique id), embeds(每個文字段落的向量), metadatas(每個文字段落的後設資料), docs(每個文字段落的內容) 。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 import akashafrom langchain_chroma import Chromadb1 = akasha.dbs() storage_directory = "chromadb/12345" emb_obj = akasha.handle_embeddings() docsearch = Chroma(persist_directory=storage_directory, embedding_function=emb_obj) db2 = akasha.dbs(docsearch) print (len (db2.get_ids())) print (len (db2.get_embeds())) print (len (db2.get_metadatas())) print (len (db2.get_docs()))
merge dbs物件之間可以使用.merge相互結合
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 import akashafrom langchain_chroma import Chromaemb_obj = akasha.handle_embeddings() docsearch1 = Chroma(persist_directory="chromadb/123" , embedding_function=emb_obj) db1 = akasha.dbs(docsearch1) docsearch2 = Chroma(persist_directory="chromadb/456" , embedding_function=emb_obj) db2 = akasha.dbs(docsearch2) db2.merge(db1) print (len (db2.get_ids())) print (len (db2.get_embeds())) print (len (db2.get_metadatas())) print (len (db2.get_docs()))
add_chromadb dbs物件可以添加新的chromadb資料
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 import akashafrom langchain_chroma import Chromaemb_obj = akasha.handle_embeddings() docsearch1 = Chroma(persist_directory="chromadb/123" , embedding_function=emb_obj) docsearch2 = Chroma(persist_directory="chromadb/456" , embedding_function=emb_obj) db = akasha.dbs(docsearch1) db.add_chromadb(docsearch2) print (len (db.get_ids())) print (len (db.get_embeds())) print (len (db.get_metadatas())) print (len (db.get_docs()))
get_Documents 使用get_Docuemnts可以得到當前dbs物件中儲存的Documents list (包含page_contents文件內容和metadata後設資料)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 import akashafrom langchain_chroma import Chromaemb_obj = akasha.handle_embeddings() docsearch1 = Chroma(persist_directory="chromadb/123" , embedding_function=emb_obj) db = akasha.dbs(docsearch1) docs = db.get_Documents() print ([doc.page_contents for doc in docs]) print ([docs.metadata for doc in docs])
提取dbs物件 extract_db_by_file可以將檔名符合file_name_list中的所有資料提取出來生成新的dbs物件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 import akashafrom langchain_chroma import Chromaemb_obj = akasha.handle_embeddings() docsearch1 = Chroma(persist_directory="chromadb/123" , embedding_function=emb_obj) db = akasha.dbs(docsearch1) file_name_list = ['f1.txt' , 'f2.docx' ] extracted_db = akasha.extract_db_by_file(db=db, file_name_list=file_name_list) print (len (extracted_db.get_ids())) print (len (extracted_db.get_embeds())) print (len (extracted_db.get_metadatas())) print (len (extracted_db.get_docs()))
extract_db_by_keyword可以將文字段落中存在任何keyword_list中keyword的所有資料提取出來生成新的dbs物件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 import akashafrom langchain_chroma import Chromaemb_obj = akasha.handle_embeddings() docsearch1 = Chroma(persist_directory="chromadb/123" , embedding_function=emb_obj) db = akasha.dbs(docsearch1) keyword_list = ["資訊產業策進會" , "AI人工智慧" ] extracted_db = akasha.extract_db_by_keyword(db=db, keyword_list=keyword_list) print (len (extracted_db.get_ids())) print (len (extracted_db.get_embeds())) print (len (extracted_db.get_metadatas())) print (len (extracted_db.get_docs()))
extract_db_by_ids可以將存在id_list中的的所有資料提取出來生成新的dbs物件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 import akashafrom langchain_chroma import Chromaemb_obj = akasha.handle_embeddings() docsearch1 = Chroma(persist_directory="chromadb/123" , embedding_function=emb_obj) db = akasha.dbs(docsearch1) id_list = ['2024-10-21-17_45_21_963065_0' , '2024-10-21-17_45_23_601845_0' ] extracted_db = akasha.extract_db_by_ids(db=db, id_list=id_list) print (len (extracted_db.get_ids())) print (len (extracted_db.get_embeds())) print (len (extracted_db.get_metadatas())) print (len (extracted_db.get_docs()))
pop_db_by_ids pop_db_by_ids 會將所選id_list中的的所有資料從dbs物件中移除
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 import akashafrom langchain_chroma import Chromaemb_obj = akasha.handle_embeddings() docsearch1 = Chroma(persist_directory="chromadb/123" , embedding_function=emb_obj) db = akasha.dbs(docsearch1) id_list = ['2024-10-21-17_45_21_963065_0' , '2024-10-21-17_45_23_601845_0' ] akasha.pop_db_by_ids(db=db, id_list=id_list) print (len (db.get_ids())) print (len (db.get_embeds())) print (len (db.get_metadatas())) print (len (db.get_docs()))
其他輔助函式 get_docs_from_doc 若不需要向量資料,只需要Documents(page_content, metadata),可使用get_docs_from_doc從文件資料夾中讀取文件內容並切割成chunk_size文件段落,此函式會回傳docs(list of Documents)和不成功的檔案名稱list。
1 2 3 4 5 6 7 8 9 10 11 12 13 import akashadocs, ignore_files = akasha.get_docs_from_doc(doc_path="docs/mic" , chunk_size=1000 , ignore_check=True ) db = akasha.dbs(docsearch1) id_list = ['2024-10-21-17_45_21_963065_0' , '2024-10-21-17_45_23_601845_0' ] extracted_db = akasha.extract_db_by_ids(db=db, id_list=id_list) print ([doc.page_contents for doc in docs]) print ([docs.metadata for doc in docs])
根據文件資料夾、嵌入模型、chunk size輸出所有文件段落的後設資料list,用於自查詢
將更新完的metadata list存回chromadb,用於自查詢
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 import akashadef add_metadata (metadata_list: list ): import json for metadata in metadata_list: metadata['testing' ]= '後設資料新增測試' dir_path = "docs/pns_query" embed_name = "openai:text-embedding-ada-002" chunk_size = 99999 emb_obj = akasha.handle_embeddings("openai:text-embedding-ada-002" ) db, _ = akasha.db.processMultiDB(dir_path, False , emb_obj, chunk_size, True ) metadata_list = akasha.db.get_db_metadata(dir_path, embed_name, chunk_size) metadata_list = add_metadata(metadata_list) akasha.db.update_db_metadata(metadata_list, dir_path, embed_name, chunk_size) print (akasha.db.get_db_metadata(dir_path, embed_name, chunk_size)[0 ])