隨著生成式 AI 的快速發展,RAG(Retrieval-Augmented Generation)技術因其結合檢索與生成的優勢,成為提升文字生成品質與相關性的關鍵技術。本文將探討如何利用 Python 實作高階 RAG,結合向量搜尋與索引式 RAG,並探討其應用。首先,我們需要理解 RAG 的核心概念,即結合檢索系統與生成模型,讓模型能根據檢索到的相關資訊生成更準確的內容,彌補傳統生成模型僅依賴預訓練資料的不足。實作 RAG 涉及環境設定、生成器函式定義、資料準備、查詢處理等步驟。我們將使用 OpenAI 的 GPT-4o 模型作為生成器,並以 Python 程式碼示範如何進行資料分塊、向量計算、人工反饋增強輸入等操作。

高階RAG:結合向量搜尋與索引式RAG的Python實作

建構模組化RAG程式

首先,讓我們從定義RAG開始。

什麼是RAG?

當生成式AI模型無法準確回答問題時,有些人會說它正在「產生幻覺」或產生偏見。簡單來說,它只是輸出無意義的內容。然而,這一切都歸結為模型訓練資料中缺乏所需資訊,或者是經典模型組態問題。這種混淆通常會導致輸出最可能的隨機序列,而非最準確的結果。

RAG的出現彌補了生成式AI的不足,為LLM模型提供了準確回答所需的資訊。RAG最初是為LLM設計的(Lewis等人,2020)。RAG框架將執行最佳化的資訊檢索任務,並將檢索到的資訊新增到輸入(使用者查詢或自動化提示)中,以產生改進的輸出。RAG框架可以在高層次上總結如下圖所示:

圖1.1:RAG驅動的生成式AI的兩個主要元件

想像你是一名在圖書館裡的大學生,你需要寫一篇關於RAG的論文。就像ChatGPT或其他AI輔助工具一樣,你已經學會了閱讀和寫作。作為大語言模型(LLM),你有足夠的訓練來閱讀進階資訊、總結並寫作內容。然而,就像Hugging Face、Vertex AI或OpenAI提供的超人AI一樣,你有很多不知道的事情。

在檢索階段,你在圖書館中搜尋所需的書籍(圖1.1左側)。然後,你回到座位,自己或與同學合作執行檢索任務,從這些書籍中提取所需資訊。在生成階段(圖1.1右側),你開始寫論文。你是一個RAG驅動的生成式人類代理,就像RAG驅動的生成式AI框架一樣。

在繼續寫論文的過程中,你遇到了一些困難的話題。你沒有時間逐一檢視所有可用的資訊!作為生成式人類代理,你就像生成式AI模型一樣卡住了。你可能會嘗試寫些什麼,就像生成式AI模型在輸出內容毫無意義時所做的那樣。但是,你和生成式AI代理都不會意識到內容是否準確,直到有人糾正你的論文並給出評分。

此時,你已經達到自己的極限,決定求助於RAG生成式AI輔助工具,以確保獲得正確的答案。然而,你被眾多的LLM模型和RAG組態所困擾。你需要先了解可用的資源以及RAG的組織方式。讓我們來看看主要的RAG組態。

簡單、高階與模組化RAG組態

一個RAG框架必然包含兩個主要元件:檢索器和生成器。生成器可以是任何LLM或基礎多模態AI平台或模型,例如GPT-4o、Gemini、Llama,或是初始架構的數百種變體之一。檢索器可以是任何新興框架、方法和工具,例如Activeloop、Pinecone、LlamaIndex、LangChain、Chroma等。

現在的問題是決定三種型別的RAG框架(Gao等人,2024)中哪一種適合專案需求。我們將在本章的「簡單、高階與模組化RAG程式碼」部分用程式碼來闡述這三種方法:

  • 簡單RAG:這種RAG框架不涉及複雜的資料嵌入和索引。它可以有效地透過關鍵字存取適量的資料,以增強使用者輸入並獲得令人滿意的回應。
  • 高階RAG:這種RAG涉及更複雜的場景,例如使用向量搜尋和根據索引的檢索。高階RAG可以使用多種方法實作,能夠處理多種資料型別以及結構化或非結構化的多模態資料。
  • 模組化RAG:模組化RAG拓寬了視野,包含了任何涉及簡單RAG、高階RAG、機器學習以及完成複雜專案所需的任何演算法的場景。

不過,在進一步討論之前,我們需要決定是否應該實作RAG還是微調模型。

RAG與微調

RAG並不總是微調的替代方案,而微調也並不總能取代RAG。如果我們在RAG資料集中累積太多資料,系統可能會變得難以管理。另一方面,我們無法對具有動態、不斷變化的資料(如每日天氣預報、股票市場價值、企業新聞和各種日常事件)進行微調。

