LlamaIndex 與 Deep Lake 的整合,為構建根據索引的 RAG 系統提供了高效的解決方案。Deep Lake 作為向量資料函式庫,儲存檔案的向量表示,而 LlamaIndex 則提供多種索引結構,例如向量儲存索引、樹索引、列表索引和關鍵字表索引,以加速查詢過程。藉由 OpenAI 的 LLM 模型,系統可以根據使用者查詢,從索引中檢索相關檔案片段,並生成具體且連貫的回應。透過 Cosine 相似度計算,系統能有效評估檔案與查詢之間的相關性,確保傳回最 pertinent 的結果。此架構有效提升查詢效率,並確保回應的準確性與一致性,尤其適用於處理大量非結構化文字資料,例如技術檔案、研究論文或新聞報導等。

9. 將大型文字分解為較小的部分是否必要以進行嵌入和儲存?

是的,將大型文字分解為較小的部分可以提高嵌入和儲存的效率。

10. 餘弦相似度指標是否用於評估檢索資訊的相關性?

是的,餘弦相似度指標可以用於評估檢索資訊的相關性。

結合 LlamaIndex、Deep Lake 和 OpenAI 建立索引基礎的 RAG

索引可以提高 RAG 的精確度和速度,並提供對生成回應源的可視性。這使得開發人員可以控制生成 AI 的輸出,並對資料源進行追蹤和審查。透過使用 LlamaIndex、Deep Lake 和 OpenAI,可以建立一個強大的索引基礎的 RAG 系統,以提高生成 AI 的效能和可靠性。

建立根據索引的語義搜尋引擎

在深度學習和自然語言處理領域中,根據索引的搜尋引擎已成為一種重要的技術,尤其是在處理大量資料時。這種技術不僅能夠提高搜尋效率,還能夠提供更精確的搜尋結果。在本章中,我們將探討如何使用LlamaIndex框架和索引方法建立根據索引的語義搜尋引擎,並將其與Deep Lake向量儲存和OpenAI整合。

根據索引的搜尋引擎架構

根據索引的搜尋引擎比根據向量的相似性搜尋更快,因為它直接使用索引存取相關資料,而根據向量的搜尋則需要順序比較所有記錄中的嵌入。為了闡明這種區別,我們先來瞭解一下根據向量的相似性搜尋程式,如下所示:

  1. 資料收集和預處理:我們收集和預處理資料,以便用於搜尋。
  2. 嵌入和向量儲存:我們將預處理的資料嵌入到向量空間中,並將其儲存在向量儲存中。
  3. 檢索查詢和生成:我們執行檢索查詢和生成AI,以處理使用者輸入,根據向量相似性搜尋進行檢索,增強輸入,生成回應,並應用效能指標。

根據索引的搜尋引擎優勢

根據索引的搜尋引擎具有多個優勢,包括:

  • 速度:根據索引的搜尋引擎比根據向量的搜尋更快,因為它直接使用索引存取相關資料。
  • 精確性:根據索引的搜尋引擎可以提供更精確的搜尋結果,因為它使用索引直接存取相關資料。
  • 可追蹤性:根據索引的搜尋引擎可以提供更好的可追蹤性,因為它使用索引直接存取相關資料。

實作根據索引的搜尋引擎

為了實作根據索引的搜尋引擎,我們需要進行以下步驟:

  1. 資料收集和預處理:我們收集和預處理資料,以便用於搜尋。
  2. 建立索引:我們建立索引,以便直接存取相關資料。
  3. 查詢和生成:我們執行檢索查詢和生成AI,以處理使用者輸入,根據索引進行檢索,增強輸入,生成回應,並應用效能指標。

結合Deep Lake和OpenAI

為了結合Deep Lake和OpenAI,我們需要進行以下步驟:

  1. 建立Deep Lake向量儲存:我們建立Deep Lake向量儲存,以便儲存預處理的資料。
  2. 整合OpenAI:我們整合OpenAI,以便使用其生成AI能力。
  3. 查詢和生成:我們執行檢索查詢和生成AI,以處理使用者輸入,根據索引進行檢索,增強輸入,生成回應,並應用效能指標。

建立根據索引的語義搜尋引擎和生成式AI代理

