RAG开发中,如何用Milvus 2.5 BM25算法实现混合搜索

一、背景

混合搜索(Hybrid Search)作为RAG应用中Retrieve重要的一环,通常指的是将向量搜索与基于关键词的搜索(全文检索)相结合,并使用RRF算法合并、并重排两种不同检索的结果,最终来提高数据的召回率。全文检索与语义检索不是非此即彼的关系。我们需要同时兼顾语义理解和精确的关键字匹配。比如学术论文的写作中,用户不仅希望在搜索结果看到与搜索查询相关的概念,同时也希望保留查询中使用的原始信息返回搜索结果,比如基于一些特殊术语和名称。因此,许多搜索应用正在采用混合搜索方法,结合两种方法的优势,以平衡灵活的语义相关性和可预测的精确关键字匹配。

从 Milvus 2.4 版本开始,我们引入了多向量搜索和执行混合搜索(多向量搜索)的能力。混合搜索允许用户同时搜索跨多个向量列的内容。这个功能使得可以结合多模态搜索、混合稀疏和全文关键词搜索、密集向量搜索以及混合密集和全文搜索,提供多样且灵活的搜索功能,增强了我们的向量相似性搜索和数据分析。

二、Milvus BM25

在最新的Milvus 2.5里,我们带来了“全新”的全文检索能力

  • 对于全文检索基于的 BM25 算法,我们采用的是 Sparse-BM25,基于 Sparse Vector 实现的 BM25 在存储效率、检索性能上都打开了更多的空间,同时也融合在了 Milvus 以向量为核心检索范式的产品理念里;

  • 同时引入了原始文本插入和查询的能力,不需要用户手动将文本转成 Sparse Vector,这使得 Milvus 朝着非结构化数据处理的方向迈进了一步。

Sparse-BM25 其原理类似 Elasticsearch 和其他全文搜索系统中常用的BM25算法,但针对稀疏向量设计,可以实现相同效果的全文搜索功能。

  • 具有数据剪枝功能的高效检索算法:通过剪枝来丢弃搜索查询中的低值稀疏向量,向量数据库可以显著减小索引大小并以最小的质量损失达成最优的性能。

  • 带来进一步的性能优化:将词频表示为稀疏向量而不是倒排索引,可以实现其他基于向量的优化。比如:用图索引替代暴力扫描,实现更有效的搜索;乘积量化(PQ)/标量量化(SQ),进一步减少内存占用。

三、Milvus BM25 Hybrid Search

1. 首先,准备数据和问题,数据来自Milvus 2.5 release notes,且通过llama-index的SentenceWindowNodeParser对于数据进行分块处理。

!wget https://raw.githubusercontent.com/milvus-io/milvus-docs/v2.5.x/site/en/release_notes.md -O milvus_2_5.md  
  
documents = SimpleDirectoryReader(  
        input_files=["./milvus_2_5.md"]  
).load_data()  
  
# Create the sentence window node parser   
node_parser = SentenceWindowNodeParser.from_defaults(  
    window_size=3,  
    window_metadata_key="window",  
    original_text_metadata_key="original_text",  
)  
  
# Extract nodes from documents  
nodes = node_parser.get_nodes_from_documents(documents)  
  
# query question  
query = "What are the key features in milvus 2.5?"  

2. 其次,创建collection的schema以及索引,其中原始文本数据存于text列,而Sparse-BM25数据存于sparse_bm25列,这里需要通过转换Function来实现

bm25_function = Function(  
        name="bm25",  
        function_type=FunctionType.BM25,  
        input_field_names=["text"],  
        output_field_names="sparse_bm25",  
    )  
schema = MilvusClient.create_schema(  
    auto_id=False,  
    enable_dynamic_field=True,  
)  
  
# Add fields to schema  
schema.add_field(field_name="id", datatype=DataType.INT64, is_primary=True)  
schema.add_field(field_name="text", datatype=DataType.VARCHAR, max_length=512, enable_analyzer=True)  
schema.add_field(field_name="sparse_bm25", datatype=DataType.SPARSE_FLOAT_VECTOR)  
schema.add_field(field_name="dense", datatype=DataType.FLOAT_VECTOR, dim=dense_dim)  
  
