使用 Milvus 和 LlamaIndex 的檢索增強世代 (RAG)

Open In Colab GitHub Repository

本指南展示了如何使用 LlamaIndex 和 Milvus 建立一個檢索-增強生成 (RAG) 系統。

RAG 系統結合了檢索系統與生成模型,可根據給定的提示生成新的文字。該系統首先使用 Milvus 從語料庫中檢索相關文件,然後根據檢索到的文件使用生成模型生成新文本。

LlamaIndex是一個簡單、靈活的資料框架,可將自訂資料來源連接至大型語言模型 (LLM)。Milvus是世界上最先進的開放原始碼向量資料庫,是為了強化嵌入式相似性搜尋與 AI 應用程式而建立的。

在本筆記簿中,我們將展示使用 MilvusVectorStore 的快速示範。

開始之前

安裝相依性

本頁面的程式碼片段需要 pymilvus 和 llamaindex 的相依性。您可以使用下列指令安裝它們:

$ pip install pymilvus>=2.4.2 milvus-lite
$ pip install llama-index-vector-stores-milvus
$ pip install llama-index

如果您使用 Google Colab,為了啟用剛安裝的相依性,您可能需要重新啟動執行時間。(按一下螢幕上方的「Runtime」功能表,然後從下拉式功能表中選擇「Restart session」)。

設定 OpenAI

讓我們先加入 openai api 金鑰。這將允許我們存取 chatgpt。

import openai

openai.api_key = "sk-***********"

準備資料

您可以使用下列指令下載範例資料:

! mkdir -p 'data/'
! wget 'https://raw.githubusercontent.com/run-llama/llama_index/main/docs/docs/examples/data/paul_graham/paul_graham_essay.txt' -O 'data/paul_graham_essay.txt'
! wget 'https://raw.githubusercontent.com/run-llama/llama_index/main/docs/docs/examples/data/10k/uber_2021.pdf' -O 'data/uber_2021.pdf'

開始

產生我們的資料

作為第一個範例,讓我們從檔案paul_graham_essay.txt 產生一個文件。這是一篇來自 Paul Graham 的單篇文章,標題是What I Worked On 。我們將使用 SimpleDirectoryReader 來產生文件。

from llama_index.core import SimpleDirectoryReader

# load documents
documents = SimpleDirectoryReader(
    input_files=["./data/paul_graham_essay.txt"]
).load_data()

print("Document ID:", documents[0].doc_id)
Document ID: 95f25e4d-f270-4650-87ce-006d69d82033

在資料中建立索引

現在我們有一個文件,我們可以建立一個索引並插入該文件。對於索引,我們將使用 MilvusVectorStore。MilvusVectorStore 需要幾個參數:

基本參數

  • uri (str, optional):要連線到的 URI,對於 Milvus 或 Zilliz 雲端服務,其形式為「https://address:port」;對於精簡本端 Milvus,則為「path/to/local/milvus.db」。預設為"./milvus_llamaindex.db"。
  • token (str, optional):登入的代碼。如果未使用 rbac,則為空,如果使用 rbac,則很可能是 "username:password"。
  • collection_name (str, optional):儲存資料的集合名稱。預設為 "llamalection"。
  • overwrite (bool, optional):是否以相同名稱覆寫現有的集合。預設為 False。

標量欄位包括 doc id & text

  • doc_id_field (str, optional):集合的 doc_id 欄位名稱。預設為 DEFAULT_DOC_ID_KEY。
  • text_key (str, optional):在傳送的集合中儲存什麼關鍵文字。當帶入您自己的 collection 時使用。預設為 DEFAULT_TEXT_KEY。
  • scalar_field_names (list, optional):要包含在集合模式中的額外標量欄位名稱。
  • scalar_field_types (list, optional):額外標量欄位的類型。

