智慧體課程文件

LlamaIndex 中的元件是什麼?

Hugging Face's logo
加入 Hugging Face 社群

並獲得增強的文件體驗

開始使用

LlamaIndex 中的元件是什麼?

還記得 Alfred 嗎?我們第一單元中樂於助人的管家代理。為了有效地幫助我們,Alfred 需要理解我們的請求並準備、查詢和使用相關資訊來幫助完成任務。這就是 LlamaIndex 元件的作用。

雖然 LlamaIndex 有許多元件,但我們將特別關注 QueryEngine 元件。為什麼?因為它可以作為代理的檢索增強生成 (RAG) 工具。

那麼,什麼是 RAG 呢?LLM 經過大量資料訓練以學習通用知識。然而,它們可能沒有經過相關和最新資料的訓練。RAG 透過從您的資料中查詢和檢索相關資訊並將其提供給 LLM 來解決此問題。

RAG

現在,想想 Alfred 是如何工作的

  1. 你讓 Alfred 幫助計劃一個晚宴
  2. Alfred 需要檢查你的日曆、飲食偏好和過去成功的選單
  3. QueryEngine 幫助 Alfred 找到這些資訊並用它來計劃晚宴

這使得 QueryEngine 成為在 LlamaIndex 中構建代理 RAG 工作流的關鍵元件。正如 Alfred 需要搜尋你的家庭資訊才能提供幫助一樣,任何代理都需要一種方式來查詢和理解相關資料。QueryEngine 正好提供了這種能力。

現在,讓我們深入瞭解一下這些元件,看看如何組合元件來建立 RAG 管道。

使用元件建立 RAG 管道

您可以按照此筆記本中的程式碼,您可以使用 Google Colab 執行它。

RAG 中有五個關鍵階段,這些階段反過來將成為您構建的大多數大型應用程式的一部分。它們是:

  1. 載入:指將資料從其所在位置(無論是文字檔案、PDF、其他網站、資料庫還是 API)匯入到您的工作流中。LlamaHub 提供了數百種整合供您選擇。
  2. 索引:指建立允許查詢資料的資料結構。對於 LLM,這幾乎總是意味著建立向量嵌入。這些是資料含義的數值表示。索引還可以指其他各種元資料策略,以便輕鬆準確地根據屬性查詢上下文相關資料。
  3. 儲存:資料索引後,您需要儲存索引以及其他元資料,以避免重新索引。
  4. 查詢:對於任何給定的索引策略,您可以透過多種方式利用 LLM 和 LlamaIndex 資料結構進行查詢,包括子查詢、多步查詢和混合策略。
  5. 評估:任何流程中一個關鍵步驟是檢查其相對於其他策略或在您進行更改時的有效性。評估提供了關於您的查詢響應的準確性、忠實性和速度的客觀衡量標準。

接下來,讓我們看看如何使用元件重現這些階段。

載入和嵌入文件

如前所述,LlamaIndex 可以在您的資料之上工作,但是,在訪問資料之前,我們需要載入它。將資料載入到 LlamaIndex 中有三種主要方式:

  1. SimpleDirectoryReader:一個內建載入器,用於從本地目錄載入各種檔案型別。
  2. LlamaParse:LlamaIndex 官方的 PDF 解析工具,可作為託管 API 使用。
  3. LlamaHub:一個包含數百個資料載入庫的登錄檔,用於從任何源攝取資料。
熟悉LlamaHub 載入器和LlamaParse 解析器以處理更復雜的資料來源。

載入資料的最簡單方法是使用 SimpleDirectoryReader這個多功能元件可以從資料夾載入各種檔案型別,並將它們轉換為 LlamaIndex 可以使用的 Document 物件。讓我們看看如何使用 SimpleDirectoryReader 從資料夾載入資料。

from llama_index.core import SimpleDirectoryReader

reader = SimpleDirectoryReader(input_dir="path/to/directory")
documents = reader.load_data()

載入文件後,我們需要將它們分解成更小的部分,稱為 Node 物件。Node 只是原始文件中的一段文字,AI 更容易處理,同時它仍然引用原始的 Document 物件。

IngestionPipeline 透過兩個關鍵轉換幫助我們建立這些節點。

  1. SentenceSplitter 透過在自然句子邊界處分割文件,將文件分解成可管理的小塊。
  2. HuggingFaceEmbedding 將每個小塊轉換為數值嵌入——捕捉語義含義的向量表示,AI 可以高效地處理。

這個過程幫助我們以一種更有利於搜尋和分析的方式組織文件。

from llama_index.core import Document
from llama_index.embeddings.huggingface import HuggingFaceEmbedding
from llama_index.core.node_parser import SentenceSplitter
from llama_index.core.ingestion import IngestionPipeline

# create the pipeline with transformations
pipeline = IngestionPipeline(
    transformations=[
        SentenceSplitter(chunk_overlap=0),
        HuggingFaceEmbedding(model_name="BAAI/bge-small-en-v1.5"),
    ]
)

nodes = await pipeline.arun(documents=[Document.example()])

儲存和索引文件

建立 Node 物件後,我們需要對其進行索引以使其可搜尋,但在此之前,我們需要一個地方來儲存資料。

由於我們正在使用攝取管道,我們可以直接將向量儲存附加到管道以填充它。在這種情況下,我們將使用 Chroma 來儲存我們的文件。

安裝 ChromaDB

LlamaHub 部分中所介紹的,我們可以使用以下命令安裝 ChromaDB 向量儲存

pip install llama-index-vector-stores-chroma
import chromadb
from llama_index.vector_stores.chroma import ChromaVectorStore