bm25_function = Function(  
        name="bm25",  
        function_type=FunctionType.BM25,  
        input_field_names=["text"],  
        output_field_names="sparse_bm25",  
    )  
schema.add_function(bm25_function)  
  
index_params = client.prepare_index_params()  
  
# Add indexes  
index_params.add_index(  
    field_name="dense",  
    index_name="dense_index",  
    index_type="IVF_FLAT",  
    metric_type="IP",  
    params={"nlist": 128},  
)  
  
index_params.add_index(  
    field_name="sparse_bm25",  
    index_name="sparse_bm25_index",  
    index_type="SPARSE_WAND",   
    metric_type="BM25"  
)  
  
# Create collection  
client.create_collection(  
    collection_name=collection_name,  
    schema=schema,  
    index_params=index_params  
)  

3. 然后,把数据进行Embedding之后,插入到Collection里,这里Embedding采用的是 OpenAI的 text-embedding-3-large

def gen_embedding(docs):  
    model_name = "text-embedding-3-large"  
    openai_ef = model.dense.OpenAIEmbeddingFunction(  
        model_name=model_name,   
        api_key=os.environ["OPENAI_API_KEY"]  
    )  
      
    return openai_ef.encode_documents(docs)  
  
docs_embeddings = gen_embedding(docs)  
query_embeddings = gen_embedding([query])  
  
# Assemble data  
data = [  
    {"id": idx, "dense": docs_embeddings[idx].data, "text": doc}  
    for idx, doc in enumerate(docs)  
]  
  
# Insert data  
res = client.insert(  
    collection_name=collection_name,  
    data=data  
)  

4. 最后,进行查询测试

4.1. 我们先测试下普通查询

search_params = {  
        "metric_type": "IP",  
        "params": {"nprobe": 10}  
    }  
  
res = client.search(  
    collection_name=collection_name,  
    data=[query_embeddings[0]],  
    anns_field="dense",  
    limit=5,  
    search_params=search_params,  
    output_fields=["text"]  
)  

查询结果

TopK results:  
                                                                                                     0  
0  Enhancements in cluster management, indexing, and data handling introduce new levels of flexibil...  
1  With this release, Milvus integrates powerful new features like term-based search, clustering co...  
2  Milvus 2.5 introduces a built-in Cluster Management WebUI, reducing system maintenance difficult...  
3  \n\nv2.5.0-beta\n\nRelease date: November 26, 2024\n\n| Milvus version | Python SDK version | No...  
4                                                 \n\nRelease Notes\n\nFind out what’s new in Milvus! 

从查询结果来看,最后一条召回内容与查询问题相关度不大。

4.2. 然后进行Hybrid Search。定义向量搜索和Sparse-BM25搜索

k=5 # get the top 5 docs related to the query  
  
search_params_dense: { "metric_type": "IP", "params": {"nprobe": 10}}  
request_dense = AnnSearchRequest([query_embeddings[0].data], "dense", search_params_dense, limit=k)  
  
search_params_bm25 = {"metric_type": "BM25"}  
request_bm25 = AnnSearchRequest([query], "sparse_bm25", search_params_bm25, limit=k)  
  
reqs = [request_dense, request_bm25]  

这里使用RRFRanker来进行Hybrid Search

ranker = RRFRanker(100)  
  
res = client.hybrid_search(  
    collection_name=collection_name,  
    reqs=reqs,  
    ranker=ranker,  
    limit=5,  
    output_fields=["text"]  
)  
for hits in res:  
    print("TopK results:")  
    for hit in hits:  
        print(hit)  

查询结果:

TopK results:  
                                                                                                     0  
0  \n\nv2.5.0-beta\n\nRelease date: November 26, 2024\n\n| Milvus version | Python SDK version | No...  
1  Enhancements in cluster management, indexing, and data handling introduce new levels of flexibil...  
2  This feature is disabled by default in Milvus 2.5 and will be officially available in version 3....  
3  With this release, Milvus integrates powerful new features like term-based search, clustering co...  
4  Powered by Tantivy, Milvus 2.5 has built-in analyzers and sparse vector extraction, extending th...  

