RAG 向量儲存技術的核心在於有效地儲存和檢索向量化資料,以便後續的相似度計算和內容生成。本文探討瞭如何使用餘弦相似度和增強相似度來評估使用者查詢與儲存記錄之間的相關性,並 demonstrated 如何將兩者結合以提升相似度得分。此外,我們也說明瞭如何利用增強的輸入來呼叫 GPT-4 模型,生成更符合使用者需求的回應,並比較了向量搜尋和索引搜尋的優劣,以及如何根據資料集規模和內容複雜度選擇合適的搜尋策略。程式碼範例展示瞭如何計算餘弦相似度、增強相似度,以及如何生成增強輸入。

RAG 向量儲存的定義與增強相似度計算

在前面的章節中,我們已經建立了相似度指標。本文將進一步應用餘弦相似度(Cosine Similarity)與增強相似度(Enhanced Similarity)來評估使用者輸入與最佳匹配記錄之間的相關性。

餘弦相似度計算

首先,我們使用餘弦相似度來衡量使用者查詢與最佳匹配記錄之間的相似程度:

# 餘弦相似度
score = calculate_cosine_similarity(query, best_matching_record)
print(f"最佳餘弦相似度得分:{score:.3f}")

輸出結果顯示,由於使用者輸入較短,而回應內容較長且完整,因此相似度得分較低:

最佳餘弦相似度得分:0.126

增強相似度計算

接下來,我們使用增強相似度計算來提高相似度得分:

# 增強相似度
response = best_matching_record
print(query, ": ", response)
similarity_score = calculate_enhanced_similarity(query, response)
print(f"增強相似度:{similarity_score:.3f}")

增強相似度計算的結果顯示,相似度得分明顯提高:

定義 RAG 儲存:RAG 向量儲存是一種資料函式庫或資料集
增強相似度:0.642

內容解密:

  • calculate_cosine_similarity 函式用於計算兩個向量之間的餘弦相似度,評估它們的方向一致性。
  • calculate_enhanced_similarity 函式採用更複雜的演算法來提高相似度評估的準確性。
  • 餘弦相似度適用於評估短文字與長文字之間的相似性,但有時可能得分較低。
  • 增強相似度透過更深入的語義分析,能夠提供更準確的相似度評估。

增強輸入

將使用者輸入與最佳匹配記錄結合,生成增強輸入:

augmented_input = query + ": " + best_matching_record
print_formatted_response(augmented_input)

輸出結果如下:

回應:
---------------
定義 RAG 儲存:RAG 向量儲存是一種資料函式庫或資料集,包含向量化資料點。
---------------

內容解密:

  • augmented_input 是將使用者查詢與檢索到的最佳匹配記錄結合,生成更完整的輸入。
  • print_formatted_response 函式用於格式化輸出結果,使其更易閱讀。

生成回應

呼叫 GPT-4o 模型生成回應:

llm_response = call_llm_with_full_text(augmented_input)
print_formatted_response(llm_response)

輸出結果顯示,GPT-4o 能夠理解輸入並提供相關且有趣的回應:

回應:
---------------
當然!讓我們進一步闡述提供的內容

RAG 儲存:**RAG(檢索增強生成)向量儲存**是一種專門設計的資料函式庫或資料集,用於儲存向量化資料點...
單純的 RAG 在許多情況下足夠使用。然而,如果檔案數量過多或內容變得更加複雜,那麼先進的 RAG 組態將提供更好的結果。現在,讓我們進一步探討先進的 RAG。

### 3. 先進 RAG

隨著資料集的增長,關鍵字搜尋方法可能變得太慢。例如,如果我們有數百份檔案,每份檔案包含數百個句子,那麼僅使用關鍵字搜尋將變得具有挑戰性。使用索引將減少計算負擔至總資料的一小部分。
在本文中,我們將超越使用關鍵字搜尋文字的方法。我們將看到 RAG 如何將文字資料轉換為數值表示,從而提高搜尋效率和處理速度。不像傳統方法直接解析文字,RAG 首先將檔案和使用者查詢轉換為向量,即數值形式,以加快計算。簡單來說,向量是一列數字,代表文字的各種特徵。簡單的向量可能計算詞語出現次數(詞頻),而更複雜的向量,稱為嵌入,能夠捕捉更深層的語言模式。
在本文中,我們將實作向量搜尋和根據索引的搜尋:
- **向量搜尋**:我們將每個句子轉換為數值向量。透過計算查詢向量(使用者查詢)與這些檔案向量之間的餘弦相似度,我們可以快速找到最相關的檔案。
- **根據索引的搜尋**:在這種情況下,所有句子都使用 TF-IDF(詞頻-逆檔案頻率)轉換為向量,這是一種用於評估詞語在檔案集合中重要性的統計度量。這些向量在矩陣中充當索引,允許快速進行相似度比較,而無需完全解析每個檔案。
讓我們從向量搜尋開始,看看這些概念的實際應用。

