Qdrant 中的相关性反馈
| 时间:30分钟 | 难度:中等 | 输出:GitHub |
|---|
在 Qdrant 1.17 版本中,我们引入了全新的相关性反馈查询 (Relevance Feedback Query),这是我们首个原生支持向量索引的、可扩展的检索方案,用于在检索过程中整合相关性反馈。
在本教程中,您将学习如何:
- 针对您的 Qdrant 集合、检索器和反馈模型自定义相关性反馈查询。
- 将自定义的相关性反馈查询添加到您的搜索流水线中。
- 评估它为该流水线带来的性能提升。
相关性反馈
相关性反馈将有关当前搜索结果相关性的信号提炼出来,并反馈到下一次检索迭代中,从而随着时间的推移呈现出更好的结果。
相关性反馈查询利用模型对搜索结果生成的一小部分反馈,在下一次检索迭代时引导检索器遍历整个向量空间,从而将搜索导向更相关的结果。
有关其工作原理的详细描述,请参阅文章《Qdrant 中的相关性反馈》。

策略
要在向量空间中利用反馈引导检索器,有几种可能的策略。目前,仅提供朴素策略 (naive strategy)——即一种根据反馈调整相似度评分的简单的三参数公式。
为了使该策略发挥良好效果,该朴素公式的参数应针对您的数据、检索器和反馈模型进行自定义。为方便起见,我们提供了一个 qdrant-relevance-feedback Python 包,它可为您提供适用于您应用场景的相关参数。
本教程将演示如何将其与相关性反馈查询 API 配合使用。
针对您的应用场景进行自定义
设置
安装上述软件包(它会自动安装 Qdrant Client 作为其依赖项):
pip install qdrant-relevance-feedback
我们将使用 Qdrant 云免费层级集群(确保版本在 1.17.0 以上),并利用该免费层级集群提供的免费嵌入推理 (Free Embedding Inference)。
创建一个 Qdrant 免费层级集群并初始化 Qdrant Client。
from qdrant_client import QdrantClient
client = QdrantClient(
url=<QDRANT_URL>,
api_key=<QDRANT_API_KEY>,
cloud_inference=True # to be able to use free embedding inference on Qdrant Cloud, for convenience & to reduce latency
)
数据集
我们将使用 Qdrant 集群 UI 中提供的数据集之一。
- 前往 Cluster UI -> Datasets(数据集)。
- 在其中的 3 个数据集中,选择第一个,“Qdrant Web Documentation”。它由来自我们文档网站的短文本片段组成。
- 按下
Import(导入)按钮,输入集合名称——documentation。

几秒钟后,您应该会看到一条绿色的状态提示 “Snapshot successfully imported”(快照导入成功),并且在所有集合列表中会出现一个名为 documentation 的集合。
现在我们有了一个可以操作并优化语义搜索的集合。
COLLECTION_NAME = "documentation"
检索器
检索器是一个嵌入模型,它将您的原始数据转换为用于语义相似度搜索的向量。相关性反馈查询将帮助您优化检索器在数据中查找相关结果的能力。
我们的检索器已由集合定义——正如数据集“VECTORS CONFIG”上的 all-MiniLM-L6-v2 标签所示,集合中的向量是使用 all-MiniLM-L6-v2 模型生成的。
让我们在 qdrant-relevance-feedback 框架中定义它。
from qdrant_relevance_feedback.retriever import QdrantRetriever
retriever = QdrantRetriever("sentence-transformers/all-minilm-l6-v2")
QdrantRetriever 支持所有 Qdrant 云推理和 FastEmbed 模型,而
all-MiniLM-L6-v2包含在 Qdrant 免费层级云推理中。您也可以定义并提供自定义检索器。
查看集合中的一个点是什么样的。