从结果来看,基于Sparse-BM25的Hybrid Search可以准确找到与查询相关的内容。相对于普通查询,召回的内容准确度更大。

四、总结

本文讲述了Milvus 2.5中引入的Sparse-BM25基础原理,以及如何利用BM25算法实现RAG开发中的Hybrid Search(混合搜索)实践。通过引入Sparse-BM25算法,Milvus能够在稀疏向量上执行高效的全文检索,并与密集向量搜索相结合,提升检索的召回率和精确度。

参考文档:

  • https://zilliz.com/blog/hybrid-search-with-milvus
  • https://milvus.io/docs/multi-vector-search.md

五、如何系统学习掌握AI大模型?

AI大模型作为人工智能领域的重要技术突破,正成为推动各行各业创新和转型的关键力量。抓住AI大模型的风口,掌握AI大模型的知识和技能将变得越来越重要。

学习AI大模型是一个系统的过程,需要从基础开始,逐步深入到更高级的技术。

这里给大家精心整理了一份全面的AI大模型学习资源,包括:AI大模型全套学习路线图(从入门到实战)、精品AI大模型学习书籍手册、视频教程、实战学习、面试题等,资料免费分享

1. 成长路线图&学习规划

要学习一门新的技术,作为新手一定要先学习成长路线图方向不对,努力白费

这里,我们为新手和想要进一步提升的专业人士准备了一份详细的学习成长路线图和规划。可以说是最科学最系统的学习成长路线。
在这里插入图片描述

2. 大模型经典PDF书籍

书籍和学习文档资料是学习大模型过程中必不可少的,我们精选了一系列深入探讨大模型技术的书籍和学习文档,它们由领域内的顶尖专家撰写,内容全面、深入、详尽,为你学习大模型提供坚实的理论基础(书籍含电子版PDF)

在这里插入图片描述

3. 大模型视频教程

对于很多自学或者没有基础的同学来说,书籍这些纯文字类的学习教材会觉得比较晦涩难以理解,因此,我们提供了丰富的大模型视频教程,以动态、形象的方式展示技术概念,帮助你更快、更轻松地掌握核心知识

在这里插入图片描述

4. 2024行业报告

行业分析主要包括对不同行业的现状、趋势、问题、机会等进行系统地调研和评估,以了解哪些行业更适合引入大模型的技术和应用,以及在哪些方面可以发挥大模型的优势。

在这里插入图片描述

5. 大模型项目实战

学以致用 ,当你的理论知识积累到一定程度,就需要通过项目实战,在实际操作中检验和巩固你所学到的知识,同时为你找工作和职业发展打下坚实的基础。

在这里插入图片描述

6. 大模型面试题

面试不仅是技术的较量,更需要充分的准备。

在你已经掌握了大模型技术之后,就需要开始准备面试,我们将提供精心整理的大模型面试题库,涵盖当前面试中可能遇到的各种技术问题,让你在面试中游刃有余。

在这里插入图片描述

全套的AI大模型学习资源已经整理打包,有需要的小伙伴可以微信扫描下方CSDN官方认证二维码,免费领取【保证100%免费

