RAG(檢索增強生成)的核心是通過外部知識庫增強大模型回答的準確性和針對性,其工作流程與優化策略如下:
一、RAG 核心流程
?知識庫構建?
?文檔加載與分割?:將非結構化文檔(PDF、Markdown等)按語義拆分為合理長度的段落或句子,避免信息碎片化或冗余?。
?向量化與存儲?:使用嵌入模型(如Embedding)將文本轉換為向量,存入向量數據庫(如FAISS、Chroma),加速相似度檢索?。
?用戶查詢處理?
?查詢向量化?:將用戶問題轉換為向量,通過相似度檢索匹配知識庫中相關段落(如Top-K個結果)
?上下文增強?:將檢索到的段落與原始查詢拼接,形成包含背景知識的提示詞輸入大模型?。
?答案生成?
大模型基于增強后的提示詞生成答案,顯著提升專業性和準確性,尤其適用于訓練數據未覆蓋的場景(如時效性知識、私有化數據)。
從chormdb 和 embedding 入手
from langchain_huggingface import HuggingFaceEmbeddings
from langchain_core.documents import Document
from langchain_chroma import Chroma
import uuid# 加載embedding 模型
en_embedding_name = "E:\models\model\qwens-embedding"embed_model = HuggingFaceEmbeddings(model_name=en_embedding_name
)# 初始化chromdb 數據庫chrom_db = Chroma(embedding_function=embed_model,collection_name="test01",persist_directory="./test_chromadb")texts = ["我愛吃西瓜","我不愛吃榴蓮","李文喜歡和奶茶","我愛睡覺"]
# 數據準備組件document
documents = [Document(page_content=text,metadata={'source':"健康檔案"}) for text in texts ]
chrom_db.add_documents(documents=documents, # 文檔的文本數據ids=[str(uuid.uuid4()) for i in range(len(documents))]) # 文檔的唯一標識符 自動生成uuid,128位print(chrom_db.similarity_search('我愛吃什么',k=1))
langchain vectorstore 的使用
# 將向量存儲轉換為檢索器
retriever = chrom_db .as_retriever()
vectorstores =chrom_db.as_retriever(search_kwargs={"k":1})
print(vectorstores.invoke("我愛吃什么?"))
混合檢索
向量索引和關鍵詞索引
from dotenv import load_dotenv
from langchain.retrievers.document_compressors import DocumentCompressorPipeline, LLMChainExtractor
from langchain_openai import ChatOpenAI
from langchain_community.embeddings import DashScopeEmbeddings
from langchain_community.vectorstores.chroma import Chroma
from langchain_community.document_loaders import PyPDFLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.retrievers.document_compressors import DocumentCompressorPipeline# 加載環境變量
load_dotenv()# 初始化大模型
langchainModel = ChatOpenAI(model="qwen-plus",api_key=os.getenv("DASHSCOPE_API_KEY"),base_url="https://dashscope.aliyuncs.com/compatible-mode/v1"
)# 加載并切分文檔
pdfLoader = PyPDFLoader(r"../LangChain/異地測試安排 20230424.pdf")
documents = pdfLoader.load()
testSplit = RecursiveCharacterTextSplitter(chunk_size=200, chunk_overlap=30)
split_documents = testSplit.split_documents(documents)# 初始化嵌入模型并創建向量數據庫
embeddings = DashScopeEmbeddings(model="text-embedding-v3",dashscope_api_key=os.getenv("DASHSCOPE_API_KEY")
)
retriever = Chroma.from_documents(split_documents, embeddings).as_retriever(search_kwargs={"k": 2})## 常見關鍵詞索引器
from langchain_community.retrievers import BM25RetrieverBM25_retriever = BM25Retriever.from_documents(split_documents)
BM25_retriever.k = 2# 創建混合索引器
from langchain.retrievers import EnsembleRetriever, ContextualCompressionRetrieverensemble_retriever = EnsembleRetriever(retrievers=[retriever, BM25_retriever], weights=[0.5, 0.5])
rag chain
etrievalQAEnsemble = RetrievalQA.from_chain_type(llm=langchainModel,chain_type="stuff",retriever=ensemble_retriever ,return_source_documents=True
)
RetrievalQAEnsembleReturn = RetrievalQAEnsemble.invoke({"query": questions[0], "k": 2})