決定是否實作RAG或微調模型取決於引數化與非引數化資訊的比例。從頭開始訓練或微調模型與RAG之間的基本差異可以歸結為引數化和非引數化知識:

  • 引數化:在RAG驅動的生成式AI生態系統中,引數化部分指的是生成式AI模型的引數(權重),這些引數是透過訓練資料學習到的。這意味著模型的知識儲存在這些學習到的權重和偏差中。原始訓練資料被轉換成數學形式,我們稱之為引數化表示。本質上,模型「記住了」它從資料中學到的東西,但資料本身並未明確儲存。
  • 非引數化:相比之下,RAG生態系統中的非引數化部分涉及儲存可以直接存取的明確資料。這意味著資料保持可用,並可以在需要時被查詢。與知識間接嵌入權重的引數化模型不同,RAG中的非引數化資料允許我們檢視和使用每個輸出的實際資料。

RAG和微調之間的差異取決於生成式AI模型必須處理的靜態(引數化)和動態(非引數化)不斷演變的資料量。過度依賴RAG的系統可能會變得過載和管理困難。而過度依賴微調生成模型的系統則會顯示出其無法適應日常資訊更新。

圖1.2展示了一個決策門檻,表明根據RAG的生成式AI專案經理在實作非引數化(明確資料)RAG框架之前,需要評估生態系統中訓練好的引數化生成式AI模型的潛力。同樣,RAG元件的潛力也需要仔細評估。

圖1.2:增強RAG或微調LLM之間的決策門檻

最終,在根據RAG的生成式AI生態系統中,增強檢索器和生成器之間的平衡取決於專案的具體需求和目標。「#### 內容解密:」 RAG和微調並非互相排斥。

# 以下是一個簡化的例子,用於展示 RAG 和微調之間的差異
def rag_vs_fine_tuning(data_type):
    if data_type == "dynamic":
        return "使用 RAG 處理動態資料"
    elif data_type == "static":
        return "使用微調處理靜態資料"
    else:
        return "根據具體需求選擇合適的方法"

# 呼叫函式
print(rag_vs_fine_tuning("dynamic"))  # 輸出:使用 RAG 處理動態資料
print(rag_vs_fine_tuning("static"))   # 輸出:使用微調處理靜態資料

內容解密:

這段程式碼展示了一個簡單的函式,用於根據資料型別決定是使用 RAG 還是微調。如果資料型別是動態的,則建議使用 RAG;如果是靜態的,則建議使用微調。這反映了 RAG 和微調在處理不同型別資料時的適用性。

我們現在將看到根據RAG的生成式AI如何涉及一個包含許多元件的生態系統。

RAG生態系統

根據RAG的生成式AI是一個可以在多種組態中實作的框架。「#### 內容解密:」 RAG的框架執行在一個廣泛的生態系統中,如圖1.3所示。然而,無論有多少檢索和生成元件,核心思想保持一致:在提供準確回應方面,結合檢索到的資訊與生成式AI模型的強大功能。

圖1.3:根據 RAG 的生成式 AI 生態系統

  graph LR;
    A[使用者查詢] --> B[檢索器];
    B --> C[知識函式庫];
    C --> D[相關資訊];
    D --> E[生成器];
    E --> F[最終回應];

圖表翻譯: 此圖展示了根據 RAG 的生成式 AI 生態系統的基本流程。首先,使用者提出查詢,該查詢被傳遞給檢索器。檢索器在知識函式庫中搜尋相關資訊,並將其傳回給系統。這些相關資訊隨後被傳遞給生成器,後者根據檢索到的資訊產生最終回應。這一流程體現了 RAG 在結合檢索與生成方面的強大能力。

隨著 AI 技術的不斷發展,根據 RAG 的應用將越來越廣泛。透過結合檢索與生成的優勢,RAG 有望在多個領域提供更準確、更具上下文感知能力的解決方案。在未來的研究和實踐中,我們將繼續探索如何進一步最佳化 RAG 框架,以滿足日益增長的需求。

RAG生態系統的四大核心領域與關鍵元件

RAG(Retrieval-Augmented Generation)生態系統是生成式人工智慧的重要架構,其核心運作涉及四大主要領域:資料、儲存、檢索和生成。本章節將探討這些領域的關鍵問題、元件及其相互關係。

