从向量检索到混合检索:如何通过 BGE-M3 解决长文本语义截断问题
很多做 RAG(检索增强生成)的开发者在处理长文档时都会撞到一堵墙:Embedding 模型的 Token 限制。传统的向量检索依赖于将文本切片(Chunking),但一旦切片太短,语义会被截断;切片太长,向量表示的精度又会稀释。BGE-M3 的出现,本质上是在尝试打破这种“非黑即白”的检索困境。
BGE-M3 核心的杀手锏在于它的 Multi-functionality(多功能性),它不再强迫开发者在稠密检索(Dense Retrieval)和稀疏检索(Sparse Retrieval)之间二选一,而是通过一个模型同时支持三种检索模式:稠密向量、稀疏向量(类似于 BM25 的关键词匹配)以及多向量(ColBERT 风格的精细匹配)。
这意味着在实际落地时,我们可以通过“混合检索”来对冲长文本截断带来的损失。当一段关键信息因为被切分在两个 Chunk 中而导致语义向量偏移时,稀疏检索可以通过关键词的硬匹配把它“捞”回来;而稠密检索则负责处理那些意思相近但用词完全不同的模糊查询。
对于开发者来说,这意味着 RAG 的调优重心从“如何切分 Chunk”转移到了“如何加权融合”。不再是简单地依赖 top_k,而是通过 RRF(Reciprocal Rank Fusion)等算法,将三种检索结果进行加权排序。
如果你想在本地快速验证 BGE-M3 的能力,可以使用 FlagEmbedding 库:
from FlagEmbedding import BGEM3FlagModel
model = BGEM3FlagModel('BAAI/bge-m3', use_fp16=True)
# 同时获取稠密向量、稀疏向量和多向量表示
sentences = ["这是一个关于混合检索的测试"]
dense_vecs = model.encode(sentences, return_dense=True)
lexical_vecs = model.encode(sentences, return_sparse=True)
colbert_vecs = model.encode(sentences, return_colbert_vecs=True)这种架构对行业的影响在于,它降低了构建高性能检索系统的门槛。以前要达到极高的召回率,得维护一套 Elasticsearch(做关键词)+ 一套 Milvus(做向量),现在用一个 BGE-M3 配合支持混合检索的数据库(如 Qdrant 或 Milvus 2.4+),就能在单模型框架下完成语义理解和精准匹配的闭环。长文本不再需要通过极其小心地手动设置 overlap 来防止截断,因为混合检索提供了足够的容错空间。
全部回复 (0)
还没有回复,来发第一条吧!
