什麼是 RAG?#
我們檢索豆包得到以下回答:
在自然語言處理領域,語言模型通常是在大規模的文本語料上進行訓練,以學習語言的模式和語義信息。然而,這些模型存在知識更新不及時、生成內容可能包含錯誤信息(如幻覺現象)等問題。RAG 技術的出現就是為了解決這些問題。
它將信息檢索和文本生成相結合。簡單來說,在生成回答之前,先從外部知識庫(如文檔數據庫、知識圖譜等)中檢索相關的信息,然後利用這些檢索到的信息來輔助語言模型生成更準確、更有針對性的回答。就像是在回答問題時,先去查閱相關的書籍資料,然後根據查到的內容來組織一個更好的回答。
工作流程:
- 檢索階段
當接收到一個用戶的問題(例如,在問答系統中),系統會使用某種檢索機制(如向量空間模型、倒排索引等)在知識庫中查找與問題相關的文本片段。例如,如果問題是 “如何治療感冒?”,系統會在醫學知識庫中檢索包含 “感冒治療方法” 相關內容的文檔段落。
這些檢索到的文本片段可以是完整的句子、段落,甚至是多個文檔的部分內容,它們被作為生成回答的參考信息。 - 生成階段
將檢索到的信息和原始問題一起輸入到語言生成模型中(如 Transformer 架構的生成式語言模型)。語言模型會根據這些輸入,結合自身學到的語言知識,生成最終的回答。例如,語言模型會對檢索到的感冒治療方法相關的文本進行分析、整合,生成諸如 “感冒可以通過多喝水、休息和服用適當的藥物來治療” 這樣的回答。
構建索引#
# 從指定文件讀取,輸入為List
from llama_index.core import SimpleDirectoryReader,Document
documents = SimpleDirectoryReader(input_files=['../docs/問答手冊.txt']).load_data()
# 構建節點
from llama_index.core.node_parser import SentenceSplitter
transformations = [SentenceSplitter(chunk_size = 512)]
from llama_index.core.ingestion.pipeline import run_transformations
nodes = run_transformations(documents, transformations=transformations)
# 構建索引
from llama_index.vector_stores.faiss import FaissVectorStore
import faiss
from llama_index.core import StorageContext, VectorStoreIndex
emb = embedding.get_text_embedding("你好呀呀")
vector_store = FaissVectorStore(faiss_index=faiss.IndexFlatL2(len(emb)))
storage_context = StorageContext.from_defaults(vector_store=vector_store)
index = VectorStoreIndex(
nodes = nodes,
storage_context=storage_context,
embed_model = embedding,
)
程式碼詳解:這個程式碼的目的是將文本數據轉化為向量表示,並構建一個可以用於快速檢索的向量索引。通過這種方式,可以實現高效的文本搜索和相似性匹配。
- 使用 SimpleDirectoryReader 從指定路徑 docs\ 問答手冊.txt 中讀取數據。load_data () 方法將文件內容加載為 Document 對象的列表。
- 使用 SentenceSplitter 將文本分割成更小的塊,每個塊的大小為 512 個字符。transformations 是一個包含分割規則的列表。
- run_transformations 函數應用之前定義的 transformations,將 documents 轉換為 nodes,這些節點將用於構建索引。
- 使用 FaissVectorStore 和 faiss 庫創建一個向量存儲。IndexFlatL2 是一種基於 L2 距離的索引。
StorageContext 用於管理存儲上下文,from_defaults 方法使用默認設置創建上下文。
VectorStoreIndex 使用節點、存儲上下文和嵌入模型構建索引。
構建問答引擎#
# 構建檢索器
from llama_index.core.retrievers import VectorIndexRetriever
# 想要自定義參數,可以構造參數字典
kwargs = {'similarity_top_k': 5, 'index': index, 'dimensions': len(emb)} # 必要參數
retriever = VectorIndexRetriever(**kwargs)
# 構建合成器
from llama_index.core.response_synthesizers import get_response_synthesizer
response_synthesizer = get_response_synthesizer(llm=llm, streaming=True)
# 構建問答引擎
from llama_index.core.query_engine import RetrieverQueryEngine
engine = RetrieverQueryEngine(
retriever=retriever,
response_synthesizer=response_synthesizer,
)
程式碼詳解:這個程式碼片段的主要功能是構建一個問答系統,利用向量檢索器和響應合成器來處理和生成對話響應。
- 導入模塊:
- 從 llama_index 庫中導入 VectorIndexRetriever 類,用於創建向量索引檢索器。
- 構造參數字典:
kwargs = {'similarity_top_k': 5, 'index': index, 'dimensions': len (emb)}:創建一個字典 kwargs,用於存儲檢索器的參數。
similarity_top_k: 設置為 5,表示在檢索時返回最相似的 5 個結果。
index: 使用之前構建的 index 對象。
dimensions: 設置為 len (emb),表示嵌入向量的維度。
創建檢索器:
retriever = VectorIndexRetriever (**kwargs):使用參數字典 kwargs 創建一個 VectorIndexRetriever 對象 retriever,用於執行向量檢索。
- 從 llama_index 庫中導入 get_response_synthesizer 函數,用於獲取響應合成器。
創建合成器:調用 get_response_synthesizer 函數,傳入參數 llm(語言模型)和 streaming=True,創建一個響應合成器 response_synthesizer,用於生成對話響應。 - 導入模塊:從 llama_index 庫中導入 RetrieverQueryEngine 類,用於創建問答引擎。
創建問答引擎:
使用之前創建的 retriever 和 response_synthesizer 對象,創建一個 RetrieverQueryEngine 對象 engine,用於處理問答查詢。
測試結果#
# 提問
question = "What are the applications of Agent AI systems ?"
response = engine.query(question)
for text in response.response_gen:
print(text, end="")