在本文中,我們將使用Deep Lake向量儲存、LlamaIndex和OpenAI建立根據索引的語義搜尋引擎和生成式AI代理。如前所述,無人機技術正在火災檢測和交通控制等領域得到廣泛應用。因此,本程式的目標是為無人機技術問題和答案提供根據索引的RAG代理。該程式將展示無人機如何使用電腦視覺技術來識別車輛和其他物體。

根據索引的RAG程式架構

我們將實作本章《架構》部分所描述的架構,如圖3.1所示。

步驟1:載入資料

首先,我們需要載入資料到Deep Lake向量儲存中。這個過程包括將檔案嵌入到高維向量中,以便進行語義搜尋和檢索。

import deep_lake

# 載入資料
data = deep_lake.load_data("drone_technology_data.csv")

# 將檔案嵌入到高維向量中
embedded_data = deep_lake.embed_documents(data)

步驟2:建立索引

接下來,我們需要建立索引以便進行快速檢索。這個過程包括建立一個索引結構,以便於高效地儲存和檢索資料。

import llama_index

# 建立索引結構
index = llama_index.create_index(embedded_data)

# 將索引儲存到Deep Lake中
deep_lake.save_index(index, "drone_technology_index")

步驟3:實作RAG代理

現在,我們可以實作RAG代理了。這個過程包括建立一個代理類別,以便於與使用者進行互動。

import openai

# 建立RAG代理類別
class RAGAgent:
    def __init__(self, index):
        self.index = index

    def respond(self, query):
        # 將查詢嵌入到高維向量中
        embedded_query = deep_lake.embed_query(query)

        # 對查詢進行索引查詢
        results = self.index.search(embedded_query)

        # 將結果傳回給使用者
        return results

# 建立RAG代理例項
agent = RAGAgent(deep_lake.load_index("drone_technology_index"))

# 測試RAG代理
query = "無人機如何使用電腦視覺技術來識別車輛和其他物體?"
response = agent.respond(query)
print(response)

結果

透過上述步驟,我們建立了一個根據索引的語義搜尋引擎和生成式AI代理,該代理可以為無人機技術問題和答案提供快速和準確的結果。該程式展示瞭如何使用Deep Lake向量儲存、LlamaIndex和OpenAI建立根據索引的RAG代理,以便於高效地儲存和檢索資料。

圖表翻譯:

以下是程式架構的Mermaid圖表:

  graph LR
    A[載入資料] --> B[建立索引]
    B --> C[實作RAG代理]
    C --> D[測試RAG代理]

該圖表展示了程式的主要步驟,包括載入資料、建立索引、實作RAG代理和測試RAG代理。

玄貓的技術專欄:打造高效能的檔案處理管線

簡介

在本文中,我們將探討如何建立一個高效能的檔案處理管線,利用 LlamaIndex、Deep Lake 和 OpenAI 等工具,實作檔案的收集、準備、索引和查詢。這個管線將分為三個主要部分:檔案收集和準備、Deep Lake 向量儲存的建立和填充,以及根據索引的 RAG 查詢處理和生成。

環境安裝

首先,我們需要安裝必要的環境和工具。這包括 LlamaIndex、Deep Lake 和 OpenAI 等。以下是安裝命令:

!pip install llama-index-vector-stores-deeplake==0.1.6
!pip install deeplake==3.9.8
!pip install llama-index==0.10.64

接下來,我們需要檢查是否可以正確匯入相關模組:

from llama_index.vector_stores.deeplake import DeepLakeVectorStore

管線 1:檔案收集和準備

在這個部分,我們將收集和準備與無人機技術相關的檔案,並新增必要的後設資料,以便追蹤檔案的來源。首先,我們需要建立一個資料目錄來儲存檔案:

!mkdir data

然後,我們使用 BeautifulSoup 和 requests 等工具從指定的 URL 中收集和清理檔案:

import requests
from bs4 import BeautifulSoup
import re

urls = [
    # 新增相關的 URL
]

def clean_text(content):
    # 移除參考和不需要的字元
    content = re.sub(r'\[\d+\]', '', content)
    content = re.sub(r'[^\w\s\.]', '', content)
    return content

def fetch_and_clean(url):
    try:
        response = requests.get(url)
        response.raise_for_status()
        soup = BeautifulSoup(response.content, 'html.parser')
        content = soup.find('div', {'class': 'mw-parser-output'})
        if content is None:
            return None
        # 移除特定的章節,包括巢狀的章節
        for section_title in ['References', 'Bibliography', 'External links']:
            section = content.find('span', id=section_title)
            while section:
                for sib in section.parent.find_next_siblings():
                    sib.decompose()
        return clean_text(content.get_text())
    except Exception as e:
        print(f"Error fetching {url}: {e}")
        return None

