LangChain 提供了便捷的工具來處理文字分割和向量檢索,結合向量資料函式庫和大語言模型,可以建構高效的問答系統。利用 RecursiveCharacterTextSplitter 可將文字分割成大小適當的區塊,並透過 FAISS 建立向量索引以提升檢索效率。實作上,先將文字塊轉換為向量表示,再利用 FAISS 搜尋相似向量,最後將搜尋結果作為上下文輸入 GPT-3.5-turbo,生成最終答案。這個流程能有效處理大量文字資料,並根據使用者提問提供精確的答案。
檔案分割與向量檢索技術在自然語言處理中的應用
在處理大量文字資料時,如何有效地分割和檢索資訊成為了一項重要的技術挑戰。LangChain 提供了一系列文字分割工具,其中 RecursiveCharacterTextSplitter 是最常用的方法之一。本文將探討該技術的原理、實作方法及其在向量檢索中的應用。
RecursiveCharacterTextSplitter 的工作原理
RecursiveCharacterTextSplitter 是一種根據遞迴字元的文字分割器,它嘗試在換行符、空格等處進行分割,直到文字塊的大小達到預設的閾值。這種方法能夠盡可能地保持段落、句子和詞彙的語義完整性。
程式碼範例:
from langchain.text_splitter import RecursiveCharacterTextSplitter
# 初始化文字分割器
text_splitter = RecursiveCharacterTextSplitter.from_tiktoken_encoder(
chunk_size=100, # 每個文字塊的 token 數量
chunk_overlap=20 # 文字塊之間的重疊 token 數量
)
# 準備待分割的文字
text = """
Welcome to the "Unicorn Enterprises: Where Magic Happens"
Employee Handbook! We're thrilled to have you join our team
of dreamers, doers, and unicorn enthusiasts. At Unicorn
Enterprises, we believe that work should be as enchanting as
it is productive. This handbook is your ticket to the
magical world of our company, where we'll outline the
principles, policies, and practices that guide us on this
extraordinary journey. So, fasten your seatbelts and get
ready to embark on an adventure like no other!
...
As we conclude this handbook, remember that at Unicorn
Enterprises, the pursuit of excellence is a never-ending
quest. Our company's success depends on your passion,
creativity, and commitment to making the impossible
possible. We encourage you to always embrace the magic
within and outside of work, and to share your ideas and
innovations to keep our enchanted journey going. Thank you
for being a part of our mystical family, and together, we'll
continue to create a world where magic and business thrive
hand in hand!
"""
# 分割文字
chunks = text_splitter.split_text(text=text)
print(chunks[0:3])
內容解密:
初始化文字分割器:使用
RecursiveCharacterTextSplitter.from_tiktoken_encoder
方法建立一個文字分割器例項,並設定chunk_size
和chunk_overlap
引數。chunk_size=100
表示每個文字塊大約包含 100 個 tokens。chunk_overlap=20
表示相鄰文字塊之間有 20 個 tokens 的重疊,以保持上下文的連貫性。
準備待分割的文字:定義一個多段落的字串,代表需要被分割的內容。
分割文字:呼叫
text_splitter.split_text
方法,將文字分割成多個塊,並傳回一個列表。輸出結果:列印前三個文字塊,以驗證分割結果是否符合預期。
向量檢索技術
將檔案處理成文字塊後,需要將它們儲存在向量資料函式庫中,以便進行高效的相似度搜尋。FAISS(Facebook AI Similarity Search)是一個由 Facebook AI 開發的開源函式庫,用於高效地進行稠密向量的相似度搜尋和聚類別。
程式碼範例:
import numpy as np
import faiss
# 取得向量嵌入(假設 get_vector_embeddings 函式已定義)
emb = [get_vector_embeddings(chunk) for chunk in chunks]
vectors = np.array(emb)
# 建立 FAISS 索引
index = faiss.IndexFlatL2(vectors.shape[1])
index.add(vectors)
# 定義向量搜尋函式
def vector_search(query_text, k=1):
query_vector = get_vector_embeddings(query_text)
distances, indices = index.search(np.array([query_vector]), k)
return [(chunks[i], float(dist)) for dist, i in zip(distances[0], indices[0])]
# 示例搜尋
user_query = "do we get free unicorn rides?"
search_results = vector_search(user_query)
print(f"Search results for {user_query}:", search_results)
內容解密:
取得向量嵌入:使用
get_vector_embeddings
函式將每個文字塊轉換為向量表示,並儲存在emb
列表中。建立 FAISS 索引:初始化一個 FAISS 索引,並將向量資料新增到索引中。
定義向量搜尋函式:實作一個
vector_search
函式,該函式根據查詢文字的向量表示,在 FAISS 索引中進行相似度搜尋,並傳回最相關的文字塊及其距離。示例搜尋:執行一個示例搜尋,查詢「do we get free unicorn rides?」,並列印搜尋結果。
圖表說明
以下是展示文字分割和向量檢索流程的
graph LR; A[原始文字] --> B[文字分割]; B --> C[向量嵌入]; C --> D[建立 FAISS 索引]; D --> E[向量搜尋]; E --> F[傳回相關結果];
圖表翻譯: 此圖示展示了從原始文字到最終檢索結果的整個流程。首先,對原始文字進行分割;然後,將分割後的文字轉換為向量表示;接著,建立一個 FAISS 索引來儲存這些向量;當接收到查詢請求時,在 FAISS 索引中進行向量搜尋;最後,傳回最相關的結果。
實作向量搜尋與問答系統:以FAISS為例
在現代人工智慧應用中,向量搜尋技術扮演著至關重要的角色。透過將文字轉換為高維向量,我們能夠實作語義層面的相似度搜尋。本篇文章將探討如何結合FAISS(Facebook AI Similarity Search)與GPT-3.5-turbo模型,建構一個強大的問答系統。
向量搜尋技術的核心概念
向量搜尋的核心在於將文字資料轉換為稠密向量表示(dense vector representations),並在高維空間中進行相似度計算。相較於傳統的關鍵字匹配方法,向量搜尋能夠捕捉更深層的語義關係。
向量表示的產生
import numpy as np
# 假設我們有一個函式可以將文字轉換為向量表示
def get_vector_embeddings(text):
# 省略實作細節
pass
# 將文字分段並轉換為向量
chunks = ["文欄位落1", "文欄位落2", "文欄位落3"]
vectors = np.array([get_vector_embeddings(chunk) for chunk in chunks])
內容解密:
get_vector_embeddings
函式負責將輸入的文字轉換為對應的向量表示。這個過程通常涉及預訓練的語言模型,如BERT或其變體。- 我們將原始文字分割成多個段落(chunks),並對每個段落進行向量化處理。
- 最終得到的
vectors
是一個numpy陣列,其中每行代表一個文欄位落的向量表示。
建構FAISS索引
為了高效地進行相似度搜尋,我們需要建立一個專門的索引結構。FAISS提供了多種索引型別,其中IndexFlatL2
是一種根據L2距離(歐幾裡得距離)的暴力搜尋索引。
import faiss
# 建立FAISS索引
dimension = vectors.shape[1]
index = faiss.IndexFlatL2(dimension)
# 將向量資料加入索引
index.add(vectors)
內容解密:
vectors.shape[1]
取得向量的維度,這是建立FAISS索引所需的引數。IndexFlatL2
是一種簡單直接的索引結構,適合用於中小規模的資料集。- 透過
index.add(vectors)
,我們將所有文欄位落的向量表示加入到索引中。
實作向量搜尋功能
現在我們可以實作一個函式,用於執行向量搜尋並傳回最相似的結果。
def vector_search(query_text, k=1):
query_vector = get_vector_embeddings(query_text)
distances, indices = index.search(np.array([query_vector]), k)
return [(chunks[i], float(dist)) for dist, i in zip(distances[0], indices[0])]
內容解密:
- 首先,我們將查詢文字轉換為向量表示。
- 使用
index.search
方法,在FAISS索引中尋找與查詢向量最相似的k個結果。 - 傳回的結果是一個列表,包含每個匹配項的原始文字和對應的距離值。
結合GPT-3.5-turbo實作問答功能
為了進一步提升系統的功能性,我們可以將向量搜尋的結果作為上下文,提供給GPT-3.5-turbo模型進行問答處理。
def search_and_chat(user_query, k=1):
search_results = vector_search(user_query, k)
prompt_with_context = f"""Context:{search_results}\nAnswer the question: {user_query}"""
messages = [
{"role": "system", "content": "Please answer the questions provided by the user. Use only the context provided to you to respond to the user, if you don't know the answer say 'I don't know'."},
{"role": "user", "content": prompt_with_context},
]
response = client.chat.completions.create(model="gpt-3.5-turbo", messages=messages)
return response.choices[0].message.content
內容解密:
search_and_chat
函式首先執行向量搜尋,取得相關的上下文資訊。- 建構一個包含上下文和使用者查詢的提示詞(prompt),並設定系統訊息以引導模型正確回應。
- 使用OpenAI的API與GPT-3.5-turbo模型進行互動,取得最終的回答結果。
系統測試與評估
透過以下範例,我們可以測試整個問答系統的功能:
user_query = "What is Unicorn Enterprises' mission?"
result = search_and_chat(user_query)
print(f"Response: {result}")
內容解密:
當我們輸入查詢"Unicorn Enterprises’ mission?“時,系統首先進行向量搜尋,找到最相關的文欄位落。
將搜尋結果作為上下文,提供給GPT-3.5-turbo模型進行回答生成。
最終輸出的回答是根據提供的上下文生成的。
多模態搜尋:未來可以考慮結合影像、音訊等多模態資訊,實作更全面的搜尋功能。
即時更新:開發支援即時更新的索引結構,以適應動態變化的資料環境。
個人化推薦:根據使用者的歷史查詢記錄,提供個人化的搜尋結果和推薦內容。
這些發展方向將進一步提升問答系統的功能性和使用者經驗,使其在更多場景中發揮價值。
參考資料
透過本文的介紹,相信讀者已經對如何建構根據FAISS和GPT-3.5-turbo的問答系統有了深入的理解。在實際應用中,可以根據具體需求進行調整和最佳化,以實作最佳的效果。
附錄:完整程式碼範例
import numpy as np
import faiss
import openai
# 省略部分函式實作細節
def main():
user_query = "What is Unicorn Enterprises' mission?"
result = search_and_chat(user_query)
print(f"Response: {result}")
if __name__ == "__main__":
main()
這個完整的程式碼範例展示瞭如何將文中討論的概念整合到一個可執行的程式中。讀者可以根據自己的需求修改和擴充套件這個基礎框架。
圖表說明
graph LR B[B] A[使用者查詢] --> B{向量搜尋} B --> C[取得相關上下文] C --> D[結合GPT-3.5-turbo生成答案] D --> E[輸出最終回答]
圖表翻譯: 此圖示展示了整個問答系統的工作流程。首先,使用者輸入查詢陳述式;然後,系統進行向量搜尋,取得相關的上下文資訊;接著,將這些資訊結合GPT-3.5-turbo模型生成答案;最後,輸出最終的回答結果。整個過程體現了向量搜尋與大語言模型的有機結合。