步骤三:实现检索模块 (Retriever Implementation)
⽬标: 根据⽤⼾的查询 (query),从已经构建好的向量数据库中检索出 top_k 个最相关的⽂本块,这些⽂本块将作为后续LLM⽣成答案的上下⽂。
具体操作:
1. ⽤⼾查询向量化: 这⼀步通常由LangChain的Retriever对象在内部封装。当我们调⽤检索器时,它会⾃动使⽤与索引构建时相同的Embedding模型来向量化⽤⼾的查询。
2. 执⾏相似度搜索: LangChain中的VectorStore对象本⾝就可以很⽅便地转换成⼀个Retriever。
# 假设前⾯的 vector_db (Chroma实例) 已经成功创建或加载
if vector_db:
user_query = "RAGFlow的核⼼特性有哪些?"
k_results = 3 # 我们希望检索最相关的3个⽂档块
# 将ChromaDB实例包装成⼀个Retriever对象
# search_type默认为"similarity",也可以指定为"mmr" (Maximal Marginal Releva
# search_kwargs⽤于传递给底层向量存储的搜索参数,如k
retriever = vector_db.as_retriever(search_kwargs={"k": k_results})
print(f"\n为查询 '{user_query}' 配置的检索器将返回 {k_results} 个结果。")
try:
# 执⾏检索
# invoke是LCEL推荐的⽅法, get_relevant_documents是旧版但仍可⽤
relevant_docs: List[Document] = retriever.invoke(user_query)
print(f"\n成功检索到 {len(relevant_docs)} 个相关⽂档块:")
for i, doc in enumerate(relevant_docs):
print(f"\n--- 相关⽂档 {i+1} ---")
# ChromaDB的as_retriever可能不直接在metadata中返回score,# 如果需要分数,可能要⽤ vector_db.similarity_search_with_score()
# print(f"Score: {doc.metadata.get('score', 'N/A')}") # ⽰例,实际
print(f"来源: {doc.metadata.get('source', '未知')}, 块起始位置: {do
print(f"内容: {doc.page_content}")
except Exception as e:
print(f"检索失败: {e}")
relevant_docs = [] # 初始化为空列表
else:
print("\n向量数据库未初始化,⽆法执⾏检索。")
relevant_docs = [] # 初始化为空列表
说明: vector_db.as_retriever() ⽅法⾮常便捷,它将我们的ChromaDB实例转换成了⼀个标准的LangChain Retriever对象。通过 search_kwargs={"k": k_results} ,我们指定了希望检索的⽂档块数量。检索操作返回的是⼀个 Document 对象列表,每个对象包含了其原始内容 page_content 和元数据 metadata (例如来源⽂件名)。这些⽂档块将作为LLM⽣成答案的关键上下⽂。