db = chromadb.PersistentClient(path="./alfred_chroma_db")
chroma_collection = db.get_or_create_collection("alfred")
vector_store = ChromaVectorStore(chroma_collection=chroma_collection)

pipeline = IngestionPipeline(
    transformations=[
        SentenceSplitter(chunk_size=25, chunk_overlap=0),
        HuggingFaceEmbedding(model_name="BAAI/bge-small-en-v1.5"),
    ],
    vector_store=vector_store,
)
有關不同向量儲存的概述,請參見 LlamaIndex 文件

這就是向量嵌入發揮作用的地方——透過將查詢和節點嵌入到相同的向量空間中,我們可以找到相關的匹配。VectorStoreIndex 為我們處理這個問題,使用與我們攝取時相同的嵌入模型,以確保一致性。

讓我們看看如何從我們的向量儲存和嵌入建立這個索引

from llama_index.core import VectorStoreIndex
from llama_index.embeddings.huggingface import HuggingFaceEmbedding

embed_model = HuggingFaceEmbedding(model_name="BAAI/bge-small-en-v1.5")
index = VectorStoreIndex.from_vector_store(vector_store, embed_model=embed_model)

所有資訊都自動持久化在 ChromaVectorStore 物件和傳入的目錄路徑中。

太棒了!現在我們可以輕鬆儲存和載入索引,讓我們探索如何以不同的方式查詢它。

使用提示和 LLM 查詢 VectorStoreIndex

在查詢索引之前,我們需要將其轉換為查詢介面。最常見的轉換選項是:

  • as_retriever:用於基本文件檢索,返回一個帶有相似性分數的 NodeWithScore 物件列表
  • as_query_engine:用於單問答互動,返回書面響應
  • as_chat_engine:用於對話式互動,可維護多個訊息之間的記憶,使用聊天曆史和索引上下文返回書面響應

我們將重點關注查詢引擎,因為它更常用於代理式互動。我們還將一個 LLM 傳遞給查詢引擎,用於生成響應。

from llama_index.llms.huggingface_api import HuggingFaceInferenceAPI

llm = HuggingFaceInferenceAPI(model_name="Qwen/Qwen2.5-Coder-32B-Instruct")
query_engine = index.as_query_engine(
    llm=llm,
    response_mode="tree_summarize",
)
query_engine.query("What is the meaning of life?")
# The meaning of life is 42

響應處理

在底層,查詢引擎不僅使用 LLM 回答問題,還使用 ResponseSynthesizer 作為處理響應的策略。同樣,這是完全可定製的,但有三種開箱即用的主要策略效果很好:

  • refine:透過依次遍歷每個檢索到的文字塊來建立和最佳化答案。這會為每個節點/檢索到的塊進行單獨的 LLM 呼叫。
  • compact(預設):類似於精煉,但在之前連線塊,從而減少 LLM 呼叫。
  • tree_summarize:透過遍歷每個檢索到的文字塊並建立答案的樹形結構來建立詳細答案。
使用低階組合 API 精細控制您的查詢工作流。此 API 允許您自定義和微調查詢過程的每個步驟,以滿足您的精確需求,這也與工作流完美搭配。

語言模型的表現並非總能預測,因此我們無法確定所得到的答案始終正確。我們可以透過評估答案質量來解決這個問題。

評估和可觀測性

LlamaIndex 提供了內建評估工具來評估響應質量。這些評估器利用 LLM 從不同維度分析響應。讓我們看看可用的三種主要評估器:

  • FaithfulnessEvaluator:透過檢查答案是否由上下文支援來評估答案的忠實性。
  • AnswerRelevancyEvaluator:透過檢查答案是否與問題相關來評估答案的相關性。
  • CorrectnessEvaluator:透過檢查答案是否正確來評估答案的正確性。
想要了解更多關於代理可觀測性和評估的資訊?繼續您的旅程,前往獎勵單元 2
from llama_index.core.evaluation import FaithfulnessEvaluator

query_engine = # from the previous section
llm = # from the previous section

# query index
evaluator = FaithfulnessEvaluator(llm=llm)
response = query_engine.query(
    "What battles took place in New York City in the American Revolution?"
)
eval_result = evaluator.evaluate_response(response=response)
eval_result.passing

即使沒有直接評估,我們也可以透過可觀測性深入瞭解系統性能。這在構建更復雜的工作流時特別有用,可以幫助我們瞭解每個元件的效能。

安裝 LlamaTrace

正如LlamaHub 部分所介紹的,我們可以使用以下命令從 Arize Phoenix 安裝 LlamaTrace 回撥:

pip install -U llama-index-callbacks-arize-phoenix

此外,我們需要將 PHOENIX_API_KEY 環境變數設定為我們的 LlamaTrace API 金鑰。我們可以透過以下方式獲取:

  • LlamaTrace上建立一個賬戶
  • 在您的賬戶設定中生成一個 API 金鑰
  • 在下面的程式碼中使用 API 金鑰啟用跟蹤
import llama_index
import os

PHOENIX_API_KEY = "<PHOENIX_API_KEY>"
os.environ["OTEL_EXPORTER_OTLP_HEADERS"] = f"api_key={PHOENIX_API_KEY}"
llama_index.core.set_global_handler(
    "arize_phoenix",
    endpoint="https://llamatrace.com/v1/traces"
)
想了解更多關於元件及其用法?繼續您的旅程,閱讀元件指南RAG 指南

我們已經瞭解瞭如何使用元件來建立 QueryEngine。現在,讓我們看看如何QueryEngine 用作代理的工具!

< > 在 GitHub 上更新

© . This site is unofficial and not affiliated with Hugging Face, Inc.