文章目录
- rag检索分类
- (1)向量查询
- (2) 过滤查询
- (3) 预置查询(Named Vectors)
- (4) 稀疏向量查询(Sparse Vector / BM25)
- (5) 混合查询(Hybrid Search)
- 入库和检索
- 入库
- 混合检索工程方案
rag检索分类
(1)向量查询
# 单一向量.query_points(query=vector,limit=10)# 多个向量(加权平均).query_points(query=[vec1,vec2],query_weights=[0.7,0.3])(2) 过滤查询
.query_points(query=vector,query_filter=Filter(must=[FieldCondition(key="category",match=MatchValue(value="AI"))]),limit=10)(3) 预置查询(Named Vectors)
# 如果入库时给向量起了名字 .query_points( collection_name="docs", query_name="document_vector", # 指定使用哪个向量字段 using="text_vector", # 使用命名的向量 with_vector=True )(4) 稀疏向量查询(Sparse Vector / BM25)
# 需要配置 sparse vector 索引 .query_points( query=sparse_vector, # 稀疏向量(词袋表示) using="sparse_text" # 指定稀疏向量字段 )(5) 混合查询(Hybrid Search)
# 结合稠密和稀疏向量 .query_points( prefetch=[ Prefetch(query=dense_vector, using="dense", limit=100), Prefetch(query=sparse_vector, using="sparse", limit=100), ], query=Filter(...), # 重排序阶段 limit=10 )入库和检索
入库
入库
# 创建 collection 时配置fromqdrant_client.http.modelsimport(VectorParams,HnswConfigDiff,PayloadIndexType)client.create_collection(collection_name="my_docs",vectors_config={"text_vector":VectorParams(size=768,# 向量维度distance=Distance.COSINE,hnsw_config=HnswConfigDiff(m=16,# 每个节点最大连接数ef_construct=100))},# 对 payload 字段建索引(用于过滤)optimizers_config=OptimizersConfigDiff(indexing_threshold=10000))# 对 payload 字段创建倒排索引(用于快速过滤)client.create_payload_index(collection_name="my_docs",field_name="category",field_type=PayloadIndexType.KEYWORD)# 对 text 内容建全文索引(稀疏向量/BM25)client.create_payload_index(collection_name="my_docs",field_name="text_content",field_type=PayloadIndexType.TEXT)混合检索工程方案
classHybridRetriever:asyncdefretrieve(self,query:str,top_k:int=10):# 1. 扩大召回dense_limit=max(top_k*3,10)# 2. 并行检索dense_task=self._dense_search(query,dense_limit)bm25_task=self._bm25_search(query,dense_limit)dense_hits,bm25_hits=awaitasyncio.gather(dense_task,bm25_task)# 3. 融合(RRF 或加权)combined=self._reciprocal_rank_fusion(dense_hits,bm25_hits)# 4. 重排序(Cross-Encoder)reranked=awaitself._cross_encoder_rerank(query,combined[:top_k*2])# 5. 返回最终 top_kreturnreranked[:top_k]需要注意的是混合检索不能直接采用并集,
错误代码如下,不可用于实际生产环境,(最优解应该使用加权融合)
results=self.client.query_points(collection_name=self.collection_name,prefetch=[# 语义检索(稠密向量)Prefetch(query=dense_embedding,using="dense_text",# 使用稠密向量字段limit=recall_limit,filter=query_filter),# 关键词检索(稀疏向量)Prefetch(query=sparse_embedding,using="sparse_text",# 使用稀疏向量字段limit=recall_limit,filter=query_filter)],# query参数在这里用于最终的融合和排序# 传入None表示只做融合,不再额外检索query=None,limit=top_k,with_payload=True,with_vectors=False)但是以下代码又是可以的
response = client.query_points( collection_name="my_collection", prefetch=[ models.Prefetch( query=models.Document( text=query, model="Qdrant/bm25", ), using="sparse", limit=20, ), models.Prefetch( query=models.Document( text=query, model="sentence-transformers/all-MiniLM-L6-v2", ), using="dense", limit=20, ) ], query=models.FusionQuery(fusion=models.Fusion.RRF), limit=10, )