密集欄位

  • enable_dense (bool):啟用或停用密集嵌入的布林標誌。預設為 True。
  • dim (int, optional):集合的嵌入向量的維度。必須在 enable_sparse 為 False 時建立新的集合。
  • embedding_field (str, optional):集合的密集嵌入欄位名稱,預設為 DEFAULT_EMBEDDING_KEY。
  • index_config (dict, optional):用來建立密集嵌入索引的設定。預設為 None。
  • search_config (dict, optional):用來搜尋 Milvus 密集索引的設定。請注意,這必須與index_config 指定的索引類型相容。預設為 None。
  • similarity_metric (str, optional):用於密集嵌入的相似度指標,目前支援 IP、COSINE 和 L2。

稀疏欄位

  • enable_sparse (bool):啟用或停用 sparse embedding 的布林標記。預設為 False。
  • sparse_embedding_field (str):sparse embedding 欄位的名稱,預設為 DEFAULT_SPARSE_EMBEDDING_KEY。
  • sparse_embedding_function (Union[BaseSparseEmbeddingFunction, BaseMilvusBuiltInFunction], optional):如果 enable_sparse 為 True,則應該提供此物件來轉換文字為稀疏嵌入。若為 None,則採用預設的稀疏嵌入函數 (BGEM3SparseEmbeddingFunction)。
  • sparse_index_config (dict, optional):用來建立稀疏嵌入索引的設定。預設為 None。

混合排序器

  • hybrid_ranker (str):指定混合搜尋查詢使用的排名器類型。目前只支援 ["RRFRanker", "WeightedRanker"]。預設為 "RRFRanker"。

  • hybrid_ranker_params (dict, optional):混合排名器的設定參數。此字典的結構取決於所使用的特定排名器:

    • 對於 "RRFRanker",它應該包括
      • "k" (int):Reciprocal Rank Fusion (RRF) 中使用的參數。此值用於計算排名分數,作為 RRF 演算法的一部分,RRF 演算法會將多種排名策略合併為單一分數,以改善搜尋相關性。
    • 對於 "WeightedRanker",它期望:
      • 「權重」(浮點數清單):一個正好包含兩個權重的清單:
        1. 密集嵌入元件的權重。
        2. sparse embedding 元件的權重。 這些權重是用來調整混合檢索過程中 embeddings 的 dense 和 sparse 元件的重要性。 預設為空字典,表示 ranker 將以其預先定義的預設值運作。

其他

  • collection_properties (dict, optional):集合屬性,例如 TTL(Time-To-Live)和 MMAP(記憶體映射)。預設為無。它可以包括
    • "collection.ttl.seconds"(int):設定此屬性後,目前集合中的資料會在指定時間內過期。資料集中過期的資料將會被清理,並且不會參與搜尋或查詢。
    • "mmap.enabled" (bool):是否在集合層級啟用記憶體映射儲存。
  • index_management (IndexManagement):指定要使用的索引管理策略。預設為 "create_if_not_exists"。
  • batch_size (int):當插入資料到 Milvus 時,設定在一個批次中處理的文件數量。預設為 DEFAULT_BATCH_SIZE。
  • consistency_level (str, optional):對於新建立的集合使用哪個一致性層級。預設為 "Session"。
# Create an index over the documents
from llama_index.core import VectorStoreIndex, StorageContext
from llama_index.vector_stores.milvus import MilvusVectorStore


vector_store = MilvusVectorStore(uri="./milvus_demo.db", dim=1536, overwrite=True)
storage_context = StorageContext.from_defaults(vector_store=vector_store)
index = VectorStoreIndex.from_documents(documents, storage_context=storage_context)

對於MilvusVectorStore 的參數:

  • uri 設定為本機檔案,例如./milvus.db ,是最方便的方法,因為它會自動利用Milvus Lite將所有資料儲存在這個檔案中。
  • 如果您有大規模的資料,您可以在docker 或 kubernetes 上架設效能更高的 Milvus 伺服器。在此設定中,請使用伺服器的 uri,例如http://localhost:19530 ,作為您的uri
  • 如果您想使用Zilliz Cloud,Milvus 的完全管理雲端服務,請調整uritoken ,對應 Zilliz Cloud 的Public Endpoint 和 Api key