四大核心領域及其關鍵問題

  1. 資料

    • 資料來源是否可靠?
    • 資料是否足夠?
    • 是否存在版權、隱私和安全問題?
  2. 儲存

    • 資料在處理前後如何儲存?
    • 需要儲存的資料量有多大?
  3. 檢索

    • 如何檢索正確的資料來增強使用者輸入?
    • 哪種型別的RAG框架適合專案需求?
  4. 生成

    • 選擇哪種生成式AI模型以配合所選的RAG框架?

RAG生態系統架構

RAG生態系統包含四個主要元件:檢索器(D)、生成器(G)、評估器(E)和訓練器(T)。這些元件共同構成了一個完整的RAG驅動生成式AI流程。

圖1.3:生成式RAG生態系統

圖1.3展示了RAG生態系統的主要元件,包括檢索器、生成器、評估器和訓練器。這些元件分別負責資料處理、輸入增強、效能評估和模型訓練等任務。

檢索器(D)

檢索器是RAG生態系統的起始點,負責資料的收集、處理、儲存和檢索。

資料收集(D1)

現代AI資料如同多媒體播放清單一般多樣化,可以是部落格文章中的一段文字、一張表情包圖片,或是最新流行的歌曲。這些資料來源廣泛,格式多樣,包括PDF檔案、網頁、純文字檔、JSON檔案、MP3音訊、MP4影片,以及PNG和JPG圖片等。

資料處理(D2)

在資料收集階段,各種型別的資料可以透過網路爬蟲技術或其他資訊來源提取。這些資料物件隨後被轉換成統一的特徵表示,例如將資料分塊(chunking)、嵌入(embedding)和索引,以提高搜尋性和檢索效率。

# 示例:使用Python進行資料分塊處理
def chunk_data(data, chunk_size):
    return [data[i:i + chunk_size] for i in range(0, len(data), chunk_size)]

# 資料分塊範例
data = "這是一段需要被分塊處理的文字。"
chunked_data = chunk_data(data, 5)
print(chunked_data)

內容解密:

上述程式碼展示瞭如何將一段文字按照指定的大小進行分塊處理。這種技術在處理大量文字資料時非常有用,可以提高資料處理的效率和靈活性。

資料儲存(D3)

收集和處理大量多樣化的網路資料後,需要使用向量儲存(如Deep Lake、Pinecone和Chroma)來儲存這些資料。這些向量儲存不僅能夠儲存資料,還能將其轉換為數學實體(如向量),從而實作強大的計算能力。

資料檢索(D4)

檢索過程由使用者輸入或自動化輸入觸發。為了快速檢索資料,需要將資料載入向量儲存和資料集中,並透過關鍵字搜尋、智慧嵌入和索引等技術來高效檢索資料。

# 示例:使用餘弦相似度進行資料檢索
import numpy as np

def cosine_similarity(vector1, vector2):
    dot_product = np.dot(vector1, vector2)
    magnitude1 = np.linalg.norm(vector1)
    magnitude2 = np.linalg.norm(vector2)
    return dot_product / (magnitude1 * magnitude2)

# 餘弦相似度計算範例
vector1 = np.array([1, 2, 3])
vector2 = np.array([4, 5, 6])
similarity = cosine_similarity(vector1, vector2)
print(similarity)

內容解密:

上述程式碼展示瞭如何使用餘弦相似度來衡量兩個向量之間的相似程度。這種技術在資訊檢索和推薦系統中非常常見,用於找出與查詢條件最相關的資料項。

生成器(G)

生成器的主要功能是增強使用者輸入,並利用生成式AI模型產生輸出。

使用者輸入(G1)

使用者輸入可以是自動化任務批次處理,也可以是透過使用者介面(UI)輸入的人工提示。

人工反饋增強輸入(G2)

可以將人工反饋加入輸入中,以提高RAG生態系統的適應性和對資料檢索及生成式AI輸入的控制力。

# 示例:結合人工反饋增強輸入
def augment_input_with_feedback(input_data, feedback):
    # 結合輸入資料和人工反饋
    augmented_input = input_data + " " + feedback
    return augmented_input

# 人工反饋增強輸入範例
input_data = "這是一個初始輸入。"
feedback = "請根據這個上下文繼續生成內容。"
augmented_input = augment_input_with_feedback(input_data, feedback)
print(augmented_input)

內容解密:

上述程式碼展示瞭如何將人工反饋與初始輸入結合,以產生增強的輸入。這種方法可以提高生成式AI模型的輸出品質和相關性。

提示工程(G3)

檢索器和生成器都依賴提示工程來準備標準和增強的訊息,供生成式AI模型處理。提示工程將檢索器的輸出和使用者輸入結合起來。

生成與輸出(G4)

選擇合適的生成式AI模型取決於專案目標。不同的模型(如Llama、Gemini、GPT等)適用於不同的需求。框架如LangChain提供了可適應的介面和工具,幫助簡化各種AI模型的整合。

