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})