DeepEval 怎么把 Qdrant 等向量数据库接入 RAG 评估流程?
【免费下载链接】deepevalThe LLM Evaluation Framework项目地址: https://gitcode.com/GitHub_Trending/de/deepeval
如果你的 RAG 系统用 Qdrant(或 PGVector)作为检索引擎,想量化"检索这一步到底行不行"——换 embedding 模型、调 top-K、改向量维度之后效果是变好还是变差——DeepEval 的做法是把检索结果组织成LLMTestCase,再用ContextualRecallMetric、ContextualPrecisionMetric、ContextualRelevancyMetric三个上下文指标对检索器打分。这三个指标分别对应检索链路中的 reranker 排序质量、embedding 模型的信息捕获能力、以及 chunk 大小和 top-K 的合理性,官方建议三个一起用以获得全面的检索评估结果(见 RAG Evaluation 指南)。
下面以 Qdrant 为主路径走通一遍:建集合、写入嵌入、构造测试用例、跑评估,最后说明同一套评估流程如何平移到 PGVector 这类其他向量数据库。
准备条件
按 Qdrant 集成文档 和 RAG Evaluation 指南 的要求,你需要:
已安装
deepeval、qdrant-client和sentence-transformers的 Python 环境。Qdrant 文档给出的安装命令:pip install qdrant-client一个本地或云端的 Qdrant 实例。本地实例默认地址是
http://localhost:6333,用 Qdrant Cloud 时替换成对应 URL。你的 RAG 流水线中生成
actual_output的 LLM。文档示例中写作generate(prompt),并注明 "hypothetical function, replace with your own LLM",即换成你自己的生成函数。一组带
input/expected_output的查询。expected_output充当 ground truth,是ContextualPrecisionMetric和ContextualRecallMetric打分所需的参照。
第一步:搭建 Qdrant 检索端
连接客户端,按文档说明提供 URL:
import qdrant_client import os client = qdrant_client.QdrantClient( url="http://localhost:6333" # Change this if using Qdrant Cloud )创建集合时指定向量维度和距离函数。示例中用 384 维、余弦相似度(all-MiniLM-L6-v2的输出维度正好是 384;如果你换 embedding 模型,这两个参数要跟着模型输出维度一起改,后面"调优"一节也会提到这一点):
# Define collection name collection_name = "documents" # Create collection if it doesn't exist if collection_name not in [col.name for col in client.get_collections().collections]: client.create_collection( collection_name=collection_name, vectors_config=qdrant_client.http.models.VectorParams( size=384, # Vector dimensionality distance="cosine" # Similarity function ), )把文档 chunk 嵌入后以PointStruct写入,文本 chunk 放在payload的text字段:
# Load an embedding model from sentence_transformers import SentenceTransformer model = SentenceTransformer("all-MiniLM-L6-v2") # Example document chunks document_chunks = [ "Qdrant is a vector database optimized for fast similarity search.", "It uses HNSW for efficient high-dimensional vector indexing.", "Qdrant supports disk-based storage for handling large datasets.", ... ] # Store chunks with embeddings for i, chunk in enumerate(document_chunks): embedding = model.encode(chunk).tolist() # Convert text to vector client.upsert( collection_name=collection_name, points=[ qdrant_client.http.models.PointStruct( id=i, vector=embedding, payload={"text": chunk} ) ] )这里document_chunks是文档中的示例值,实际接入时换成你自己知识库的 chunk。
第二步:准备 LLMTestCase
评估的前提是有可核对的四元组:input、actual_output、expected_output、retrieval_context。其中retrieval_context必须真实来自你的检索端,所以先定义一个search函数,用与入库时相同的 embedding 模型把查询编码,取 top 3 最相似结果:
def search(query, top_k=3): query_embedding = model.encode(query).tolist() search_results = client.search( collection_name=collection_name, query_vector=query_embedding, limit=top_k # Retrieve the top K most similar results ) return [hit.payload["text"] for hit in search_results] if search_results else None query = "How does Qdrant work?" retrieval_context = search(query)再把检索结果插进 prompt 模板,生成actual_output(下面是文档示例,generate需替换为你自己的 LLM 调用):
prompt = """ Answer the user question based on the supporting context User Question: {input} Supporting Context: {retrieval_context} """ actual_output = generate(prompt) # hypothetical function, replace with your own LLM最后组装测试用例。文档中这条用例的input是"How does Qdrant work?",对应的expected_output是"Qdrant performs fast and scalable vector search using HNSW indexing and disk-based storage.":
from deepeval.test_case import LLMTestCase test_case = LLMTestCase( input=input, actual_output=actual_output, retrieval_context=retrieval_context, expected_output="Qdrant is a powerful vector database optimized for semantic search and retrieval.", )一个容易踩的坑:input只放原始用户输入,不要把整个 prompt 模板塞进去——prompt 模板本身就是你要优化的独立变量。这一点在 RAG Evaluation 指南 中被明确标注为 caution。
第三步:运行检索评估
定义三个上下文指标,然后调用evaluate:
from deepeval import evaluate from deepeval.metrics import ( ContextualRecallMetric, ContextualPrecisionMetric, ContextualRelevancyMetric, ) contextual_recall = ContextualRecallMetric() contextual_precision = ContextualPrecisionMetric() contextual_relevancy = ContextualRelevancyMetric() evaluate( [test_case], metrics=[contextual_recall, contextual_precision, contextual_relevancy] )测试用例多时,把[test_case]换成用例列表批量跑即可。想逐条查看分数和原因时,指南给出的方式是单个指标直接measure:
contextual_precision.measure(test_case) print("Score: ", contextual_precision.score) print("Reason: ", contextual_precision.reason)另外,所有指标都支持设置threshold(低于阈值即不通过)、strict_mode和include_reason,并可以用任意 LLM 作为评判模型。如果你还想评估生成端而不只是检索端,RAG 指南给出的组合是再加上AnswerRelevancyMetric和FaithfulnessMetric,与三个上下文指标一起传入evaluate做端到端评估。
其他向量数据库:PGVector 走同一套评估流程
标题里的"等"主要指 PGVector,官方 PGVector 集成文档 与 Qdrant 文档是同构的:检索端搭建换成 PostgreSQL 侧,评估端完全不变。
检索端差异在于用psycopg2连接、启用扩展并建带vector(384)列的表(安装命令为pip install psycopg2 pgvector):
# Enable the pgvector extension (only needed once) cursor.execute("CREATE EXTENSION IF NOT EXISTS vector;") # Define table schema for text and embeddings cursor.execute(""" CREATE TABLE IF NOT EXISTS documents ( id SERIAL PRIMARY KEY, text TEXT, embedding vector(384) -- Defines a 384-dimension vector ); """) conn.commit()相似度检索改为 SQL,<->算子按文档注释用于余弦相似度排序:
def search(query, top_k=3): query_embedding = model.encode(query).tolist() cursor.execute(""" SELECT text FROM documents ORDER BY embedding <-> %s -- Use <-> for cosine similarity LIMIT %s; """, (query_embedding, top_k)) return [row[0] for row in cursor.fetchall()]拿到retrieval_context和actual_output之后,构造LLMTestCase和调用evaluate的代码与 Qdrant 路径一致。也就是说,评估流程与底层向量库无关,你只需要把search函数指向自己的向量库即可;可优化的超参数也随之对应——Qdrant 侧是size、distance、limit,PGVector 侧是LIMIT和 embedding 模型。
仓库里还有一个可运行的完整示例 rag_evaluation_with_qdrant.py:它从数据集加载文档、用RecursiveCharacterTextSplitter切块、通过 Qdrant Cloud 的client.add(基于 FastEmbed 生成嵌入)写入集合,再用atitaarora/qdrant_doc_qna数据集的问答对批量构造LLMTestCase,最后一次性跑AnswerRelevancyMetric、FaithfulnessMetric加三个上下文指标。该脚本需要按文件头部注释替换OPENAI_API_KEY、CONFIDENT_AI_API_KEY、QDRANT_URL、QDRANT_API_KEY等占位符,并安装datasets、langchain、langchain-text-splitters、openai、qdrant-client、deepeval等依赖;其中 Confident AI 的 key 用于把评估结果记录到平台,若只想本地跑评估可以只参考其构造用例与调用evaluate的部分。
分数不理想时调哪些参数
Qdrant 文档给出了一个 Contextual Precision 偏低的示例场景(下表数值是文档中的示例结果,仅用于说明现象,不是固定预期):
| Query | Contextual Precision Score | Contextual Recall Score |
|---|---|---|
| "How does Qdrant store vector data?" | 0.39 | 0.92 |
| "Explain Qdrant's indexing method." | 0.35 | 0.89 |
| "What makes Qdrant efficient for retrieval?" | 0.42 | 0.83 |
Precision 低意味着检索回了相关 context,但其中一些并非与查询最匹配的块,给生成端引入了噪声。文档给出的三个改进方向:
- 换更贴合领域的 embedding 模型。
all-MiniLM-L6-v2是通用模型,技术文档场景可测试BAAI/bge-small-en(检索排序)、sentence-transformers/msmarco-distilbert-base-v4(稠密段落检索)、nomic-ai/nomic-embed-text-v1(长文档检索)。 - 保持向量维度一致。换模型后 Qdrant 集合里的向量维度必须与模型输出匹配,否则会对不上。
- 用元数据过滤。对查询附加 metadata filters 可以排除拉偏 precision 的无关 chunk。
PGVector 文档对低 precision 的建议类似:换领域 embedding 模型,以及调整检索查询里的LIMIT控制返回条数。
调整后的验证方式:重新生成一批测试用例、再跑一遍evaluate,重点盯 Contextual Precision 是否上升。如果要系统对比多组 embedding 模型或超参数组合,指南给出的做法是先deepeval login登录 Confident AI,再用@deepeval.log_hyperparameters把每次运行的 embedding 模型、chunk size、top-K 等参数记录下来,在平台上按配置维度看分数变化。
边界与限制
- 三个上下文指标评估的是检索器;
ContextualPrecisionMetric和ContextualRecallMetric依赖expected_output作为 ground truth,没有标注答案时可用 RAG 指南提到的 RAG triad(AnswerRelevancyMetric、FaithfulnessMetric、ContextualRelevancyMetric)做无参照评估。 - Qdrant 文档示例使用
client.search/client.add等 API,具体可用方法以你安装的qdrant-client版本为准;示例中QdrantClient(url=...)的本地/云端切换只体现在 URL 一个参数上。 - 本文只覆盖单轮(单查询-单检索-单生成)场景。多轮 RAG 需要改用
ConversationalTestCase和Turn*系列指标,retrieval_context挂在每个Turn上,属于另一条评估路径。
更多向量库(Chroma、Weaviate、Elasticsearch、Cognee 等)的集成页在同一目录下,评估侧的接法与本文一致:把检索端换成对应数据库,复用LLMTestCase+ 上下文指标的部分。
【免费下载链接】deepevalThe LLM Evaluation Framework项目地址: https://gitcode.com/GitHub_Trending/de/deepeval
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考