我们的文档集合中每个点只有一个向量——Default vector。然而,在 Qdrant 中,每个点可以拥有多个命名向量。
我们需要提供与我们要通过反馈优化的检索器相关联的向量名称。
RETRIEVER_VECTOR_NAME = None # None if it's a default vector or your named vector handle in Qdrant's collection
我们还需要将框架指向使用我们的检索器模型向量化的原始数据。在这里,原始数据是点有效载荷 (payload) 中的 text 字段。简单来说,我们是在 text 片段的向量化形式上进行搜索。
PAYLOAD_KEY = "text"
如果您的原始数据存储在 Qdrant 之外的其他地方,您可以在 qdrant-relevance-feedback 中重新定义 payload_retrieval 部分。
反馈模型
反馈模型会查看检索器提供的结果,并对其相关性进行评分。随后,检索器会通过相关性反馈查询接口利用此反馈,在向量空间中更好地定位,并呈现更相关的文档。
在本教程中,作为反馈模型的提供者,我们将使用 Qdrant 的轻量级推理库 FastEmbed。
pip install fastembed
由于 all-MiniLM-L6-v2 是一个小模型(仅 384 维)且性能较弱,我们不必选择过于强大或昂贵的反馈模型。这样一个小型检索器无论如何也不会对复杂的反馈做出灵敏响应。
因此,为简单起见,我们可以使用一个维度更大的双编码器(bi-encoder),例如 1024 维的 mxbai-embed-large-v1。
from qdrant_relevance_feedback.feedback import FastembedFeedback
feedback = FastembedFeedback("mixedbread-ai/mxbai-embed-large-v1")
此代码将下载 mxbai-embed-large-v1 用于本地推理。
我们为 FastembedFeedback 提供了所有 FastEmbed 模型。不过,您也可以定义并提供自定义的反馈模型。它可以是任何模型:双编码器、后期交互模型 (late interaction model)、交叉编码器 (cross-encoder) 或大语言模型 (LLM)。
接入集合、检索器和反馈模型
现在一切准备就绪:检索器、集合、反馈模型。
from qdrant_relevance_feedback import RelevanceFeedback
relevance_feedback = RelevanceFeedback(
retriever=retriever,
feedback=feedback,
client=client,
collection_name=COLLECTION_NAME,
vector_name=RETRIEVER_VECTOR_NAME,
payload_key=PAYLOAD_KEY
)
我们可以运行一个小型的训练过程,它将收集数据并为这个三元组调整相关性反馈查询参数(naive strategy)。
培训
训练数据
相关性反馈公式对数据的拟合程度取决于训练数据的数量和质量(对于您的用例来说它有多真实)。
通常,我们只需要很少量的数据(50-300 个查询就足够了),因为我们只需要训练 3 个参数。
我们使用 Claude Code 生成了 50 个查询,提示词为:“生成 50 个短搜索查询(每个 3-10 个单词),供开发人员在浏览 Qdrant 网站时可能输入的内容。”。
训练查询
train_queries = [
"qdrant filtering nested object payload",
"vector database for fraud detection",
"qdrant golang client example",
"sparse dense fusion ranking qdrant",
"qdrant write ahead log explained",
"sentence transformers qdrant integration",
"qdrant ef_construct m parameter tuning",
"music recommendation engine vector search",
"qdrant on kubernetes helm chart",
"qdrant payload index types keyword integer",
"qdrant segment optimizer internals",
"content moderation with embeddings",
"qdrant point struct fields",
"zero shot classification vector database",
"qdrant telemetry prometheus grafana",
"document deduplication vector similarity",
"qdrant replication factor setup",
"llama index qdrant integration",
"qdrant single node vs distributed",
"news article clustering embeddings",
"qdrant read consistency levels",
"face recognition vector search",
"qdrant timeout configuration tuning",
"langchain qdrant vector store",
"qdrant exact search brute force",
"job matching semantic search qdrant",
"qdrant shard transfer rebalancing",
"openai embeddings qdrant tutorial",
"qdrant versioning API changelog",
"patent search vector database use case",
"qdrant cohere embeddings example",
"customer support ticket routing qdrant",
"qdrant memory mapped files",
"multilingual search qdrant embeddings",
"qdrant indexing speed optimization",
"code search semantic embeddings qdrant",
"qdrant terraform cloud infrastructure",
"reducing hallucinations LLM qdrant grounding",
"qdrant aws deployment guide",
"long document search chunking qdrant",
"qdrant community discord forum",
"e-learning personalization vector search",
"qdrant concurrent requests handling",
"graph neural networks vector store",
"qdrant enterprise security features",
"product catalog search qdrant retail",
"qdrant contributing open source guide",
"time series anomaly vector embeddings",
"qdrant gRPC vs REST performance",
"qdrant vector search instagram feed ranking",
]
控制训练数据大小的另一个参数是我们为每个查询从集合中检索多少个响应。
TRAIN_LIMIT = 25
TRAIN_LIMIT 越大,我们的公式获得的训练数据就越多,但训练的开销和耗时也会增加。
对于训练,我们需要反馈模型提供真实的相关性评分,因此它会重新计算 #查询 * TRAIN_LIMIT,此处为 50 * 25 = 1250 对查询-文档对。请根据您的训练预算进行调整。
训练过程
现在我们可以运行训练:
formula_params = relevance_feedback.train(
queries=train_queries,
limit=TRAIN_LIMIT,
)
您将看到一个在 50 个查询上运行的“Building training data”(构建训练数据)过程。此外,该框架还会为您提供完整性检查,类似如下:
On 22.00% of training queries the feedback model strongly disagreed with the retriever model.
如果反馈模型在所有情况下都与您的检索器意见一致(如果百分比为 0.00),那么使用所选设置进行基于相关性反馈的检索意义不大,请考虑更改设置。
经过极速的训练后,您将获得参数,类似如下:
Naive formula params: a=0.240764, b=1.348897, c=0.590883
这些是针对我们的 documentation 集合、all-MiniLM-L6-v2 检索器和 mxbai-embed-large-v1 反馈模型自定义的参数。
现在,您可以使用您选择的任何客户端将其用于基于相关性反馈的检索。
将相关性反馈查询添加到搜索流水线
让我们看看如何在此应用场景中将相关性反馈查询引入检索流水线。
原因:假设您正在使用 all-MiniLM-L6-v2 支持文档搜索,因为它非常便宜且快速,但它往往不能提供足够相关的结果,而且您知道文档中存在比 all-MiniLM-L6-v2 所能获取到的更相关的部分。
例如,让我们看看这个查询:
query = "recommendations API how to use"
1. 初始原始检索
我们像通常在搜索应用程序中所做的那样,使用检索器运行简单的语义相似度搜索。
query_embedding = retriever.embed_query(query)
CONTEXT_LIMIT = 3
responses = client.query_points(
collection_name=COLLECTION_NAME,
query=query_embedding,
with_payload=True,
with_vectors=True,
limit=CONTEXT_LIMIT,
using=RETRIEVER_VECTOR_NAME,
).points
让我们看看得到什么结果:
responses_raw = [r.payload[PAYLOAD_KEY] for r in responses]
print("\n--- Initial Retrieval Results ---")
for i, text in enumerate(responses_raw, 1):
print(f" [{i}] {text[:200]}")
print()
我们将得到类似这样的结果:
--- Initial Retrieval Results ---
[1] Recommendation API
[2] recommendation API.
[3] So, even when the API is not called recommend, recommendation systems can also use this approach and adapt it for their specific use-cases.
我们看到了重复内容,因为我们的集合由文档网站的片段组成,某些文本在不同章节中是相同的。
这虽然有效,但或许在我们的集合中还有其他内容能更好地回答该查询——只是检索器太弱而无法捕捉到它。
2. 获取初始检索的反馈
现在,我们从 mxbai-embed-large-v1 反馈模型那里获取关于查询 “recommendations API how to use” 的前 3 个结果的反馈。
反馈模型根据其对语义相似度的判断对它们进行重新评分。我们只向它展示少量结果(CONTEXT_LIMIT = 3),以保持流水线的快速和低成本。
feedback_model_scores = feedback.score(query, responses_raw)
3. 基于相关性反馈的检索
现在,我们可以利用 3 个初始检索到的响应反馈,来增强我们的 all-MiniLM-L6-v2 检索器。
我们将反馈作为 (示例, 分数) 对的列表提供。在底层,这使用了文章中描述的上下文对挖掘机制。
from qdrant_client import models
responses_point_ids = [p.id for p in responses] # CONTEXT_LIMIT responses from initial vanilla retrieval (their point IDs)
#responses_vectors = [p.vector for p in responses]
relevance_feedback_responses = client.query_points(
collection_name=COLLECTION_NAME,
query=models.RelevanceFeedbackQuery(
relevance_feedback=models.RelevanceFeedbackInput(
target=query_embedding,
feedback=[
models.FeedbackItem(example=example, score=score)
for example, score in zip(responses_point_ids, feedback_model_scores) # or zip(responses_vectors, feedback_model_scores)
],
strategy=models.NaiveFeedbackStrategy(
naive=models.NaiveFeedbackStrategyParams(**formula_params) # our parameters from above
),
)
),
with_payload=True,
limit=3,
using=RETRIEVER_VECTOR_NAME,
).points
让我们看看基于相关性反馈的检索带来了什么:
relevance_feedback_responses_raw = [r.payload[PAYLOAD_KEY] for r in relevance_feedback_responses]
print("\n--- Additional Results from Relevance Feedback-based Retrieval ---")
for i, text in enumerate(relevance_feedback_responses_raw, 1):
print(f" [{i}] {text[:200]}")
print()
它应该返回类似这样的结果:
--- Additional Results from Relevance Feedback-based Retrieval ---
[1] Recap of the old recommendations API
[2] The result of this API contains one array per recommendation requests.
[3] Deliver Better Recommendations with Qdrant's new API
4. 结合所有步骤
现在,您可以以不同的方式使用相关性反馈查询结果:
- 与初始检索相结合,例如,使用反馈模型对两个结果集的并集进行重排序。
- 用作您的主要结果,即依赖相关性反馈查询作为搜索结果的主要来源。
该方法取决于您在 FeedbackItem(或其它客户端中的类似项)的 example 字段中传递的内容:是检索器生成的原始嵌入,还是集合中的点 ID。
如果您传递点 ID 作为
example,这些点会自动从结果中排除。要将它们包含在其他点中,请传递原始向量(请参阅注释掉的responses_vectors)而不是点 ID。
评估
经验表明,上述查询的相关性反馈查询结果看起来是相关的。然而我们可以想象,这可能不足以证明为您流水线增加额外复杂性的必要性。
我们发布的框架还提供了一个评估模块。
同样,我们生成了一组测试查询。
测试查询
test_queries = [
"how to install qdrant locally",
"qdrant vector similarity search",
"qdrant HNSW filtering vs pre-filtering performance",
"qdrant payload filtering and indexing",
"qdrant docker setup",
"cosine similarity vs dot product qdrant",
"qdrant REST API authentication",
"batch upsert vectors qdrant",
"qdrant cloud deployment",
"scalar quantization qdrant",
"qdrant internals storage engine blog post",
"delete points by filter qdrant",
"qdrant named vectors",
"sparse vectors qdrant",
"qdrant scroll points pagination",
"what is a vector database",
"qdrant vs pinecone comparison",
"semantic search tutorial qdrant",
"RAG pipeline with qdrant",
"recommendations API how to use",
"qdrant use cases e-commerce sparse vectors",
"multimodal search images text qdrant",
"qdrant performance benchmarks",
"how vector search works explained",
"qdrant hybrid search blog",
"building chatbot with qdrant",
"qdrant new features release",
"neural search vs keyword search",
"qdrant fastembed integration tutorial",
"anomaly detection vector database",
"qdrant customer success story",
"LLM memory storage qdrant",
"qdrant product quantization explained",
"qdrant scalar vs product quantization comparison",
"qdrant binary quantization blog post",
"chunking strategies for RAG qdrant blog",
"qdrant JavaScript TypeScript SDK",
"real time vector search qdrant",
"qdrant rust performance internals",
"open source vector database comparison",
"qdrant snapshot backup restore",
"image search with qdrant clip",
"qdrant geo filtering use case",
"drug discovery vector search qdrant",
"qdrant multitenant architecture",
"on premise vs cloud vector database",
"qdrant web UI dashboard",
"qdrant funding news announcement",
"fine tuning embeddings qdrant",
"getting started vector search beginner",
]
现在,让我们在这个测试集上运行评估,看看在反馈模型每个查询接收 CONTEXT_LIMIT 个结果以提供反馈的情况下,我们获得了多少收益。
from qdrant_relevance_feedback.evaluate import Evaluator
N = 10 # as in metric@N
evaluator = Evaluator(relevance_feedback=relevance_feedback)
results = evaluator.evaluate_queries(
at_n=N,
formula_params=formula_params, # from above
eval_queries=test_queries,
eval_context_limit=CONTEXT_LIMIT # from above
)
我们将获得类似如下的输出,提供 相对结果相关性增益 和 N (此处为 10) 处的折扣累积增益 (DCG) 胜率。
On the 2nd retrieval iteration, over this test set:
Relevance feedback retrieval surfaced 44 more relevant results (according to the feedback model)
Vanilla retrieval surfaced 39 more relevant results (according to the feedback model)
Relative results relevance gain over this test set is: 12.82051282051282%
DCG win rates (which approach ranks results better):
Vanilla retrieval: 38.0% wins
Relevance feedback retrieval: 48.0% wins
Ties: 14.0%
相对结果相关性增益:在这 50 个生成的测试查询集上,基于相关性反馈的检索从集合中多拉取了 5 个(44 - 39)相关文档,这是原始检索无法“察觉”到的——比原始检索提升了 13%。
DCG 胜率:在约一半的查询(48%)中,基于相关性反馈的检索在评估窗口 N 内的结果排名优于原始检索器。在 14% 的查询中,两种方法相同;而在 38% 的查询中,相关性反馈误导了检索器。
关于这些指标的详细说明,请参阅文章,其中包含配套的可视化图表。
结论
在本教程中,我们演示了如何对文本数据使用相关性反馈,以提高检索流水线中的结果相关性。以下是需要记住的要点:
- 适应您的数据——适用于不同模态,不仅限于文本。例如,您可以对图像进行相同的操作。
- 灵活的模型选择——您可以使用我们在云推理和 FastEmbed 中支持的预定义检索器和反馈模型,或者定义您自己的模型,任何东西都可以,包括大语言模型和自定义 LTR 模型。
- 内置评估——使用我们的框架,您还可以在投入生产之前评估使用相关性反馈查询的潜在收益。
如果您想了解有关相关性反馈查询用法的建议,或者对如何增强该方法有想法,请在我们的 Discord 社区中与我们联系。