大模型:Retriever,BM25
下面给你一个完整的、可直接运行的 Retriever Demo涵盖了 4 种最常用的 Retriever 类型并配有详细的注释和输出示例。你可以把它当作面试时的“武器库”来使用。 环境准备pipinstalllangchain langchain-community chromadb rank_bm25 sentence-transformers openai 完整 Demo 代码importosfromlangchain_core.documentsimportDocumentfromlangchain_community.vectorstoresimportChromafromlangchain_community.embeddingsimportHuggingFaceEmbeddingsfromlangchain.retrieversimportBM25Retriever,MultiQueryRetriever,EnsembleRetrieverfromlangchain.retrievers.multi_queryimportMultiQueryRetrieverfromlangchain.retrievers.ensembleimportEnsembleRetrieverfromlangchain_core.retrieversimportBaseRetrieverfromlangchain_openaiimportChatOpenAI# # 1. 准备测试数据10 篇关于宠物的文档# docs[Document(page_content猫是独立而优雅的宠物喜欢清洁和安静的环境。,metadata{source:cat_article}),Document(page_content狗是人类最忠实的朋友需要大量的运动和社交。,metadata{source:dog_article}),Document(page_content金鱼是常见的观赏鱼适合在室内鱼缸中饲养。,metadata{source:fish_article}),Document(page_content仓鼠是小型啮齿动物夜间活跃适合城市家庭。,metadata{source:hamster_article}),Document(page_content鹦鹉是非常聪明的鸟类能模仿人类语言。,metadata{source:parrot_article}),Document(page_content兔子是温顺的食草动物需要宽敞的笼子和新鲜蔬菜。,metadata{source:rabbit_article}),Document(page_content乌龟是长寿的爬行动物适应力强但需要特定的温度和光照。,metadata{source:turtle_article}),Document(page_content猫和狗可以和平共处但需要适当的引导和训练。,metadata{source:pet_guide}),Document(page_content饲养宠物需要考虑空间、时间和经济成本。,metadata{source:pet_care}),Document(page_content宠物可以缓解压力提高生活质量。,metadata{source:pet_benefits}),]# # 2. Retriever 类型 1基于向量库的检索最常用# print(*50)print(1. VectorStoreRetriever向量检索)print(*50)# 使用轻量级中文嵌入模型embeddingsHuggingFaceEmbeddings(model_namesentence-transformers/paraphrase-multilingual-MiniLM-L12-v2)# 创建向量库vectorstoreChroma.from_documents(documentsdocs,embeddingembeddings,collection_namepet_demo)# 转换成 Retrievervector_retrievervectorstore.as_retriever(search_kwargs{k:3}# 返回 Top-3)query适合家庭养的宠物有哪些resultvector_retriever.invoke(query)print(f查询{query})fori,docinenumerate(result):print(f{i1}.{doc.page_content}(来源:{doc.metadata[source]}))# # 3. Retriever 类型 2BM25 关键词检索# print(\n*50)print(2. BM25Retriever关键词检索)print(*50)bm25_retrieverBM25Retriever.from_documents(docs,k3)resultbm25_retriever.invoke(猫 狗)print(f查询{猫 狗})fori,docinenumerate(result):print(f{i1}.{doc.page_content})# # 4. Retriever 类型 3MultiQueryRetriever多查询增强# print(\n*50)print(3. MultiQueryRetriever多角度生成查询)print(*50)# 需要 LLM 来生成多个不同表述的查询llmChatOpenAI(modelgpt-3.5-turbo,temperature0)# 可换成通义千问等multi_retrieverMultiQueryRetriever.from_llm(retrievervectorstore.as_retriever(k3),llmllm,include_originalTrue# 包含原始查询)resultmulti_retriever.invoke(哪种宠物好养又可爱)print(f查询哪种宠物好养又可爱)# MultiQueryRetriever 不保证结果数量固定这里打印所有结果fori,docinenumerate(result[:5]):print(f{i1}.{doc.page_content})# # 5. Retriever 类型 4EnsembleRetriever混合检索# print(\n*50)print(4. EnsembleRetriever混合检索BM25 向量)print(*50)ensemble_retrieverEnsembleRetriever(retrievers[bm25_retriever,vector_retriever],weights[0.5,0.5]# 两者权重相等)resultensemble_retriever.invoke(宠物 陪伴 减压)print(f查询宠物 陪伴 减压)fori,docinenumerate(result):print(f{i1}.{doc.page_content})# # 6. 自定义 Retriever演示扩展能力# print(\n*50)print(5. 自定义 Retriever按文档长度过滤)print(*50)classLengthFilterRetriever(BaseRetriever):只返回长度小于 30 个字符的文档演示自定义逻辑retriever:BaseRetriever max_len:int30def_get_relevant_documents(self,query:str)-list[Document]:docsself.retriever.invoke(query)return[dfordindocsiflen(d.page_content)self.max_len]asyncdef_aget_relevant_documents(self,query:str)-list[Document]:docsawaitself.retriever.ainvoke(query)return[dfordindocsiflen(d.page_content)self.max_len]custom_retrieverLengthFilterRetriever(retrievervector_retriever,max_len30)resultcustom_retriever.invoke(宠物)print(f查询宠物仅返回长度 30 个字符的文档)fori,docinenumerate(result):print(f{i1}.{doc.page_content}(长度:{len(doc.page_content)}))print(\n✅ Demo 执行完毕) 预期输出部分节选 1. VectorStoreRetriever向量检索 查询适合家庭养的宠物有哪些 1. 仓鼠是小型啮齿动物夜间活跃适合城市家庭。 (来源: hamster_article) 2. 兔子是温顺的食草动物需要宽敞的笼子和新鲜蔬菜。 (来源: rabbit_article) 3. 宠物可以缓解压力提高生活质量。 (来源: pet_benefits) 2. BM25Retriever关键词检索 查询猫 狗 1. 猫是独立而优雅的宠物喜欢清洁和安静的环境。 2. 狗是人类最忠实的朋友需要大量的运动和社交。 3. 猫和狗可以和平共处但需要适当的引导和训练。 ... 面试时如何讲解这个 DemoRetriever 类型一句话讲清楚适用场景VectorStoreRetriever用向量相似度找语义相关的文档通用 RAG 标配BM25Retriever用关键词精确匹配产品名、代码等精确检索MultiQueryRetriever让 LLM 从多角度生成查询提高召回率用户表述模糊时EnsembleRetriever混合关键词和向量检索取长补短生产环境推荐自定义 Retriever继承BaseRetriever实现业务逻辑有特殊过滤需求的场景面试加分句“在生产环境中我通常采用EnsembleRetriever组合 BM25 和向量检索因为用户既可能输入口语化的描述也可能输入精确的专有名词混合检索能保证两种情况的召回率。同时我会配置一个Reranker对结果重排序进一步优化相关性。”你可以直接复制上述代码到本地运行需要配置OPENAI_API_KEY或替换成通义千问亲身体验每种 Retriever 的效果差异。如果遇到任何问题欢迎继续提问 什么是 BM25在深入面试题之前我们首先需要理解 BM25 是什么。BM25Best Matching 25是一种词袋检索模型用于信息检索系统评估文档与给定搜索查询的相关性。它基于词频TF和逆文档频率IDF等统计信息进行打分是 TF-IDF 的进化版它根据查询词项在文档中出现的频率进行打分同时对那些在整个语料库中过于常见的词进行惩罚。其核心思想是如果一篇文档包含了用户查询中的关键词且这些词在其他文档中不常见那么这篇文档的相关性就越高。⚔️ BM25 与向量检索差异与互补这是面试中的核心问题理解两者的差异是回答所有后续问题的基础。特性BM25 (稀疏检索)向量检索 (密集检索)检索方式基于关键词匹配和词频统计。基于语义相似度将文本映射为向量。擅长处理专有名词、ID、代码函数、产品型号等精确词汇。同义词、语义相近但词汇不同的查询。优点精确匹配能力强对稀有词汇敏感可解释性强。泛化能力强能理解用户意图处理自然语言。缺点无法理解同义词对“一词多义”场景无能为力。对精确的专有名词不敏感可能召回语义相关但非精确的内容。典型场景用户搜索“ERR_CONN_RESET_4XX”等具体错误码。用户搜索“如何解决网络连接问题”等意图类问题。面试金句向量检索懂“语义”BM25 懂“字词”。两者是互补关系而非替代关系。 为什么真实 RAG 系统通常需要两者面试官常会问“为什么有的项目用 BM25有的用 Embedding还有的非要上混合检索”。答案是没有一个检索器是万能的。只用向量检索当用户查询一个只在文档中出现过一次的专有名词如“重排序”时仅靠语义相似度可能无法召回该文档。只用 BM25当用户查询“如何让应用响应更快”时它无法匹配到内容为“性能优化”的文档因为缺少共同的关键词。混合检索Hybrid Search正是为了解决这个矛盾。它在生产环境中的效果往往优于仅使用密集检索的系统通过结合 BM25 的关键词匹配能力和向量检索的语义理解能力实现11 2的效果。 BM25Retriever 实战LangChain 中的用法在 LangChain 中BM25Retriever是一个开箱即用的组件。1. 安装pipinstallrank_bm252. 基本使用fromlangchain_community.retrieversimportBM25Retrieverfromlangchain_core.documentsimportDocument# 从文档列表创建检索器docs[Document(page_content猫是独立而优雅的宠物。),Document(page_content狗是人类最忠实的朋友。),]retrieverBM25Retriever.from_documents(docs,k2)3. 检索resultsretriever.invoke(狗)# 输出: [Document(page_content狗是人类最忠实的朋友。), ...]4. 自定义分词为了更好的效果可以传入自定义的分词函数。importnltkfromnltk.tokenizeimportword_tokenize retrieverBM25Retriever.from_documents(docs,preprocess_funcword_tokenize# 使用 NLTK 分词)5. 使用 BM25Plus 变体对于短文本或分块文档BM25Plus变体能有效提升召回率。retrieverBM25Retriever.from_documents(docs,bm25_variantplus,# 启用 BM25Plusbm25_params{delta:0.5}# 可调参数) 高频面试题与解答1. 为什么在 RAG 系统中要引入 BM25参考答案引入 BM25 是为了弥补向量检索在精确关键词匹配上的不足。向量检索擅长理解语义但当用户查询的是精确的专有名词、产品型号或代码函数时它可能会召回语义相关但不包含精确关键词的内容。BM25 通过词频统计能精准地捕获这些关键词两者结合能显著提升系统的召回率。2. 混合检索的流程是什么BM25 和向量检索的结果如何融合参考答案典型的混合检索流程是多路召回分别使用 BM25 检索器和向量检索器对同一查询进行检索各自得到一组候选文档。结果融合使用RRF倒数排名融合算法将两路结果合并。RRF通过公式RRF(d) Σ 1/(k rank_i(d))计算文档的最终得分能有效平衡不同检索器的排名。重排序可选对融合后的 Top-N 结果使用一个更强大的模型如Cohere Rerank进行重排序进一步提升顶部结果的相关性。3. 如何确定混合检索中 BM25 和向量检索的权重参考答案权重的设置没有固定公式通常需要根据具体业务场景和数据特性进行实验调优。可以从1:1 的比例或使用 RRF开始作为基线。然后通过评估指标如Recallk在验证集上进行迭代优化。此外也可以设计一套动态权重策略例如当检测到查询中包含明显的专有名词时自动提升 BM25 的权重。4. BM25 有什么局限性参考答案BM25 的主要局限在于它是词袋模型完全基于词汇匹配无法理解同义词或语义。当查询和文档使用不同词汇表达相同含义时它会失效。此外当知识库规模增大例如超过 1000 个条目时其效率会显著下降。在超大规模检索场景下近似最近邻ANN的密集检索在效率上更具优势。 总结BM25Retriever 是 LangChain 生态中实现关键词检索的核心组件是构建高性能 RAG 系统不可或缺的基石。面试时你需要清晰地阐述其基于词频统计的原理准确说明它与向量检索的优势互补关系并能够结合 RRF 等算法说明混合检索的具体实现流程。展示你对检索质量如何影响生成质量的深刻理解将是你从众多候选人中脱颖而出的关键。