本文深入探讨了RAG技术在实际应用中的关键步骤。首先文章分析了不同Embedding模型如BGE-M3、M3E、GTE-Qwen2-7B-instruct、text-embedding-3-large的特点与选型建议强调模型选择并非决定性因素。接着通过实例展示了如何使用BGE-M3模型计算文本相似度并介绍了指令感知型Embedding模型GTE-Qwen2的应用。文章进一步阐述了召回与重排序的区别及其在RAG流程中的作用。最后以DeepSeekFaissLangChain为例完整演示了构建本地知识库问答系统的过程包括PDF文本提取、文本分割、向量化存储、持久化及问答环节并总结了LangChain的几种问答策略。强调数据质量是RAG项目的关键建议先从数据质量较好的场景入手逐步完善系统。上次聊了RAG的概念——知道它是什么知道它为什么有用。但看完还是有点虚吧正常。理论是理论真要动手的时候光一个选什么Embedding模型就能把人搞懵。参数林立榜单几十页各家都说自己最好。这篇我们直接上手从为什么选这个Embedding模型开始到怎么用Faiss搭一个本地知识库检索全部手写代码。不扯框架不搞封装你看到的就是能跑的东西。Embedding模型怎么选先说结论选哪个模型差别不会特别大核心是你的切片策略和Reranker。但选还是要选的。目前最主流的几个BGE-M3智源研究院支持百余种语言最大上下文长度8192 tokens是融合密集向量 稀疏词级 多向量的三合一混合检索嵌入模型。社区认可度高、HuggingFace 下载量超 200 万次是通用多语言 RAG 首选模型大小约2.3G长文档、跨语言、通用检索场景适配性极强。M3E-Base中文优化轻量版主打轻量化中文专属嵌入模型模型体积仅约0.4G硬件门槛低、极适合本地私有化部署。通用文档、企业知识库、法律、医疗等垂直中文场景精度足够资源占用小、推理速度快是个人和中小项目本地 RAG 性价比优选。GTE-Qwen2-7B-instruct阿里通义属于指令感知型 Embedding 模型底座基于 Qwen2-7B 大模型做指令微调。这里的「instruct」只针对检索任务意图而非控制大模型生成格式。举例给查询加上任务指令「学术文献知识点检索特斯拉成立时间」模型能识别检索场景与任务意图做更精准的语义匹配不负责后续回答字数、语种、格式限制这类生成约束由上层 LLM 处理。适合复杂意图、多场景混用的高阶 RAG 检索。text-embedding-3-largeOpenAI默认向量维度3072 维英文语义检索表现顶尖支持动态降维节省存储。短板非常明显中文理解弱于国产开源模型国内调用存在网络延迟、API 按量收费且闭源无法私有化有数据出境合规风险仅适合无隐私要求、以英文为主的高精度检索场景。我的建议先从BGE-M3或者M3E中文场景上手不要纠结排名。做RAG更重要的东西在后面。用BGE-M3算一段相似度别想复杂了核心代码就这几行from FlagEmbedding import BGEM3FlagModelmodel BGEM3FlagModel(BAAI/bge-m3, use_fp16True)sentences_1 [What is BGE M3?, Defination of BM25]sentences_2 [ BGE M3 is an embedding model supporting dense retrieval, lexical matching and multi-vector interaction., BM25 is a bag-of-words retrieval function that ranks a set of documents based on query terms appearing in each document]embeddings_1 model.encode(sentences_1, batch_size12, max_length8192)[dense_vecs]embeddings_2 model.encode(sentences_2)[dense_vecs]similarity embeddings_1 embeddings_2.Tprint(similarity)# [[0.626 0.3477]# [0.3499 0.678 ]]注意看输出里的数字。What is BGE M3?和BGE M3 is an embedding model…的相似度0.626明显高于和BM25的0.3477——合理。但有个细节挺有意思的BGE-M3和BM25这两个完全不相关的内容相似度也不会是0。这不是Bug。Embedding模型不是精确打分模型它是向量空间上的夹角基本上不会完全为零。空间上总有些相似学到的语义总会有些重合。GTE-Qwen2的指令模式另一个用法基于SentenceTransformer的更简洁版本from sentence_transformers import SentenceTransformermodel SentenceTransformer(iic/gte_Qwen2-1___5B-instruct, trust_remote_codeTrue)model.max_seq_length 8192queries [how much protein should a female eat, summit define]documents [ As a general guideline, the CDCs average requirement of protein for women ages 19 to 70 is 46 grams per day..., Definition of summit for English Language Learners: the highest point of a mountain...]query_embeddings model.encode(queries, prompt_namequery)document_embeddings model.encode(documents)scores (query_embeddings document_embeddings.T) * 100print(scores.tolist())# [[78.5, 17.0], [14.9, 75.4]]*100是为了让分数更好看。本质上还是向量点积那一套。说真的我有段时间特较真觉得Embedding排行榜上相差1分的差距非常重要。折腾了两周后发现——选哪个和选哪个差别真没你想的那么大。你的切片策略、Reranker选型、甚至是分词器的处理方式对效果的影响都比换Embedding模型大一个数量级。别在这个环节钻牛角尖。一个关键的区分召回 vs 重排序很多人搞混这两个概念。假设你的知识库里有1000万个切片像1000万份简历。召回FAISS 通过关键词快速筛选简历筛出1000份你觉得符合条件的。特点是快几百毫秒对10亿数据做一次召回。重排序Reranker 对这1000份简历逐一面试打分。一个一个的精确打分质量高但慢。所以流程是先召回粗筛→ 再重排序精排Embedding是批量计算向量相似度不是精确打分。Reranker是基于问题和知识一对一打分结果更准。这俩不是替代关系是配合关系。DeepSeek Faiss完整代码实战来直接上最硬的。用DeepSeek Faiss LangChain搭一个本地知识库问答系统。项目的场景是用一个PDF文件客户经理考核办法让AI能回答投诉一次扣几分这类问题。Step 1PDF文本提取页码记录from PyPDF2 import PdfReaderdefextract_text_with_page_numbers(pdf): text page_numbers [] for page_number, page inenumerate(pdf.pages, start1): extracted_text page.extract_text() if extracted_text: text extracted_text page_numbers.extend([page_number] * len(extracted_text.split(\n))) return text, page_numberspdf_reader PdfReader(./客户经理考核办法.pdf)text, page_numbers extract_text_with_page_numbers(pdf_reader)print(f提取了{len(text)}个字符)这里有个小设计不光是提取文本还逐行记录了文本来自哪一页。后面用户问问题时系统能回答这个答案在第X页方便溯源。Step 2文本分割from langchain.text_splitter import RecursiveCharacterTextSplittertext_splitter RecursiveCharacterTextSplitter( separators[\n\n, \n, ., , ], chunk_size1000, chunk_overlap200,)chunks text_splitter.split_text(text)print(f文本被分割成{len(chunks)}个块)为什么切分如果不切分一个1000页的知识全部扔进Embedding语义会被稀释。chunk_overlap200的意思是每个片段之间重叠200个token。这是为了信息不遗漏——万一切分把一句话从中间砍断了下个块因为重叠了前面的内容信息大概率是完整的。Step 3向量化Faiss存储from langchain_community.embeddings import DashScopeEmbeddingsfrom langchain_community.vectorstores import FAISSembeddings DashScopeEmbeddings( modeltext-embedding-v1, dashscope_api_keyDASHSCOPE_API_KEY,)knowledgeBase FAISS.from_texts(chunks, embeddings)你品一下这一步做了什么每个chunk走了一遍Embedding模型变成了一个向量然后存进了Faiss的索引结构里。Step 4持久化knowledgeBase.page_info {chunk: page_numbers[i] for i, chunk in enumerate(chunks)}保存三个文件faiss_index.faiss向量索引、faiss_index.pkl文档内容、page_info.pkl页码映射。下次直接load不用再跑一遍Embedding了——这个步骤省的不是一点点时间。Step 5问答from langchain_community.llms import Tongyillm Tongyi(model_namedeepseek-v3, dashscope_api_keyDASHSCOPE_API_KEY)query 客户经理被投诉了投诉一次扣多少分docs knowledgeBase.similarity_search(query)chain load_qa_chain(llm, chain_typestuff)response chain.invoke({input_documents: docs, question: query})print(response[output_text])# 根据文件内容客户经理被投诉一次扣2分...整个链路跑通了用户提问 → Faiss召回 → 文档组合上下文 → DeepSeek推理 → 输出答案。源数据只有3881个字符的PDF分割成了5个块。就这么点东西跑出来效果就已经很好了。LangChain的几种问答策略上面用的是chain_typestuff意思是把所有检索到的chunk一股脑喂给大模型。这是最省钱也是最常用的只要上下文放得下就用这种。还有三个变种Map Reduce每个chunk单独推理再合并结果。可以并发但块之间缺少上下文照应。Refine第一块推理 → 合并第二块再推理 → 第三块……逐步优化token消耗也多。Map Rerank大模型对每个chunk打分选分数最高的。质量好但贵。一个经验80%的时间花在数据上这是所有企业做RAG项目的共识。不是技术层面的切片和向量化——那些跑一遍代码就完事了。真正花时间的是数据是否重复是否过期同一个术语在A文档和B文档里意思一样吗没有工具能批量回答这些问题。你得找业务人员一个一个确认。所以别一上来就把所有文档清洗一遍再跑。先找一个数据质量还不错的场景打一个PoC把流程跑通让领导看到这玩意儿能干活。后续的事情都是做加法。说白了不要把时间花在证明这事多复杂上把时间花在证明这事儿能干上。那是两种完全不同的思维方式。假如你从2026年开始学大模型按这个步骤走准能稳步进阶。接下来告诉你一条最快的邪修路线3个月即可成为模型大师薪资直接起飞。阶段1:大模型基础阶段2:RAG应用开发工程阶段3:大模型Agent应用架构阶段4:大模型微调与私有化部署配套文档资源全套AI 大模型 学习资料朋友们如果需要可以微信扫描下方二维码免费领取【保证100%免费】配套文档资源全套AI 大模型 学习资料朋友们如果需要可以微信扫描下方二维码免费领取【保证100%免费】