管線 2:Deep Lake 向量儲存的建立和填充

在這個部分,我們將建立和填充 Deep Lake 向量儲存,使用前面準備好的檔案。

管線 3:根據索引的 RAG 查詢處理和生成

在這個部分,我們將實作根據索引的 RAG 查詢處理和生成,使用 LlamaIndex 和 OpenAI 等工具。

內容解密:

以上程式碼使用了 BeautifulSoup 和 requests 等工具從指定的 URL 中收集和清理檔案,並增加了必要的後設資料以便追蹤檔案的來源。然後,使用 LlamaIndex 和 Deep Lake 等工具建立了高效能的檔案處理管線。

圖表翻譯:

以下是 Mermaid 圖表,展示了檔案處理管線的流程:

  flowchart TD
    A[檔案收集] --> B[檔案準備]
    B --> C[Deep Lake 向量儲存]
    C --> D[根據索引的 RAG 查詢處理和生成]

這個圖表展示了檔案處理管線的三個主要部分:檔案收集、檔案準備和 Deep Lake 向量儲存的建立和填充,以及根據索引的 RAG 查詢處理和生成。

文字提取與儲存

為了從網頁中提取文章內容,玄貓設計了一個名為 fetch_and_clean 的函式。這個函式負責傳送 HTTP 請求到指定的 URL,然後使用 BeautifulSoup 這個 Python 函式庫來解析 HTML 內容。接下來,它會從解析後的內容中提取並清理文字。

def fetch_and_clean(url):
    try:
        response = requests.get(url)
        response.raise_for_status()  # Raise an exception for HTTP errors
        content = BeautifulSoup(response.text, 'html.parser')
        
        # 移除不需要的部分
        section.parent.decompose()
        
        # 找到目標段落
        section = content.find('span', id=section_title)
        
        # 提取和清理文字
        text = content.get_text(separator=' ', strip=True)
        text = clean_text(text)
        
        return text
    except requests.exceptions.RequestException as e:
        print(f"Error fetching content from {url}: {e}")
        return None  # 傳回 None 表示發生錯誤

儲存提取的文字

為了儲存每篇文章的內容,玄貓定義了一個目錄 ./data/ 來存放這些檔案。每篇文章都會根據其 URL 的最後部分命名,並以 .txt 為副檔名儲存。

# 定義儲存目錄
output_dir = './data/'
os.makedirs(output_dir, exist_ok=True)

# 處理每個 URL 並將其內容寫入單獨的檔案
for url in urls:
    article_name = url.split('/')[-1].replace('.html', '')
    filename = os.path.join(output_dir, article_name + '.txt')
    
    clean_article_text = fetch_and_clean(url)
    with open(filename, 'w', encoding='utf-8') as file:
        file.write(clean_article_text)
    print(f"Content written to files in the './data/' directory.")

載入檔案

載入儲存的檔案使用 SimpleDirectoryReader 類別,它可以遞迴掃描目錄,識別和載入所有支援的檔案型別(如 .txt.pdf.docx),然後提取每個檔案的內容並傳回包含其文字和後設資料(如檔名和檔案路徑)的檔案物件列表。

# 載入檔案
documents = SimpleDirectoryReader("./data/").load_data()

顯示第一個檔案的內容:

print(documents[0])

這將展示第一個檔案的詳細資訊,包括其文字內容和相關後設資料。

建立和填充 Deep Lake 向量儲存

在這個部分,我們將建立一個 Deep Lake 向量儲存並用我們的檔案資料填充它。為了保證透明度和控制,我們將實作一個標準的張量組態,包括:

  • text(str):文字是檔案中的一個文字檔案的內容。它將是無縫的,且 chunking 將被最佳化,將文字分成有意義的塊。
  • metadata(json):在這種情況下,後設資料將包含每個文字塊的檔名源,以保證完全的透明度和控制。稍後我們將看到如何在程式碼中存取這些資訊。
  • embedding(float32):嵌入是無縫的,使用由玄貓直接呼叫的 OpenAI 嵌入模型。
  • id(str,自動填充):每個塊都會自動分配一個唯一的 ID。向量儲存還將包含一個索引,它是一個從 0 到 n 的數字,但它不能被語義化使用,因為每次我們修改資料集時它都會改變。然而,唯一的 ID 欄位將保持不變,直到我們決定使用根據索引的搜尋策略對其進行最佳化,如我們稍後在 Pipeline 3:根據索引的 RAG 部分中所見。

