利用 MongoDB Atlas 的向量搜尋功能,結合 LangChain 和 OpenAI,可以有效率地建構 RAG 應用。首先,將資料文字嵌入向量化後儲存至 MongoDB,接著運用 LangChain 簡化向量搜尋流程,並結合 OpenAI 的大語言模型,實作根據語義相似度的檔案檢索和問答系統。透過調整提示工程技巧,可以更精準地控制模型輸出,滿足不同應用場景的需求。此方法有效提升了資訊檢索效率,並降低了開發成本。
步驟2:計算嵌入
接下來,我們需要計算每個文字的嵌入(embedding)。由於 玄貓 的API有速率限制,我們需要將資料分成小批次進行處理。每個批次的大小為100。
step = int(np.ceil(df['final'].shape[0]/100))
embeddings_t = []
lines = []
for x, y in list(map(lambda x: (x, x+step), list(range(0, df.shape[0], step)))):
lines += [df.final.values[x:y].tolist()]
for i in tqdm(lines):
embeddings_t += openai.embeddings.create(
model='text-embedding-ada-002', input=i).data
步驟3:提取嵌入
然後,我們需要從API的回應中提取嵌入資料。
out = []
for ele in embeddings_t:
out += [ele.embedding]
步驟4:儲存嵌入
最後,我們需要將提取的嵌入資料儲存回原始的DataFrame中。
df['embedding'] = out
步驟5:初始化MongoDB Atlas
現在,我們需要初始化MongoDB Atlas並插入資料到集合中。
from pymongo import MongoClient
import os
mongo_client = MongoClient(os.environ["MONGODB_CONNECTION_STR"])
output_collection = mongo_client["sample_movies"]["embed_movies"]
步驟6:插入資料
最後,我們可以將資料插入到MongoDB集合中。
output_collection.insert_many(df.to_dict('records'))
圖表翻譯:
以下是使用Mermaid語法繪製的流程圖,描述了上述步驟的執行流程。
flowchart TD A[準備資料] --> B[計算嵌入] B --> C[提取嵌入] C --> D[儲存嵌入] D --> E[初始化MongoDB Atlas] E --> F[插入資料]
內容解密:
上述程式碼的作用是計算文字的嵌入,並將其儲存到MongoDB集合中。這個過程包括了資料的準備、嵌入的計算、嵌入的提取、儲存嵌入、初始化MongoDB Atlas和插入資料等步驟。每個步驟都非常重要,缺少任何一步驟都可能導致最終結果的錯誤。
建立向量搜尋索引
在上一步驟中,我們已經將測試資料匯入 MongoDB Atlas,以建立向量搜尋功能。現在,讓我們建立向量搜尋索引。
建立向量索引定義
首先,我們需要建立向量索引定義。這可以在 MongoDB Atlas Vector Search UI 中完成。所需的向量索引定義如下:
{
"fields": [
{
"type": "vector",
"numDimensions": 1536,
"path": "embedding",
"similarity": "cosine"
},
{
"type": "filter",
"path": "year"
}
]
}
一旦向量索引定義被新增到 MongoDB Atlas UI 中,向量搜尋索引就會被建立在指定的路徑欄位中。
執行向量搜尋查詢
現在,我們可以使用 $vectorSearch
查詢 MongoDB 向量索引。MongoDB Atlas 提供了使用向量搜尋和搜尋過濾器的靈活性。此外,我們可以使用聚合管道應用範圍、字串和數值過濾器。
以下程式碼示範如何執行向量搜尋查詢,同時對 year
欄位進行預過濾,以取得 1990 年後發布的電影:
def query_vector_search(q, prefilter={}, postfilter={}, path="embedding", topK=2):
#...
vs_query = {
"index": "default",
"path": path,
"queryVector": query_embedding,
"numCandidates": 10,
"limit": topK,
}
if len(prefilter) > 0:
vs_query["filter"] = prefilter
#...
new_search_query = {"$vectorSearch": vs_query}
project = {"$project": {"score": {"$meta": "vectorSearchScore"}, "_id": 0, "title": 1, "release_date": 1, "overview": 1, "year": 1}}
#...
res = list(output_collection.aggregate([new_search_query, project]))
return res
# 範例查詢
query_vector_search("I like Christmas movies, any recommendations for movies release after 1990?", prefilter={"year": {"$gt": 1990}}, topK=5)
這個查詢會傳回 1990 年後發布的電影,同時考慮向量相似度。
使用 LangChain 進行向量搜尋
LangChain 提供了一個簡單的方式來使用 MongoDB Atlas Vector Search 建立語義相似度檢索器。以下示範如何使用 LangChain 進行向量搜尋:
from langchain_mongodb.vectorstores import MongoDBAtlasVectorSearch
from langchain_openai import OpenAIEmbeddings
import json
embedding_model = OpenAIEmbeddings(model="text-embedding-ada-002")
vector_search = MongoDBAtlasVectorSearch(output_collection, embedding_model, text_key='final')
這個例子展示瞭如何使用 LangChain wrapper 類別來建立向量搜尋功能。
建立RAG架構系統
在現代商業的快速變化中,企業不斷追求效率和準確性,導致自動化技術成為核心。然而,傳統方法在面對大量複雜資料時往往難以應對,人工介入則容易產生錯誤。因此,瞭解RAG(Retrieval-Augmented Generation)架構的重要性便浮現出來。
RAG架構的組成
- 檔案載入:首先從資料儲存中載入檔案,包括文字提取、解析、格式化和清理,以準備檔案分割。
- 檔案分割:將檔案分割成較小、可管理的段落或塊。分割策略可以從固定大小的塊到內容感知的分割,考慮內容結構。
- 文字嵌入:使用OpenAI嵌入、句子嵌入等技術將檔案塊轉換為向量表示。這一步對於理解塊的語義內容至關重要。
- 向量儲存:生成的向量與檔案塊一起儲存在向量儲存中,連同其他從MongoDB Atlas集合中提取的檔案塊和相關資料。
- 查詢處理:當使用者提交查詢時,查詢也被轉換為向量表示,使用與步驟3相同的嵌入技術。
- 檔案檢索:檢索元件定位和擷取語義上與查詢相似的檔案塊。這個過程使用向量相似度搜尋技術和MongoDB Atlas的HNSW演算法,快速找到鄰近的向量而不犧牲搜尋結果的準確性。
- 檔案塊後過濾:相關檔案塊從MongoDB集合中檢索,並可以輕易地後過濾以轉換輸出檔案塊為所需格式。
- LLM提示建立:檢索的檔案塊和查詢結合以建立LLM的上下文和提示。
- 答案生成:最終,LLM根據提示生成回應,完成RAG過程。
RAG系統型別
- 簡單RAG:實作了一種天真的方法,根據查詢的相似度從知識函式庫中檢索固定數量的檔案。這些檔案與查詢一起輸入語言模型以生成回應。
- 高階RAG:根據具體工作流程和使用者群體的需求,選擇合適的RAG型別。
建立RAG架構系統的關鍵點
- 工作流程特異性:定義要自動化的具體工作流程,可能與問答、資料增強、摘要、推理或斷言相關。
- 使用者經驗:與目標使用者群體合作,以瞭解他們可能提出的查詢型別,從而確定使用者旅程。
- 資料來源:識別資料來源的性質(結構化或非結構化),並將其對映到位置。然後,根據是否為操作或分析目的進行分類別,並觀察資料模式以確定答案是否容易獲得或需要從多個來源聚合。
檔案分割策略
檔案分割是RAG系統中的一個關鍵步驟,尤其是在處理大型檔案時。有多種分割策略可供選擇,包括:
- 遞迴分割:遞迴地將輸入文字分割成較小的塊,使用不同的分隔符或標準。
- 句子分割:使用基本標點符號(如句號和新行)或更先進的NLP函式庫(如spaCy和NLTK)進行句子分割。
- 結構化內容:針對具有特定格式(如Markdown或LaTeX)的檔案,使用專門的技術。
使用LangChain建立簡單RAG應用
以下示範如何使用LangChain和OpenAI API建立一個簡單的RAG應用。這個應用使用前面載入到MongoDB Atlas集合中的資料集,並允許對可用的電影進行查詢和推薦。
from openai import OpenAI
client = OpenAI()
def invoke_llm(prompt, model_name='gpt-3.5-turbo-0125'):
# 實作LLM邏輯
pass
瞭解Prompt的重要性
在與大語言模型(LLM)互動時,prompt扮演著至關重要的角色。它是使用者提供的指令或輸入,引導模型的回應。一個好的prompt應該是清晰、具體和結構化的,以便能夠有效地將使用者的意圖傳達給LLM,從而生成最準確和最有用的回應。
結論:建構根據向量資料函式庫的 RAG 系統,實作高效知識檢索與應用
隨著資料量的爆炸式增長,傳統的關鍵字搜尋已無法滿足企業對知識檢索的效率和精準度要求。本文深入探討瞭如何利用 MongoDB Atlas 向量資料函式庫和 LangChain 框架構建 RAG 系統,實作根據語義理解的知識檢索和應用。透過 OpenAI 嵌入模型將文字轉換為向量,並結合 HNSW 索引演算法,大幅提升了搜尋效率。同時,LangChain 的整合簡化了開發流程,降低了技術門檻。
然而,向量資料函式庫的建置並非一蹴可幾。資料的清洗、分割策略的選擇、向量維度的設定等都會影響最終的搜尋效果。此外,LLM 提示的設計也至關重要,一個清晰、具體且結構化的提示才能引導模型生成準確的答案。目前,RAG 系統的應用仍面臨一些挑戰,例如計算資源的消耗、模型的偏差以及資料的隱私安全等。
展望未來,隨著向量資料函式庫技術的持續發展和 LLM 模型的效能提升,RAG 系統的應用場景將更加廣泛。預計未來 3-5 年內,RAG 系統將成為企業知識管理的核心元件,並在智慧客服、商業分析、決策支援等領域發揮更大的價值。對於企業而言,及早佈局向量資料函式庫技術,探索 RAG 系統的最佳實踐,將有助於提升競爭力並在數位化轉型中取得領先地位。玄貓認為,結合向量資料函式庫和 LLM 的 RAG 架構代表了未來知識檢索和應用的主流方向,值得企業深入研究和應用。