以下是对 gc-qa-rag-server/ragapp/services/search.py
文件的详细 Markdown 文档说明:
文档:search.py
代码详解
文件概述
本文件实现了基于 Qdrant 向量数据库的语义检索服务,支持密集(dense)、稀疏(sparse)及混合(hybrid)检索。其核心功能是:接收用户查询,将其转化为向量表示,调用 Qdrant 检索相关文档或问答内容,并对结果去重、排序,最终返回最相关的若干条数据。该模块是智能问答、知识检索等系统的关键后端组件。
主要结构与函数说明
1. 集合名称映射(collection_name_map
)
该字典定义了不同产品(如 forguncy、wyn、spreadjs、gcexcel)在不同数据类别(文档、论坛问答、论坛教程)下的 Qdrant 集合名称。通过该映射,检索函数可以根据产品和类别动态选择目标集合,保证了系统的灵活性和可扩展性。
2. 向量与稀疏向量转换
-
transform_sparse(embedding)
将稀疏嵌入(通常为倒排索引或稀疏特征)转换为 Qdrant 需要的格式,分别提取索引和值,便于后续检索。 -
get_embedding_pair(inputs: List)
调用create_embedding
(外部依赖,负责生成密集和稀疏嵌入),并返回第一个输入的嵌入结果。如果嵌入生成失败,则返回空向量,保证了后续流程的健壮性。
3. 检索结果去重
distinct_search_hits(hits)
检索结果可能存在重复(如同一问答在不同集合或多次命中)。该函数通过组合file_index
、group_index
、question_index
生成唯一键,去除重复项,只保留唯一结果。这一设计保证了最终返回结果的多样性和有效性。
4. 语义检索函数
-
search_sementic_single(client, query, collection)
针对单一集合,先将查询转为密集向量,然后在指定集合中检索最相关的 8 条数据,分数阈值为 0.4。检索结果去重后返回。 -
search_sementic_hybrid_single(client, query, collection)
混合检索,既用密集向量(question/answer)也用稀疏向量(question/answer),通过 Qdrant 的多路预取(Prefetch)和融合(Fusion.RRF)机制,综合多种相似度信号,提升检索效果。最终返回去重后的前 8 条结果。 -
search_sementic_hybrid(client, query, product)
针对一个产品,分别在文档、论坛问答、论坛教程三个类别下进行混合检索。每个类别检索结果都标记上所属类别,最后将所有结果合并并按分数降序排序。这种多源融合的设计,能最大化覆盖不同类型的知识内容,提升检索的全面性和相关性。
实现原理与设计考虑
1. 多模态融合检索
本模块充分利用了 Qdrant 的多向量检索能力,将密集语义向量(如 Transformer 生成的 embedding)与稀疏向量(如 BM25、TF-IDF 等)结合,通过融合排序(RRF,Reciprocal Rank Fusion)提升检索的准确性和鲁棒性。这种混合检索方式兼顾了深层语义和关键词匹配的优势,适应了多样化的用户查询需求。
2. 灵活的集合与类别管理
通过 collection_name_map
,系统可以灵活扩展支持新的产品或数据类别,无需修改检索逻辑,只需补充映射表即可。这种设计极大提升了系统的可维护性和可扩展性。
3. 健壮性与异常处理
在混合检索过程中,若某个类别或集合检索失败(如集合不存在、网络异常等),系统会捕获异常并记录日志,而不会影响整体检索流程。这保证了服务的高可用性和容错性。
4. 结果去重与排序
多路检索可能导致同一条数据多次命中。通过唯一键去重,保证了结果的多样性。最终统一按分数排序,确保用户获得最相关的内容。
5. 日志与可观测性
模块初始化了日志记录器,对检索异常进行详细记录,便于后续问题排查和系统监控。
应用场景
该模块适用于企业知识库、智能问答、文档检索、社区论坛等多种场景。通过密集与稀疏向量的融合检索,能够高效、准确地从大规模多源数据中找到最相关的答案或文档片段,是现代语义检索系统的核心组件。
代码示例
from qdrant_client import QdrantClient
client = QdrantClient("localhost", port=6333)
query = "如何使用Forguncy进行数据可视化?"
product = "forguncy"
results = search_sementic_hybrid(client, query, product)
for hit in results:
print(hit.payload, hit.score)
总结
search.py
通过对 Qdrant 多模态检索能力的深度封装,实现了高效、灵活、健壮的语义检索服务。其设计兼顾了多源数据融合、检索准确性、系统可扩展性和异常容错性,是构建智能知识检索系统不可或缺的基础模块。