#### 3.1 向量搜尋

向量搜尋將使用者查詢和檔案轉換為數值向量,從而實作數學計算,在處理大量資料時能夠更快地檢索相關資料。
程式執行過程中,會遍歷資料集中的每條記錄,透過計算查詢向量與資料集中每個記錄之間的餘弦相似度,找到最佳匹配的檔案:
```python
def find_best_match(text_input, records):
    best_score = 0
    best_record = None
    for record in records:
        current_score = calculate_cosine_similarity(text_input, record)
        if current_score > best_score:
            best_score = current_score
            best_record = record
    return best_score, best_record

呼叫向量搜尋函式並顯示最佳匹配記錄:

best_similarity_score, best_matching_record = find_best_match(query, records)
print_formatted_response(best_matching_record)

輸出結果令人滿意:

回應:
---------------
RAG 向量儲存是一種資料函式庫或資料集,包含向量化資料點。
---------------

內容解密:

  • find_best_match 函式遍歷資料集中的每條記錄,計算查詢與每條記錄之間的餘弦相似度,找到最佳匹配記錄。
  • 向量搜尋透過將文字轉換為數值向量,能夠更快速地在大量資料中檢索相關資訊。

評估指標

無論是使用餘弦相似度還是增強相似度,評估指標都保持一致,因為檢索到的檔案相同:

print(f"最佳餘弦相似度得分:{best_similarity_score:.3f}")

輸出結果如下:

最佳餘弦相似度得分:0.126

使用增強相似度時,結果與單純 RAG 相同:

# 增強相似度
response = best_matching_record
print(query, ": ", response)
similarity_score = calculate_enhanced_similarity(query, best_matching_record)
print(f"增強相似度:{similarity_score:.3f}")

輸出結果如下:

定義 RAG 儲存:RAG 向量儲存是一種資料函式庫或資料集
增強相似度:0.642

內容解密:

  • 評估指標用於衡量檢索到的檔案的相關性。
  • 餘弦相似度和增強相似度提供了不同的評估角度,前者關注向量方向的一致性,後者則提供更深入的語義分析。

為什麼使用向量搜尋?

儘管在本例中,向量搜尋與單純 RAG 產生相同的輸出,但在處理包含數百萬份複雜檔案的資料集時,向量搜尋能夠捕捉到關鍵字搜尋無法捕捉的細微差別。

圖表翻譯:

此圖示展示了向量搜尋與關鍵字搜尋的比較,向量搜尋透過將文字轉換為數值向量,能夠更快速地在大量資料中檢索相關資訊。

索引搜尋與向量搜尋在RAG中的應用與比較

在上一節中,我們探討了向量搜尋的基本原理及其在RAG(Retrieval-Augmented Generation)系統中的應用。向量搜尋透過將檔案和查詢轉換為向量表示,並計算它們之間的相似度,從而找到最相關的檔案。然而,隨著資料集規模的增加,向量搜尋的效率可能會下降。為瞭解決這一問題,本文將介紹索引搜尋(Index-based Search)的方法,並比較其與向量搜尋的差異。

索引搜尋的基本原理

索引搜尋並不是直接將查詢向量與檔案向量進行比較,而是透過預先建立的索引向量來代表檔案內容,從而加速搜尋過程。在實作索引搜尋時,我們首先需要匯入必要的類別和函式:

from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics.pairwise import cosine_similarity

內容解密:

  • TfidfVectorizer類別用於將文字檔案轉換為TF-IDF特徵矩陣。TF-IDF是一種用於評估單詞在檔案中重要性的量化方法,它透過考慮單詞在整個檔案集中的頻率來計算。
  • cosine_similarity函式用於計算查詢向量與TF-IDF矩陣中向量之間的餘弦相似度,以衡量它們之間的相似程度。

索引搜尋的實作

接下來,我們定義了一個名為find_best_match的函式,用於尋找與查詢最相似的檔案:

def find_best_match(query, vectorizer, tfidf_matrix):
    query_tfidf = vectorizer.transform([query])
    similarities = cosine_similarity(query_tfidf, tfidf_matrix)
    best_index = similarities.argmax()
    best_score = similarities[0, best_index]
    return best_score, best_index

內容解密:

  1. 轉換查詢向量:使用提供的vectorizer將輸入查詢轉換為TF-IDF向量格式。
  2. 計算相似度:透過cosine_similarity函式計算查詢向量與tfidf_matrix中所有向量之間的餘弦相似度。
  3. 識別最佳匹配:找到相似度得分最高的索引(best_index)。
  4. 檢索最佳匹配得分:提取最高的餘弦相似度得分(best_score)。

向量搜尋與索引搜尋的比較

向量搜尋直接比較查詢向量與檔案向量,適合用於語義豐富的檔案檢索。然而,當資料集規模較大時,其效率會降低。索引搜尋透過預先計算檔案的索引向量,加速了搜尋過程,適合大規模資料集。

模組化RAG的設計

在實際應用中,單一的搜尋方法可能無法滿足所有需求。因此,我們設計了一個名為RetrievalComponent的類別,能夠根據專案的不同階段和需求,靈活選擇關鍵字搜尋、向量搜尋或索引搜尋。

class RetrievalComponent:
    def __init__(self, method='vector'):
        self.method = method
        if self.method in ['vector', 'indexed']:
            self.vectorizer = TfidfVectorizer()
            self.tfidf_matrix = None

    def fit(self, records):
        if self.method in ['vector', 'indexed']:
            # 建立TF-IDF矩陣
            pass

內容解密:

  • __init__方法初始化RetrievalComponent例項,根據選擇的搜尋方法決定是否建立TfidfVectorizer
  • fit方法用於根據記錄建立TF-IDF矩陣,適用於向量搜尋和索引搜尋。

檢索增強生成(RAG)技術深度解析

在現代人工智慧領域中,檢索增強生成(RAG)技術已成為提升生成式AI模型準確性和效率的重要工具。本文將探討RAG的核心元件、實作方法及其在不同應用場景中的優勢。

RAG的核心架構

RAG系統主要由兩個關鍵元件組成:檢索器(Retriever)和生成器(Generator)。檢索器負責處理資料並定義搜尋方法,而生成器則利用檢索到的資訊增強其輸出結果。

檢索方法的實作

在RAG系統中,檢索方法的選擇至關重要。以下是一個Python實作範例,展示了三種不同的檢索方法:關鍵字搜尋、向量搜尋和索引搜尋。

class RetrievalComponent:
    def __init__(self, method='keyword'):
        self.method = method
        self.vectorizer = TfidfVectorizer()
        self.tfidf_matrix = None

    def fit(self, documents):
        self.tfidf_matrix = self.vectorizer.fit_transform(documents)

    def retrieve(self, query):
        if self.method == 'keyword':
            return self.keyword_search(query)
        elif self.method == 'vector':
            return self.vector_search(query)
        elif self.method == 'indexed':
            return self.indexed_search(query)

    #### 內容解密:
    # 這段程式碼定義了檢索元件的初始化和檢索方法。
    # 檢索方法根據設定的策略(關鍵字、向量或索引)執行不同的搜尋操作。

    def keyword_search(self, query):
        best_score = 0
        best_record = None
        query_keywords = set(query.lower().split())
        for index, doc in enumerate(self.documents):
            doc_keywords = set(doc.lower().split())
            common_keywords = query_keywords.intersection(doc_keywords)
            score = len(common_keywords)
            if score > best_score:
                best_score = score
                best_record = self.documents[index]
        return best_record

    #### 內容解密:
    # 關鍵字搜尋方法透過計算查詢與檔案中共同的關鍵字數量來評估匹配度。
    # 這種方法簡單直觀,適用於簡單的文字匹配任務。

    def vector_search(self, query):
        query_tfidf = self.vectorizer.transform([query])
        similarities = cosine_similarity(query_tfidf, self.tfidf_matrix)
        best_index = similarities.argmax()
        return self.documents[best_index]

    #### 內容解密:
    # 向量搜尋方法利用TF-IDF向量化查詢和檔案,並透過餘弦相似度計算匹配度。
    # 這種方法能夠捕捉更深層的語義關係,適用於複雜的查詢任務。

    def indexed_search(self, query):
        query_tfidf = self.vectorizer.transform([query])
        similarities = cosine_similarity(query_tfidf, self.tfidf_matrix)
        best_index = similarities.argmax()
        return self.documents[best_index]

    #### 內容解密:
    # 索引搜尋方法與向量搜尋類別似,但通常用於預先計算好的TF-IDF矩陣,以提高檢索效率。
    # 這種方法在處理大規模資料集時特別有效。

RAG的應用場景與優勢

RAG技術在多個領域展現出其獨特的優勢。無論是簡單的關鍵字匹配還是複雜的語義搜尋,RAG都能夠提供靈活且高效的解決方案。

RAG的模組化策略

透過模組化的設計,RAG能夠根據不同的需求選擇合適的檢索和生成策略。這種靈活性使得RAG能夠在多種應用場景中發揮作用,從簡單的問答系統到複雜的內容生成任務。

問題與討論

  1. RAG是否能夠提高生成式AI模型的準確性?
  2. 簡單RAG組態是否依賴複雜的資料嵌入?
  3. 在什麼情況下應該選擇RAG而不是微調模型?
  4. RAG是否能夠即時檢索外部資料以增強回應?
  5. RAG是否僅限於處理文字資料?

透過深入理解RAG的原理和應用,我們能夠更好地利用這項技術來提升AI系統的效能和準確性。未來,RAG有望在更多領域中發揮其獨特的優勢。