在信息检索系统中,检索器通常会返回一组 Document 对象,这些对象默认情况下不包含关于检索过程的信息,例如与查询的相似度分数。在本文中,我们将演示如何将检索分数添加到文档的元数据中。我们将探讨以下两种情况:
- 从向量存储检索器获取分数。
- 从高阶 LangChain 检索器(如
SelfQueryRetriever或MultiVectorRetriever)获取分数。
对于第一种情况,我们将实现一个简单的包装函数来调用相应的向量存储库。对于第二种情况,我们将更新相应类的方法,以实现功能增强。
创建向量存储
首先,我们使用一些数据填充一个向量存储。在这里,我们将使用 PineconeVectorStore,但此指南也适用于实现 similarity_search_with_score 方法的任何 LangChain 向量存储。
from langchain_core.documents import Document
from langchain_openai import OpenAIEmbeddings
from langchain_pinecone import PineconeVectorStore
docs = [
Document(
page_content="A bunch of scientists bring back dinosaurs and mayhem breaks loose",
metadata={"year": 1993, "rating": 7.7, "genre": "science fiction"},
),
Document(
page_content="Leo DiCaprio gets lost in a dream within a dream within a dream within a ...",
metadata={"year": 2010, "director": "Christopher Nolan", "rating": 8.2},
),
# 更多文档...
]
vectorstore = PineconeVectorStore.from_documents(
docs, index_name="sample", embedding=OpenAIEmbeddings()
)
实现检索器函数
为了从向量存储检索器中获取分数,我们将包装底层向量存储的 similarity_search_with_score 方法,并将分数添加到相关文档的元数据中。
from typing import List
from langchain_core.documents import Document
from langchain_core.runnables import chain
@chain
def retriever(query: str) -> List[Document]:
docs, scores = zip(*vectorstore.similarity_search_with_score(query))
for doc, score in zip(docs, scores):
doc.metadata["score"] = score
return docs
# 使用自定义检索器
result = retriever.invoke("dinosaur")
print(result)
# 输出包含检索分数的文档列表
高阶检索器实现
对于 SelfQueryRetriever 和类似的高阶检索器,我们可以通过子类化并重载特定方法来传播相似度分数。
自定义 SelfQueryRetriever
我们需要重载 _get_docs_with_query 方法,以使用 similarity_search_with_score 方法从向量存储中获取相似度分数,并将其添加到文档的元数据中。
from typing import Any, Dict
from langchain.retrievers.self_query.base import SelfQueryRetriever
class CustomSelfQueryRetriever(SelfQueryRetriever):
def _get_docs_with_query(
self, query: str, search_kwargs: Dict[str, Any]
) -> List[Document]:
docs, scores = zip(
*vectorstore.similarity_search_with_score(query, **search_kwargs)
)
for doc, score in zip(docs, scores):
doc.metadata["score"] = score
return docs
# 示范调用
retriever = CustomSelfQueryRetriever(
llm=ChatOpenAI(temperature=0),
vectorstore=vectorstore,
document_content_description="Brief summary of a movie",
metadata_field_info=[
# 指定元数据信息
]
)
result = retriever.invoke("dinosaur movie with rating less than 8")
print(result)
实践建议
在应用这些实现时,确保你的向量存储已优化,能够快速计算相似度得分。通过为元数据添加相似度分数,你可以更好地分析和调试检索结果。
结束语:如果遇到问题欢迎在评论区交流。
—END—
1503

被折叠的 条评论
为什么被折叠?