評估器(E)

評估器負責評估生成式AI模型的效能,包括數學指標評估和人工評估。

數學指標(E1)

數學指標(如餘弦相似度)用於評估檢索資料的相關性和準確性。這些指標為評估模型的效能和可靠性提供了堅實的基礎。

人工反饋(E2)

除了數學指標外,人工評估也是評估AI效能的重要手段。人類評估者可以提供關於AI輸出品質和相關性的寶貴意見。

RAG技術的實務應用與程式碼實作

RAG(Retrieval-Augmented Generation)技術結合了檢索與生成的優勢,廣泛應用於自然語言處理領域。以下章節將探討RAG技術的原理、實務應用,並透過Python程式碼範例展示其實作方法。

RAG技術的核心概念

RAG技術的核心在於結合檢索系統與生成模型,以提升文字生成的品質與相關性。傳統的生成模型(如GPT)依賴於預訓練資料,而RAG則進一步引入了外部知識函式庫,使得模型能夠根據檢索到的相關資訊生成更準確的內容。

RAG的實作架構

RAG的實作主要分為以下幾個步驟:

  1. 環境設定:安裝必要的套件並組態OpenAI API金鑰。
  2. 生成器函式:定義一個使用OpenAI GPT模型的生成函式。
  3. 資料準備:準備用於檢索的檔案資料。
  4. 查詢處理:處理使用者輸入的查詢請求。

環境設定

首先,我們需要安裝OpenAI套件並設定API金鑰。

!pip install openai==1.40.3

接著,從安全儲存位置讀取API金鑰並設定環境變數。

from google.colab import drive
drive.mount('/content/drive')

f = open("drive/MyDrive/files/api_key.txt", "r")
API_KEY = f.readline().strip()
f.close()

import os
import openai
os.environ['OPENAI_API_KEY'] = API_KEY
openai.api_key = os.getenv("OPENAI_API_KEY")

生成器函式

定義一個使用GPT-4o模型的生成函式,用於根據輸入文字生成回應。

import openai
from openai import OpenAI
import time

client = OpenAI()
gpt_model = "gpt-4o"

def call_llm_with_full_text(itext):
    text_input = '\n'.join(itext)
    prompt = f"Please elaborate on the following content:\n{text_input}"
    
    try:
        response = client.chat.completions.create(
            model=gpt_model,
            messages=[
                {"role": "system", "content": "You are an expert"},
                {"role": "assistant", "content": "1. You can explain"},
                {"role": "user", "content": prompt}
            ],
            temperature=0.1
        )
        return response.choices[0].message.content.strip()
    except Exception as e:
        return str(e)

#### 內容解密:
此函式的作用是呼叫GPT-4o模型生成文字首先它將輸入文字連線成一個字串並構建一個提示詞然後透過OpenAI客戶端傳送請求並取得模型的回應其中,`temperature`引數設為0.1以獲得更精確的回應

資料準備

假設我們已經有一個包含檔案資料的列表db_records,這些資料已經被預處理並分割成句子。

# 假設db_records是一個包含檔案資料的列表
db_records = ["檔案1的內容", "檔案2的內容", ...]

查詢處理與回應生成

定義一個函式,用於格式化模型的回應。

import textwrap

def print_formatted_response(response):
    wrapper = textwrap.TextWrapper(width=80)
    wrapped_text = wrapper.fill(text=response)
    print("Response:")
    print("---------------")
    print(wrapped_text)
    print("---------------\n")

#### 內容解密:
此函式使用`textwrap`模組將模型的回應格式化為寬度為80個字元的段落使輸出更易閱讀

RAG的進階實作

在基礎實作的基礎上,我們可以進一步開發進階的RAG功能,包括根據關鍵字的檢索、向量搜尋和索引檢索等方法。

進階檢索方法

  1. 根據關鍵字的檢索:實作一個簡單的關鍵字匹配函式,用於檢索相關檔案。

  2. 向量搜尋:使用向量嵌入技術,將檔案和查詢轉換為向量,並計算相似度以進行檢索。

  3. 索引檢索:建立檔案索引,以提高檢索效率。

  4. 最佳化檢索演算法:研究更高效的檢索演算法,以提升RAG系統的效能。

  5. 擴充套件知識函式庫:不斷擴充和更新知識函式庫,以提高RAG系統的知識覆寫範圍。

  6. 增強生成品質:透過微調生成模型和最佳化提示詞,提升生成文字的品質和多樣性。

透過不斷最佳化和改進,RAG技術有望在更多領域發揮重要作用,為自然語言處理應用帶來新的突破。