程式碼實作

# 定義向量儲存和資料集路徑
vector_store_path = "hub://denis76/drone_v2"
dataset_path = "hub://denis76/drone_v2"

# 用您的賬戶名稱和要使用的資料集名稱替換向量儲存和資料集路徑
vector_store_path = "hub://[YOUR VECTOR STORE/ "

# 建立向量儲存並填充資料
vector_store = DeepLakeVectorStore(dataset_path=dataset_path, overwrite=True)

# 建立檔案索引
index = VectorStoreIndex.from_documents(documents, storage_context=StorageContext.from_defaults(vector_store=vector_store))

輸出結果

Your Deep Lake dataset has been successfully created!
Uploading data to deeplake dataset.
100%|██████████| 41/41 [00:02<00:00, 18.15it/s]

資料集結構

Dataset(path='hub://denis76/drone_v2', tensors=['text', 'metadata', 'embedding'])

載入資料集

# 載入資料集到記憶體
dataset = DeepLakeDataset.load(vector_store_path)

內容解密:

上述程式碼建立了一個 Deep Lake 向量儲存,並用檔案資料填充它。向量儲存包含四個張量:textmetadataembeddingidtext 張量儲存檔案的內容,metadata 張量儲存檔名源,embedding 張量儲存使用 OpenAI 嵌入模型生成的嵌入,id 張量儲存每個塊的唯一 ID。向量儲存還包含一個索引,可以用於搜尋和查詢資料。

圖表翻譯:

  graph LR
    A[檔案] -->|填充|> B[向量儲存]
    B -->|建立索引|> C[索引]
    C -->|搜尋和查詢|> D[結果]

上述 Mermaid 圖表展示了建立 Deep Lake 向量儲存和索引的過程。首先,檔案被填充到向量儲存中。然後,向量儲存建立一個索引,可以用於搜尋和查詢資料。最終,搜尋和查詢結果被傳回。

載入與視覺化資料集

首先,我們需要載入資料集。這可以透過 deeplake.load() 函式實作:

import deeplake
ds = deeplake.load(dataset_path)  # 載入資料集

接下來,我們可以使用 Jupyter Notebook 將資料集視覺化。然而,為了更好地展示資料,我們將建立一個函式來顯示資料集的內容。

資料集顯示函式

為了顯示資料集的內容,我們需要建立一個函式。這個函式將迭代資料集中的張量,並將其轉換為 Pandas DataFrame:

import json
import pandas as pd
import numpy as np

def display_dataset(ds):
    data = {}
    for tensor_name in ds.tensors:
        tensor_data = ds[tensor_name].numpy()
        if tensor_data.ndim > 1:
            data[tensor_name] = [np.array(e).flatten().tolist() for e in tensor_data]
        else:
            if tensor_name == "text":
                data[tensor_name] = [t.tobytes().decode('utf-8') if isinstance(t, bytes) else t for t in tensor_data]
            else:
                data[tensor_name] = tensor_data.tolist()
    df = pd.DataFrame(data)
    return df

記錄顯示函式

為了顯示特定記錄的內容,我們需要建立另一個函式。這個函式將根據記錄號碼從 DataFrame 中提取記錄,並以字典的形式傳回:

def display_record(record_number, df):
    record = df.iloc[record_number]
    display_data = {
        "ID": record["id"] if "id" in record else "N/A",
        "Metadata": record["metadata"] if "metadata" in record else "N/A",
        "Text": record["text"] if "text" in record else "N/A",
        "Embedding": record["embedding"] if "embedding" in record else "N/A"
    }
    return display_data

執行與展示

現在,我們可以載入資料集,建立 DataFrame,並選擇一個記錄來顯示其內容:

ds = deeplake.load(dataset_path)
df = display_dataset(ds)
record_number = 0  # 選擇要顯示的記錄號碼
display_data = display_record(record_number, df)
print(display_data)

內容解密:

上述程式碼的作用是載入一個 Deep Lake 資料集,將其轉換為 Pandas DataFrame,然後根據指定的記錄號碼顯示該記錄的內容。這個過程涉及到迭代資料集中的張量,轉換張量為列表,並建立一個 DataFrame。接著,根據記錄號碼從 DataFrame 中提取記錄,並以字典的形式傳回記錄的內容。

