rag混合检索

文章目录

rag检索分类

(1)向量查询

python 复制代码
# 单一向量
.query_points(query=vector, limit=10)

# 多个向量(加权平均)
.query_points(query=[vec1, vec2], query_weights=[0.7, 0.3])

(2) 过滤查询

python 复制代码
.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
)

入库和检索

入库

入库

python 复制代码
# 创建 collection 时配置
from qdrant_client.http.models import (
    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
)

混合检索工程方案

python 复制代码
class HybridRetriever:
    async def retrieve(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 = await asyncio.gather(dense_task, bm25_task)
        
        # 3. 融合(RRF 或加权)
        combined = self._reciprocal_rank_fusion(dense_hits, bm25_hits)
        
        # 4. 重排序(Cross-Encoder)
        reranked = await self._cross_encoder_rerank(query, combined[:top_k*2])
        
        # 5. 返回最终 top_k
        return reranked[:top_k]

需要注意的是混合检索不能直接采用并集,

错误代码如下,不可用于实际生产环境,(最优解应该使用加权融合)

python 复制代码
        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,
)
相关推荐
卷卷说风控5 小时前
【卷卷观察】Google I/O 炸场背后:AI 行业正在经历一场“越南战争“
人工智能
SLD_Allen5 小时前
AI-Infra双轨战略:承托当下GPU算力,布局未来CPU替代
人工智能·gpu算力·ai-infra
wait5 小时前
Vibe Coding 开发技巧
前端·javascript·人工智能
bloxed5 小时前
【AI大模型--NumPy-06】随机数生成与蒙特卡洛模拟
人工智能·numpy
szxinmai主板定制专家5 小时前
基于ZYNQ MPSOC图像采集与压缩系统总体设计方案
linux·arm开发·人工智能·嵌入式硬件·fpga开发
水木流年追梦5 小时前
大模型入门-大模型的推理策略
开发语言·python·算法·正则表达式·prompt
GOTXX5 小时前
SenseNova U1 实战体验:API 调用 + OpenClaw 接入全流程
服务器·网络·人工智能·语言模型
生成论实验室5 小时前
用事件关系网络重新理解AI(三):激活函数、微调与元学习
人工智能·学习·算法·语言模型·可信计算技术
@蔓蔓喜欢你5 小时前
Jest 测试框架:构建可靠的测试体系
人工智能·ai
Narv工程师5 小时前
嵌入式机器人控制器算力评估:从DMIPS到WCET的完整指南
人工智能·算法·机器学习