智慧體課程文件
LlamaIndex 中的元件是什麼?
並獲得增強的文件體驗
開始使用
LlamaIndex 中的元件是什麼?
還記得 Alfred 嗎?我們第一單元中樂於助人的管家代理。為了有效地幫助我們,Alfred 需要理解我們的請求並準備、查詢和使用相關資訊來幫助完成任務。這就是 LlamaIndex 元件的作用。
雖然 LlamaIndex 有許多元件,但我們將特別關注 QueryEngine
元件。為什麼?因為它可以作為代理的檢索增強生成 (RAG) 工具。
那麼,什麼是 RAG 呢?LLM 經過大量資料訓練以學習通用知識。然而,它們可能沒有經過相關和最新資料的訓練。RAG 透過從您的資料中查詢和檢索相關資訊並將其提供給 LLM 來解決此問題。
現在,想想 Alfred 是如何工作的
- 你讓 Alfred 幫助計劃一個晚宴
- Alfred 需要檢查你的日曆、飲食偏好和過去成功的選單
QueryEngine
幫助 Alfred 找到這些資訊並用它來計劃晚宴
這使得 QueryEngine
成為在 LlamaIndex 中構建代理 RAG 工作流的關鍵元件。正如 Alfred 需要搜尋你的家庭資訊才能提供幫助一樣,任何代理都需要一種方式來查詢和理解相關資料。QueryEngine
正好提供了這種能力。
現在,讓我們深入瞭解一下這些元件,看看如何組合元件來建立 RAG 管道。
使用元件建立 RAG 管道
RAG 中有五個關鍵階段,這些階段反過來將成為您構建的大多數大型應用程式的一部分。它們是:
- 載入:指將資料從其所在位置(無論是文字檔案、PDF、其他網站、資料庫還是 API)匯入到您的工作流中。LlamaHub 提供了數百種整合供您選擇。
- 索引:指建立允許查詢資料的資料結構。對於 LLM,這幾乎總是意味著建立向量嵌入。這些是資料含義的數值表示。索引還可以指其他各種元資料策略,以便輕鬆準確地根據屬性查詢上下文相關資料。
- 儲存:資料索引後,您需要儲存索引以及其他元資料,以避免重新索引。
- 查詢:對於任何給定的索引策略,您可以透過多種方式利用 LLM 和 LlamaIndex 資料結構進行查詢,包括子查詢、多步查詢和混合策略。
- 評估:任何流程中一個關鍵步驟是檢查其相對於其他策略或在您進行更改時的有效性。評估提供了關於您的查詢響應的準確性、忠實性和速度的客觀衡量標準。
接下來,讓我們看看如何使用元件重現這些階段。
載入和嵌入文件
如前所述,LlamaIndex 可以在您的資料之上工作,但是,在訪問資料之前,我們需要載入它。將資料載入到 LlamaIndex 中有三種主要方式:
SimpleDirectoryReader
:一個內建載入器,用於從本地目錄載入各種檔案型別。LlamaParse
:LlamaIndex 官方的 PDF 解析工具,可作為託管 API 使用。LlamaHub
:一個包含數百個資料載入庫的登錄檔,用於從任何源攝取資料。
載入資料的最簡單方法是使用 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
透過兩個關鍵轉換幫助我們建立這些節點。
SentenceSplitter
透過在自然句子邊界處分割文件,將文件分解成可管理的小塊。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,
)
這就是向量嵌入發揮作用的地方——透過將查詢和節點嵌入到相同的向量空間中,我們可以找到相關的匹配。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
:透過遍歷每個檢索到的文字塊並建立答案的樹形結構來建立詳細答案。
語言模型的表現並非總能預測,因此我們無法確定所得到的答案始終正確。我們可以透過評估答案質量來解決這個問題。
評估和可觀測性
LlamaIndex 提供了內建評估工具來評估響應質量。這些評估器利用 LLM 從不同維度分析響應。讓我們看看可用的三種主要評估器:
FaithfulnessEvaluator
:透過檢查答案是否由上下文支援來評估答案的忠實性。AnswerRelevancyEvaluator
:透過檢查答案是否與問題相關來評估答案的相關性。CorrectnessEvaluator
:透過檢查答案是否正確來評估答案的正確性。
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"
)
我們已經瞭解瞭如何使用元件來建立 QueryEngine
。現在,讓我們看看如何將 QueryEngine
用作代理的工具!