圖表翻譯:

  flowchart TD
    A[載入資料集] --> B[建立 DataFrame]
    B --> C[選擇記錄號碼]
    C --> D[顯示記錄內容]

圖表翻譯:

此流程圖描述了載入資料集、建立 DataFrame、選擇記錄號碼以及顯示記錄內容的過程。每個步驟之間的箭頭表示了邏輯上的流程順序。

根據索引的RAG管道

在本文中,我們將使用LlamaIndex實作根據索引的RAG管道,利用Deep Lake準備和處理的資料。透過OpenAI的LLM模型,我們將從異構(含雜訊)的無人機相關檔案集合中檢索相關資訊,並合成回應。

索引引擎

我們將實作四種索引引擎:

  1. 向量儲存索引引擎:從檔案中建立向量儲存索引,實作高效的根據相似性的查詢。
  2. 樹索引:從檔案中構建分層樹索引,提供替代的檢索結構。
  3. 列表索引:從檔案中構建直接的列表索引。
  4. 關鍵字表索引:從檔案中提取關鍵字,建立根據關鍵字的索引。

查詢與回應

我們將實作使用LLM進行查詢:

  1. 查詢回應和源:使用使用者輸入查詢索引,檢索相關檔案,並傳回合成的回應以及源資訊。

評估指標

我們將使用時間加權平均指標與LLM評分和餘弦相似性來評估回應。內容和執行時間可能會因為實作的隨機演算法而在每次執行中有所不同。

使用者輸入和查詢引數

使用者輸入將作為四個索引引擎的參考問題。我們將根據每個索引引擎的檢索結果和評分來評估每個回應,並使用時間和評分比率進行衡量。使用者輸入為:

user_input = "無人機如何識別車輛?"

四個查詢引擎將使用相同的引數無縫地呼叫OpenAI模型。三個引數將被設定:

Mermaid 圖表:RAG管道流程

  graph LR
    A[使用者輸入] --> B[查詢引擎]
    B --> C[向量儲存索引]
    B --> D[樹索引]
    B --> E[列表索引]
    B --> F[關鍵字表索引]
    C --> G[合成回應]
    D --> G
    E --> G
    F --> G
    G --> H[評估指標]

圖表翻譯:

上述Mermaid圖表描述了RAG管道的流程。使用者輸入被送入查詢引擎,然後根據不同的索引引擎(向量儲存索引、樹索引、列表索引和關鍵字表索引)進行檢索。每個索引引擎傳回相關檔案,然後合成回應。最後,根據評估指標(時間加權平均指標與LLM評分和餘弦相似性)對回應進行評估。

內容解密:

上述程式碼和流程描述瞭如何實作根據索引的RAG管道。首先,定義使用者輸入和查詢引數。然後,根據不同的索引引擎進行檢索和合成回應。最後,使用評估指標對回應進行評估。這個流程展示瞭如何使用LlamaIndex和OpenAI模型實作高效的根據相似性的查詢和合成回應。

建立高效的查詢引擎:Cosine 相似度和向量儲存索引

在探索無人機技術的過程中,我們需要一個高效的查詢引擎來從大量檔案中找出最相關的資訊。為了實作這一目標,我們將使用 Cosine 相似度作為評估檔案之間相似性的指標,並建立一個向量儲存索引(Vector Store Index)來加速查詢過程。

從技術架構視角來看,利用 LlamaIndex、Deep Lake 和 OpenAI 構築的檔案處理管線,展現了高度整合性和可擴充套件性。透過 Deep Lake 向量儲存,結合 OpenAI 的嵌入模型,實作了語義化的檔案檢索。根據索引的 RAG 管線,特別是向量儲存索引和樹狀索引的應用,有效提升了查詢效率和回應速度。然而,目前系統的評估指標仍侷限於時間加權平均、LLM 評分和餘弦相似度,未來可考慮引入更多維度的指標,例如:查詢結果的準確性、多樣性和可解釋性,以更全面地評估系統效能。此外,針對不同型別的查詢需求,動態調整索引策略和查詢引數,將是進一步最佳化效能的關鍵。玄貓認為,此架構展現了根據語義搜尋的 RAG 系統的發展潛力,隨著技術的持續演進,預期將在知識管理和資訊檢索領域扮演更重要的角色。