<think>好的,我现在需要回答用户关于Dify RAG的问题。首先,我需要明确用户的问题是什么。用户提到“dify rag”,可能是在询问Dify平台中的RAG(检索增强生成)技术是如何工作的,或者它的应用场景、优势等。用户还提供了两个参考链接,我需要结合这些资料来构建回答。 首先,我应该回顾一下RAG的基本概念。RAG结合了检索和生成两个步骤,通过从外部知识库中检索相关信息来增强生成模型的结果,使其更准确和可靠。在Dify中,RAG被整合到知识库功能中,用于提升生成式AI应用的表现。 接下来,我需要确定Dify RAG的具体实现机制。根据提供的参考资料,Dify的RAG流程可能包括知识库构建、检索策略、信息增强生成这几个步骤。知识库可能支持多种格式的数据,比如文本、PDF等,并通过嵌入模型将文档转化为向量存储。检索时,用户的查询也会被向量化,通过相似度匹配找到相关文档片段,然后这些片段作为上下文输入到生成模型中,比如LLM,生成最终回答。 然后,我需要考虑用户可能关心的方面,比如Dify RAG的优势、应用场景、优化方法等。优势可能包括提升生成内容的准确性,减少模型幻觉,支持动态更新知识库。应用场景可能涉及客服、知识问答系统、内容生成等需要实时准确信息的领域。优化方法可能涉及检索策略的调整,比如调整top-k参数,使用混合检索(结合关键词和向量搜索),或者优化知识库的结构。 用户可能还会想知道如何在自己的项目中使用Dify的RAG功能,可能需要简要说明操作步骤,比如创建知识库、上传文档、配置检索参数等。不过根据用户提供的参考链接,可能不需要详细的操作指南,而是更侧重原理和结构。 另外,需要确保回答符合用户给出的格式要求,比如使用中文,行内公式用$...$,独立公式用$$...$$,但根据当前问题,可能涉及数学公式的地方不多。不过如果有提到相关算法,比如向量相似度计算,可能需要用到内联公式,比如余弦相似度公式$ \cos(\theta) = \frac{\mathbf{A} \cdot \mathbf{B}}{|\mathbf{A}| |\mathbf{B}|} $。 还需要生成相关问题,这部分需要根据回答内容提出几个相关的问题,比如Dify RAG的技术原理、优化方法、应用场景等。 需要确保回答引用参考链接,在适当的位置添加引用标识,例如在提到Dify中的RAG和知识库时引用[^1],在检索增强生成的概念时引用[^2]。 现在组织回答结构:首先概述Dify RAG,然后分点讲解核心机制、优势、应用场景,接着给出示例代码或配置片段(如果有的话),最后生成相关问题。 检查是否有遗漏的部分,比如是否提到了知识库构建、检索策略、生成整合等步骤。确保每个部分都简明扼要,符合用户要求的清晰结构。 最后,生成的相关问题需要与Dify RAG相关,可能包括技术细节、优化、应用案例、与其他RAG系统的比较等。</think>### Dify中的RAG(检索增强生成)技术解析 Dify通过整合**检索增强生成(RAG)**技术,将外部知识库与生成式AI结合,显著提升模型输出的准确性和可靠性。以下是其核心机制: #### 1. **知识库构建与向量化** - Dify支持上传多种格式文档(如PDF、文本),并通过嵌入模型(如OpenAI的text-embedding-ada-002)将内容转化为向量$ \mathbf{v} \in \mathbb{R}^d $,存储至向量数据库。 - 文档分块策略采用滑动窗口(例如512 tokens)结合语义分割,平衡检索效率与上下文完整性。 #### 2. **混合检索策略** - **向量检索**:计算查询向量与知识库向量的余弦相似度$ \cos(\theta) = \frac{\mathbf{q} \cdot \mathbf{v}}{|\mathbf{q}| |\mathbf{v}|} $,返回Top-K相关片段。 - **关键词增强**:结合BM25算法补充传统关键词匹配,缓解语义鸿沟问题。 #### 3. **生成阶段优化** - 检索结果通过Prompt模板注入LLM上下文,例如: ```text 根据以下知识回答问题: [检索片段1] [检索片段2] 问题:{用户输入} ``` - 支持调整**温度(temperature)**参数控制生成多样性,默认0.7平衡准确性与创造性。 #### 4. **动态知识更新** - 知识库支持增量更新,新文档触发自动向量化与索引重建(如FAISS或Milvus),保障信息时效性。 #### 优势对比 | 特性 | 传统生成模型 | Dify RAG | |--------------------|-------------------|-----------------------| | 知识时效性 | 固定训练数据 | 支持动态更新 | | 事实准确性 | 易产生幻觉 | 基于检索结果约束 | | 领域适应性 | 需微调模型 | 仅需更新知识库 |
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值