RAG优化:Embedding缓存 + 批处理+Faiss索引原理 + 不同索引对比

张开发
2026/4/3 16:05:24 15 分钟阅读
RAG优化:Embedding缓存 + 批处理+Faiss索引原理 + 不同索引对比
回顾前面讲过RAG检索基于的核心是相关领域知识检索当用户问到一个问题后RAG系统会到知识数据库中去检索与该问题相关的知识然后基于找到的知识回答用户的问题。实现过程中将会利用到一个绕不开的过程那就是Embedding嵌入…所以这次咱们就来实现文本嵌入加检索等功能让咱们的系统有一个RAG的雏形。首先需要先讲一讲这个系统的运行逻辑文本——切Chunk——Embedding嵌入转为知识向量——存起来 问题——Embedding嵌入转为问题向量——找到与问题相似的知识向量retrieve——找到知识向量对应的Chunk——将找到的相关知识和问题丢给大模型——大模型基于知识回答问题通过上述流程可以看到Embedding展现出了其解释和推理能力我们通过问题的Embedding可以找到与它距离相近的知识Embedding这样完成了领域知识的搜索。开始实战1.安装依赖我们在开始之前需要用到FAISS这个库‌FAISS‌Facebook AI Similarity Search是由 ‌Meta原 FacebookAI 实验室‌开发的开源库专为高效检索‌高维向量的相似性‌而设计适用于大规模向量数据支持十亿级的近似最近邻搜索Approximate Nearest Neighbor Search, ANNS‌工具。通过这个工具我们可以实现问题Embedding和知识Embedding向量的紧邻检索。pipinstallfaiss-cpu2.获取Embedding定义Embedding函数获得词嵌入向量模型嵌入的方法选择大语言模型嵌入我用到是OpenAI的嵌入模型当然还有其他模型可供选择。fromopenaiimportOpenAIimportnumpyasnp#Step 2获取 embedding用 OpenAIclient2OpenAI(api_key,base_urlhttps://api.openai.com/v1#defget_embedding(text):responseclient.embeddings.create(modeltext-embedding-3-small,imputtext)returnnp.array(response.data[0].embedding,dtypefloat32)如果没有大语言模型可以选择当然还有其他的嵌入方法可以用一些本地的python库例如sentence-transformers它是一个基于 PyTorch 和 Hugging Face Transformers 的 Python 库专门用于生成句子、段落或图像的语义嵌入向量广泛应用于语义相似度计算、语义搜索、聚类等自然语言处理任务。‌‌pipinstallsentence-transformersfromsentence_transformsimportSentenceTransformer modelSentenceTransform(all-MiniLM-L6-v2)defget_embedding(text):returnnp.array(model.encode(text),dtypefloat32)3.构建向量数据库importfaiss# 前面已经写过文本切片text隐写分析steganalysis是指针对隐写术的检测与破解技术旨在通过分析数字载体的统计特性判断其中是否存在隐蔽信息并在可能的情况下进一步提取或破解隐秘内容。作为信息安全监管的重要手段隐写分析的核心在于破坏隐秘通信的隐蔽性实现对潜在威胁的感知与阻断。从技术路径上隐写分析可分为被动分析与主动分析两类前者仅判断载体中是否包含秘密信息后者则进一步尝试恢复嵌入内容或推断隐写算法参数。检测对象覆盖图像、音频、视频等多模态载体分析方法经历了从早期基于统计特征如均值、直方图、高阶统计量的检测到利用离散余弦变换DCT、离散小波变换DWT等频域变换检测块效应与嵌入痕迹再到当前以卷积神经网络CNN为代表的深度学习模型自动提取高维语义特征的发展历程。评估检测性能的关键指标包括真阳性率与假阳性率等。隐写分析的概念于1998年由Neil F. Johnson等学者在国际信息隐藏会议上正式提出早期研究以统计检测方法为主近年来研究重心逐步转向特征表达优化与分类器设计并开始探索面向生成式隐写等新兴技术的通用分析框架以适应隐蔽通信技术不断演进的对抗需求。defsplit_text(text,chunk_size100):chunks[]foriinrange(0,len(text),chunk_size):chunks.append(text[i:ichunk_size])returnchunks# 知识切片chunkssplit_text(context,chunk_size100)# 计算每个chunk的向量embeddings[get_embedding(c)forcinchunks]# 转成矩阵embedding_matrixnp.vstack(embeddings)# 建立索引dimembedding_matrix.shape[1]indexfaiss.IndexFlatl2(dim)# 加入知识向量index.add(embedding_matrix)4.查询最相关chunk(retrieve)有了知识数据就可以根据问题查询相关的知识了。这里一开始踩了个坑仅查询最相关的知识那么RAG系统回答的效果其实并不好因为只有基于最相关的一批知识才能很好的提高系统回答效果。defretrieve(query,k5)#查询5条相关知识query_vecget_embedding(query).reshape(1,-1)distances,indicesindex.search(query_vec,k)return[chunks[i]foriinindices[0]]求向量之间的余弦距离求两个向量之间的相似度一般采用余弦距离余弦距离的计算方式是两个向量的点积除以两个向量的范数。defcosine_distance(a,b)returnnp.dot(a,b)/(np.linalg.norm(a)*np.linglg.norm(b))5.完整流程串起来clientOpenAI(api_key,base_urlhttps://api.deepseek.com)question这篇文章的核心方法是什么relevant_chunksretrieve(question,k5)context_for_llm\n.join(relevant_chunks)responseclient.chat.completions.create(modeldeepseek-chat,messages[{role:system,content:你是一个论文分析助手},{role:user,content:context_for_llm\n\n问题question}])print(response.choices[0].message.content)如果这篇文章对你有帮助可以点个赞完整代码地址https://github.com/1186141415/A-Paper-Rag-Agent

更多文章