查詢資料

現在我們的文件已儲存在索引中,我們可以針對索引提出問題。索引會使用本身儲存的資料作為 chatgpt 的知識庫。

query_engine = index.as_query_engine()
res = query_engine.query("What did the author learn?")
print(res)
The author learned that philosophy courses in college were boring to him, leading him to switch his focus to studying AI.
res = query_engine.query("What challenges did the disease pose for the author?")
print(res)
The disease posed challenges for the author as it affected his mother's health, leading to a stroke caused by colon cancer. This resulted in her losing her balance and needing to be placed in a nursing home. The author and his sister were determined to help their mother get out of the nursing home and back to her house.

下一個測試顯示覆寫會移除先前的資料。

from llama_index.core import Document


vector_store = MilvusVectorStore(uri="./milvus_demo.db", dim=1536, overwrite=True)
storage_context = StorageContext.from_defaults(vector_store=vector_store)
index = VectorStoreIndex.from_documents(
    [Document(text="The number that is being searched for is ten.")],
    storage_context,
)
query_engine = index.as_query_engine()
res = query_engine.query("Who is the author?")
print(res)
The author is the individual who created the context information.

下一個測試顯示在已存在的索引中加入額外的資料。

del index, vector_store, storage_context, query_engine

vector_store = MilvusVectorStore(uri="./milvus_demo.db", overwrite=False)
storage_context = StorageContext.from_defaults(vector_store=vector_store)
index = VectorStoreIndex.from_documents(documents, storage_context=storage_context)
query_engine = index.as_query_engine()
res = query_engine.query("What is the number?")
print(res)
The number is ten.
res = query_engine.query("Who is the author?")
print(res)
Paul Graham

元資料篩選

我們可以透過篩選特定來源來產生結果。以下範例說明從目錄載入所有文件,並隨後根據元資料過濾這些文件。

from llama_index.core.vector_stores import ExactMatchFilter, MetadataFilters

# Load all the two documents loaded before
documents_all = SimpleDirectoryReader("./data/").load_data()

vector_store = MilvusVectorStore(uri="./milvus_demo.db", dim=1536, overwrite=True)
storage_context = StorageContext.from_defaults(vector_store=vector_store)
index = VectorStoreIndex.from_documents(documents_all, storage_context)

我們只想擷取檔案uber_2021.pdf 中的文件。

filters = MetadataFilters(
    filters=[ExactMatchFilter(key="file_name", value="uber_2021.pdf")]
)
query_engine = index.as_query_engine(filters=filters)
res = query_engine.query("What challenges did the disease pose for the author?")

print(res)
The disease posed challenges related to the adverse impact on the business and operations, including reduced demand for Mobility offerings globally, affecting travel behavior and demand. Additionally, the pandemic led to driver supply constraints, impacted by concerns regarding COVID-19, with uncertainties about when supply levels would return to normal. The rise of the Omicron variant further affected travel, resulting in advisories and restrictions that could adversely impact both driver supply and consumer demand for Mobility offerings.

當從檔案paul_graham_essay.txt 擷取時,我們會得到不同的結果。

filters = MetadataFilters(
    filters=[ExactMatchFilter(key="file_name", value="paul_graham_essay.txt")]
)
query_engine = index.as_query_engine(filters=filters)
res = query_engine.query("What challenges did the disease pose for the author?")

print(res)
The disease posed challenges for the author as it affected his mother's health, leading to a stroke caused by colon cancer. This resulted in his mother losing her balance and needing to be placed in a nursing home. The author and his sister were determined to help their mother get out of the nursing home and back to her house.

免費嘗試托管的 Milvus

Zilliz Cloud 無縫接入,由 Milvus 提供動力,速度提升 10 倍。

開始使用
反饋

這個頁面有幫助嗎?